
最近组里在做综合能源系统规划方向的项目正好有同学在复现一篇“计及P2G厂站的电-气综合能源系统规划研究”的硕士论文拉着我一起把整个模型和Matlab代码捋了一遍。说实话这类题目在现阶段非常典型双碳背景下风电光伏大规模并网弃风问题突出电转气Power to Gas作为一种能打通电网和气网、把多余电能转化成天然气的技术被越来越多的规划研究拿来做核心内容。这篇复现工作本质上是解决一个带混合整数变量的优化规划问题在给定电网、气网拓扑和负荷预测的前提下决定P2G厂站的选址、定容以及整个系统在多场景下的运行方式使得总成本最低同时满足电网潮流、天然气节点平衡、压缩机、设备爬坡等一系列约束。Matlab代码采用Yalmip工具箱建模配合商业求解器求解混合整数二阶锥规划MISOCP问题。这篇文章适合正在做综合能源系统优化、需要复现论文算例的硕士生和研究人员也适合第一次接触电-气耦合建模、想了解P2G如何进规划模型的工程师。我会从模型原理、数学推导、代码框架、算例设计到调试踩坑全都展开给你一条能直接照着走的路。1. 先弄明白为什么是P2G厂站规划问题到底在“规划”什么1.1 P2G在系统里扮演的角色没那么玄乎电转气本质上就两步先电解水制氢再把氢和二氧化碳甲烷化得到天然气注入气网。规划层面关注的是设备整体的“电-气转换效率”也就是输入多少电功率能输出多少天然气功率典型效率在0.4到0.65之间视电解槽和甲烷化工艺的配置而定。从系统角度看P2G厂站的引入给整个电-气综合能源系统增加了一个可控的耦合环节。电网负荷低谷期或风电大发时电用不完与其弃掉不如驱动P2G把电变成天然气存进气网气网需要调峰时这部分气又能变成天然气供给。规划研究加入P2G目标就是算清楚这笔账多花多少投资建设P2G能在运行阶段省下多少弃风惩罚、减少多少购气成本甚至代替一部分新建输电线路或储能的投资。1.2 规划问题拆解投资决策与运行决策是两层事这类综合能源规划常见做法是把投资决策和运行决策粘在一个模型里也就是“投资-运行联合优化”。投资决策是0-1整数变量比如在哪个节点建P2G、建多大的容量运行决策是连续变量比如各时段电网出力、气网节点压力、P2G输入功率。这里有个特别容易忽略的点运行变量必须“适配”投资方案。如果没有在某节点建设P2G那个节点就不该出现任何P2G的输入输出功率。这个逻辑在建模时是一组“大M约束”或者“指示约束”来保证的。我复现时遇到的一个问题就是这些耦合约束的系数写法后文会详细讲。另外规划模型里通常还要考虑风电出力的不确定性。论文中常用的手段是“典型场景法”把全年的风电出力曲线聚类成几个典型场景每个场景对应不同的出力系数和持续时间然后在目标函数里乘上各自权重。这样既能反映不确定性的影响又不会把模型搞成复杂的随机规划求解规模还能接受。2. 模型数学内核目标函数和约束体系逐项拆解2.1 目标函数是总成本最小不是只算运行钱规划模型目标函数核心就是最小化总成本一般为[ \min \quad C_{\text{inv}} C_{\text{op}} ]其中 (C_{\text{inv}}) 是投资成本常见形式为[ C_{\text{inv}} \sum_{i \in \Omega_{\text{P2G}}} \alpha_i \cdot c_i \cdot S_i ]这里 (\alpha_i) 是P2G候选节点 i 的0-1建设变量(c_i) 是单位容量投资成本元/kW(S_i) 是建站容量。注意有些论文还会把投资成本的“等年值”折算加进去也就是考虑设备寿命L乘以一个资本回收系数。一共多少年折算到每年这个细节直接决定经济性结论不能漏。如果不折算成本现值运行成本被高估P2G可能被过度建设。我做复现时用了10年等年值折算折现率5%。(C_{\text{op}}) 是运行成本一般包括购电成本、购气成本、弃风惩罚成本可能还有CO₂处理或碳税成本。公式形式大致是[ C_{\text{op}} \sum_{s \in \Omega_S} \omega_s \sum_{t} \left( c_e P_{t,s}^{\text{buy}} c_g F_{t,s}^{\text{buy}} c_{\text{cut}} P_{t,s}^{\text{cut}} \right) ](\omega_s) 是场景权重这一项的求和体现了多场景期望成本。这里的关键是“弃风惩罚成本”不能设得太低否则模型宁愿弃风也不建P2G结果会失真。一般设成略高于风电上网电价才能让模型主动用P2G消纳弃风。2.2 电网侧约束除了潮流平衡别忘了联络线容量电网侧建模通常采用直流潮流近似因为规划问题规模大、时段多非线性交流潮流会让求解器直接崩溃。直流潮流的节点功率平衡是[ \sum_{j \in \Omega_{\text{line}}} B_{ij}(\theta_i - \theta_j) P_i^{\text{P2G}} P_i^{\text{load}} P_i^{\text{gen}} P_i^{\text{buy}} - P_i^{\text{cut}} ]额外需要约束联络线功率不越限即 (|P_{ij}| \le P_{ij}^{\max})。这里有个容易被坑的细节电-气系统的耦合节点上P2G用电 (P_i^{\text{P2G}}) 是把电负荷往上加如果代码里写成电源项方向搞反整个算例的潮流会乱掉。我当时调了好久最后把功率方向标注到注释里才理顺。2.3 天然气网侧约束节点流量平衡和Weymouth方程是难点天然气网的节点流量平衡相对直观[ \sum_{k} f_{ki} - \sum_{k} f_{ik} F_i^{\text{P2G}} F_i^{\text{source}} F_i^{\text{load}} ]其中管道流量 (f_{ij}) 和管道两端压力的关系是经典的Weymouth方程[ f_{ij}^2 K_{ij}^2 \left( \pi_i^2 - \pi_j^2 \right) ](\pi) 是节点压力。这个方程是非线性的求解极不友好。论文中常规操作是两种一是用增量分段线性化把平方项和乘积项逐段逼近二是用二阶锥松弛把 (\pi_i^2) 替换成新变量方程重写成[ f_{ij}^2 \le K_{ij}^2 \left( \Pi_i - \Pi_j \right) ]变成凸约束。这样整个模型就是“混合整数二阶锥规划”商用求解器能直接求解。但要注意松弛后约束变松了理论上可能让最优解高估可传输流量需要检查解是否满足原始等式约束不满足就得往目标函数里加压惩罚项。这个细节在算法调参时极重要。3. Matlab代码实现Yalmip建模 商业求解器的工程化套路3.1 为什么选MatlabYalmip这套组合做科研复现Matlab配合Yalmip工具箱是目前学术圈最顺手的组合。我个人的实际体验是用Yalmip建模可以用sdpvar、binvar、intvar这种变量类型直接写数学表达式比如约束写成 (F \le G)、目标函数写成 (C_{\text{inv}} C_{\text{op}})底层会自动转换为求解器需要的标准形式能省掉大量手写矩阵拼接的返工时间。规划课题到了求解阶段一般交给商业求解器处理MISOCP问题。如果是学生做学术复现用免费学术license即可容量限制对中等规模算例完全够。如果建模出的是非凸二次约束常规商业求解器会直接报错或提醒你加非线性设置这个坑后面细说。总之Yalmip适合快速验证模型同时又保留了调参的灵活性。3.2 代码模块化设计主程序、数据、建模、求解、后处理分开从工程化角度我建议复现代码按这五个模块拆分数据初始化脚本定义所有系统参数如电网节点数、气网节点数、负荷曲线、风电场景、管道参数、成本系数。变量定义区定义所有sdpvar和binvar并把维度、含义写清楚。约束组装区把目标函数、各类约束逐个写入一个约束元胞数组或矩阵方便debug。求解调用区设置求解器选项如求解时间上限、gap容忍度然后调用optimize函数求解。结果提取与画图区提取变量绘制节点压力、P2G容量、各场景出力图并计算成本明细。刚开始复现时很多人习惯把全部代码写在一个大脚本里但后面调试约束维度、排查不可行问题会非常痛苦。我用的是拆成init_data.m、build_model.m、solve_model.m、plot_results.m四个文件只要保持参数结构体统一调试时改一处就能全局生效。3.3 核心代码结构示例从变量到约束的手把手写法给出一个缩减版框架非完整可运行代码供理解逻辑% 变量定义 alpha binvar(n_p2g_candidate, 1); % P2G选址变量 S_p2g sdpvar(n_p2g_candidate, 1); % P2G容量变量 P_p2g sdpvar(n_p2g_candidate, n_time, n_sc); % 各时段/场景P2G用电功率 F_p2g sdpvar(n_p2g_candidate, n_time, n_sc); % 各时段/场景P2G产气量 theta sdpvar(n_bus_e, n_time, n_sc); % 电网相角 Pi sdpvar(n_bus_g, n_time, n_sc); % 气网节点压力平方变量约束方面最关键的耦合约束是确保“没建P2G就不能用P2G”% 未建设节点P2G功率和产气均为0 Constraints [Constraints, P_p2g 1e5 * alpha]; % 大M约束 Constraints [Constraints, F_p2g 1e5 * alpha]; Constraints [Constraints, S_p2g 0, S_p2g S_max * alpha];这里的量级要看系统规模1e5这个M值是在系统最大功率几十MW量级时取的如果负荷上万千千瓦就必须调大。M值太小会砍掉可行域M太大又会让0-1整数变量区分度变差求解效率下降。我的经验是M值设为节点最大注入功率的10倍左右比较稳。P2G运行约束则是输入电功率和输出气功率之间的转换关系F_p2g eta_p2g * P_p2g; % 效率约束此处可写成等式或不等式约束如果论文还考虑了P2G爬坡约束可以在代码里追加一维时间差约束例如abs(P_p2g(:,t,:) - P_p2g(:,t-1,:)) ramp_rate。3.4 二阶锥约束怎么写进Yalmip气网Weymouth方程的二阶锥松弛形式在Yalmip里直接写for i 1:n_pipe for t 1:n_time for s 1:n_sc Constraints [Constraints, f_pipe(i,t,s)^2 K_pipe(i)^2 * (Pi_up(i,t,s) - Pi_dn(i,t,s))]; end end end这里 (f_{pipe}) 是管道流量变量(Pi_up) 和 (Pi_dn) 是对应管道首末节点的压力平方变量。如果Yalmip识别不了这种锥约束你可以手动用cone命令把约束改写成cone(f_pipe, K*sqrt(Pi_up-Pi_dn))的形式通常麻烦就在这个地方。一旦识别成功求解器会把它当作二阶锥约束处理比非线性规划稳得多。3.5 求解设置别让默认参数拖慢收敛调用optimize时几乎所有规划复现我都建议关掉求解器多余的输出同时设置合理的mip gap。Yalmip里可以这样设置options sdpsettings(solver,gurobi,verbose,2,... gurobi.MIPGap,0.01,gurobi.TimeLimit,1800);MIPGap设为0.01意思是1%最优性间隙就能接受TimeLimit设为1800秒防止模型卡死。一般来说规划类模型MIPGap设到0.005或0.01已经足够工程精度没必要死磕0.0001%不然求解时间会翻好几倍。4. 算例设计与结果分析怎么验证你的模型“自圆其说”4.1 测试系统选择与参数怎么来复现论文第一步是选测试系统。电-气综合能源系统常见的做法是电网用某个标准测试系统气网用一个配套的节点天然气网络两者通过P2G候选节点耦合。选系统时要注意节点的“等值机制”例如电网节点电负荷和气网节点气负荷需要归一化到同一个基准值否者P2G容量结果无法对应。参数设置方面个人经验是优先从论文或典型数据来不要自己瞎编。如果论文没公布具体参数取行业共识数据也可以例如P2G单位投资成本取在4000-6000元/kW范围电转气效率取0.6弃风惩罚成本取风电上网电价的1.5倍左右。不同成本设定得到的建站结果差异很大论文图表复现的关键往往就在这些参数上。4.2 典型结果长什么样选址、定容、运行出力求解完成后一般会输出以下几样关键结果P2G厂站的选址位置、各候选站点的建设容量、各典型场景下的电功率输入和气功率输出、电网弃风率变化、总成本及成本构成。分析结果时有个关键技巧把成本拆开看。比如不建P2G时总成本多少建了P2G后投资成本增加多少、购气成本降低多少、弃风惩罚成本变化多少。如果建P2G后总成本反而上升排除参数设置因素大概率是模型或数据出了问题要么P2G效率太低要么弃风惩罚和购气成本差异没拉开。这些都可以作为结果合理性的“自检验证”。容量设置上有个常见现象P2G不会建在气网负荷极高或极低的节点而是倾向于建在电网侧弃风严重、气网侧有足够负荷消纳空间的耦合点。如果一个节点电网电气距离很远、气网管道容量又小即使弃风再多也很难成为最优选址。对比结果时你要能从拓扑上解释P2G选址而不是只给一个“算出来就是这样”的结论。4.3 有/无P2G对比实验这样设计才叫谈“计及”做“计及P2G”研究的核心展示方式就是设置对照工况一个不包含P2G设备的基准系统一个包含P2G候选厂站方案的“P2G系统”再对比两者的总成本、弃风率、购气量、电网潮流等指标。如果你只是在原系统里塞几个P2G变量就跑不设对照组审稿人或导师一眼就会觉得论证不足。正确的对比操作是基准工况不提供P2G候选直接优化记录总成本和弃风率。P2G工况加入选址定容变量优化记录结果。敏感性分析改变P2G投资成本或效率观察选址和容量如何迁移。我复现时比较喜欢画这么一张图横轴是P2G投资成本系数0.5倍、1倍、2倍纵轴是总成本和弃风率曲线交叉点能很直观地说明P2G投放的“经济临界点”。这张图放论文里很有说服力也方便你验证模型逻辑是否通顺。5. 常见问题与调试经验这些坑我替你们先踩了5.1 环境配置工具箱和求解器的链路问题这种复现项目第一步就是搭环境。我先装了较新版本的Matlab然后用系统命令行安装Yalmip工具箱。问题高发点是Yalmip装好了但求解器路径没配好调用optimize时一直报“No solver found”或者“Solver not available”。这是最常见的坑。解决办法是在Matlab里运行yalmiptest这个命令会把注册的求解器检测一遍看哪些可用。如果检测不到商业求解器确认你的求解器license文件是否有效或者重新将求解器目录添加到Matlab路径。我调试时还遇到过求解器只装了命令行版、没有Matlab接口的情况这种直接把整个安装目录都addpath(genpath(...))就行。提示安装工具包不要盲目用破解版很多问题反而是破解版不完整导致的用正规的学术license在设置里的报错信息会清晰很多。5.2 约束维度不匹配最常见的模型报错来源用Yalmip时最恼人的报错是“Unable to perform assignment because the size of the left side is...”或者“Inconsistent dimensions”。出现这种基本上都是变量维度定义和约束维度对不上。我的排错方法是从第一个约束开始逐行注释掉跑一次optimize看是否报错然后二分定位。维护二次元矩阵运算可以避免很多问题例如P_p2g是三维变量候选节点数×时段数×场景数对应约束循环下标就要严格按这个顺序来。建议在定义每个变量后立刻用size()检查维度和拓扑数据。实际项目里我见过太多时间被浪费在“约束写反”“转置漏掉”这类低级错误上。还有一类隐藏问题整数变量和连续变量混乘。Yalmip对此支持还不错但如果式子写成alpha .* S_p2g这种双线性形式会引出非线性求解路径导致求解器不认。所以规划模型里要避免整数变量和连续变量的乘积用大M约束或引入辅助变量线性化。5.3 二阶锥松弛不紧或解不可行检查Weymouth方程变形二阶锥松弛在气网约束中是关键。如果求解结果中管道流量和压力关系差很多那松弛可能“不紧”即约束被放宽太多了。这时目标函数值会比真实可行解低很多失去了参考意义。处理思路有两个一是把所有管道的松弛后的对偶值/间隙打印出来找出哪个管道放松最严重给该管道加精度罚项二是直接对每个管道写两个方向的不等式约束把松弛收紧成等式加一个小容忍误差但这样模型可能重新变非凸求解变慢。如果遇到“模型不可行”报错优先怀疑是气网拓扑中存在孤立节点即没有气源也没有管道连接。常规做法是检查节点关联矩阵的连通性或者给每个气源节点设置一个高价的虚拟供气变量让模型在任意极端工况下至少有一个可行解。这个技巧在调试时非常救命。5.4 求解时间过长从时间复杂度上动刀规划运行联合优化时间和场景稍多变量规模会到几十万个求解器跑几小时都可能。这时候别急着抱怨先做两件事一是压缩场景。典型场景数从10个压缩到5个只要覆盖高弃风、高负荷、普通三种类型结果差异其实很小。二是压缩候选P2G节点数量。候选从20个降到8个运行速度能提升一个量级。然后再把容量变量离散化改成少数几档标准容量把连续变量变成整数选择也可以大幅缩短求解时间。我做过一个对比实验同样规模的算例候选节点从10个减到5个求解时间从2100秒直接降到480秒成本结果只差约2%。对于规划问题这个精度完全能接受。5.5 结果不太对劲时先回归“傻瓜检测”复现过程中我会周期性地做“傻瓜检测”把P2G效率设成0验证模型会不会自动不建P2G把弃风惩罚设成极大验证模型会不会把所有机端弃风消纳掉把气网负荷全设成0验证会不会导致无解或购气为0。这些自我检验看起来简单但能快速暴露模型中的隐藏Bug。我当时就是因为没做“P2G效率为0”的测试迟迟没发现耦合约束中的大M绑定错误导致P2G在效率为0时居然还能出力。6. 实操心得与扩展方向复现这类题目最难的不是单个模块而是让一堆学科术语“电网潮流、气网Weymouth、混合整数规划、场景聚类、二阶锥松弛”在一个模型里彼此衔接。我的心得体会是一步一步来先跑通最简单的“无P2G”基准模型验证潮流和物理量纲正确后再逐步加入气网和P2G每加一层就做一次校验。这比一次性写完所有代码再debug要高效得多也避免了“模型永远跑不动”的挫败感。还有个小技巧分享一下所有构建参数的脚本建议用结构体统一管理并加上中文注释比如data.P2G_cost 5000; % P2G单位造价元/kW。后面做敏感性分析时只要改这个字段重跑就能自动遍历多个算例不必改代码。这个习惯在正式做论文复现乃至写报告时都特别值回时间。后续想在这个基础上扩展可以尝试加入储能系统或氢气储罐联合规划或者考虑碳流和碳税对P2G经济性的影响。也可以把确定性规划替换成两阶段鲁棒优化把风电出力不确定性用不确定集合描述。每一条路都能做成一篇新论文但核心的建模和代码骨架和这次复现是完全相通的。先把基础版本跑通畅后面的路就好走了。