P2G厂站电-气综合能源系统规划:Matlab建模与代码复现 1. 项目概述与核心价值1.1 P2G厂站到底是什么它为什么能打通电-气两套系统最近我在复现一篇关于计及P2G厂站的电-气综合能源系统规划研究的硕士论文顺手把整套Matlab代码逻辑和建模思路梳理了一遍。P2G是Power-to-Gas的缩写中文叫“电转气”核心思路是利用电力系统的多余电能电解水制氢再把氢气和二氧化碳通过甲烷化反应合成天然气最终可以注入天然气管网。也就是说这台设备扮演的是“电能变气能”的转换器角色。你可能会问为什么要费劲把电变成气直接用电不行吗关键在于综合能源系统的耦合需求。当风电、光伏出力较大时电网可能面临弃风弃光而天然气系统这边可能正好缺气。P2G厂站建起来之后多余电力可以就地转化为天然气既缓解了电力消纳压力又补充了天然气供应相当于在两个能源网络之间架起了一座可双向调节的桥梁。另一个角度看类似的转换过程也可以反向发生——燃气轮机把气变成电所以电-气综合能源系统本质上是两个网络之间形成闭环互济。从技术路线看P2G通常有两段流程。第一段是电解水制氢电能转化为氢气的效率大约在60%到80%之间。第二段是甲烷化氢气与二氧化碳反应生成甲烷也就是合成天然气。如果只算“电到天然气”的全过程综合效率一般落在50%到65%之间。虽然这个数字不算高但P2G的价值更多体现在能量时移、可再生能源消纳以及降低系统整体碳排放上不能单看局部效率。这一篇论文里P2G厂站被当作规划对象来看待要不要新建、在哪些节点建、建多大规模、每个调度时段怎么运行。整个规划模型要把电力系统、天然气系统和P2G设备放在一个统一框架里优化。复现这样的研究对正在做综合能源系统相关课题的研究生来说是很好的练手项目对工程师来说也能通过案例推演评估P2G厂站在实际区域里的经济价值和减排潜力。1.2 复现这篇论文能帮你解决什么问题做论文复现最怕的就是模型看得懂、代码写不出。论文里通常只有数学公式和最终结果表最关键的参数、约束表达、场景设置往往藏在附录甚至正文之外。我这次复现的最大体会是把抽象的优化模型翻译成Matlab代码需要的不是单纯写代码的能力而是对建模逻辑的全局把控。你可能花一周时间搭建第一版模型却要再用两周时间跟“求解失败”“维度不匹配”“结果明显不合理”这些问题死磕。复现的价值在于它会逼着你把每一个符号落实成矩阵、向量和约束。比如论文中写着“节点功率平衡”你要考虑的是变量维度是节点数乘时段数平衡方程等号右边是电源出力加P2G消耗电功率等号左边是电负荷加外送功率。任何一个地方对不上求解器就给你返回infeasible。这种训练比单纯读十篇文献都管用。读完这篇文章你至少能获得三样东西第一一个清晰的规划建模路线图包括目标函数、约束集合、耦合设备模型第二一套可直接上手的Matlab代码框架基于YalmipGurobi实现第三一份我在复现过程中踩到的坑清单能让你少走很多弯路。2. 整体建模思路拆解2.1 目标函数钱花在哪里省在哪里规划问题首先要想清楚“以什么为目标”。绝大多数规划论文把目标函数设定为总成本最小化包括投资成本和运行成本两部分。投资成本是新建P2G厂站、输电线路、天然气管道的费用运行成本是购电费用、购气费用以及设备运行维护费用。投资成本有一个年份折算问题。P2G厂站使用寿命通常在20年以上但规划周期可能只有一年或几年所以要把总投资乘以一个“年分摊系数”换算成等效年度成本。这个系数一般用等额年值公式计算。具体形式是r * (1r)^N / ((1r)^N - 1)其中r是贴现率N是设备寿命。很多初学者忽略这一层直接把总投资叠加到单年运行成本上做出来的结果一定是设备投资占比异常大求解器会因为投资成本太高而选择不建设任何设备。除了成本项还可以加碳排放惩罚。P2G虽然本身是清洁转换技术但它消耗的电如果来自火电实际上也存在间接碳排放。同时它产出的天然气替代了传统天然气供应又减少了气源侧的碳排。因此碳排放建模可以做得很细在目标函数中加上火电购电排放、气源开采排放、P2G产气带来的净减排收益等。在Matlab代码里目标函数通常写成obj investment_cost operation_cost carbon_cost的形式。用Yalmip时变量是sdpvar目标函数可以直接是这些变量的线性组合。注意这里有个很关键的点目标函数必须是凸的或者至少是线性的混合整数线性规划求解器才能高效处理。如果出现非线性项比如两个变量相乘就要考虑线性化处理。2.2 约束条件电力系统、天然气系统与耦合设备的组合规划模型的核心约束分三层。第一层是电力系统约束第二层是天然气系统约束第三层是耦合设备约束。电力系统约束中最基本的是节点功率平衡。对一个简单的直流潮流模型每个节点在每个时段的注入功率等于负荷功率。注入功率包括常规火电出力、风电光伏出力、从外部电网购电功率同时减去P2G消耗的电功率和线路传输功率。直流潮流模型里线路潮流与节点相角差成正比这要求系统有统一的基准功率和足够的电压相位支撑。在规划层面大多数论文用直流潮流因为交流潮流非线性太强会严重影响求解效率。天然气系统约束稍微复杂一些。首先是节点气流量平衡包括气源注气、管道流入流出、储气库充放气、P2G注入的合成天然气以及用户用气负荷。管道流量通常用Weymouth方程描述管道流量与两端气压差的平方根成正比。这个方程是非线性的在规划问题里必须线性化处理。常见的做法是分段线性化或者采用增量线性化方法把气压差和流量之间的关系拆成若干个线性区间。如果你不做线性化Matlab内置求解器和Yalmip调用的Gurobi都很难处理这类非凸约束。耦合设备约束是电-气综合能源系统的精髓。对P2G设备约束方程是输出天然气流量 输入电功率 × 转换效率 × 热值换算系数。对燃气轮机方程是输出电功率 输入天然气功率 × 发电效率。除此之外设备有出力上下限约束例如一台额定功率100MW的P2G设备运行功率一般在20%到100%容量之间。规划变量还存在“是否建设”的0-1决策变量对应的约束是如果该节点不建设P2G则容量取0输出也取0如果建设实际安装容量要在最大可行容量范围内。投资约束常常用大M法处理。比如P2G输入功率 ≤ 容量变量 × 0-1变量再加一个右端项M。当0-1变量为0时输入功率强制为0当0-1变量为1时输入功率上限是容量变量。类似的处理也用在新建线路和管道的投运状态上。这类约束是典型的混合整数线性规划结构求解器可以通过分支定界法处理。2.3 场景与不确定性用典型日近似全年运行规划问题面临的最大不确定性来自负荷波动和可再生能源出力。如果直接把全年8760个小时全部纳入优化模型变量数量和约束数量会爆炸式增长。以一个小型电-气系统为例假设电力节点24个天然气节点20个每小时一组变量全年就是8760组加上投资变量整个模型会变得极难求解。论文里普遍采用的做法是场景缩减。先把全年的风电、光伏、电力负荷、气负荷数据收集起来用K-means聚类或同步回代消除技术提取几个典型日。每个典型日代表一类相似运行状态再乘以该类状态在全年的天数权重就能近似还原全年运行成本。这样变量规模从8760小时降到几个代表性时段比如24个典型时段乘以4个季节场景总共96个时段模型规模就完全可控了。我在复现时用的是3个典型日场景每个场景取24小时分辨率。虽然相比更精细的随机规划模型粗糙一些但运行时验证效率高优化结果也具备参考价值。如果你想把不确定性建模做得更严谨可以在典型日基础上加随机场景集合用两阶段随机规划框架第一阶段做投资决策第二阶段做运行决策。不过那会大幅增加计算量建议先把确定性版本跑通再考虑扩展。2.4 为什么线性化这么关键很多刚接触规划模型的人容易忽视线性化的重要性。Yalmip和Gurobi确实支持非线性优化但代价非常大。一个包含上百个二进制变量和上千个连续变量的MILPGurobi可能几十秒解完但如果模型里混入大量非线性约束求解时间可能从几十秒变成几小时甚至根本求不出全局最优解。以P2G设备运行功率与容量乘积产生的约束为例如果写成“输入功率效率×容量×运行状态”这个约束包含了“效率”参数乘以两个变量属于非线性。正确做法是把运行状态用0-1变量分离并通过大M法把非线性关系拆成线性不等式组。做线性化时要注意两点一是松弛幅度要控制好M值取太大容易导致求解精度下降取太小又可能错误剪掉可行域二是分段线性化的断点数量要适中断点太少精度不够断点太多又增加二进制变量数量。3. Matlab代码实现与实操要点3.1 代码整体架构把模型拆成文件来管写Matlab代码最忌讳的是把所有内容都堆在一个脚本里。规划模型代码天然包含数据准备、参数定义、变量声明、约束构建、求解、结果分析六个模块。我建议按下面这个结构拆分文件每个文件只负责一件事出问题时也好定位。main.m主程序按顺序调用各模块。data_load.m加载系统拓扑、负荷数据、新能源出力数据、设备参数。define_parameters.m定义所有常量包括贴现率、设备寿命、效率、价格。define_variables.m统一声明优化变量包括投资变量、运行变量、辅助变量。constraints.m构建所有约束条件。objective.m构建目标函数。solve_model.m调用Yalmip的optimize命令选择求解器并输出状态。plot_results.m绘制P2G容量配置、各时段出力、系统成本构成等图表。参数统一放在一个文件里调参方便。变量单独声明再传给约束和目标能避免“变量在约束里突然找不到”的尴尬。我见过不少同学的代码约束定义和变量声明混在一起一旦修改参数整个矩阵维度全乱调试过程非常痛苦。3.2 从参数到变量的核心代码片段解读下面给出几段关键的Matlab代码。第一段是定义优化变量展示如何使用sdpvar和binvar。% 假设电力节点数为N_e天然气节点数为N_g场景数为S每个场景时段数为T % 投资变量 x_p2g binvar(N_e, S, full); % 是否在电力节点新建P2G cap_p2g sdpvar(N_e, S, full); % P2G安装容量单位MW % 运行变量 p_p2g sdpvar(N_e, S, T, full); % P2G消耗电功率 g_p2g sdpvar(N_g, S, T, full); % P2G注入天然气功率注意P2G厂站通常接在电力系统的某个节点上但注入天然气的位置可能在气网的某一节点。如果P2G与气网节点之间还有压缩机或者管道连接需要额外建模。我这里为简化处理假设建在电力节点i上同时连接到对应的气网节点j。第二段是目标函数年投资成本和年运行成本的总和。投资成本用安装容量乘以单位投资成本再乘以年分摊系数。annuity (r * (1r)^N) / ((1r)^N - 1); inv_cost sum(sum(unit_p2g_inv .* cap_p2g)) * annuity; % 运行成本购电成本 购气成本 运维成本 op_cost sum(sum(sum(pg_cost .* p_p2g))) ...;第三段是P2G设备的核心约束。转换关系是注入气网节点单位时段的热值能量等于电功率乘以转换效率。for s 1:S for t 1:T % P2G输出气体功率折算到天然气热值 输入电功率 * 转换效率 g_p2g(j, s, t) p_p2g(i, s, t) * eta_p2g; % 最大出力约束用容量变量和0-1变量限制 p_p2g(i, s, t) cap_p2g(i, s); p_p2g(i, s, t) M * x_p2g(i, s); end end如果你把这一块写进循环嵌套层数是三层。绝大多数Matlab新手标配错误就是循环变量名冲突或者矩阵索引不一致。我的经验是先把小规模测试系统跑通比如3个电节点、2个气节点再用完整系统数据。第四段是电力系统节点功率平衡约束的简化示例。P2G消耗电力作为一个“负电源”放入平衡方程。P_balance(e, s, t) P_load(e, s, t) p_p2g(e, s, t) sum(P_line(:, e, s, t));其中P_balance是节点注入功率包括发电机组出力和外部购电。这里P_p2g只有在当前节点为P2G接入节点时才非零因此约束里要加上“x_p2g0则p_p2g0”的条件。3.3 数据准备与单位换算规划模型最隐蔽的坑是单位制混乱。电力系统习惯用MW和MWh天然气系统习惯用m³/h或者MW按热值折算。如果P2G效率用的是“千瓦时电换立方米气”那你在同一个模型里必须统一把气网数据换算成MW热值。天然气热值通常取36 MJ/m³左右1 m³天然气热值约等于10 kWh。也就是说1000 m³/h的气流量约等于10 MW的热值功率。建立模型前先把电力负荷和气负荷全部转成统一单位再编写约束否则单位换算错误会导致优化结果偏离实际。另外场景数据也需要预处理。每年风电出力和光伏出力的量纲是MW负荷数据可能是MW但气负荷原始数据如果是立方米/小时就直接用上述系数换算。换算完成后所有数据格式统一为二维矩阵“节点数×时段数”然后按场景序号堆叠成三维数组。三维数组的顺序建议一律用“节点×场景×时段”这样在Matlab里索引不混乱。4. 复现过程中的常见问题与避坑指南4.1 环境配置问题Yalmip与Gurobi的那些坑使用Yalmip需要提前安装并配置求解器。Gurobi是学术界常见的商业求解器但需要许可证。你可以在Gurobi官网申请学术许可证免费用于科研。安装步骤不复杂但有一个细节特别容易忽略Matlab的addpath路径要指向Gurobi安装目录下的matlab文件夹而不是Gurobi的根目录。很多同学用addpath(genpath(...))一把梭可能会导致Yalmip加载到多个版本的求解器接口反而报错。安装好之后在Matlab里输入yalmiptest会弹出一个诊断窗口显示是否成功找到Gurobi。如果显示No suitable solver最常见的两个原因一是环境变量没配好二是Matlab版本不兼容。Gurobi对旧版Matlab的兼容性一般建议用MATLAB R2020a以上版本。还有一种情况你明明装好了求解器但优化时Yalmip自动选用了默认的内置求解器。这时候需要在求解命令前手动指定assign或者用optimize的选项参数ops sdpsettings(solver, gurobi, verbose, 2); result optimize(F, obj, ops);4.2 编译报错、维度不匹配与求解困难维度不匹配是规划模型中最高频的错误。原因是Yalmip对矩阵维度的敏感度极高两个sdpvar变量做加法时维度必须完全一致。你定义容量变量时用了N_e×S后来在循环里试图给(i, s, t)赋值某个逻辑表达式维度不一致就直接报错。排查方法很简单在错误行前暂停程序打印变量尺寸检查当前索引的实际维度。另一个常见问题是约束构建后求解器返回infeasible。不要急着改求解器参数先检查模型本身是否矛盾。我常用一个“最小可行模型”调试技巧第一步固定所有投资变量为1求解运行模型如果运行模型可行说明问题出在投资约束的逻辑上。第二步把约束数量减半逐步加回来找到哪条约束导致不可行。通常罪魁祸首是某条线路容量上限太小或者某个节点的负荷数据填写错误。4.3 结果异常怎么排查从模型和数据入手如果求解器报告成功但结果明显不合理比如P2G设备没有被选择、或者容量为0那大概率不是求解器的问题而是目标函数或参数有误导信息。先检查单位投资成本是否偏高若每年分摊到成本里的费用高于它能带来的运行收益优化器当然选择不建。再检查气网购入天然气价格是否偏低如果天然气太便宜P2G产气的经济性就没有体现出来。还有一个容易忽视的点是效率参数方向。P2G效率若写成“输入气等于输出电乘以效率”那效率大于1时相当于凭空造能量求解器会利用这个漏洞疯狂产气而不用消耗电。一定要确认效率在0到1之间且正向关系正确。4.4 提高求解效率的几个技巧规划模型的求解规模受场景数和节点数影响极大。当模型变量超过几万时直接求解会非常慢。我试过有效的几个优化手段一是给每个0-1变量提供合理的初值用assign函数指定初始解二是设置sdpsettings(solver,gurobi,mipgap,0.01)允许1%的相对间隙求解时间往往能缩短好几倍三是减少无效约束比如没有建设P2G的节点就不生成对应约束四是把对称约束剔除避免求解器在等价的决策分支上重复搜索。5. 个人体会、扩展方向与最后一句话5.1 我的复现心得把这篇论文的模型完整在Matlab里实现一遍之后我对“电-气综合能源系统规划”的理解比之前只读文献要扎实很多。最大的体会是P2G不一定在所有场景下都有经济效益它的价值高度依赖电力系统的新能源渗透率、气价、电价以及碳排放价格。如果所在区域弃电很少、天然气价格很便宜P2G设备很可能在优化结果里不会被选择。这不是模型错误而是经济性的真实反映。代码层面最大的收获是理解了大规模规划模型要“拆得开、合得上”。拆成模块之后我可以快速替换场景数据、修改效率参数重新运行一次全套流程只需要几分钟。这给后续研究留了很大空间。5.2 可以扩展的研究点这个模型其实有很多扩展方向。比如加入储能装置、氢燃料电池车负荷、碳捕集与封存、需求响应机制甚至做成跨季节新能源消纳的长期规划。也可以把确定性模型扩展为两阶段随机规划加入风速和负荷预测误差的随机分布。如果追求更贴近工程实际还可以加入N-1安全校验约束评估P2G厂站在故障状态下对系统供能安全性的支持作用。我个人的建议是先把这个版本复现通透再逐步增加复杂度。每加一种新元素先在小规模节点系统上测试模型逻辑确认无误后再推广到完整数据。这套方法论比单纯拿到一段可以跑的代码更有价值。最后再说一句复现论文的过程一定会遇到各种细节问题但每解决一个你对综合能源系统规划的理解就深一层这种收获是直接调包代码很难替代的。