做综合能源优化调度的人,这两年大概率绕不开一个词:氢能。我自己从单纯的电-热耦合模型改成电-氢-热三者联动,过程比预想中曲折。不是加两行公式的事——系统边界、能量平衡关系、时间尺度和求解规模全都要重新捋一遍。这篇贴子把搭建"计及氢能的综合能源优化调度"模型并用Matlab实现的完整过程写下来,包括设备建模、优化问题构造、求解器调用、场景分析和踩坑记录。如果你的课题正好涉及P2G、燃料电池或储氢罐参与调度,这篇应该能帮你少走不少弯路。
正文会按"建模 -> 优化 -> 实现 -> 算例 -> 避坑"的顺序展开。所有代码思路基于Matlab + YALMIP + 商业求解器的组合,手头没有商业求解器时,文章最后也给出用intlinprog替代的方案。整体来说,这篇适合研究生、工程师和刚接触优化调度的同学参考,读完至少能搭出一套能跑起来的24小时调度程序。
1. 为什么综合能源系统里要引入氢能——从"电热耦合"到"电氢热"的转变
做过综合能源优化调度的人应该都有体会:传统IES(Integrated Energy System)里的核心矛盾,是电和热在时间和品位上的错配。电负荷和热负荷的变化曲线往往反着走,白天电负荷高、夜间热负荷高;热电联产机组一旦按热需求开机,电出力就被"锁定",遇到风电大发时段就只能被迫弃风。这个约束在模型里表现为CHP的可行域,在实际运行中则是考核弃风率的重要来源。氢能真正吸引人的地方,在于它给系统打开了一条"电-氢-热"的横向通道:多余的电变成氢存起来,需要时再通过燃料电池转回电和热,相当于给系统装了一个大容量、低自放电的"慢电池",同时还能当热源用。
我一开始接触这类课题时,第一反应是"这不就是把储能电池改成储氢罐吗"。真做下来发现完全不是一回事。电池储能建模基本只关心电量状态、充放功率和效率,但氢能系统的物理环节更长:电解槽的效率受负载率影响、储氢罐涉及压力和泄漏损失、燃料电池还带热电联产特性。每一个环节都和电网侧模型的常见假设不太兼容,这也是很多人卡在建模阶段的原因。
1.1 传统综合能源系统的问题所在
传统的综合能源园区,常见配置是风电、光伏、CHP、燃气锅炉、电锅炉加电储能。这种结构里,热力平衡和电力平衡通过CHP耦合在一台机组上:CHP的发电量和发热量之间不是独立的,而是落在一个多边形可行域内。热负荷尖峰时段,CHP必须高负荷运行,电出力被抬高,挤压风电上网空间;反过来说,要为风电让出通道,CHP就得降低出力,热负荷又补不上。热储能能缓解一部分,但热储能只能解决热侧问题,弃风压力仍然压在电力平衡上。
电储能理论上可以吸收多余风电,但工程上电储能容量越大成本越高,对跨日、跨周的中长周期能量平移能力有限。这里就浮现两个实质问题:一是电和热的解耦能力不足,二是系统缺少大容量能量载体。氢能恰好在这两个维度上都有价值。
1.2 氢能参与下的系统架构变化
引入氢能后,系统的耦合关系从"电-热"二维变成"电-氢-热"三维。比较典型的架构包括四类新增设备:
- 电解槽(P2G):把富余电力转化为氢气,相当于一个可调的"电负荷"。
- 储氢罐(HST):为氢提供小时级到日级的存储缓冲,地下盐穴储氢则可以做到季节级储能。
- 燃料电池(FC):将氢气转化为电和热,电效率约40%~50%,加上热回收后综合效率可达85%以上。
- 氢能负荷:可以是加氢站、工业氢负荷,或者掺氢天然气的终端用户。
和电池储能相比,氢储能的自放电率低、单位能量成本低、扩容简单,但往返效率低(电→氢→电的全流程效率通常在30%~45%之间)。这两个载体不是简单的"替代关系",合理的做法是把氢储能视为对电储能时间和容量维度的补充。表1给出典型特性对比。
| 特性 | 电储能(锂电池) | 氢储能 |
|---|---|---|
| 往返效率 | 85%~95% | 30%~45% |
| 自放电率 | 约1%~3%/月 | 极低(小时级可忽略) |
| 单位能量成本 | 较贵(容量成本高) | 较便宜(储罐容积成本低) |
| 扩展性 | 模块化,单站容量受限 | 可做到GWh级 |
| 热电联供 | 一般不提供热 | 燃料电池可回收余热 |
| 响应速度 | 毫秒级 | 秒至分钟级 |
1.3 电、氢、热三种能量的时空解耦
氢能的核心价值是时间解耦和品位解耦。时间解耦:电解槽在低电价或弃风时段多制氢,燃料电池在晚高峰或次日早峰再把氢转化为电,实现跨时段能量平移。品位解耦:燃料电池的余热为系统提供热量,让CHP不必在高热需求时段硬扛发电,相当于把原本绑在一起的"发电义务"和"发热义务"分开了。
建模时,这种解耦会直接体现在平衡方程里:电力平衡多了一项"电解槽负荷"和"燃料电池出力",热力平衡多了一项"燃料电池余热",氢平衡则是一个独立的物质守恒方程。我接触过的不少初学模型都会忽略这种解耦带来的自由度增加——乍看觉得多加设备就是多加约束,实际约束变多了,但可行域也变大了,这正是优化调度能挖出经济效益的地方。
2. 系统建模:电网、热网、气网与储氢环节的数学描述
构建优化模型之前,先要把每个设备的输入输出关系用数学语言写清楚。这一章按"发电侧、转换侧、存储侧"三条线来讲,每条线都给出可以直接转成约束矩阵的表达式。
2.1 风机与光伏出力模型
风电和光伏的可再生出力曲线是调度模型的边界条件,一般用预测值建模。风机出力根据风速 $v(t)$ 和功率曲线来:
$$ P_{wt}(t) = \begin{cases} 0 & v(t) < v_{ci} \ P_r \cdot \left(\frac{v(t)^3 - v_{ci}^3}{v_r^3 - v_{ci}^3}\right) & v_{ci} \le v(t) \le v_r \ P_r & v_r < v(t) \le v_{co} \ 0 & v(t) > v_{co} \end{cases} $$
其中 $v_{ci}$、$v_r$、$v_{co}$ 分别是切入、额定和切出风速,$P_r$ 是额定功率。这个分段函数是连续非线性的,但调度中通常直接加载预测出力序列,不把它当作决策变量,所以无需线性化。光伏采用更简单的一阶模型:
$$ P_{pv}(t) = P_{stc} \cdot \frac{G(t)}{G_{stc}} \cdot \left[ 1 + k \cdot \left(T_c(t) - T_{stc}\right) \right] $$
$G(t)$ 为辐照度,$T_c(t)$ 为电池板温度,$P_{stc}$、$G_{stc}$、$T_{stc}$ 是标准测试条件下的对应值。对研究性质的调度问题,两条曲线提前给成向量就行;实际工程里如果要做滚动优化,再把预测误差用场景集或区间表示。
2.2 热电联产、燃气锅炉与电锅炉模型
CHP是综合能源系统里耦合度最高的设备,我建议用多边形可行域模型,而不是简单的"固定热电比"。设CHP电出力为 $P_{chp}$、热出力为 $H_{chp}$,典型约束为:
$$ 0 \le P_{chp} \le P_{chp,\max} \ H_{chp} \le A_{chp} \cdot P_{chp} + B_{chp} \ H_{chp} \ge C_{chp} \cdot P_{chp} + D_{chp} \ H_{chp} \ge 0 $$
这个多边形把CHP的背压运行区和抽汽运行区都包进去了。$A_{chp}$ 是上限斜率(对应最大热出力线),$C_{chp}$ 是下限斜率(对应最小凝汽线),具体系数由机组热力特性试验数据拟合得到。示意数值可取 $A_{chp}=0.8$、$B_{chp}=120$、$C_{chp}=0.2$、$D_{chp}=30$,单位兼容kW即可。
燃气锅炉出力 $H_{gb}$ 看成效率为 $\eta_{gb}$ 的转换器:$H_{gb} = \eta_{gb} \cdot P_{gas,gb}$,其中 $P_{gas,gb}$ 是输入燃气功率。电锅炉同理,$H_{eb} = \eta_{eb} \cdot P_{eb,elec}$。实际建模时燃气锅炉和CHP共用燃气购入成本,我会在优化目标里把两者合成一个气耗量,避免重复计量。
2.3 电解槽、储氢罐与燃料电池模型
电解槽的输入是电功率 $P_{p2g}$,输出是氢气质量流率 $M_{p2g}$(kg/h)。忽略负载率对效率的影响,用常数效率建模:
$$ M_{p2g}(t) = \frac{\eta_{p2g} \cdot P_{p2g}(t)}{LHV_{H_2}} $$
$LHV_{H_2}$ 是氢气低位热值,约33.33 kWh/kg。若 $\eta_{p2g}=0.6$,输入100 kW电约产生1.8 kg/h氢。更精细的模型要考虑电解槽的负载率-效率曲线,那是凸函数,也能用分段线性近似加进约束,但会显著增加变量数,初版模型用常数效率完全够用。
这里有一个单位陷阱:氢气的密度和能量密度跟压力有关,储罐压力变化时,储氢质量不能简单按体积线性换算。在Matlab代码里我直接用质量kg做状态量,天然避开了压力-体积换算问题。如果工程上要求按压力建模,就得把状态量换成压强,再加一个非线性存储方程;目前多数研究和应用都用质量模型,够用。
储氢罐是状态变量,记储氢量 $S(t)$(kg),上下限分别为 $S_{\min}$、$S_{\max}$。动态方程:
$$ S(t+1) = S(t) \cdot (1 - \alpha_{loss}) + M_{p2g}(t) - M_{fc}(t) - M_{demand}(t) $$
$M_{fc}(t)$ 是燃料电池消耗的氢,$M_{demand}(t)$ 是直接供应给氢负荷的部分,$\alpha_{loss}$ 是罐体泄漏系数,小时级可取0.5%~1%。注意这里默认时间步长是1小时,所以 $M$ 的量纲都是 kg/h。
燃料电池输出电功率 $P_{fc}$ 和热功率 $H_{fc}$ 分别由其氢耗量和效率决定:
$$ P_{fc}(t) = \eta_{fc,e} \cdot M_{fc}(t) \cdot LHV_{H_2} \ H_{fc}(t) = \eta_{fc,h} \cdot M_{fc}(t) \cdot LHV_{H_2} $$
典型取 $\eta_{fc,e}=0.45$、$\eta_{fc,h}=0.40$。这两条方程把氢平衡与电、热平衡串起来,是整个模型的关键耦合点。
2.4 负荷与能量耦合关系
系统的能量平衡是模型骨架。我建议把平衡方程写得越"笨"越好——能用一个等式表达就不用两个。典型24小时调度的平衡关系只需三个:
$$ P_{grid}(t) + P_{wt}(t) + P_{pv}(t) + P_{chp}(t) + P_{fc}(t) = P_{load}(t) + P_{eb}(t) + P_{p2g}(t) $$
$$ H_{chp}(t) + H_{gb}(t) + H_{fc}(t) + H_{eb}(t) = H_{load}(t) $$
$$ M_{p2g}(t) = M_{fc}(t) + M_{demand}(t) + \frac{S(t+1) - S(t)}{\Delta t} + \alpha_{loss} S(t) $$
第一个式子里的 $P_{grid}$ 若为负值,表示向电网反送电。实际工程中还要加购电/售电交互约束,这里先不展开。三条平衡方程配合设备约束和储氢动态方程,模型的主要框架就搭完了。
3. 优化调度模型的构建:目标函数、约束与决策变量
建模框架确定后,要把它转成标准优化问题。放在Matlab里跑,无非三件事:定义决策变量、写目标函数、列约束。但顺序和细节决定求解效率。
3.1 决策变量的组织方式
以24小时、步长1小时为例。我把决策变量按设备分块排成一个列向量 $x$:
$$ x = [P_{chp}(1{:}24), , H_{chp}(1{:}24), , P_{gb}(1{:}24), , P_{eb}(1{:}24), , P_{p2g}(1{:}24), , M_{fc}(1{:}24), , S(1{:}25)]^T $$
这样排的好处是后续写约束矩阵时,每一块对应一个时间序列,方便用Matlab的reshape函数做批量索引。如果模型还要考虑机组启停,就在 $x$ 里加入对应的二进制变量,模型变成MILP(混合整数线性规划)。我一般先跑一个纯LP版本确认可行域没问题,再加二进制约束,这样排查错误成本低很多。
3.2 目标函数与成本构成
调度目标通常是最小化系统总运行成本,我采用的目标写法如下:
$$ \min ; C_{fuel} + C_{om} + C_{curt} + C_{grid} $$
其中 $C_{fuel}$ 是燃气和购电费用,$C_{om}$ 是设备运维成本,$C_{curt}$ 是弃风弃光惩罚,$C_{grid}$ 是电网交互成本。每一项都可以表示成决策变量的线性函数:
$$ C_{fuel} = \sum_{t=1}^{24} \left( c_{gas} \cdot (P_{chp,gas}(t) + P_{gb,gas}(t)) + c_{grid}(t) \cdot P_{grid}^+(t) - c_{sell}(t) \cdot P_{grid}^-(t) \right) $$
$P_{chp,gas}(t)$ 是CHP的燃气输入功率,需要用气耗系数反推,我采用简化公式 $P_{chp,gas} = a_{chp} P_{chp} + b_{chp} H_{chp}$,其中 $a,b$ 是热耗系数。运维成本按单位出力单价计:
$$ C_{om} = \sum_{t} \sum_{i \in \Omega} c_{om,i} \cdot P_i(t) $$
弃风弃光惩罚给可再生能源不发电的机会成本定价:把"理论可用出力与实际出力的差额"算进目标函数,数值上等于在平衡方程里把消纳量做成决策变量。这个惩罚单价本质上是在扮演"希望系统多消纳可再生能源"的政策信号,取值大小会显著影响储氢罐的行动意愿。
3.3 关键约束的线性化处理
用YALMIP建模时,约束直接写成线性等式或不等式就行。但三个地方容易写出非线性,得提前处理:
- CHP可行域多边形:第2章的四个不等式全部保留为线性约束,注意写成 $H_{chp} - A_{chp} P_{chp} \le B_{chp}$ 这种标准形式,避免带入乘积项。
- 储氢罐SOC范围:$S_{\min} \le S(t) \le S_{\max}$ 是区间约束,但初始状态和终态约束都要写清楚。我习惯加 $S(25) \ge S(1)$,让24小时周期首尾相接,不然求解器总爱把储氢罐清空来省成本。
- 电和氢的单位换算:$M_{p2g}(t)=\eta_{p2g} P_{p2g}(t)/LHV_{H_2}$ 表面是线性关系,但如果 $LHV_{H_2}$ 用kWh/kg、功率是kW、时间是小时,就要保证 $M$ 的单位是kg/h。换算做错,结果会差一个数量级,这是新手最容易踩的坑。
4. Matlab代码实现:从矩阵搭建到求解器调用
建模理论讲完,进入代码层面。我用YALMIP写模型,因为它可以把约束以近乎数学公式的方式写出来,不易出错;求解器用Gurobi。下面按模块给关键代码段,并解释为什么这样写。
4.1 整体代码结构安排
一个完整的调度程序,我分成五个文件(或五个函数):
load_data.m:读入风速、辐照、电负荷、热负荷、分时电价等时间序列。build_vars.m:定义所有决策变量,统一按24小时向量化。build_constraints.m:逐条写入平衡约束、设备约束、储氢动态约束。set_objective.m:构建目标函数的各成本项并汇总。solve_and_plot.m:调用求解器,解析结果,画图。
数据文件我习惯统一存成Matlab结构体data,包含data.wind、data.pv、data.load_e、data.load_h、data.price等字段,后续函数直接data.wind引用,既清晰又不混变量顺序。这个结构的好处是调试方便——出问题时只需改动某一个函数,不用从头读整套代码。
4.2 用YALMIP搭模型的关键代码
核心代码片段如下:
T = 24; % 决策变量,每个变量都是一个 T×1 的向量 Pchp = sdpvar(T, 1, 'full'); % CHP 电出力 Hchp = sdpvar(T, 1, 'full'); % CHP 热出力 Pgb = sdpvar(T, 1, 'full'); % 燃气锅炉热出力 Peb = sdpvar(T, 1, 'full'); % 电锅炉热出力 Pp2g = sdpvar(T, 1, 'full'); % 电解槽输入电功率 Mfc = sdpvar(T, 1, 'full'); % 燃料电池氢耗 HS = sdpvar(T+1, 1, 'full'); % 储氢罐氢量,T+1个状态点 Con = []; % CHP 可行域 Con = [Con, 0 <= Pchp <= Pchp_max]; Con = [Con, Hchp <= Achp * Pchp + Bchp]; Con = [Con, Hchp >= Cchp * Pchp + Dchp]; Con = [Con, Hchp >= 0]; % 电解槽和燃料电池换算关系 Con = [Con, Mp2g == eta_p2g * Pp2g / LHV_H2]; Con = [Con, Pfc == eta_fc_e * Mfc * LHV_H2]; Con = [Con, Hfc == eta_fc_h * Mfc * LHV_H2]; % 储氢罐动态方程(t=1..T) Con = [Con, HS(2:T+1) == (1-alpha_loss)*HS(1:T) ... + Mp2g - Mfc - M_demand]; Con = [Con, HS >= HS_min, HS <= HS_max]; % 初始与终态衔接 Con = [Con, HS(1) == HS0, HS(T+1) >= HS1]; % 电、热平衡 Con = [Con, Pgrid + Pwt + Ppv + Pchp + Pfc == Pelec + Peb + Pp2g]; Con = [Con, Hchp + Hgb + Hfc + Heb == Hheat];第一个版本里Pwt、Ppv、Pelec、Hheat是预测序列常量,Pgrid是变量,所以电平衡方程其实等价于Pgrid = Pelec + Peb + Pp2g - Pwt - Ppv - Pchp - Pfc,再给Pgrid加电价约束。Mp2g、Pfc、Hfc这类中间变量也要定义为sdpvar,YALMIP允许在约束里做这种代数替换,代码可读性高,运行效率也稳定。
4.3 求解器选择与参数调试
推荐顺序:Gurobi >= CPLEX > intlinprog。前两者性能好、MIP求解快,intlinprog是Matlab自带的免费方案,模型规模小的时候完全够用。用Gurobi时,在YALMIP里设置选项:
ops = sdpsettings('solver', 'gurobi', 'verbose', 1, ... 'gurobi.MIPGap', 0.001, 'gurobi.TimeLimit', 300); optimize(Con, Objective, ops);如果模型含二进制变量,MIPGap设到0.1%或0.5%就够工程精度,低于0.01%会让求解时间成倍上升。求解前我会用check(Con)检查约束残差,确保没有无界或不可行问题。若出现不可行,优先查储氢罐初值约束和平衡方程是否矛盾——这条经验帮我省了很多次调试时间。
4.4 结果提取与可视化思路
求解结果存到value(Pchp)、value(HS)等变量中。最常用的可视化有三种:
- 时序堆叠图:画出各电源的出力叠放柱状图,直观看出风电消纳情况和CHP、燃料电池的出力变化。
- 储氢罐SOC曲线:看储氢量一天内的充放过程,判断氢储能是否真的在削峰填谷。
- 成本构成堆叠柱或饼图:对比燃料费、运维费、网电购入费,快速定位成本大头。
画图建议用Matlab的bar和stairs,数据格式是 $N \times 24$ 的矩阵,一行一个设备。这部分不用写得太复杂,重点是把调度策略呈现清楚,给报告或论文用。
5. 典型场景算例分析:氢能引入前后的调度结果对比
算例是检验模型有没有意义的试金石。我习惯用两个场景对比:场景A是无氢能基准场景(只含CHP、燃气锅炉、电锅炉和电储能),场景B是加入P2G、储氢罐和燃料电池的氢能场景。两者用同一套风电、光伏、负荷时序数据,参数一致,只允许设备清单不同。
5.1 算例场景设计
示意参数如表2。注意这些只是演示值,实际工程参数要按厂家手册或试验数据来。
| 设备 | 参数 | 数值 |
|---|---|---|
| 风电 | 额定功率 | 500 kW |
| 光伏 | 额定功率 | 300 kW |
| CHP | 电出力上限 | 400 kW |
| CHP | 电热可行域系数 | A=0.8, B=120, C=0.2, D=30 |
| 燃气锅炉 | 热出力上限 | 300 kW |
| 电锅炉 | 热出力上限 | 200 kW |
| 电解槽 | 输入功率范围 | 50~200 kW,η=0.6 |
| 燃料电池 | 电出力上限 | 150 kW,ηe=0.45, ηh=0.40 |
| 储氢罐 | 容量 | 100 kg |
| 储氢罐 | 初始氢量 | 50 kg |
| 购电价 | 峰/平/谷 | 1.0 / 0.6 / 0.3 元/kWh |
| 弃风惩罚 | 单价 | 0.5 元/kWh |
负荷曲线设置为典型冬季日:电负荷早晚双峰、热负荷夜间高。风电出力取夜间大、日间小的日特性,光伏为日间单峰。这个组合能同时检验夜间弃风消纳和日内电热耦合,在学术研究中很常见。
5.2 系统运行成本与弃风率对比
两个场景的优化结果对比如表3所示。数据和结果均为示意性质,重点看趋势。
| 指标 | 场景A(无氢) | 场景B(含氢) |
|---|---|---|
| 系统总运行成本 | 100%基准 | 约88% |
| 弃风率 | 12.5% | 2.1% |
| 风电消纳量 | 低 | 高(富余时段由电解槽多用电) |
| 储氢SOC平均 | 无 | 约45% |
| 燃气消耗量 | 基准 | 略降 |
成本下降主要来自两个渠道:一是弃风减少后系统可再生能源利用率提升,等效降低了购电成本;二是燃料电池在晚高峰发电阻止峰值购电,把高价时段电量压力转移给氢气储能。燃气消耗量下降的原因是燃料电池部分替代了CHP的热出力,同时CHP能在优化解里调整到更经济的工作点。
5.3 氢储能"削峰填谷"的行为分析
看储氢罐SOC曲线,场景B里电解槽在凌晨2点到6点几乎满负荷制氢(对应风电高峰和低谷电价时段),储氢罐SOC从50%升到约85%;傍晚17点到21点,燃料电池持续放电,SOC逐渐回落。这条曲线的形状完全由电价和弃风信号驱动,说明氢储能具备与电价联动的价格响应能力。
还有一个容易被忽略的点:添加氢能后,系统的热平衡方程里多了一个热源(燃料电池余热),这让CHP在夜间的热出力约束变得宽松,进而让CHP有机会降低电出力,进一步减少清晨时段的弃风。所以氢能的影响是间接且多条路径叠加的,只看弃风率或只看成本都不全面,建议至少从三个维度看:弃风率、购电成本、燃料消耗量。
如果把弃风惩罚单价从0.5元/度调到0.2元/度,储氢罐的充放次数会明显减少,系统更依赖购电而不是制氢。这说明弃风惩罚参数本质上在传递政策信号,调参时要结合实际的消纳考核目标去设定,不能简单套文献值。
6. 我踩过的坑和一点经验总结
代码跑通只是第一步,结果合理才算真的做完。以下几条是反复调试中总结出来的,分享出来帮大家省时间。
6.1 数值量级问题
Matlab求解器对模型矩阵的尺度很敏感。电功率单位kW、成本单位元、氢气单位kg,三者数值差好几个数量级。如果直接把约束矩阵交给求解器,个别约束的容差判断会出问题,表现为"明明满足约束,求解器却报不可行"。
我的做法是先统一单位,再对变量做归一化。比如把功率单位统一为MW、成本统一为百元、氢量统一为吨;或者在建模时给不同物理量加上合适的惩罚权重,让目标函数各项处于同一数量级。实测下来,数值尺度问题可以通过一个经验法则来规避:约束矩阵里最大元素和最小非零元素的比值保持在1e6以内。
6.2 储氢罐SOC约束的退化风险
氢储能模型里有一个很隐蔽的坑:如果储氢罐容量约束设得太松,同时末时刻氢量写成硬约束,求解器会倾向于让SOC在初值附近基本不动,整个氢储能环节"名存实亡"。这不是模型错了,而是价格信号不足以说服系统利用储氢罐。解决办法是提高弃风惩罚单价,或者在目标里加入储氢罐的充放收益项。
相反,如果SOC的终态约束设得太松,求解器会为了压低成本把罐子放空,曲线毫无实际意义。我最终的做法是把 $S(25) \ge S(1)$ 写进约束,同时把弃风惩罚设置得略高于电价低谷差,保证氢储能在经济上"值得动"。
6.3 混合整数规模膨胀与求解时间
加入机组启停变量后,模型变量数会在24小时维度上线性增长。CHP启停24个变量、电锅炉24个、电解槽24个,仅二进制变量就72个,MILP规模会到数百个约束。举个例子,我调试过的一个模型,加入24小时启停二进制变量后,约束从120个涨到近400个,求解时间从2秒跳到80秒以上;后来通过冻结夜间固定时段的启停状态,把求解时间压回15秒。
实操经验是:先不加启停约束跑LP解,确认运行点合理后再逐步加入启停,并把启停惩罚系数设到合适量级,避免高频启停的锯齿解。YALMIP里用binvar定义二进制变量,写implies关系时注意它会把问题转成大M约束;大M值选太大又会恶化数值稳定性,一般取设备出力上限的两倍就够。
6.4 用两层调试来验证模型正确性
最后分享一个常用的两层调试法。第一层是"平凡解测试":把所有购电价设成一样,风电、光伏、负荷曲线设为常数,跑出来的调度结果应该近似于按设备效率排队分配出力。如果结果出现奇怪的震荡,说明某个平衡约束写错了。第二层是"极端天气测试":把某时段风电降为零,看对应时段电解槽是否同步降到最小出力;若无变化,说明风电接入平衡方程的符号搞反了。这两层测试通过后,基本可以确信模型可靠,再跑多场景对比就有底气了。
除了解模型本身,我还会留一个"无氢基准模型"作为持续对照。后续每改一版约束或参数,都和基准场景对一次结果,这样既能快速发现回归错误,也能让我对氢能引入带来的实际收益保持清醒认识——不是每个场景都值得建储氢罐,算出来的经济账才最有说服力。