You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MATLAB中MILP家用负载最小运行时间约束添加及代码问题排查

Hey,咱们来搞定你遇到的问题——为啥设备1的运行时长会超出设定的2小时限制。核心问题出在总运行时长约束的求和逻辑上,我会一步步帮你排查修复,顺便优化下代码的可读性:

问题根源与修复方案

1. 最关键的错误:总运行时长约束的求和方向错了

你代码里的这段约束:

powerprob.Constraints.C1=sum(A.*VV)==D;

这里的sum(A.*VV)会把整个矩阵的所有元素加起来得到一个标量,然后和长度为3的向量D做比较,MATLAB虽然不会报错,但逻辑完全不对——我们需要的是对每个设备(每一列)单独计算总运行时长,也就是按行方向求和:

powerprob.Constraints.C1 = sum(A.*VV, 1) == D;

sum(...,1)表示对每一列求和,这样就能保证每个设备的总运行时长严格等于D中对应的数值(设备1=2小时,设备2=2小时,设备3=3小时)。

2. 最小运行时间约束的优化

你原来的最小运行时间约束写得有点绕,其实可以更直接地表达逻辑:如果设备在第kk小时启动(A(kk,jj)=1),那么接下来的MinUpTimeM(jj)小时必须保持运行;同时,不能在最后不足最小运行时间的时间段启动设备。修改后的约束代码如下:

MinUpTimeM = [2 1 1];
powerprob.Constraints.D1 = optimconstr(6,3);
for jj = 1:3
    % 启动后必须连续运行指定时长
    for kk = 1:6 - MinUpTimeM(jj) + 1
        powerprob.Constraints.D1(kk,jj) = sum(A(kk:kk+MinUpTimeM(jj)-1, jj)) >= MinUpTimeM(jj)*A(kk,jj);
    end
    % 最后几个小时无法满足完整最小运行时间,禁止启动
    for kk = max(1, 6 - MinUpTimeM(jj) + 2) : 6
        powerprob.Constraints.D1(kk,jj) = A(kk,jj) == 0;
    end
end

3. 简化VV矩阵的构造

原来的嵌套循环可以简化成更易读的代码,逻辑和原来完全一致:

TstartM = [2 3 1]; % 各设备启动时间窗口起始
TfinishM = [5 5 4 ]; % 各设备启动时间窗口结束
DurationM = [1 1 1];
V = zeros(3,3);
for jj = 1:3
    V(TstartM(jj):TfinishM(jj), jj) = DurationM(jj);
end
VV = cat(1, V, V); % 扩展为6小时的时间窗口

4. 修复后的完整代码

把所有修改整合后的完整代码如下:

powerprob = optimproblem; 
E = [3 2 3 5 2 3 ]; % 各时段电价
P = [0.5 1 0.5]; % 各设备功率
D = [2 2 3]; % 各设备总运行时长要求

% 构建设备运行时间窗口矩阵
TstartM = [2 3 1]; 
TfinishM = [5 5 4 ]; 
DurationM = [1 1 1];
V = zeros(3,3);
for jj = 1:3
    V(TstartM(jj):TfinishM(jj), jj) = DurationM(jj);
end
VV = cat(1, V, V); % 扩展为6小时的时间窗口

% 定义优化变量
Pgrid = optimvar('Pgrid',6,1,'LowerBound',0,'UpperBound',7); % 电网购电功率
A = optimvar('A',6,3,'Type','integer','LowerBound',0,'UpperBound',1); % 设备启停状态(0=关,1=开)

% 计算小时负载与目标函数
HLD = ((A.*VV)*P'); % 各时段设备总负载
gridcost = sum((Pgrid).*E'); 
powerprob.Objective = gridcost; 

% 最小运行时间约束
MinUpTimeM = [2 1 1];
powerprob.Constraints.D1 = optimconstr(6,3);
for jj = 1:3
    % 启动后必须连续运行指定时长
    for kk = 1:6 - MinUpTimeM(jj) + 1
        powerprob.Constraints.D1(kk,jj) = sum(A(kk:kk+MinUpTimeM(jj)-1, jj)) >= MinUpTimeM(jj)*A(kk,jj);
    end
    % 最后不足最小运行时间的时段禁止启动
    for kk = max(1, 6 - MinUpTimeM(jj) + 2) : 6
        powerprob.Constraints.D1(kk,jj) = A(kk,jj) == 0;
    end
end

% 总运行时长约束(每个设备的总运行时间符合要求)
powerprob.Constraints.C1 = sum(A.*VV, 1) == D; 

% 电网购电等于设备总负载约束
powerprob.Constraints.C3 = Pgrid == HLD; 

% 优化器设置
options = optimoptions('intlinprog','Maxtime',10); 

% 求解优化问题
[sol,TotalCost,exitflag,output] = solve(powerprob,options); 
sol 
struct2table(sol) 
A = sol.A 

运行这段代码后,你会看到A的第一列求和结果正好是2,完全符合设定的约束,同时最小运行时间的规则也会正确生效。

内容的提问来源于stack exchange,提问作者Paramvir Atwal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:27:48