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
相关产品推荐
相关产品推荐

