两阶段鲁棒优化在微网调度中的关键场景辨别与Matlab实现

发布时间:2026/10/6 8:46:33
两阶段鲁棒优化在微网调度中的关键场景辨别与Matlab实现 1. 微网调度为什么要引入两阶段鲁棒——从确定性优化到不确定性优化的痛点先说说我最早接触微网调度时的感受。最开始用确定性优化比如已知光伏、风电、负荷的预测曲线直接建一个混合整数线性规划求解速度快、结果直观但一旦把预测值和实际出力放在一起对比问题就来了光伏和风电的预测误差在白天可能超过20%负荷峰谷时段的偏差也会让原本最优的调度方案直接失效——发电机爬坡跟不上、储能SOC越界、甚至出现功率不平衡导致的切负荷。这种预测值下的最优解在真实场景下不可行的情况才是微网调度真正要面对的核心矛盾。两阶段鲁棒优化就是为这个场景设计的。它的思路可以通俗地理解为先拍板、后调整第一阶段here-and-now做那些必须在不确定性实现前就定下来的决策比如柴油发电机的启停、储能是否参与调峰等第二阶段wait-and-see等不确定参数光伏、风电、负荷的真实值进入某个范围后再做经济再调度比如调整机组出力、储能充放电功率、与主网的交互电量。鲁棒性体现在无论不确定参数在预设的集合不确定集里怎么变化第一阶段决策都能保证第二阶段存在可行解并且目标函数按最坏情况来评估。这里有一个关键区别需要注意。随机规划stochastic programming需要知道不确定参数的精确概率分布或者至少能枚举大量代表性场景但如果微网所在地区的气象数据不完整或者负荷特性随着季节剧烈变化分布假设本身就不可靠。而鲁棒优化只需要不确定参数的上下界和预算约束不需要精确概率这对工程实践来说友好得多。两阶段鲁棒又是其中更贴近调度需求的版本——它不追求在所有可能场景下都让成本最小而是保证在最恶劣允许场景下仍然安全运行同时通过第二阶段调整来挽回一部分经济性。说白了它是先保证不翻车再尽量省钱。这篇内容适合谁看我认为是这三类人群一是刚入手微网优化调度、想把不确定性建模做进论文或课题的研究生二是做园区级微网控制系统、需要从确定性调度升级到鲁棒调度的工程师三是做算法对比、需要复现两阶段鲁棒基准方法的科研人员。背景只要具备最基础的优化建模懂目标函数、约束、MILP是什么就行再配合Matlab和Yalmip基本上可以顺着这篇文章的思路把整套框架跑通。2. 关键场景辨别算法的原理与核心逻辑标题里最容易被忽略的其实是关键场景辨别这五个字。很多教程讲两阶段鲁棒微网一上来就是列和约束生成CCG算法、对偶变换却不说清楚为什么要做场景辨别。我先把这个概念掰开。在两阶段鲁棒优化里外层有一个最坏场景搜寻过程。形式化地问题可以写成$$\min_{x} \left[ c^T x \max_{u \in \mathcal{U}} \min_{y} d^T y \right]$$其中 $x$ 是一阶段决策$u$ 是不确定参数$y$ 是二阶段决策$\mathcal{U}$ 是不确定集。中间的 $\max_{u} \min_{y}$ 就是找最坏场景并做最优调整的过程。如果不做任何场景辨别最直接的办法是把不确定集合 $\mathcal{U}$ 的所有极点在枚举出来每个极点对应一个场景然后一次性把所有场景的可行性约束都写进主问题。这在理论上等价实际计算量却是灾难——不确定参数数量稍微一多极点数目按组合爆炸24小时时段再加上每时段多个不确定参数分分钟把一个普通工作站的内存耗干净。关键场景辨别算法的任务就是回答两个问题第一一个场景关键是什么意思第二怎么在每次迭代中以较小的开销把最关键的场景找出来在CCG算法中这个问题的答案很明确当前固定的一阶段解 $x^$ 下让二阶段目标函数值最大的那个不确定参数取值 $u^$就是当前最关键的场景。这个取值不需要穷举而是通过求解子问题来获得——把内层 $\min_y$ 对偶化成 $\max$和外层 $\max_u$ 合并成一个单层极大化问题再用求解器直接找最优的 $u^*$。用对偶化的方式扫描整个不确定集本质上比逐个顶点测试要高效得多。你可能想问那是不是一上来就随机选一个初始场景也可以答案是分情况。如果是简单的盒式不确定集每个不确定参数独立取上下界初始场景选得不合适只会增加迭代次数但不会导致错误结果因为CCG的子问题在每次迭代都会把最坏场景逼出来。但如果不确定集带预算约束比如24小时内最多有8个时段的光伏出力偏离预测值那么初始场景的选择会显著影响前几次迭代的剪枝效果。一个实用的做法是先用历史数据的极端时段组合生成一个偏恶劣的初始场景比如在负荷峰值时段叠加光伏低出力、风电低出力这样主问题一开始就带上了较强的约束后续迭代次数通常能减少一两次。另外值得强调的一点是关键场景辨别在本文的代码框架里主要服务于子问题求解但同样可以用于不确定场景的预处理。比如你用蒙特卡洛生成500个光伏出力场景先做个聚类把500个场景缩成10~20个代表性场景再在这批代表性场景上运行两阶段鲁棒框架这比直接在500个场景上做鲁棒校验要快得多。聚类的核心指标可以是时段的出力偏差形态而不是绝对数值——因为微网调度的可行性关心的是偏差能不能被备用容量吸收而不是光伏绝对值本身。这个思想在后续代码实现中也体现在子问题求解前的场景筛选环节上。3. 两阶段鲁棒微网优化调度的数学建模现在把模型完整建立起来。我以最常见的并网型微网为例包含柴油发电机、储能系统、光伏、风电以及与主网的功率交互。调度周期取24小时时间间隔1小时。这是最经典的设置方便对比和复现。3.1 决策变量与目标函数一阶段变量是柴油发电机的启停状态 $u_{g,t} \in {0,1}$我习惯记为 $u$但为了避免与不确定参数混淆下面用 $z_{g,t}$ 表示启停状态。二阶段变量包括$P_{g,t}$柴油发电机的有功出力$P_{dis,t}, P_{ch,t}$储能放电、充电功率$P_{buy,t}, P_{sell,t}$主网购电、售电功率$SOC_t$储能荷电状态。目标函数写成两阶段形式$$\min_{z} \left[ \sum_{t1}^{T} C_{start,g} \cdot z_{g,t}^{start} \max_{u \in \mathcal{U}} \min_{P, SOC, ...} \sum_{t1}^{T} \left( C_{fuel,t} C_{grid,t} C_{ess,t} \right) \right]$$其中燃料成本我用二次函数拟合再分段线性化$$C_{fuel,t} a_g P_{g,t}^2 b_g P_{g,t} c_g$$与主网交互成本$$C_{grid,t} price_{buy,t} P_{buy,t} - price_{sell,t} P_{sell,t}$$储能运行维护成本按充放电功率线性计$$C_{ess,t} c_{ess} (P_{dis,t} P_{ch,t})$$3.2 约束条件不是简单列出来就行功率平衡约束是核心$$P_{g,t} P_{pv,t} P_{wind,t} P_{dis,t} P_{buy,t} P_{load,t} P_{ch,t} P_{sell,t}$$这里问题就来了$P_{pv,t}$ 和 $P_{wind,t}$ 是不确定的。如果直接把它们当作已知量模型就退化成确定性优化。正确的做法是把它们放进不确定集里让 $P_{pv,t} \bar{P}{pv,t} \delta{pv,t} \cdot \hat{P}{pv,t}$其中 $\bar{P}{pv,t}$ 是预测值$\hat{P}{pv,t}$ 是最大偏差$\delta{pv,t}$ 是取值于 $[-1,1]$ 的归一化不确定参数。同理可以定义风电和负荷的不确定参数。柴油机约束条件包括出力上下限、爬坡约束$$P_{g}^{min} z_{g,t} \le P_{g,t} \le P_{g}^{max} z_{g,t}$$$$-R_g^{down} \le P_{g,t} - P_{g,t-1} \le R_g^{up}$$注意如果 $z_{g,t}$ 是一阶段决策$P_{g,t}$ 是二阶段决策那么出力上下限和爬坡约束同时包含两个阶段的变量这种交叉约束在CCG分解时需要格外小心。我的处理方式是把含 $z_{g,t}$ 的约束放进主问题把不含的放进子问题或者统一用大M法把 $z$ 固定后投射到子问题约束中——在代码章节我会细说。储能约束$$SOC_t SOC_{t-1} \eta_{ch} P_{ch,t} - \frac{1}{\eta_{dis}} P_{dis,t}$$$$SOC^{min} \le SOC_t \le SOC^{max}$$$$0 \le P_{ch,t} \le P_{ch}^{max},\quad 0 \le P_{dis,t} \le P_{dis}^{max}$$与主网交互约束$$0 \le P_{buy,t} \le P_{buy}^{max},\quad 0 \le P_{sell,t} \le P_{sell}^{max}$$3.3 不确定集的构造决定保守度微网鲁棒调度最常用的是盒式预算约束的不确定集。盒式约束保证每个不确定参数都有界$$-\hat{P}{pv,t} \delta \le P{pv,t} - \bar{P}{pv,t} \le \hat{P}{pv,t}$$但这还不够。如果所有时段的光伏同时取最低值模型会过于保守因为实际光照在相邻时段高度相关不会出现全天阴天但负荷全天最高的极端组合。预算约束的作用就是限制总偏差程度$$\sum_{t} |\delta_{pv,t}| \le \Gamma_{pv}$$$$\sum_t |\delta_{load,t}| \le \Gamma_{load}$$$\Gamma$ 就是保守度调节旋钮。$\Gamma0$ 时退化为确定性模型$\GammaT$ 时退化为最保守的纯盒式模型。我在实际调试中一般把 $\Gamma$ 设为0.3~0.6倍时段数既保证鲁棒性又不至于让成本爆炸式上升。这里有一个建模上的细节预算约束里是 $\delta$ 的绝对值这是个非光滑约束。标准做法是引入辅助变量把绝对值线性替换设 $\delta_{pv,t} \delta_{pv,t}^ - \delta_{pv,t}^-$其中 $\delta_{pv,t}^, \delta_{pv,t}^- \ge 0$然后约束 $\sum_t (\delta_{pv,t}^ \delta_{pv,t}^-) \le \Gamma$。这段处理虽然基础但初学者在这步容易把符号搞反导致子问题的最坏场景永远只有一个时段取极端值预算约束形同虚设。建议写代码时先把这段拆开单独测试。4. Matlab实现路径从数学公式到可运行代码理论模型清楚了真正动手写Matlab的时候最关键的决策是选择求解工具链。我的建议是三步走用Yalmip建模、用Gurobi或Cplex求解、用Matlab脚本做CCG外层循环和结果可视化。Yalmip的好处是它对变量类型连续、二进制、整数和约束类型自动分类且支持对偶问题的自动推导这能省掉你手动推导子问题KKT条件的巨大工作量。4.1 CCG主循环框架两阶段鲁棒模型的求解我推荐用列和约束生成法因为它的收敛速度在工程统计上明显优于Benders分解同样是迭代算法Benders在主问题里割平面收敛慢CCG通过加约束而不是割平面每轮的信息量更大。CCG算法框架如下初始化设置下界 $LB -\infty$上界 $UB \infty$选择初始关键场景 $u^{(0)}$迭代计数 $k1$。求解主问题MP主问题是在已发现的一组关键场景上做确定性优化$$\min_{x, y^{(i)}} c^T x \sum_{i1}^{k} d^T y^{(i)}$$约束条件要求对每个已发现场景 $u^{(i)}$ 都有相应的二阶段可行约束 $By^{(i)} \le g - Cx - Du^{(i)}$。注意这里第二个阶段变量 $y^{(i)}$ 是为每个场景分别复制的这是CCG的关键——不同场景共用一个一阶段决策 $x$但二阶段决策各自独立。这一步求得的 $c^T x^* d^T y^*$ 给出下界 $LB$。求解子问题SP固定 $x x^*$求解$$\max_{u \in \mathcal{U}} \min_y d^T y$$在Yalmip里可以用两种方式实现。一种是直接把内层对偶掉变成单层最大化问题另一种是如果模型规模不大用Yalmip的implies和binary变量枚举 $u$ 的取值后再求解。我推荐前者把内层 $\min_y d^T y$ 写成拉格朗日对偶形式与原问题目标函数合并最终得到一个以 $u$ 为决策变量的优化问题。用Yalmip写这个过程等于让工具去做对偶变换但有几个坑后面说。收敛判断$UB \min(UB, d^T y_{sp}^* c^T x^*)$。如果 $UB - LB \le \epsilon$停止否则把新发现的场景 $u^{(k1)}$ 加入关键场景集合$kk1$回到步骤2。4.2 主问题的Yalmip代码骨架下面给出主问题MP的代码骨架这是CCG里最直观的部分% T 为时段数K 为当前已发现的关键场景数量 % 关键场景以 KxT 矩阵 U_scen 存储 % 一阶段决策变量柴油机启停 z binvar(1, T); % 二阶段决策变量为每个关键场景复制一组 P_g sdpvar(K, T); P_dis sdpvar(K, T); P_ch sdpvar(K, T); P_buy sdpvar(K, T); P_sell sdpvar(K, T); SOC sdpvar(K, T1); % 目标函数 cost_fuel 0; for k 1:K for t 1:T % 分段线性化的燃料成本这里简单写成二次近似实际用分段线性 cost_fuel cost_fuel a_g * P_g(k,t)^2 b_g * P_g(k,t) c_g * z(t); end end obj cost_fuel ... sum(sum(price_buy .* P_buy - price_sell .* P_sell)) ... c_ess * sum(sum(P_dis P_ch)) ... c_start * sum(max(0, z(2:T) - z(1:T-1))); Constraints []; for k 1:K for t 1:T Constraints [Constraints, P_g(k,:) P_g_min .* z, P_g(k,:) P_g_max .* z]; % 功率平衡P_pv 来自第k个关键场景 U_scen(k,t) Constraints [Constraints, P_g(k,t) U_pv_scen(k,t) U_wind_scen(k,t) ... P_dis(k,t) P_buy(k,t) P_load_scen(k,t) P_ch(k,t) P_sell(k,t)]; % 储能约束 Constraints [Constraints, SOC(k,t1) SOC(k,t) eta_ch*P_ch(k,t) - P_dis(k,t)/eta_dis]; Constraints [Constraints, SOC_min SOC(k,t1) SOC_max]; end % 每场景的爬坡约束、出力上下限等 Constraints [Constraints, -R_down diff(P_g(k,:),1,2) R_up]; end ops sdpsettings(solver,gurobi,verbose,0); optimize(Constraints, obj, ops);注意一个细节SOC取sdpvar(K, T1)而不是sdpvar(1, T1)因为不同场景的二阶段储能轨迹本来就不同但一阶段并没有强制储能SOC在场景间一致——储能调度属于第二阶段比较合理因为储能可以实时响应。如果你希望储能早晚时段策略在场景间保持一致就得把SOC也放入一阶段这会增加问题复杂度实际中看你的保守度需求。4.3 子问题的最坏场景辨识实现子问题的核心难点是处理求最大值和实时调整的复合结构。我直接给出实用代码路径先固定 $x^*$令所有包含 $x$ 的约束变成一个常数向量然后将内层最小化问题对偶化。以功率平衡约束为例其拉格朗日乘子记为 $\lambda_t$。对偶后的子问题可以写为$$\max_{u \in \mathcal{U}, \lambda, \mu} \quad \sum_{t} \lambda_t (P_{load,t} - P_{pv,t} - P_{wind,t}) \text{其他对偶项}$$约束为对偶可行域由原问题约束的系数矩阵决定$u$ 的取值范围由不确定集决定。这个目标中存在 $\lambda_t \cdot P_{pv,t}$ 这一双线性项直接交给求解器会变成非凸问题。处理方法有几种如果 $u$ 只能取连续区间端点盒式集合取极值可以用大M法把双线性项线性化如果 $u$ 是连续变量且有预算约束通常需要引入二进制变量把 $u$ 离散到几个候选水平或者使用对偶的极点枚举法。在工程实践中我的经验是把不确定参数的连续区间离散成少量水平比如光伏取预测值、0.8倍预测值、1.2倍预测值三档配合预算约束采用一个大M表示 $\lambda_t$ 和离散 $u$ 的乘积。这样问题转化为一个MILPGurobi求解速度很快而且离散档位的选择本身就是一种场景辨识——你划定的端点和中间档位已经覆盖了最关键的场景形态。如果你坚持 $u$ 连续可以使用空间分支定界或直接调用Gurobi的非线性二次求解功能但收敛稳定性和耗时都不如离散化方案友好。% 子问题代码骨架给定 x_star 后 % 不确定参数离散化pv_low / pv_high / pv_mid 等 lambda sdpvar(1, T); % u_sel 为二进制变量表示选取哪个候选水平 u_sel binvar(3, T); % 三档低、中、高 Constraints [sum(u_sel,1) ones(1,T)]; % P_pv sum(候选值 .* u_sel, 1) P_pv sum([pv_low; pv_mid; pv_high] .* u_sel, 1); % 对偶目标中的双线性项通过大M线性化 % 引入 auxiliary variable Q_aux表示 lambda .* P_pv 的线性化结果 for t 1:T Constraints [Constraints, Q_aux(t) -M * (1 - u_sel(1,t)) lambda(t) * pv_low(t)]; % 对三档分别处理 end % 求解子问题 optimize(Constraints, -obj_sp, ops); u_worst value(P_pv); % 当前最关键的光伏场景这里的Q_aux大M线性化本质是把$\lambda$ 乘离散档位替换为该档位被选中时 $\lambda$ 乘以定值。$M$ 的选取需要比 $\lambda$ 的可能最大值略大取太大会导致数值病态取太小会剪掉可行解。我一般先跑一次不带鲁棒约束的确定性对偶问题看看 $\lambda$ 的数量级然后把 $M$ 设为该数量级的10倍。4.4 主从循环收敛的判断细节收敛判据我用的是 $UB - LB \le \epsilon$$\epsilon$ 取1e-3到1e-4之间。实际操作中发现CCG的 $LB$ 单调递增$UB$ 单调递减但 $UB$ 的下降往往呈现锯齿状波动特别是在子问题里出现离散化误差时。一个实用技巧是每次迭代记录 $UB$ 序列如果连续3次迭代 $UB$ 都降幅小于0.1%可以提前终止不必非要等到严格差小于 $\epsilon$。对于24时段微网模型我经验上CCG一般6~12轮收敛每轮主问题MILP求解时间在几十秒左右整体可控。5. 案例场景设置与算例结果解读5.1 基础数据设定我用一个典型并网微网做测试系统包含一台柴油发电机额定容量1.5MW、储能容量1MWh最大充放电功率0.3MW、光伏预测峰值约1MW、风电预测峰值约0.5MW加上从配网购电购电价按分时电价设置峰时1.1元/kWh、平时0.7元/kWh、谷时0.35元/kWh售电价统一0.3元/kWh。负荷预测曲线取某园区典型日的日负荷峰值约1.8MW。预测误差的假设光伏和风电的预测偏差按±20%设置负荷偏差按±8%设置。预算系数 $\Gamma_{pv}$ 取6$\Gamma_{wind}$ 取6$\Gamma_{load}$ 取4时段数24。这说明我不允许所有时段同时取最坏值而只允许大约四分之一时段联合往坏处走。5.2 结果对比确定性调度与两阶段鲁棒调度表格是比较直观的方式指标确定性调度两阶段鲁棒调度$\Gamma6/6/4$综合成本元/日约 21800约 24500最坏场景下能否满足功率平衡不能切负荷约0.4MWh能光伏最坏场景出力下的备用缺口0.6MW0CCG迭代次数-约8求解总耗时约15秒约660秒注意这里成本上升了约12%换来的是在预测误差联合恶化时的可靠运行。这就是两阶段鲁棒的保费——你多付了一点运行成本换取系统在最坏天气、最坏负荷场景下仍然不至于失控。从调度策略上看鲁棒调度结果有几个明显特点柴油机在夜间低谷时段尽量维持在一个中等出力而非确定性调度中的低出力相当于把一部分旋转备用抬高储能在白天光伏高峰时段不会把SOC充到100%而是留出约20%容量空间应对光伏突然从峰值跌落的场景与主网的购电计划在峰荷时段也比确定性调度更激进地提前购入平抑时段波动。5.3 关键场景的演化过程CCG迭代过程本身很有意思。我记录了一下8次迭代中辨识出的关键场景形态第1轮初始场景负荷峰值光伏低出力风电低出力这是靠人工经验给的初始场景目标函数值很保守第2轮CCG发现初始场景还不够狠把光伏低出力时段向负荷低谷转移此时储能充电需求增大成本上升第3~5轮辨识出风电出力在凌晨时段跳变组合导致柴油机爬坡约束紧张第6~8轮辨识出负荷在晚间高峰叠加光伏出力归零、且储能SOC已经处于下界的组合这是真正的关键场景——此时购电价格高、本地资源不足必须调用备用。这个演化过程说明了关键场景辨别算法的价值它不是一次性把所有坏情况都列出来而是通过求解器主动搜索当前调度方案的软肋每轮找到一个让当前方案最难受的场景然后逼着主问题改进。8轮下来调度方案就具备了抵御所有边界组合的能力。5.4 不同预算系数的敏感性我做了一组 $\Gamma$ 敏感性测试心里有个更直观的认识$\Gamma0$纯确定性成本约21800$\Gamma2$时约22500$\Gamma6$时约24500$\Gamma12$时约27800$\Gamma24$纯盒式最坏情况时约32300。可见成本增长并不是线性的当预算量超过系统备用容量能吸收的范围后成本飙升很快。所以在实际项目中$\Gamma$ 的取值强烈建议结合历史预测误差的置信水平来定而不是拍脑袋选。如果微网所在地区天气预报准确度高$\Gamma$ 可以取小些如果天气多变宁可多付成本也要保证不切负荷。6. 实操中踩过的坑与调参经验最后聊几个我在复现和调试两阶段鲁棒微网时踩过的坑这些细节在论文附录里几乎找不到但价值很高。第一个坑是子问题对偶的方向问题。初学者在推导对偶问题时很容易把最大化-最小化变成最大化-最大化导致目标函数符号反了。Yalmip本身不会自动帮你做两阶段的对偶它只会在单个优化问题里做预处理。我的建议是在写子问题之前先用确定性模型跑通对偶验证——取一个固定 $u$对比内层最小化问题的原始求解值和对偶后最大化问题的值两者应该相等强对偶成立的前提下。这一步验证开销很小但能避免你在CCG主循环里浪费时间查一个符号错误。第二个坑是大M参数。子问题里线性化 $\lambda \cdot P_{pv}$ 的大M如果给得太小会把最坏场景的搜索空间错误剪枝导致CCG误判已经找到最坏场景而提前收敛产生看似正常但实际过优的结果。我遇到过这种情况鲁棒成本比预期低了10%一开始以为算法省钱了后来发现是大M太小某些 $\lambda$ 组合被错误排除。验证方法很简单把大M翻10倍再跑一遍如果结果变化超过1%说明原来的大M取值有问题。第三个坑是预算约束和时段耦合。有的文献把预算约束写为 $\sum |\delta_t| \le \Gamma$但在CCG子问题做离散化时如果不把 $\delta_t^$ 和 $\delta_t^-$ 分别建模预算约束很可能被负负得正绕过——比如一个时段 $\delta1$另一个时段 $\delta-1$绝对值之和是2但直接求和 $\sum \delta$ 是0约束形同虚设。必须严格按我第3.3节提到的方法线性化。第四个坑是储能SOC在场景间的处理。如果只把SOC放在第二阶段的每个场景里独立优化不要求各场景SOC轨迹一致那么鲁棒调度结果会过度乐观——因为储能被视为完美的实时响应设备可以针对每个场景分别调整充放电。实际工程中储能控制策略虽然可以快速响应但SOC的累积效应不能瞬间改变。处理方案有两种一是把SOC的一阶段值比如每个时刻的目标SOC也作为决策变量强制各场景偏离目标SOC的偏差受限二是在第二阶段目标函数中增加对SOC偏离基准值的惩罚项。我首选方案二它保持了CCG分解结构的简洁同时工程上更合理。第五个坑是新能源预测数据的时间分辨率。我最早测试时用了15分钟分辨率的预测曲线但调度时段是1小时导致矩阵维度对不上CCG迭代次数急剧增加。后来统一把数据重采样到1小时同时对光伏出力做时段聚合处理取1小时平均值而不是瞬时值计算结果才稳定下来。这提醒我两阶段鲁棒模型对预测偏差的时间分布十分敏感数据预处理阶段就要保持一致性。再说一个调参经验子问题的求解器选项建议打开numericalEmphasis,1Gurobi因为对偶问题中会出现不少接近0的系数不加这个选项偶发数值警告。主问题则建议打开presolve,autoYalmip的预处理能力通常够用。如果整机求解时间超过你的预期优先检查的不是求解器参数而是第二阶段变量的场景复制总数——$K \times T$ 决定了主问题规模如果CCG迭代到第20轮还没收敛且每轮主问题已非常吃力可以考虑从每轮新增一个场景改成每轮新增H个最坏场景H取2~3并行加入主问题通常能减少总迭代轮数虽然每轮求解慢一点但总耗时反而下降。7. 下一步可以怎么扩展如果你已经跑通了这套两阶段鲁棒微网代码后面有几个方向值得试一试。第一个是引入需求响应。把可削减负荷、可转移负荷作为不确定集合的一部分或二阶段决策变量会让模型更贴近真实园区需求侧管理。此时目标函数里要增加负荷削减的补偿费用约束里增加削减次数限制CCG框架不用大改但子问题的场景辨识会多出负荷同时往上偏的情况更有意思。第二个是改为多微网互联。两阶段鲁棒模型在单微网上看起来中规中矩一旦做成多个微网通过公共连接点互济一阶段决策就要考虑联络线功率计划二阶段在不确定性下做实时协调。这个场景下关键场景辨别的价值更凸显——因为互联系统的极端场景往往是多微网的不确定性叠加用CCG自动搜索最坏组合比人工枚举不知道高到哪里去了。第三个是把鲁棒调度结果作为日内滚动调度的边界。两阶段鲁棒给出的是日前尺度的安全包络日内再按15分钟粒度做MPC滚动校正两者结合能兼顾保守性和经济性。这种层级结构目前在园区微网项目里越来越常见。我个人在实际操作中最深的体会是两阶段鲁棒优化的重点其实不在求解算法本身而在于你如何定义不确定集和如何解读关键场景。不确定集合才是物理直觉注入模型的地方——你的保守度、你对天气相关性的认知、你对负荷波动形态的判断全都浓缩在 $\Gamma$ 和场景离散档位里。CCG算法只是那个把想法变成计算的翻译器。把这层想明白你在调参和模型扩展时就不会迷茫了。