ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

综合能源系统鲁棒调度:绿证-碳排协同建模与Matlab复现

综合能源系统鲁棒调度:绿证-碳排协同建模与Matlab复现 一年多前我接了一个复现任务把一篇综合能源系统调度优化的论文转成 Matlab 代码。论文标题挺长核心是“计及动态绿证-碳排协同交易机制的含复综合能源系统鲁棒优化调度”。我第一反应是这标题至少叠了三层东西复合型综合能源系统的设备建模、绿色电力证书交易和碳排放权交易的协同联动、用两阶段鲁棒优化对抗不确定性。很多人做 IES 调度只碰其中一块要把“机制 鲁棒”完整复现出来难点其实不在代码本身而在于模型结构是否搭对、交易机制有没有耦合清楚、鲁棒子问题转单层时有没有出错。这篇博文就把我整理好的思路、建模过程、代码骨架和踩过的坑一次讲完适合正在做能源系统优化、准备复现论文或者想系统学习鲁棒调度求解框架的读者参考。1. 论文解读这个标题到底在说什么1.1 先动手拆标题复现的第一步永远是理解对象“计及”二字翻译成建模语言就是“目标函数和约束里要充分考虑”。后面的“动态绿证-碳排协同交易机制”是被考虑的对象这句话决定了整个模型不是传统的经济调度而是把环境权益类市场机制嵌进了优化问题里。先说“动态绿证”。绿证是对可再生能源发电环境属性的确认理论上每发 1MWh 绿色电力就对应一张证书。传统论文里绿证往往固定价格、固定配额算出来的结果比较“平”复现价值有限。这篇强调的是动态绿证意思是证书价格会随着供需关系、配额完成进度、新能源出力变化而上下波动所以绿证收益项不能写成常量乘发电量而是要把每个调度时段的证书供需比考虑进去变成一个随运行状态变化的非线性项。然后是“碳排协同”。碳市场给碳排放定价排放越多、成本越高。绿证和碳机制不是各算各的而是协同产生作用绿色电力一边产生证书收益一边降低整体碳排放进而减少碳交易成本。如果模型只考虑其中一个市场另一个外部性就丢失了两个市场同时进目标函数新能源的价值才被完整刻画出来。实际复现时两个机制之间的“协同”到底以什么形式表达是除法、抵扣系数还是阶梯折扣需要仔细看原文假设我后文会给出常用的建模处理方法。1.2 “含复综合能源系统”指的是什么标题里的“含复”我按复现版本理解为“复合型”也就是系统里不止一种能源转换与存储设备。典型的复合综合能源系统包括外部电网购电、风机光伏、燃气轮机或热电联产机组、燃气锅炉、电锅炉、蓄电池、蓄热罐甚至可能包含电制氢和储氢环节。这些设备共同满足电、热、气三类负荷。为什么要用复合系统因为单个能源形式没办法自然形成协同。电负荷不足时可以靠风机光伏也可以靠外部购电热负荷上升时燃气轮机发电余热可以供热燃气锅炉也能顶上。当系统既有电转热、又有热电联产、还有储能时设备之间的运行耦合会给调度优化带来比单一系统更多的可行域也更接近实际园区或区域能源站的结构。复现时我建议把设备按“源-网-荷-储”四个口径归纳源侧是风、光、外购电、气源转换侧是 CHP、燃气锅炉、电锅炉存储侧是蓄电、蓄热负荷侧是电、热负荷。每一类设备需要一套运行约束这些约束最终全部进入优化模型。1.3 为什么一个调度模型要同时考虑两种交易机制单纯做经济调度时系统调度员只看燃料费和购电费环境成本是外部的。但双碳背景下绿证和碳市场会真实影响项目收益一个综合能源系统如果大量使用燃气轮机碳排放量高碳交易支出就大如果同时配置较多光伏和风电绿证出售可以增加收入还能压低碳成本。模型里同时出现两种机制之后原来“多发电并不一定划算”的现象会更加明显某些时段甚至会出现新能源小幅弃电、购电策略后移的决策这是单机制模型看不到的结果。从复现角度说这类论文的价值就在于把政策类变量量化成了调度决策的一部分。绿证价格动态变化、碳价阶梯上升时系统的鲁棒最优运行点会随之移动。复现代码要想与论文结论对上核心就是把这两个机制“耦合”进目标函数而不是简单拼两个独立成本项。1.4 复现工作的难点到底在哪里复现论文不是抄公式真正的难点有三个。第一论文省略了很多参数和中间推导比如动态绿证价格的具体函数形式、碳排配额的免费额度设定、不确定集的预算值这些都需要补全第二模型通常是混合整数非线性问题MINLP必须做线性化或分段处理否则 Matlab 直接求解非常吃力第三两阶段鲁棒问题需要反复迭代求解主问题和子问题代码结构比普通经济调度复杂得多调试周期长。我把自己的复现路径分成四步先建 IES 设备模型再分别建模绿证机制和碳排机制然后把环境机制并入目标函数最后搭两阶段鲁棒框架并用列与约束生成算法求解。下面按这个顺序展开。2. 建模准备设备约束、动态绿证与碳排成本怎么进模型2.1 首先把设备方程写清楚这是所有机制落地的载体任何调度模型都必须先建立设备模型。下面列出我复现时最常用的一组设备方程不一定和论文一字不差但覆盖了大部分复合综合能源系统的设备集合。燃气轮机或热电联产机组是系统中的“供能核心”它的电功率和热功率满足热电比关系Q_chp(t) k_heat_electric * P_chp(t)其中P_chp(t)是机组电出力k_heat_electric是热电比。同时机组有出力上下限和爬坡约束P_chp_min P_chp(t) P_chp_max -P_chp_ramp P_chp(t) - P_chp(t-1) P_chp_ramp燃气锅炉和电锅炉结构类似直接把燃料或电能转换成热能主要约束是容量限值0 Q_gb(t) Q_gb_max储能装置蓄电池、蓄热罐用通用充放能模型描述。以蓄电池为例E_st(t1) E_st(t) eta_ch * P_ch(t) * dt - P_dis(t) / eta_dis * dt 0 P_ch(t) P_ch_max * u_ch(t) 0 P_dis(t) P_dis_max * u_dis(t) u_ch(t) u_dis(t) 1 E_st_min E_st(t) E_st_max这个模型的细节之处在于充放电效率分开放且引入u_ch(t)、u_dis(t)两个二进制变量把“不能同时充放”这一物理约束建模到位。很多人复现时把这两个变量漏掉结果出现同一时段充电又放电的虚假解跑出来效率高得离谱一看就知道模型错了。电、热功率平衡约束是最后收口的部分P_grid(t) P_wind(t) P_pv(t) P_chp(t) P_dis(t) P_load(t) P_eb(t) P_ch(t) Q_chp(t) Q_gb(t) Q_st_dis(t) Q_load(t) Q_st_ch(t)写设备模型时我给自己的建议是先列设备清单再写对应约束最后统一写平衡约束不要边写代码边想设备否则约束之间很容易重复或互相矛盾。2.2 动态绿证交易机制的建模方法绿证机制的核心有三个要素证书产出、配额需求、证书价格。证书产出简单理解就是可再生能源发电量。每 1MWh 绿色电力对应 1 张绿证N_gc(t) (P_wind(t) P_pv(t)) * dt / 1000配额需求表示系统按照政策要求必须持有或消纳一定比例绿色电力证书。设配额比例系数为quota_ratio则时段配额需求为N_quota(t) quota_ratio * P_load(t) * dt / 1000注意这里的配额需求是按负荷还是按售电量计算论文里定义可能不同复现时务必保持一致。动态价格的建模方式是整个机制的关键。常见做法是引入证书供需比指标d_gc(t) (N_quota(t) - N_gc(t)) / N_quota(t)当d_gc(t) 0表示证书不足价格上升d_gc(t) 0表示证书富余价格下降。模型化为P_gc(t) P_gc_base * (1 k_gc * d_gc(t))其中P_gc_base是基准证书价格k_gc是弹性系数。再设定上下限约束防止价格出现明显背离实际的数值P_gc_min P_gc(t) P_gc_max绿证收益进入目标函数时有两种处理方式。如果系统是绿证卖方收益为Revenue_gc(t) P_gc(t) * N_gc(t)如果系统有强制配额义务则需要把“缺少配额需购买证书”作为惩罚成本Cost_gc(t) P_gc(t) * max(0, N_quota(t) - N_gc(t))。为了避免max函数给求解器带来麻烦可以引入辅助变量N_buy_gc(t)N_buy_gc(t) N_quota(t) - N_gc(t) N_buy_gc(t) 0这样惩罚成本项就线性化了整个模型的可解性大幅提升。2.3 碳排协同交易机制怎么表示碳排机制在我复现的模型里分成三部分实际碳排放核算、免费配额、碳交易成本。实际碳排放源有三类外购电力的间接排放、燃气轮机燃烧排放、燃气锅炉燃烧排放。统一写成E_total(t) ef_grid * P_grid(t) * dt ef_gas * F_chp(t) * dt ef_gas * F_gb(t) * dt其中F_chp(t)、F_gb(t)是天然气消耗量。对于纯凝汽式机组或锅炉燃气消耗可以近似为F_chp(t) (P_chp(t) / eta_chp) / LHV_NG F_gb(t) (Q_gb(t) / eta_gb) / LHV_NG免费配额是政策给出的“排放许可”一般按系统和基准排放强度计算A_total(t) allowance_intensity * P_load(t) * dt剩下的就是净排放量和碳交易成本E_net(t) E_total(t) - A_total(t)碳交易成本可以写成线性函数也可以写成阶梯碳价。阶梯碳价的建模更贴近现行政策排放量越高边际成本越大Cost_carbon(t) lambda1 * E_net(t), 0 E_net(t) E1 lambda1 * E1 lambda2 * (E_net(t)-E1), E1 E_net(t) E2 lambda1 * E1 lambda2 * E2 lambda3 * (E_net(t)-E2), E_net(t) E2注意阶梯碳价是个分段线性函数可以直接用Yalmip的pwf或手动引入辅助变量线性化不要把它当成连续线性函数直接塞入模型否则结果偏差很大。2.4 绿证和碳排如何“协同”而不是简单叠加如果两个机制只是各自算一遍成本再相加从数学上讲是“同时考虑”但不叫“协同”。协同机制通常要建立耦合关系。我在复现中使用的方法是引入环境权益抵扣系数。绿色电力有一个很重要的特征是“环境属性唯一性”当绿证被出售并用于消纳证明后对应的电量在核算碳排放时通常不再重复计算间接排放优惠。但在综合能源系统内部调度时可以建立相对宽松的协同关系每消纳一部分绿证电量系统在碳市场中获得的免费配额或排放抵扣额度会相应提高A_effective(t) A_total(t) k_co2_gc * N_gc(t)这个式子说明绿证产出越多系统的碳配额余量就越大碳市场支出越小。k_co2_gc是协同系数取 0 到 1 之间具体大小取决于机制设计假设。同时绿证收益和碳成本的“协同”还体现在目标函数里绿证收益项与碳成本项共享同一个可再生能源出力变量。也就是说风、光出力提高时一方面绿证数量增加、动态价格可能下降另一方面碳排放减少、碳价成本降低两条链路同时反向作用。这种“共享决策变量、相互影响交易价格”的结构才是标题里“协同交易机制”的精髓。3. 鲁棒优化模型构建min-max-min 的三层逻辑3.1 为什么用鲁棒优化而不是随机规划或场景法综合能源系统调度面临的不确定性非常多最典型的是风光预测误差、负荷预测误差、绿证价格波动、碳价波动。处理不确定性的常规方案有两种随机规划需要给出不确定变量的概率分布再生成大量场景计算量很大而且分布参数本身很难准确获取机会约束规划则需要假设分布形式有时还与实际偏差较大。鲁棒优化的思路是完全不同的不关心概率只给不确定变量一个取值范围也就是“不确定集”然后寻找在最坏情况下依然可行的调度方案。这个方法天然适合工程应用我不需要知道明天的风电功率服从什么分布只需要给定“明天可能会比预测低 15%”或者“绿证价格可能上涨 10%”这样直观的波动区间模型就能给出保守但可靠的决策。代价也很明显鲁棒优化结果偏保守系统成本通常会比确定性模型高。为了控制这种保守性工程上普遍采用带预算参数的盒式不确定集通过调节“最坏情况出现程度”来平滑成本和鲁棒性之间的矛盾。3.2 不确定集设计不能只看单变量复现过程中最容易被低估的就是不确定集设计。很多论文用简单的盒式区间tilde{P}_wind(t) ∈ [P_wind_pred(t) - ΔP_down(t), P_wind_pred(t) ΔP_up(t)]每个时段单独波动这种方式建模简单但数学上是所有时段同时取最坏值等效于让风机在所有时段同时最小出力过于保守。更合理的做法是引入总量预算约束sum_{t1}^{T} ( |tilde{P}_wind(t) - P_wind_pred(t)| / ΔP_up(t) ) Γ_windΓ_wind 是鲁棒预算参数控制“最坏情况下最多有多少个时段同时偏差较大”。Γ 越大模型越保守Γ 0 时退化为确定性模型。对绿证价格和碳价也可以构造相似的不确定集tilde{P}_gc(t) ∈ [P_gc_pred(t) - ΔP_gc(t), P_gc_pred(t) ΔP_gc(t)] sum_t (|tilde{P}_gc(t) - P_gc_pred(t)| / ΔP_gc(t)) Γ_gc多个不确定变量之间如果相互独立可以分别建集如果电价和风电出力存在相关性比如大风天现货电价往往偏低理论上应该用多维不确定集描述。但作为复现实现我会优先选择独立盒式 预算约束的方式因为求解稳定性和代码可读性都更好。3.3 两阶段鲁棒模型的标准写法与求解思路两阶段鲁棒调度的标准形式如下min_x ( c^T x max_{u∈U} min_{y∈F(x,u)} d^T y )第一阶段决策变量x包含机组启停、储能充放状态这类“现在定了就没法改”的变量第二阶段决策变量y是真实看到不确定性参数u之后的调整量比如机组出力、购电量、锅炉功率、证书购买量、碳交易量。这个“min-max-min”在计算上不能直接丢给求解器通常用列与约束生成算法CCG或 Benders 分解求解。CCG 的基本思路是迭代初始化下界 LB -inf上界 UB inf。求解主问题得到第一阶段决策更新 LB。固定第一阶段决策求解子问题找到最坏场景和对应目标值更新 UB。如果 (UB - LB) / UB小于设定误差停止否则把最坏场景产生的第二阶段约束和变量加入主问题回到第 2 步。子问题本身还是“max-min”结构不能直接解。最常见的处理方法是对内层 min 问题取强对偶把 max-min 变成 max-max再合并为单层 maximization 问题交给求解器。需要注意只有在第二阶段问题满足线性规划或混合整数线性规划强对偶条件时才能这样做所以建模阶段要尽量保持约束线性化。我在复现时的代码里用了一个非常直观的替代思路对每个候选的不确定变量顶点做组合枚举但只在变量维度很低时这么做维数超过 4 个时稳妥起见还是老老实实做对偶重构不然顶点数量会爆炸。4. Matlab 复现实操从参数准备到 CCG 迭代闭环4.1 环境与求解器选型这套组合最省心Matlab 环境里做鲁棒优化我推荐Yalmip Gurobi/Cplex。Yalmip 本身不是一个求解器而是建模层它能把约束和目标函数自动翻译成求解器能识别的格式尤其适合快速搭建两阶段迭代模型。安装部分简单说明下载 Yalmip 后把文件夹加入 Matlab 路径再安装 Gurobi 或 Cplex并在 Matlab 里完成接口配置。Gurobi 提供学术免费许可普通学习者申请个人学术授权即可不要去找来路不明的授权文件求解器这类商业软件还是用正规渠道舒服至少不会在关键时刻遇到 license 抽风。调用时在sdpsettings里指定求解器ops sdpsettings(solver, gurobi, verbose, 2, outputflag, 1);如果只是做小规模实验且没有商业求解器也可以直接用 Matlab 内置的intlinprog或linprog但两阶段鲁棒问题迭代几十轮时内置求解器速度会明显吃力我后面提到的调试建议就是基于 Gurobi 写的。4.2 数据组织把论文里不容易找到的参数全部拆成结构体复现论文时数据准备是工作量最大的环节。我会用结构体统一管理参数这样主程序、子问题、主问题之间传参特别清晰。参数类别参数示例典型取值标幺化负荷电负荷峰值、热负荷峰值100 MW / 80 MW风电预测功率曲线、上下偏差预测误差 ±15%光伏预测功率曲线、上下偏差预测误差 ±10%CHP电效率、热电比、爬坡速率0.4 / 1.2 / 0.3储能容量、最大充放功率、效率20 MWh / 5 MW / 0.95绿证基准价格、弹性系数、配额比例50 元/张、0.6、0.15碳市场基准配额强度、阶梯价格区间0.6、60/100/150 元/吨鲁棒风电预算、绿证价格预算Γ_wind 4, Γ_gc 3数据准备里最容易犯的错是量纲不统一。绿证按张计、碳排按吨计、电量按 MWh 计三者通过公式换算时一旦漏掉时间尺度或单位系数目标函数里的成本数量级就会完全失衡。复现时我会跑一个纯确定性模型做“标定测试”确保在简单场景下目标函数值合理再进入两阶段鲁棒迭代。4.3 主问题代码骨架先搭框架再填细节主问题负责给出第一阶段决策变量和当前累积的 CCG 切割约束。初始时只有基本设备约束和平衡约束随着迭代不断加入子问题反馈的约束。下面是一段我在复现时使用的核心骨架function [x_val, LB] solve_master(Constraints_MP, obj_MP, ops, yalmip_vars) optimize(Constraints_MP, obj_MP, ops); x_val value(yalmip_vars.x); LB value(obj_MP); end实际写代码时主问题里的第一阶段变量通常包括x binvar(T, 1); % CHP 开停 u_ch binvar(T, 1); % 储能充电状态 u_dis binvar(T, 1); % 储能放电状态 P_chp sdpvar(T, 1); % CHP 电出力 P_grid sdpvar(T, 1); % 外购电 P_ch sdpvar(T, 1); P_dis sdpvar(T, 1);第二阶段变量单独在子问题里定义不放进主问题主问题只引入一个连续变量eta表示子问题目标值的下界估计eta sdpvar(1,1);主问题的目标函数是obj_MP sum(ope_cost fuel_cost start_cost) eta;迭代时子问题返回某个最坏场景u_k主问题增加一组约束把第二阶段目标值“锚定”到 eta 上Constraints_MP [Constraints_MP, eta sub_cost_expr_k];这个约束里sub_cost_expr_k是在固定最坏场景u_k下第二阶段目标函数关于主问题变量x的表达式。注意每次迭代新增的这组约束必须带上这次迭代得到的场景参数不能在循环里覆盖同名变量否则前面的切割约束全被冲掉了。4.4 子问题代码骨架从 max-min 到单层 max子问题的输入是主问题传过来的第一阶段决策xk输出是最坏场景u_k和对应的第二阶段目标值。我处理 max-min 的标准方式是先对内层 min 问题做强对偶重构再用Yalmip直接建模成单层最大化问题。先给出原始子问题形式max_{u∈U} min_{y∈F(xk,u)} d^T y第二阶段约束写成矩阵形式A_y * y b_y B_u * u C_x * xk对固定xk和u内层问题是线性规划。取对偶后min变成max外层max和目标合并得到单层 maximize 问题其中同时对偶变量λ和不确定变量u进行优化max_{λ,u} (b_y B_u * u C_x * xk)^T * λ s.t. A_y^T * λ d λ 0 u ∈ U这个单层问题是带双线性项(B_u * u)^T * λ的二次约束规划如果直接求解会比较麻烦。实际复现时我采用了一个工程化做法不确定集U是有界的盒式集合目标函数中双线性项的最优解总是出现在顶点上因此可以枚举顶点的“关键组合”或对双线性项做 McCormick 松弛。简单情况下我会直接对有限的顶点做循环逐个计算内层 min 的目标值取最大者为子问题结果。这个方法虽然看起来“笨”但在不确定变量维数不超过 5 个时完全够用而且不容易出数值问题。4.5 主循环与整体迭代逻辑CCG 主循环如下LB -1e6; UB 1e6; tol 1e-3; k 0; while (UB - LB) / abs(UB) tol k k 1; % 求解主问题得到第一阶段决策 xk [xk, LB] solve_master(...); % 求解子问题固定 xk得到最坏场景 uk 和目标值 sub_obj [sub_obj, uk] solve_subproblem(xk, ...); % 更新上界 UB min(UB, sum(ope_cost(xk)) sub_obj); % 根据 uk 构造新的第二阶段约束加入主问题 Constraints_MP [Constraints_MP, eta stage2_expr(xk, uk)]; end这里有一个非常容易踩的坑LB是主问题目标函数值包含eta这个下界估计但UB计算用的是“第一阶段真实成本 第二阶段真实目标值”。如果我计算UB时直接把主问题的eta拿进来迭代很早就收敛了但结果根本不对。务必保证 LB 和 UB 的定义口径一致上界永远是子问题返回的实际目标。5. 复现过程中的常见问题与调试技巧5.1 子问题一直提示不可行怎么办两阶段鲁棒里最常见的报错就是“子问题不可行”。它通常意味着第二阶段约束在某个最坏场景下找不到任何可行出力。排查顺序我固定为三步。第一步检查第一阶段决策变量是不是有取值跑出物理范围比如储能充放状态同时为 1导致功率平衡约束崩掉第二步检查不确定集参数有些论文会设置很极端的偏差比如风电预测功率本身只有 30 MW却允许上下偏差 20 MW那在最坏场景下风功率变成 50 MW 或 10 MW工况很难平衡第三步检查子问题里是否遗漏了松弛变量。如果确认模型本身没错可以在第二阶段给功率平衡约束加一个非负松弛变量P_balance(t) slack_pos(t) - slack_neg(t) 0 slack_pos(t), slack_neg(t) 0子问题目标里加上对松弛变量的大系数惩罚项。这个处理有两个好处一是迭代早期能快速返回一个可行近似解避免主问题被卡住二是可以从松弛量的分布判断哪个时段和哪个约束最难满足指导后续调整不确定集预算或设备容量限制。5.2 迭代收敛慢甚至来回震荡怎么定位CCG 迭代几十轮不收敛通常不是算法错了而是主问题添加切割约束的方式出了问题。最常见情况是新增的场景约束里第二阶段变量没有“继承”之前的场景下标导致每轮新增变量和新增约束互相覆盖。另一个原因是数值尺度差异。如果绿证收益是几千元量级而碳成本是几十万元量级目标函数的尺度差会让求解器数值病态表现为每轮主问题目标值不稳定。我的习惯是在数据准备阶段把所有成本和功率统一折算到同一基准比如都用标幺值或者都用“万元”为单位这样可以大幅减少数值问题。还有一个容易被忽略的点主问题的eta更新约束只在当前迭代场景下成立但第二阶段成本表达式必须在固定场景uk下严格按第二阶段变量计算。如果我在表达式里误用了其他场景的参数就会引入错误切割造成振荡。5.3 结果和论文数值对不上先检查机制耦合系数复现类工作最怕“程序能跑、结果不对”。我遇到过最典型的偏差是模型跑出来新能源大量消纳、绿证收益很高但系统总成本反而比确定性模型更低。乍一看违反直觉细查才发现是k_co2_gc设置太大绿证抵扣配额的力度过大把碳成本的约束作用抵消掉了。这种问题没有快速修复方式只能逐项对账。我会把目标函数按成本分项输出列出绿证成本、碳成本、燃料成本、购电成本、运维成本五列再和确定性模型对比。通过分项差值定位到具体是哪个机制项引入的偏差。再提醒一个细节动态绿证价格函数里的d_gc(t)分母是配额需求如果某个时段负荷极低导致配额需求接近零公式会出现分母极小、价格剧烈波动的情况。复现时一定要给分母加个下限保护比如N_quota_safe(t) max(N_quota(t), N_quota_min);不然部分时段的价格会出现几个数量级的跳变模型收敛性直接崩掉。5.4 代码调试速查表现象优先排查方向处理建议主问题求解时间暴涨二进制变量过多、Big-M松弛过紧减少启停变量维度使用紧的Big-M值子问题不可行冷热负荷平衡无法满足添加松弛变量或在不确定集中降低预算Γ目标函数为负且持续下降某成本项符号写反常见为绿证收益变成成本逐时段输出分项成本对账迭代不收敛切割约束遗漏场景下标变量被覆盖切割约束使用独立命名空间结果过于保守、成本奇高Γ预算设置过大把 Γ 从 1、2、4 逐步增加绘制成本-保守度曲线价格出现极端值动态绿证价格函数分母过小对分母添加下限保护6. 关于复现这件事我最后想说的几句把这篇论文从标题变成可运行的 Matlab 代码整个过程中最深的体会是复现不是“把公式翻译成代码”而是把论文里没有被明写的决策补全。动态绿证价格函数的具体参数、协同系数的大小、不确定集预算的选择这些地方论文往往只给一个范围甚至完全不给此时我的做法是参考同类文献取典型值然后做灵敏度分析把结果对参数的依赖关系摸清楚。这样即使复现结果不能和论文完全一致也能给别人一个清晰的解释我的模型在这个参数假设下得到什么结论。如果你也在复现同类综合能源系统鲁棒调度问题我建议不要一上来就追求完整复现所有机制先把确定性模型跑通再把绿证、碳排机制分别加进去做对比最后才进入两阶段鲁棒。每一步都能看到中间结果出错时可以快速缩小范围。最后分享一个小技巧在子问题里求解最坏场景时除了返回目标值我还会把u的最优取值单独存下来画成一条曲线对比预测值。这条曲线能直观反映模型认为的“最坏场景”长什么样是风电低谷持续全天还是绿证价格在峰值时段突然暴涨。有了这张图给任何人讲解模型行为都会事半功倍。这个习惯我现在一直保留后面对接生产环境、和业务方沟通时比贴一堆公式和代码管用得多。
返回列表