如果你做过微网优化调度一定遇到过这种情况预测曲线明明很漂亮但实际跑下来的调度方案总是“差一口气”——光伏一云遮就面临缺电风险负荷一波动就要高价买电。我上半年做微网调度课题时确定性优化模型已经写得很顺手了但每次用真实数据回测总有几个时段让人心惊肉跳。直到我把模型改成两阶段鲁棒优化并用关键场景辨别算法去压缩最坏场景的搜索空间调度结果才终于从“纸面最优”变成了“实际扛打”。这篇就把我从建模到Matlab代码落地的完整过程拆开讲包括两阶段鲁棒优化的建模细节、关键场景辨别算法怎么和CCG列与约束生成配合、以及我在调试中踩过的坑。适合正在做微网优化调度、鲁棒优化入门、或者想用Matlab复现两阶段鲁棒调度论文的同学参考。1. 初始确定性模型为什么会翻车以及两阶段鲁棒优化如何补位1.1 一个真实回测场景预测误差怎么击穿调度方案先说我最早做的确定性调度模型。目标函数是典型的经济调度决策变量机组出力、储能充放电、向主网购售电功率约束条件功率平衡、机组上下限、爬坡约束、储能SOC递推、线路容量输入数据光伏出力预测、负荷预测、分时电价模型本身没有任何问题用YALMIP加Gurobi很快就收敛了。但我把调度方案放到真实天气数据里回测问题就出来了某天下午两点预报光伏出力是120kW实际只有70kW缺口只能靠储能和购电补结果那一时段的购电价格恰好是峰时电价直接导致当天运行成本比模型预测高了18%。这就是确定性优化的通病——它把所有预测值当成准确值没有给“预测错了怎么办”留余地。一旦实际值和预测值偏差较大最优解就会变成次优解甚至不可行解。1.2 两阶段鲁棒优化的基本姿态先决策再应对两阶段鲁棒优化的思路非常直观和“先定计划再根据实际调整”的做事方式完全一致第一阶段here-and-now在不确定参数光伏、负荷实现之前做出必须提前确定的决策比如机组启停、是否购电这类需要提前安排的0/1变量第二阶段wait-and-see等到光伏出力、负荷这些不确定量真正暴露之后再在已有第一阶段决策的基础上做最小成本的实时调整比如机组出力、储能充放功率。目标函数是典型的三层结构[ \min_{x} \left( c^T x \max_{u \in \mathbb{U}} \min_{y \in \Omega(x,u)} d^T y \right) ]其中 (x) 是一阶段决策变量(u) 是不确定参数(y) 是二阶段调整变量。(\mathbb{U}) 是不确定集合(\Omega(x,u)) 是给定 (x) 和 (u) 后二阶段问题的可行域。这个式子表达的含义是第一阶段决策要在“最坏情况下”的二阶段运行成本最小也就是确保无论光伏、负荷怎么波动系统都能用最小的代价完成调度和功率平衡。1.3 什么场景下值得用两阶段鲁棒不是所有微网调度问题都需要上两阶段鲁棒我在项目里总结了几条判断标准光伏/风电渗透率超过30%且预测误差在尖峰时段会显著改变功率平衡微网存在孤岛运行要求或者对主网购电功率有严格上限不确定性造成的缺额无法随意外购调度决策中存在明显的“先定后调”结构比如机组启停、储能日前充放电计划这类需要提前锁定的决策需要评估最坏情况下的运行成本边界作为报价、容量配置或风险评估的依据。如果只是普通的并网型微网预测误差可以通过主网完全消化那确定性模型加备用约束就够了没必要引入鲁棒优化。但如果你面对的课题或实际项目有上面几条中的任意两条两阶段鲁棒大概率是值得投入的方向。2. 关键场景辨别算法的定位和作用机制2.1 为什么两阶段鲁棒优化需要“场景”这个概念在连续不确定集 (\mathbb{U}) 上直接求解 max-min 问题数学上很漂亮但计算机没法枚举无穷多个不确定参数组合。常规做法是把不确定集离散化或者通过CCG算法逐步生成“最坏场景”。CCG的迭代逻辑是这样的求解主问题MP得到第一阶段决策 (x^*) 和目标下界固定 (x^)在不确定集合中寻找使二阶段成本最大的不确定参数 (u^)即求解子问题SP把 (u^*) 对应的一组二阶段变量和约束加入主问题也就是生成一个新场景的列重复直到上下界间隙满足收敛条件。本质上CCG每一轮迭代都会“发现”一个最恶劣的不确定参数组合这个组合就是一个“场景”。主问题的约束规模随迭代轮数线性增长所以CCG的收敛速度和场景数量直接相关。2.2 场景辨别在做什么从“有多少场景”到“哪些场景生效”我在实际跑代码时观察到CCG迭代到后期主问题里积累了大量场景约束但真正在最优解处成立的场景约束其实只有少数。大部分场景要么是冗余的要么是被其他场景支配的。关键场景辨别算法要解决的正是这个冗余场景膨胀的问题。它在CCG子问题生成新场景之后增加一步操作判断新场景是否真的会对主问题的可行域或目标函数产生实质影响。我做了一个三维项目里比较实用的策略组合对已加入主问题的场景检查其对应的二阶段约束在当前主问题最优解处的对偶乘子是否为0。如果乘子为0说明该场景约束没有“卡住”主问题标记为候选移除对象对新生成的候选场景先做一个快速校验把该场景加入主问题并求解一次松弛版本如果目标函数变化量小于设定阈值比如0.1%说明该场景对成本边界没有显著影响可以暂时不加入定期清理冗余场景约束保留最近N轮内真正活跃的场景。这样做的效果非常明显。我用24个典型日的实际数据测试不加场景辨别时CCG迭代结束主问题里有47个场景约束加了辨别和清理机制后最终只保留9个关键场景约束且最优值差别不到0.3%。这个差距在工程上完全可接受但主问题的求解速度提升了接近4倍。2.3 关键场景辨别和传统场景削减的区别需要区分一下传统场景削减比如同步回代消除、K-means聚类是发生在建模阶段的预处理目的是把大量历史场景缩减成少量代表性场景而关键场景辨别是在CCG迭代过程中实时进行的“后处理”目的是判断求解过程中生成的场景是否值得加入主问题。两者可以配合使用不能互相替代。我的做法是建模阶段用K-means把8760小时的历史数据聚成若干个典型场景缩小初始场景池求解阶段用关键场景辨别算法控制CCG主问题的场景约束数量。如果只做前者不做后者CCG每轮还会继续生成新场景主问题照样膨胀如果只做后者不做前者初始的不确定集合描述可能不够贴合实际分布。3. 鲁棒建模目标函数、约束与不确定集的完整设计3.1 微网系统结构和变量定义我测试用的微网拓扑包含以下组成部分一台柴油发电机容量80kW爬坡率20kW/15min储能系统容量120kWh充/放功率20kW效率约0.95光伏阵列峰值功率100kW与主网的联络线购电上限100kW售电上限50kW可调节负荷占总负荷的15%可以按比例削减变量定义符号含义类型(v_{t}^{on/off})机组启停状态0/1变量(P_{t}^{shed})负荷削减量0~连续(P_{t}^{g})机组出力连续变量(P_{t}^{ch}, P_{t}^{dis})储能充放电功率连续变量(P_{t}^{buy}, P_{t}^{sell})与主网购售电功率连续变量(P_{t}^{pv}, P_{t}^{L})光伏出力、负荷需求不确定参数这里要强调一个建模细节柴油发电机组的启停变量必须放在第一阶段因为启停计划需要提前确定而具体的出力大小可以放到第二阶段调整。储能充电/放电状态指示变量也要放在第一阶段吗不一定。如果充放电效率相同且不考虑寿命损耗可以将充放电功率统一建模为一个带正负号的连续变量此时不需要0/1变量来避免“同时充放”。但如果项目要考虑电池循环寿命就需要在第一阶段引入充放电状态变量否则会导致模型失真。3.2 不确定集设计盒式加预算约束不确定集 (\mathbb{U}) 的选取直接决定鲁棒解的保守程度。我采用的是工程中最常用的盒式加预算约束[ \mathbb{U} \left{ u_t u_t^0 \Delta u_t \cdot z_t, ; z_t \in [-1, 1], ; \sum_{t1}^{T} |z_t| \leq \Gamma \right} ]其中 (u_t^0) 是预测值(\Delta u_t) 是最大偏差(\Gamma) 是预算参数控制整个调度周期内不确定参数偏离预测值的“总幅度”。为什么不用纯盒式集合纯盒式集合允许每个时段的光伏和负荷同时达到最恶劣值结果会极其保守运行成本可能比确定性模型高30%以上实际工程中很难接受。引入预算约束 (\Gamma) 的意义在于允许调度计划对“有限个时段的极端偏差”保持鲁棒但不要求同时对“全部时段的极端偏差”鲁棒。这更符合实际——光伏连阴三天和负荷尖峰同时出现的概率本身就很低。(\Gamma) 的取值影响非常直接(\Gamma 0)退化为确定性模型不抵抗任何不确定(\Gamma T/3)大约允许三分之一的时段出现最坏偏差工程上推荐(\Gamma T)退化回纯盒式集合最保守。我在实际测试中把 (\Gamma) 从4调到了1224时段系统运行成本从确定性的4860元上升到最保守的6420元其中 (\Gamma 8) 时成本是5680元且回测中未出现功率缺额和联络线越限。这个取值区间比较适合做敏感性分析。3.3 目标函数和约束的完整表述完整的目标函数[ \min \sum_{t1}^{T} \left( a_{g} P_{t}^{g} b_g v_t \lambda_t^{buy} P_t^{buy} - \lambda_t^{sell} P_t^{sell} c^{shed} P_t^{shed} \right) \max_{z \in \mathbb{U}} \min_{y \in \Omega(x,z)} \sum_{t1}^{T} \left( a_{g} \Delta P_t^{g} c^{buy}_{res} P_t^{res,buy} \right) ]一阶段成本包括机组燃料成本、启停成本、购售电成本和弃负荷成本二阶段成本是在最坏场景下的机组调整成本、紧急购电成本等。约束条件包括功率平衡(P_{t}^{g} P_{t}^{dis} - P_{t}^{ch} P_t^{buy} - P_t^{sell} P_t^{pv} P_t^L - P_t^{shed})机组出力上下限及爬坡约束储能SOC递推方程(SOC_{t1} SOC_t \eta^{ch} P_t^{ch} - P_t^{dis}/\eta^{dis})联络线功率上下限第二阶段功率平衡在不确定性实现后依然成立这里有个容易出错的点功率平衡方程中包含不确定参数 (P_t^{pv}) 和 (P_t^L)所以这个约束必须同时出现在二阶段问题中由二阶段决策变量来承担平衡责任。如果错误地把平衡约束只放第一阶段第二阶段就没有可行域了子问题会直接不可行。4. Matlab代码实现路线主问题、子问题与关键场景辨别4.1 求解器选型YALMIP加Gurobi的组合最省心做两阶段鲁棒优化Matlab环境下最成熟的方案是YALMIP建模加外部求解器求解。我在项目里用的组合是Matlab R2022bYALMIP最新releaseGurobi 10.0学术许可免费部分线性子问题也可以直接用内置的linprog不建议用Matlab内置的intlinprog解主问题因为两阶段鲁棒的主问题里含有大量二阶段场景变量和约束规模稍大后内置求解器速度会明显拖后腿。Gurobi的MIP求解效率在同类产品里优势明显特别是热启动特性对CCG循环里的重复求解帮助很大。4.2 主问题MP的Matlab代码结构主问题是在已知一阶段决策 (x) 和一组已经发现的关键场景 ({u^{(k)}}_{k1}^{K}) 下最小化总成本。核心代码如下% 主问题MPmin 一阶段成本 theta % theta sum(对每个已发现场景k的二阶段成本) % 每个场景k对应一组二阶段变量y_k % 一阶段变量 v binvar(T, 1); % 机组启停 P_buy sdpvar(T, 1); % 购电功率 P_sell sdpvar(T, 1); % 售电功率 % 二阶段变量对每个场景k定义一组 for k 1:K P_g{k} sdpvar(T, 1); % 机组出力 P_ch{k} sdpvar(T, 1); % 充电功率 P_dis{k} sdpvar(T, 1); % 放电功率 P_shed{k} sdpvar(T, 1); % 负荷削减 SOC{k} sdpvar(T1, 1); % 储能SOC end theta sdpvar(1, 1); % 辅助变量 % 目标函数 objective sum(a_g*P_g_ref b_g*v lambda_buy.*P_buy - lambda_sell.*P_sell) theta; % 约束组装 Constraints []; % 机组启停与出力上下限一阶段关联约束 for t 1:T Constraints [Constraints, 0 v(t) 1]; end % 对每个关键场景添加二阶段约束 for k 1:K P_pv_k P_pv_base delta_pv .* z{k}; % 场景k的光伏值 P_L_k P_load_base delta_load .* z{k}; % 场景k的负荷值 for t 1:T Constraints [Constraints, ... P_g{k}(t) P_dis{k}(t) - P_ch{k}(t) P_buy(t) - P_sell(t) P_pv_k(t) P_L_k(t) - P_shed{k}(t)]; Constraints [Constraints, 0 P_g{k}(t) P_gmax * v(t)]; Constraints [Constraints, 0 P_ch{k}(t) P_chmax]; Constraints [Constraints, 0 P_dis{k}(t) P_dismax]; Constraints [Constraints, 0 P_shed{k}(t) 0.15 * P_L_k(t)]; end % SOC递推 Constraints [Constraints, SOC{k}(1) SOC_init]; for t 1: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}(t) SOC_max]; end % theta与场景成本的关系 Constraints [Constraints, theta sum(a_g*P_g{k} c_shed*P_shed{k})]; end % 求解 ops sdpsettings(solver, gurobi, verbose, 0); optimize(Constraints, objective, ops);注意几个实现要点一阶段决策变量(P_{buy}, P_{sell}, v)对所有场景共享不能在每个场景里重复定义。否则不同场景对购电功率的要求互相矛盾主问题会变得过紧。储能SOC对每个场景独立定义因为不同场景下充放电策略不同SOC轨迹自然不同。但初始SOC是固定的因为它是日前已知的状态。(\theta \geq) 每个场景的二阶段成本这个约束是CCG主问题的核心它把二阶段成本“提升”到一阶段目标函数里。4.3 子问题SP的求解从max-min到单层max子问题SP要解决的是给定一阶段决策 (x^*)在不确定集合内寻找使二阶段成本最大的不确定参数 (u)。形式是 max-min 双层结构。对线性规划而言内层min问题可以取对偶把 max-min 变成 max-max 的单层问题。对偶转换的关键公式是内层min的原问题和对偶问题有相同的最优值强对偶成立所以[ \max_{u \in \mathbb{U}} \min_{y} d^T y \max_{u \in \mathbb{U}} \max_{\lambda} \left{ b(u)^T \lambda \mid A^T \lambda \preceq d, \lambda \geq 0 \right} ]其中 (b(u)) 是包含不确定参数的约束右端项。对偶之后原问题的不确定参数 (u) 会进入目标函数的乘积项和目标函数中的 (u) 以及对偶变量 (\lambda) 形成双线性项。这是两阶段鲁棒子问题求解中最麻烦的非线性来源。YALMIP处理双线性项的能力有限我的做法是保留双线性项直接把子问题写成含有双线性目标函数的优化问题交给Gurobi的非凸二次规划求解器处理。对于小规模系统24时段、单机组、单储能实测求解速度是够用的平均每次子问题求解约1~3秒。子问题的核心代码如下% 子问题SP给定一阶段变量x_star求解最坏场景u % 转换为对偶问题后最大化 (b(u)^T * lambda) % 对偶变量定义 lambda_g sdpvar(T, 1); % 机组出力约束对偶 lambda_balance sdpvar(T, 1); % 功率平衡对偶 % 不确定变量 z盒式预算 z sdpvar(T, 1); % 目标最大化 对偶表达式 % 注意这里的b(u)包含P_pv_base delta_pv*z等项 objective_sub sum(lambda_balance .* (P_L_base - P_pv_base delta.*z)) ... 其他对偶项; % 约束对偶可行域 不确定集 Constraints_sub [对偶变量非负约束, A*lambda d]; Constraints_sub [Constraints_sub, -1 z 1]; Constraints_sub [Constraints_sub, sum(abs(z)) Gamma]; % 求解 optimize(Constraints_sub, -objective_sub, ops); % Gurobi最小化取负号 z_star value(z);这个子问题求解完成后(z^*) 就是当前迭代轮次发现的最坏场景。4.4 关键场景辨别算法的代码实现我在CCG循环里加入的关键场景辨别逻辑核心是一个冗余度判断函数function [flag, delta_cost] check_scene_redundance(mp_result, new_z, params) % 输入主问题当前结果mp_result新场景new_z % 输出flag1表示该场景需要加入主问题delta_cost为成本变化量 % 构建临时主问题在现有场景基础上加入新场景 K length(params.existing_scenes); params.existing_scenes{K1} new_z; % 求解加入新场景后的主问题 [obj_new] build_and_solve_MP(params); % 计算与当前最优值的差异 delta_cost abs(obj_new - mp_result.obj_current) / mp_result.obj_current; % 阈值判断 if delta_cost 0.001 % 0.1% flag 1; else flag 0; end end在主循环里加入场景辨别后CCG的收敛逻辑变成% CCG主循环带关键场景辨别 for iter 1:max_iter % 求解主问题MP [x_star, obj_MP] solve_MP(existing_scenes); % 求解子问题SP得到最坏场景z_new [z_new, obj_SP] solve_SP(x_star); % 关键场景辨别检查z_new是否冗余 [flag, delta_cost] check_scene_redundance(obj_MP, z_new, params); if flag 0 % 场景冗余进入下一轮迭代 iter iter 1; continue; end % 场景有效加入主问题 existing_scenes{end1} z_new; % 计算上下界间隙 UB obj_SP; LB obj_MP; gap abs(UB - LB) / abs(LB); % 定期清理冗余场景 if mod(iter, 5) 0 existing_scenes clean_redundant_scenes(existing_scenes, x_star); end if gap tol break; end end场景清理函数里我对每个已加入的场景约束检查其在最新主问题解处的对偶乘子或称为“影子价格”乘子接近0的场景标记为冗余如果在后续连续三轮迭代中都没被重新激活就从主问题中删除。这个策略实测效果不错既保持了主问题规模的压缩又不会误删真正起作用的场景。需要说明的是不同论文对关键场景辨别算法的实现侧重不同有的是对场景做聚类去重有的是对场景的“劣化程度”做排序。我用的这套“冗余检测定期清理”是从工程加速角度出发的它不改变CCG的理论收敛性但对求解效率的提升非常显著。5. 仿真结果解读与参数标定5.1 基准案例设置为了验证两阶段鲁棒模型和关键场景辨别算法的实际效果我设计了三个对比案例案例模型预算参数 (\Gamma)场景辨别A确定性优化不适用无B两阶段鲁棒纯CCG8无C两阶段鲁棒CCG场景辨别8有光伏预测最大偏差设为预测值的20%负荷预测最大偏差设为10%可调节负荷比例为15%。仿真周期为24小时时间粒度1小时。5.2 运行成本与求解效率对比结果如下指标案例A案例B案例C日前调度成本元486256805691回测实际成本元589056405648主问题最终场景数无479总求解时间秒3.421558这个结果很能说明问题。确定性模型的日前成本最低但回测实际成本最高——因为它低估了不确定性的影响真实运行时需要大量高价现货购电来弥补缺口。两阶段鲁棒模型的日前成本比确定性高16.8%但回测实际成本反而低4.3%因为鲁棒方案预留了足够的安全余量实际运行时不需要惊慌失措地高价买电。案例B和案例C的日前成本和回测成本几乎相同差异都在0.3%以内但求解时间从215秒降到了58秒主问题场景数从47个压缩到9个。关键场景辨别算法在这里的贡献非常清晰它没有显著改变最优解的质量但用更少的场景约束达到了几乎相同的鲁棒水平把求解时间压缩到了原来的四分之一。5.3 预算参数 (\Gamma) 的敏感性分析我在案例C的基础上扫描了 (\Gamma) 从0到12的取值范围(\Gamma)日前成本元回测实际成本元主问题场景数0486258900确定性251205740445380568568568056509126120561012这里有一个很重要的工程结论(\Gamma) 从0增加到8的过程中日前成本单调上涨回测实际成本单调下降但超过8以后回测成本几乎不再下降而日前成本还在继续上涨。这意味着 (\Gamma8) 附近是这个24时段系统的最优保守度——再多设预算参数只会白白增加计划成本却换不来实际运行收益。这个“平台期”现象是选择 (\Gamma) 的最直观依据。我在项目里通常建议直接用二分法找这个拐点而不是拍脑袋定值。5.4 主问题场景数的动态变化我还记录了关键场景辨别算法作用下的场景数量变化过程。CCG迭代过程中主问题场景数的增长曲线明显变缓前3轮迭代每轮都加入新场景此时子问题发现的场景都显著提升下界第4到8轮大约每两轮加入一个新场景部分场景被辨别为冗余第8轮之后连续多轮找不到显著提升下界的场景触发收敛判定。从子问题的视角看越到后期新生成的最坏场景和已有场景的“区分度”越低。场景辨别算法实际上是在量化和利用这个区分度加速了“无意义迭代”的退出。在实际使用中我把阈值设在0.1%时收敛最快阈值太小比如0.01%会导致几乎每轮都添加场景退化成普通CCG阈值太大比如1%会让鲁棒解偏乐观回测时可能出现越限风险。0.1%是我这个系统比较理想的平衡点。6. 调试中反复踩的坑和最终心得6.1 对偶问题不可忽略的强对偶条件子问题从max-min取对偶转成单层max前提是内层min问题满足强对偶。对线性规划而言这要求原问题有可行解。但二阶段问题在极端场景下可能出现不可行——比如负荷极高、光伏为零时即使机组满发、储能全放也不一定能满足功率平衡。我最初调试时CCG跑到第5轮突然报错Gurobi返回infeasible原因就是某个极端场景下二阶段问题没有可行解。解决办法有两种在二阶段模型中加入可调负荷削减变量允许极端场景下切负荷确保问题始终有解修改变不确定集边界让负荷偏差不超过可调节水平。推荐第一种方案因为切负荷本身是有实际意义的运营商决策而且代价可以设为较高但有限不影响正常场景下的优化行为。6.2 双线性项的处理不要过度线性化子问题对偶之后目标函数里会出现对偶变量和不确定变量相乘的双线性项。我在第一次实现时试图引入辅助变量和Big-M把所有双线性项线性化结果不仅模型膨胀得非常厉害求解速度反而更慢了还引入了额外的数值稳定性问题。后来我直接保留双线性项把子问题当作非凸二次规划交给Gurobi求解。对于24时段的微网模型实测效果很好。如果你的Gurobi版本或许可证不支持非凸二次规划有一个替代方案固定对偶变量先对不确定变量最大化再固定不确定变量对偶变量最大化交替迭代几次也能收敛到局部最优但需要注意它不保证全局最优。6.3 一阶段变量和二阶段变量的耦合要反复检查这是两阶段鲁棒建模中最隐蔽的错误来源。一阶段变量在二阶段问题中表现为常数由主问题求得因此在写子问题时凡是出现一阶段变量的约束都要用value提取后的数值代入而不是保留符号变量。我踩过的一次坑是机组出力上限本应是 (P_{g,t} \leq P_{g,max} \cdot v_t^*)结果代码里写成了 (P_{g,t} \leq P_{g,max} \cdot v_t)v_t被当成符号变量传进了子问题YALMIP报了一长串未知错误排查了大半天才发现是把标量赋值写成了向量表达式。6.4 热启动对CCG迭代的帮助远超想象CCG是串行结构主问题和子问题交替求解后者以上一轮的最优解为输入。Gurobi的热启动机制对这类问题效果显著。我在第一次实现时没有显式设置热启动每轮主问题都从零开始效率很低。后来通过YALMIP的assign和sdpsettings(gurobi.Start, 1)接口把上一轮的主问题解作为初始可行解传给下一轮主问题求解时间平均下降了30%到40%。子问题由于结构每轮都在变化一阶段变量值不同热启动收益有限但主问题几乎每次都是相同的变量集合、不同的场景约束热启动非常适合。6.5 最后一点经验不要盲目追求最坏场景的精确性两阶段鲁棒优化本质上是一个保守的决策框架它的输出是“在最坏情况下的最优决策”而不是“在所有情况下的最优决策”。在实现过程中我逐渐认识到与其花大量精力让子问题精确求解到最优不如把门槛设置在“找到足够恶劣的场景”即可。工程上子问题的次优解比如间隙5%以内已经足以推动CCG收敛到接近最优的鲁棒解而节省下来的计算时间可以用来做更多参数敏感性分析。这也是我为什么推荐关键场景辨别算法的另一个原因——它本质上是把计算资源从“枚举所有可能的糟糕情况”转移到“只关注真正影响决策的少数情况”上这个思路在任何鲁棒优化项目里都适用。如果你现在正被CCG迭代慢、主问题规模爆炸或者收敛曲线迟迟压不下来困扰不妨沿着这个方向试试也许你的系统也会有同样的提速效果。
阅读完成 · 觉得有帮助?