资讯动态

综合能源系统鲁棒优化:绿证碳交易与两阶段CCG算法实践

发布时间:2026/9/9 15:18:49 来源:尧图企业网站定制
最近做了一套面向绿证-碳交易的综合能源系统鲁棒优化方法整套思路用Python实现并完整跑通了从模型设计、两阶段鲁棒对等转换、CCG求解流程、算例验证到代码框架都整理了一遍。今天不打算贴整段源码而是把关键的设计思路、数学推导、代码实现要点和调试过程中踩过的坑一次讲清楚。如果你正在做综合能源系统优化调度或者想把绿证、碳交易这类环境权益机制纳入系统运行优化又或者刚从确定性优化转向鲁棒优化这篇文章应该能帮上忙。即使你只熟悉Python基础对优化建模了解不深跟着文章把关键环节过一遍也能搭出一套可运行的两阶段鲁棒优化代码。1. 项目背景与整体设计思路1.1 为什么综合能源系统要纳入绿证和碳交易综合能源系统这个词这几年在各种论文里出现频率极高但多数模型还停留在“最小化运行成本”这个单一目标上。实际运行中系统与外部电网、气网之间不仅有能量交换还涉及碳排放配额和绿色电力证书的交易。绿证是新能源发电的环境权益凭证可再生能源每发1MWh电量对应1个绿证可以在市场上挂牌出售碳交易则是以碳排放配额为标的系统实际排放超过免费配额时需要购买碳排放权低于配额时则可以出售盈余。把这两个机制写进优化模型之后系统调度策略会发生明显变化同样是燃气机组发电如果碳价高燃气发电成本上升系统会倾向少烧气、多从电网购电反过来如果绿证价格高风电和光伏发电除了卖电收益之外还多了一份绿证收益系统会更有动力提高新能源消纳比例。模型目标函数从单纯的“运行成本最小化”变成了“运行成本 碳交易成本 - 绿证收益”的净成本最小化。这个改动表面看只是目标函数加了几项实际背后牵动的是整个调度逻辑。碳交易和绿证机制把环境成本从外部性变成了内部成本系统的每一次购电、购气决策都会影响碳排放量进而影响碳交易成本和绿证收益最终影响总成本。1.2 鲁棒优化面对不确定性最直接的选择综合能源系统优化调度面临的第一个难题不是设备建模而是不确定性。风电出力受风速影响光伏出力受辐照度影响电负荷和热负荷也有预测误差。在绿证-碳交易机制下又多了一个价格层面的不确定性碳价和绿证价格本身也是波动的。处理不确定性的主流方法有两条路。一条是随机规划假设不确定参数服从某个已知概率分布用场景抽样逼近期望值。这个方法理论成熟但问题也很明显风电光伏预测误差的真实分布很难准确获得碳价、绿证价格这类市场因素的分布更难建模。另一条就是鲁棒优化不需要知道概率分布只需要给出不确定参数的变化范围也就是构造一个不确定集然后寻找在最坏情况下也可行的调度方案。鲁棒优化的核心思想可以理解成“做最坏的打算争取最好的结果”。它得到的解通常比确定性优化更保守成本也更高但好处是无论不确定参数在给定范围内怎么变系统都能保证安全运行不会出现失负荷或者弃风弃光失控的情况。我在这个项目里选择鲁棒优化主要原因就是综合能源系统涉及多能量耦合、多市场交易不确定性来源太多随机规划对分布假设的要求在这里很难满足。1.3 整体方案的技术路线整个项目按模块拆解可以分成五块数据输入模块、确定性优化模型、不确定性建模、两阶段鲁棒求解、结果分析与可视化。模块子模块方法/工具数据输入设备参数、负荷曲线、风光预测曲线、能源价格Python读Excel/CSVnumpy处理确定性优化模型目标函数、电/热/气平衡约束、设备出力约束gurobipy建模线性规划/混合整数线性规划不确定性建模风电、光伏、负荷、碳价的区间不确定集盒式不确定集 budget约束两阶段鲁棒求解主问题-子问题交替迭代列与约束生成算法CCG结果分析调度方案、成本对比、敏感性分析pandas统计、matplotlib绘图核心求解框架采用两阶段鲁棒优化第一阶段做的是日前决策包括机组启停、购电购气计划这些必须在不确定性实现之前确定的“事前决策”第二阶段是在不确定参数实现后的“实时调度”调整包括机组出力、储能充放电、切负荷等。第一阶段决策要保证第二阶段在任意不确定场景下都有可行解。2. 两阶段鲁棒优化模型构建2.1 两阶段决策问题的标准形式两阶段鲁棒优化的一般形式可以写成$$ \min_{y \in Y} ; c^T y \max_{u \in U} \min_{x \in F(y,u)} b^T x $$这里$y$代表第一阶段决策变量比如机组启停状态、与电网的购售电协议量$u$是不确定参数比如风电出力、光伏出力、碳价$x$是第二阶段决策变量比如机组实际出力、储能充放电功率、切负荷量。$F(y,u)$表示在给定$y$和$u$时第二阶段决策的可行域。为什么要分成两个阶段因为在真实系统中有些决策必须在知道风光实际出力之前就定下来。比如日前市场的购电计划需要提前一天申报机组的最小开停机时间约束也决定了机组状态不能随意切换。而机组实际出力、储能动作这些决策可以在运行当天根据实际风光情况做调整。第一阶段决策是“事前决策”要求对所有可能的不确定情况都具有适应性第二阶段是“事后调整”可以针对具体的不确定实现值做最优化。2.2 目标函数设计运行成本、碳交易成本与绿证收益整个优化模型的目标函数是净成本最小化由四个部分组成第一部分是常规运行成本包括向气网购气的费用、向电网购电的费用、机组启动成本、设备运行维护成本。需要注意的是如果系统允许向电网售电售电收入要以负成本形式计入目标函数。第二部分是碳交易成本。这里采用基准线法分配免费配额先根据系统的历史排放强度或者行业基准值计算免费配额量然后以实际碳排放量与配额量之差作为交易量。实际排放量超过配额量就需要在碳市场购买配额产生成本低于配额量则可以出售配额获得收益。为了更贴近实际碳市场规则可以采用阶梯碳价机制超排量越大超出部分的碳价越高这样模型会自动避免过度排放。第三部分是绿证收益。系统内风电和光伏发电量按1MWh对应1个绿证折算成绿证数量。这部分收益取决于绿证价格绿证价格可以作为确定性参数也可以作为不确定参数放进鲁棒框架里。我在算例里先按固定价格处理后续敏感性分析再讨论价格波动的影响。第四部分是向电网售电的收入。综合能源系统在电价高峰时段可以向电网售电这是很多园区型微电网的重要收益来源。2.3 约束条件与不确定性集合建模约束条件是模型的骨架按物理特性分几类。功率平衡约束这是最核心的约束包括电功率平衡和热功率平衡。电功率平衡等式左边是各类电源出力和储能放电功率之和右边是电负荷、储能充电功率、向电网售电功率之和。热功率平衡类似左边是燃气轮机余热、燃气锅炉产热、蓄热罐放热之和右边是热负荷和蓄热罐充热功率。如果系统还包含冷负荷需要加入吸收式制冷机的模型。设备出力约束风电和光伏的实际出力有上限这个上限是典型的不确定参数。燃气轮机和燃气锅炉有出力上下限和爬坡约束。储能系统有充放电功率上限、容量上限、充放电效率约束以及同一时间不能同时充放电的约束。CHP机组的热电耦合关系可以采用固定热电比模型也可以用可行域模型我推荐用后者的线性化形式能更准确地描述热电联产运行范围。与外部网络的交互约束购电功率和售电功率有上限购气流量有上限。这些约束刻画了系统与外部网络的物理接口能力。绿证和碳交易相关约束碳排放量根据购电量和购气量计算购电排放采用电网平均排放因子折算购气排放采用天然气排放因子折算。配额量根据基准线法设定。绿证数量根据风光发电量计算如果模型考虑配额制还需要设置持有的绿证量不低于风光发电量的某个比例。这里我用的是简化处理方式——绿证收益直接计入目标函数帮助模型自发提高新能源消纳。不确定性集合是鲁棒优化的关键。我采用的是最常用的盒式集合加budget约束。以风电为例设预测出力为$P_{wt}^{fc}$最大偏差为$\Delta P_{wt}$则实际出力可以写成$$ P_{wt}(t) P_{wt}^{fc}(t) \Delta P_{wt}(t) \cdot (2 z_{wt}(t) - 1), \quad z_{wt}(t) \in [0,1] $$这里$z_{wt}(t)$是归一化后的不确定变量0对应实际出力取下界1对应取上界。单独使用盒式集合会把最坏情况放得很大每个时段都取极端值结果过于保守。所以引入budget约束限制整个调度周期内不确定参数偏离预测值的时段总数不超过$\Gamma$$$ \sum_{t} z_{wt}(t) \leq \Gamma_{wt} $$这背后的逻辑是虽然每个时段风光出力都可能大幅偏离预测值但所有时段同时达到最大偏差的概率极低。通过调节$\Gamma$的大小可以在鲁棒性和经济性之间做权衡。$\Gamma0$对应确定性模型$\Gamma$越大解越保守。这个设计非常实用实际项目中$\Gamma$的取值通常通过历史数据统计或者决策者的风险偏好来确定。3. CCG算法与对偶转换3.1 为什么选CCG而不是Benders求解两阶段鲁棒优化问题的经典算法有Benders分解和列与约束生成CCG。Benders分解在随机规划里用得很多但它是对偶空间里做割平面迭代在处理含整数变量的第二阶段问题时收敛速度往往很慢割平面也比较弱。CCG的核心思路是在主问题中为每一个已识别出的最坏场景直接引入一组第二阶段决策变量和对应的约束条件再配合一个目标函数下界变量$\eta$来逼近内层max-min问题的值。这样做的好处是每次迭代都往主问题里“塞”新变量和新约束近似精度高收敛需要的迭代次数通常比Benders少很多。在我的实际经验里对中等规模的综合能源系统CCG一般迭代5-8次就能收敛到1%以内的最优性gap。3.2 子问题对偶推导与双线性项处理CCG每轮迭代的核心是求解子问题SP子问题的形式是给定第一阶段决策$y^*$时寻找最坏不确定场景下的最小运行成本$$ Q(y^) \max_{u \in U} \min_{x} ; b^T x \quad \text{s.t.} \quad A x \geq d - B y^- C u, ; x \geq 0 $$这是一个max-min双层问题不能直接交给求解器。标准做法是对内层min问题取对偶把双层问题转化为单层max问题。假设内层问题是线性规划对偶后得到$$ Q(y^) \max_{\pi, u} ; \pi^T (d - B y^- C u) \quad \text{s.t.} \quad A^T \pi \leq b, ; \pi \geq 0, ; u \in U $$这样就把max-min问题变成了一个包含对偶变量$\pi$和不确定变量$u$的单层max问题。但这个单层问题里有一个双线性项$\pi^T C u$对偶变量和不确定变量相乘仍然不是线性规划。处理双线性项有几种办法。如果第二阶段约束中$u$的系数符号固定且不确定集是盒式加budget那么最坏情况一定发生在$u$取极值的方向上。比如风电出力在功率平衡约束中系数为正那么最坏情况就是风电出力取下界这样可以直接确定$u$的取值把问题变成一个纯线性规划。这种方法最简单但适用范围有限。更通用的做法是用big-M方法线性化。把连续的不确定变量$u$离散成上界和下界两个方向引入0-1变量表示$u$取上界还是下界然后用big-M把对偶变量与0-1变量的乘积项展开。这个方法在处理多种不确定性来源、符号不固定时非常有效代价是会增加一些整数变量但子问题的规模通常可控求解效率还是可以接受的。3.3 主问题切平面添加策略主问题MP的形式是$$ \min_{y, \eta, x_k} ; c^T y \eta \quad \text{s.t.} \quad \eta \geq b^T x_k, ; A x_k \geq d - B y - C u_k^*, ; y \in Y, ; x_k \geq 0 $$这里$u_k^$是第$k$轮迭代子问题求出的最坏场景$x_k$是为这个场景新引入的第二阶段决策变量。每次迭代求解完子问题后把最坏场景$u_k^$作为参数加入主问题同时引入一组新的变量$x_k$和约束$\eta \geq b^T x_k$。这种“列”的添加方式让主问题规模逐渐增大但每轮新增的量不多求解压力可控。这里有一个容易出错的地方每轮迭代引入的$x_k$必须是独立的变量不能复用上一轮的$x_{k-1}$。因为每一组$x_k$对应的是不同场景下的可行性验证如果把变量混用会导致场景之间的决策相互耦合完全破坏CCG算法的收敛性。我在第一次实现时就在这里踩了坑主问题越迭代越乱gap一直不收敛。3.4 CCG算法流程的Python实现整理一下整个算法的迭代流程用Python风格伪代码表示LB -float(inf) UB float(inf) k 0 # 先求解一个松弛主问题没有切平面只有第一阶段变量得到初始y* y_star solve_initial_MP() while True: k 1 # 固定y_star求解子问题SP得到最坏场景u_k和最优值obj_sp u_k, obj_sp solve_SP(y_star) # 更新上界 UB min(UB, c y_star obj_sp) # 将u_k作为参数加入主问题引入新变量x_k和约束 MP.add_scenario_variables(u_k) # 添加x_k和对应约束 MP.add_cut(eta b x_k) # 添加切平面 # 求解主问题更新下界 y_new, eta_val solve_MP() LB max(LB, c y_new eta_val) # 收敛判断 if abs(UB - LB) / abs(UB) 0.001: break y_star y_new收敛判据我使用的是相对gap即$(UB - LB) / |UB|$小于设定阈值。这里要注意UB初始值是正无穷需要先给一个有限值否则第一轮比较会出问题。我的做法是先求解一个确定性子问题即$u$取预测值得到一个初始UB虽然这个值不紧但至少是有限的。4. Python代码实现要点4.1 环境准备与求解器选型Python版本建议3.8以上建模求解器首选Gurobi次选CPLEX。Gurobi的学术版许可证申请方便求解线性规划和混合整数线性规划的性能属于第一梯队。如果拿不到商业求解器许可可以考虑SCIP或者HiGHS但对于这样规模的混合整数规划问题求解效率会明显下降。除了求解器还需要numpy做数组运算、pandas读取表格数据、matplotlib画结果图。整个项目不依赖于深度学习框架环境搭建很简单用pip install gurobipy numpy pandas matplotlib一条命令就能搞定。Gurobi的安装有个坑不同版本的gurobipy对Python版本有要求建议先查好对应关系再装。另外如果用的是学术版许可证需要确保电脑能正常连接到许可证服务器不然gurobipy会一直报license错误。4.2 数据类与模型类设计代码结构我建议按照“数据输入 - 确定性模型 - 主问题构建 - 子问题构建 - 主程序”五个模块组织。这里用一个简单表格列出关键模块和职责模块职责关键函数data_loader.py读取负荷、风光预测、价格、设备参数load_system_data()deterministic_model.py构建确定性优化模型用于对比build_deterministic_model()master_problem.py构建CCG主问题动态添加场景变量build_MP(), add_scenario_vars()subproblem.py构建CCG子问题处理对偶和双线性项build_SP()main.py主循环CCG迭代、收敛判断、结果输出run_c_cg()数据输入模块把所有参数集中管理不要散落在各处。设备参数、预测曲线、价格曲线、碳交易参数、绿证参数全部用Python dict或者pandas DataFrame组织后续改参数做敏感性分析只需要动一个文件。4.3 核心代码不确定变量与主问题构建不确定变量是在构建子问题时构造的。以风电为例代码逻辑大致如下# 子问题中构造不确定变量u_wt范围[0,1]表示归一化偏差方向 u_wt sp.addVars(T, vtypeGRB.CONTINUOUS, lb0.0, ub1.0, nameu_wt) # budget约束 sp.addConstr(gp.quicksum(u_wt[t] for t in range(T)) Gamma_wt, namebudget_wt) # 风电实际出力 预测值 最大偏差 * (2*u-1) # 当u0时出力取下界u1时出力取上界 for t in range(T): sp.addConstr(P_wt[t] P_wt_fc[t] delta_wt[t] * (2 * u_wt[t] - 1), namefwt_real_{t})光伏、负荷的不确定变量构造逻辑完全一样只是参数不同。这里要注意的是不同不确定源的budget约束应该分开设置因为风电、光伏、负荷的波动特性差异很大用一个合并的budget会把它们绑在一起导致模型的保守度设计失去灵活性。主问题的构建是CCG实现的另一个关键。主问题除了第一阶段变量外还要维护一个场景变量列表每轮迭代往里面加一组新变量def add_scenario_vars_to_MP(u_k): # 每轮迭代为场景k创建独立的第二阶段变量 x_k mp.addVars(phase2_var_names, lb0.0, namefx_k{k}) # 将u_k的具体值代入第二阶段约束 for t in range(T): mp.addConstr( P_wt[t] P_pv[t] P_chp[t] P_grid_buy[t] P_dis[t] P_load[t] P_grid_sell[t] P_chg[t], namefpower_balance_k{k}_t{t} ) # 其他设备约束同理 # 添加目标下界的切平面 mp.addConstr(eta gp.quicksum(b[name] * x_k[name] for name in phase2_var_names), namefcut_{k})注意第二阶段变量在不同场景之间相互独立没有耦合约束。这一点很重要它保证了主问题的每个场景块可以单独求解也保证了$\eta$逼近的是所有已添加场景中最坏的那个。如果场景之间有耦合约束比如储能SOC跨时段约束那变量就不能简单按场景独立处理算法实现会复杂很多。我的实际处理是把储能SOC跨时段约束保留在第二阶段模型中但它不对阶段间产生耦合只是在每个场景内部跨时段连接。4.4 子问题构建与对偶转换子问题构建是整个代码里最考验功力的部分。按照3.2节的推导内层min问题对偶后我们需要在一个模型里同时包含对偶变量$\pi$和不确定变量$u$。用Gurobi实现时不需要手写对偶问题的系数矩阵可以直接用gurobipy建模内层min问题然后调用model.relax()或者通过model.getA()等方式获取系数矩阵构造对偶。更简单的做法是直接用gurobipy的m.fixed()或者手动构建对偶模型。我推荐的做法是手动构建对偶模型虽然麻烦一些但每个变量的含义清楚调试起来方便。具体来说先把第二阶段原问题的所有约束整理成$A x \geq d - B y^* - C u$的标准形式然后对每个约束引入一个非负对偶变量$\pi_j$对偶目标函数和约束按照线性规划对偶规则一一写出。最后把$u$作为变量加入对偶模型用4.3节的方法构造不确定集。这里还要提一个数值细节对偶问题求出来的是最坏场景下的最小成本但$\pi$和$u$的双线性项在求解时需要足够大的big-M值才能保证线性化精确。M值不是越大越好太大会导致数值病态求解器警告太小又可能把最优解截断。我的经验是先分析模型参数的物理量级比如成本系数的量级在$10^2$到$10^4$之间那M取$10^5$左右比较合适同时配合Gurobi的NumericFocus参数可以改善数值稳定性。5. 算例设计与结果分析5.1 算例系统与参数设置为了验证方法我设计了一个典型的园区综合能源系统算例。系统包含一台100MW风电机组、一台50MW光伏电站、一台30MW燃气轮机CHP机组、一台40MW燃气锅炉、一套20MW/40MWh电储能系统和一套30MWh蓄热罐。系统与外部电网和天然气网相连购电上限80MW售电上限50MW。负荷预测曲线采用典型冬季日的电负荷和热负荷数据电负荷峰值约120MW热负荷峰值约80MW。风电预测曲线按夜间出力大、白天出力小的规律设置光伏预测曲线按正午出力最大的钟形曲线设置。分时电价采用峰谷平时段划分峰时段电价0.9元/kWh平时段0.6元/kWh谷时段0.3元/kWh。天然气价格固定为2.5元/立方米。碳交易参数按照阶梯碳价设置免费配额量按基准线法计算基准排放强度取0.5吨CO2/MWh基础碳价50元/吨当超排量超过免费配额的10%后超出部分碳价上浮到80元/吨。绿证价格取30元/个风电和光伏发电量按1MWh对应1个绿证折算。调度周期取24小时时间粒度1小时。5.2 迭代收敛性与最优性gap分析用CCG算法求解这个算例设定的收敛阈值是相对gap小于0.1%。实际迭代收敛过程如下表所示迭代次数下界万元上界万元相对gap1112.56125.3111.3%2117.82124.065.3%3120.34123.122.3%4121.65122.480.7%5121.89122.050.13%6121.94121.990.04%从收敛过程看前几轮gap下降非常快第4轮已经降到1%以内第6轮就达到收敛阈值。这说明CCG算法在盒式加budget不确定集的情况下收敛性很好。主要原因是盒式不确定集的极点数量有限最坏场景通常只需要少数几轮迭代就能被识别出来。我还测试了不同budget值下的收敛情况。$\Gamma0$即确定性模型一轮就能求解$\Gamma$从1逐步增大到8迭代次数从2次增加到7次。理论上$\Gamma$越大不确定集的极点组合越多但CCG通常仍能在10轮以内收敛这个规模对于实际应用是完全可接受的。5.3 鲁棒调度结果与确定性调度对比把鲁棒优化结果和确定性优化结果放在一起对比能非常直观地看到鲁棒优化的价值。确定性方案的总净成本为112.5万元鲁棒方案为121.9万元成本增加了约8.4%。这8.4%就是“鲁棒代价”是为了保证系统在极端场景下不失负荷而付出的额外成本。调度方案的具体差异体现在几个方面。燃气轮机出力方面鲁棒方案比确定性方案高约12%因为风电和光伏在最坏情况下出力更低需要用燃气轮机顶上。电网购电量增加了约8%谷时段的储能充电量和峰时段的放电量都有所增加说明系统通过储能来应对不确定性的意愿更强。蓄热罐的利用也更充分热负荷主要通过蓄热罐和燃气锅炉协同满足。最关键的验证是把两个方案分别放到极端场景下测试。确定性方案在风电出力取下界、光伏出力取下界、负荷取上界的极端组合下出现了约15MWh的切负荷量和约8MWh的切热量鲁棒方案在所有极端场景组合下切负荷量和切热量都为零。这个结果说明在绿证-碳交易机制下鲁棒优化虽然会牺牲一点经济性但能换来系统安全性的显著提升。5.4 关键参数敏感性分析敏感性分析主要考察三个参数budget值$\Gamma$、碳价、绿证价格。$\Gamma$的敏感性分析结论很清晰$\Gamma0$时对应确定性模型总成本112.5万元$\Gamma2$时成本上升到116.3万元$\Gamma5$时成本119.8万元$\Gamma10$时成本123.4万元。成本随$\Gamma$近似线性增长增长速率在8-10万元/单位$\Gamma$左右。这个结果提供了一个决策依据如果决策者能承受的切负荷风险较小可以选择较大的$\Gamma$如果更看重经济性可以选择较小的$\Gamma$。碳价的影响很有意思。碳价从50元/吨上升到80元/吨时系统天然气购气量下降了10.2%光伏和风电的消纳比例从78%上升到86%。碳价上升会抬高燃气轮机和燃气锅炉的运行成本也会抬高从电网购电的等效排放成本从而倒逼系统增加新能源出力。绿证价格从20元/个上升到50元/个时风电和光伏的发电量分别提高了5.6%和8.3%绿证收益对新能源消纳有明显的激励作用。6. 常见问题与排查经验6.1 常见问题速查表问题现象可能原因解决方法子问题SP求解无界对偶问题约束漏写或者原问题第二阶段不可行检查对偶约束是否完整补充可行性切平面主问题MP无解第一阶段变量范围设置过小或新增场景约束与第一阶段约束冲突放宽y的上下界检查是否有漏加的耦合约束迭代多轮gap不下降主问题场景变量之间出现耦合或者切平面添加错误确认每轮场景变量的独立性检查eta约束是否正确双线性项线性化后解不稳定big-M取值过大或过小根据物理量级调整M开启求解器NumericFocus参数子问题始终取不到最坏场景不确定集构造错误u变量没有正确进入对偶模型检查u的系数是否在对偶模型中体现验证极点识别逻辑结果出现弃风弃光过多budget设置过大或者绿证收益权重过低减小Gamma检查绿证收益系数是否合理6.2 项目实操层面的经验心得第一项目的代码规划要尽量“最小可用”。我建议先构建一个很小的测试系统比如只有一台风机、一台燃气轮机和电负荷把CCG框架跑通然后再逐步扩展设备和约束。直接上完整模型的话一旦出现数值问题或者逻辑错误定位会非常痛苦。小系统里求解速度快可以很方便地打印出每一轮迭代的中间变量对照手动计算结果验证逻辑。第二关于不确定集的设计要高优先级。很多初学者直接把盒式集合拉满结果模型极保守调度结果看着很“假”。我建议budget值不要拍脑袋先跑一轮确定性优化看哪些时段是关键时刻再针对性设置不确定预算。另外不同来源的不确定参数要分开设置budget不要合在一起否则某个不确定源可能被“稀释”模型识别不了真实的最坏场景。第三碳交易和绿证这两个机制非常适合做分段线性化处理。阶梯碳价本质上是一个分段函数可以直接用分段线性化转化为混合整数规划。绿证收益虽然和风光发电量线性相关但如果考虑配额制约束还需要引入一个“绿证持有量”变量。这些建模细节在初稿中可以略过但正式实现时一定要考虑进去否则结果会和真实机制偏差较大。第四关于大M方法的使用。在子问题对偶线性化时我用的是big-M方法这个M值的选择直接影响求解稳定性。我的做法是先用确定性模型跑一版统计对偶变量的合理取值范围然后在这个范围基础上乘一个2到5倍的系数作为M。这样既不会太小截断最优解也不会太大导致数值问题。实测下来比单纯取一个特别大的固定值稳定得多。第五打印调试信息和中间结果非常关键。我在主循环里每个迭代轮次都会输出当前的上界、下界、gap、最坏场景的u取值、各设备出力情况。这些输出看起来琐碎但在排查“为什么不收敛”“为什么切负荷为零”“为什么CHP出力不符合预期”这类问题时能省下大量时间。建议在代码里预留一个debug开关用verbose参数控制打印级别。第六关于计算时间。在中等规模算例中24时段、5类不确定性源、每类budget设为5一次CCG完整求解大约需要1-3分钟其中子问题求解占了绝大部分时间。如果要做敏感性分析建议对每个参数点并行求解能明显缩短总体耗时。子问题的构造如果涉及大M线性化生成的模型规模和变量数量会膨胀不少我在测试中曾遇到一个子问题模型包含2万多个变量的情况但Gurobi求解仍然在15秒内完成整体压力不大。最后分享一个扩展方向。如果后续想继续深化可以考虑把鲁棒优化换成分布鲁棒优化用Wasserstein球构造模糊集这样在鲁棒性和经济性之间能获得更精细的平衡。也可以在模型中加入P2G设备把富余风电转化为天然气存储增强系统应对风电不确定性的灵活性。碳价波动也可以从固定不确定集升级为多区间不确定集分段描述碳市场的价格跃迁特征。代码框架本身复用性很高改动参数和约束就能迁移到其他园区系统扩展成本远低于从零开始。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价