最近在复现刘大神的微电网两阶段鲁棒优化模型时,发现这个CCG算法确实有点东西。咱们今天就拆开代码看看这个“先挨最毒的打,再找最优解“的逻辑是怎么落地的

📅 发布时间:2026/7/4 19:21:31 👁️ 浏览次数:
最近在复现刘大神的微电网两阶段鲁棒优化模型时,发现这个CCG算法确实有点东西。咱们今天就拆开代码看看这个“先挨最毒的打,再找最优解“的逻辑是怎么落地的
微电网两阶段鲁棒优化程序 基于matlabyalmipcplex实现 代码完美地复现了中国电机工程学报的文献《微电网两阶段鲁棒优化经济调度方法_刘一欣》。 代码基于matlabyalmipcplex实现注释详细结构清晰有条理运行的图形效果很好。 对于任意随机生成的初始化光伏和负荷场景都可实现有效的收敛。 所提出的模型考虑了分布式电源和负荷的不确定性通过对两阶段鲁棒优化模型的求解微电网能够得到“最恶劣”场景下系统运行成本最小的调度方案。 代码构建了基于两阶段鲁棒优化的微电网经济调度模型考虑微电网内可再生分布式电源和负荷的不确定性及储能、需求响应负荷和可控分布式电源等的协调控制通过一系列的模型推导和转换将两阶段问题转变为具有混合整数线性形式的主问题和子问题利用CCG进行求解。先看代码骨架长啥样%% 主程序结构 while gap epsilon MP buildMasterProblem(); % 构建主问题 SP buildSubProblem(); % 构建子问题 [obj_mp, sol_mp] solveMP(MP); % 求解主问题 [obj_sp, sol_sp] solveSP(SP); % 求解子问题 gap abs(obj_sp - obj_mp)/abs(obj_mp); updateConstraints(); % 添加最优割/可行割 end这个while循环就是CCG的核心每次迭代主问题给个调度方案子问题就负责找这个方案下的最恶劣场景然后把新约束怼回主问题接着算。主问题里的决策变量定义挺有意思% 主问题决策变量 x sdpvar(ng, T); % 机组出力 s binvar(nw, T); % 风机启停 y sdpvar(nb, T); % 储能充放电 theta sdpvar(1); % 辅助变量这里用到了YALMIP的sdpvar和binvar把连续变量和0-1变量分开定义。特别注意theta这个辅助变量它就像个中间人负责在主问题和子问题之间传递成本信息。子问题建模时有个骚操作把光伏/负荷不确定性写成多面体集合% 不确定性集合定义 U []; for t 1:T U [U, (P_pv(t) P_pv_min(t)) : PV_min]; U [U, (P_pv(t) P_pv_max(t)) : PV_max]; U [U, (P_load(t) P_load_min(t)) : Load_min]; U [U, (P_load(t) P_load_max(t)) : Load_max]; end这相当于给不确定参数划了个活动范围后续用对偶原理把max-min问题转成单层优化时这些约束就派上大用场了。看看迭代过程中的成本变化曲线!迭代过程收敛图微电网两阶段鲁棒优化程序 基于matlabyalmipcplex实现 代码完美地复现了中国电机工程学报的文献《微电网两阶段鲁棒优化经济调度方法_刘一欣》。 代码基于matlabyalmipcplex实现注释详细结构清晰有条理运行的图形效果很好。 对于任意随机生成的初始化光伏和负荷场景都可实现有效的收敛。 所提出的模型考虑了分布式电源和负荷的不确定性通过对两阶段鲁棒优化模型的求解微电网能够得到“最恶劣”场景下系统运行成本最小的调度方案。 代码构建了基于两阶段鲁棒优化的微电网经济调度模型考虑微电网内可再生分布式电源和负荷的不确定性及储能、需求响应负荷和可控分布式电源等的协调控制通过一系列的模型推导和转换将两阶段问题转变为具有混合整数线性形式的主问题和子问题利用CCG进行求解。横轴是迭代次数纵轴是总成本。可以看到前5次迭代成本剧烈波动这就是主问题和子问题在互相试探对方的底线。第6次之后两条线逐渐贴合说明找到了双方都能接受的均衡点。最后展示下典型日的优化结果% 结果可视化关键代码 plot(timeline, P_grid,LineWidth,2); hold on; stairs(timeline, P_bat,--); bar(timeline, P_pv_actual,FaceAlpha,0.3); legend(外网购电,储能出力,光伏实际出力);!调度结果图中光伏出力低谷时段12-15时储能放电加大外网购电来补缺。有意思的是在最恶劣场景下光伏实际出力刚好卡在预测区间的下限这验证了模型确实找到了系统最脆弱的状态。代码里有个处理对偶问题的trick值得注意% 子问题对偶转换 dualConstraints dualize(SP.constraints); SP_dual optimizer(dualConstraints, SP.objective, sdpsettings(solver,cplex), SP.parameters, SP.objective);这个dualize函数直接把max问题转成min问题避免了手动推导对偶形式的麻烦。不过要小心当原问题存在强对偶间隙时这招可能会翻车。写完代码最大的感悟是鲁棒优化就像给微电网买了份保险。虽然日常调度成本可能比随机规划高5%-8%但当遇到极端天气或者设备故障时这套方案能确保系统不崩盘。对于新能源渗透率高的微电网来说这种稳如老狗的特性比省那点电费重要多了。