基于纳什谈判的风光氢多主体合作博弈与收益分配
2026/9/18 2:49:33 网站建设 项目流程

先说清楚这个项目是干什么的:风电场、光伏电站、氢能站三个独立主体,原本各干各的,风电光伏出力受天气影响大,发电高峰遇上电价低谷只能少发或者被电网限制出力;氢能站单独从电网买电制氢,电价一高成本就压不住。把它们放进同一个园区内部互联,让氢能站吃下风光的多余电力制氢,电价高的时候再通过燃料电池把电卖回去,三方的整体收益都能涨。但问题来了:联盟总收益能涨多少?涨出来的钱怎么分才算公平?分少了风电不愿意合作,分少了氢能觉得白忙活。这个项目就是用纳什谈判理论解决“多合作、怎么分”的问题,并在MATLAB里完成建模、求解和分配计算。文章里我会把建模思路、推导过程、YALMIP代码框架和踩坑实录全部拆开讲,适合正在做综合能源系统优化、合作博弈方向毕业设计,或者搞园区微网调度研究的朋友参考。

1. 项目整体思路:多主体为什么必须合作,合作后收益怎么分

1.1 三个独立主体各自算账时的困境

先说风电和光伏。这俩主体有一个共同痛点:出力曲线和电价曲线经常错位。风电多数是夜间出力大,而夜间电价通常处于低谷;光伏正好反过来,中午出力最大,但中午如果晴天多、装机多,现货市场电价反而容易被压下去。独立运行时,风电场只能按上网电价卖电,高峰时段多发的电卖不上价,极端情况下还要弃掉;光伏虽然白天出力能对上部分高峰负荷,但超出消纳能力的部分同样面临低电价或弃光。

再算氢能站的账。氢能站的收益来自售氢,成本大头是制氢耗电。独立运行时它只能从电网买电,电价波动的风险完全自己扛,高峰时段制氢几乎不划算,所以设备利用率上不去,固定成本摊不下来。这个局面就像种苹果的找不到果汁厂,开果汁厂的又觉得鲜果太贵,中间还缺一个冷库来调节供需节奏。

1.2 合作后联盟内部怎么运作

把三个主体拉进一个联盟后,内部逻辑是:风电和光伏的电力优先满足自身直接售电需求,富余量不浪费,直接送到氢能站的电解槽制氢;氢能站的电解槽如果还不够吃,再从电网买一部分电补足;储氢罐把氢气存起来,一部分外售给加氢站或工业用户,另一部分在电价高峰时段供给燃料电池发电,发出来的电并回母线参与对外售电。这样风光的弃电率降下去,氢能的用能成本降下来,高峰时段还能多赚一笔售电收入。

联盟的功率平衡关系可以简单写成:

风电出力 + 光伏出力 + 燃料电池出力 + 电网购电 = 对外售电 + 电解槽用电

这个等式的形式很朴素,但它把三个主体的运行边界全部耦合到了一起。电网购电是唯一的松弛变量,购电多了成本上升,购电少了电解槽吃不饱,所以优化器会在风光出力、氢能设备出力和电价曲线的共同约束下,自动找出一条最优的功率流路径。

1.3 合作博弈要解决的关键问题

合作不是一句口号,落到实处需要回答三个问题。

第一个,联盟总收益最大化怎么建模。这就是一个典型的混合整数线性规划问题,时间尺度可以取24小时甚至96时段,决策变量包括风电上网功率、光伏上网功率、电解槽输入功率、燃料电池输出功率、储氢罐储量变化、购电功率、售电功率、售氢量。目标函数是总售电收入加售氢收入,减去购电成本和运维成本。

第二个,个体理性约束怎么满足。这是合作博弈能不能成立的前提:任何一个主体加入联盟后的收益,都不能低于它自己单干时的收益。这个“不合作也能拿到的收益”在博弈论里叫谈判破裂点。如果合作后有个主体分到的钱比独立运行时还少,它分分钟退出联盟,整个合作框架就崩了。

第三个,合作增量怎么分配。联盟总收益等于所有主体独立收益之和加上合作增量,这个增量来自弃风弃光减少、氢能购电成本下降、高峰售电增收。纳什谈判理论解决的就是“增量怎么分”的问题:既要让每个主体都满意,又要保证分配结果满足帕累托最优。实际求解时,收益分配可以单独做一个优化层,也可以利用合作的数学结构直接得出解析解,这一点后面我会重点讲。

2. 纳什谈判模型与计算原理:从目标函数到可求解代码

2.1 纳什谈判解是什么,凭什么它分钱最服众

纳什谈判理论来自博弈论里经典的讨价还价问题。几个人坐在谈判桌上分一笔固定数量的合作剩余,每人有一个底线收益,低于这个底线就谈崩。纳什证明,在满足帕累托最优、对称性、线性变换不变性、无关选择独立性这四个公理的前提下,唯一合理的分配方案是最大化所有参与者“合作收益减去底线收益”的乘积。

用公式表达就是:

max ∏ (R_i - D_i)

其中 R_i 是主体 i 在合作中获得的收益,D_i 是它的谈判破裂点收益,也就是独立运行时的最优收益。这个目标函数叫纳什积。它的好处是:单独看某一个人的增量最大不行,因为其他人增量太小甚至为负,乘积就上不去;只有大家增量都比较大时,乘积才最大。这个性质天然满足“共同富裕”式的公平分配。

实际MATLAB实现里,一般不对纳什积本身求最大值,而是取对数:

max ∑ ln(R_i - D_i)

取完对数后单调性不变,但目标函数从乘法变成加法,数值稳定性好很多。更重要的是,很多文献里会再加一个权重系数 w_i,表示不同主体的谈判筹码或重要程度,目标函数变成:

max ∑ w_i ln(R_i - D_i)

权重系数可以理解成“谁对联盟的贡献大谁就多分一点”,实际设置时可以用独立运行收益占联盟总收益的比例来衡量,也可以按投资比例、承担风险程度来给。

2.2 “总收益固定时,纳什解就是增量均分”这条隐藏结论

联盟运行优化的结果会给出一个固定的联盟总收益 R_total,三个主体分配到的收益 R_A、R_B、R_C 之和就等于 R_total。在这个约束下,无权重纳什谈判解有一个非常漂亮的解析结果:

R_i = D_i + (R_total - D_A - D_B - D_C) / 3

翻译成人话就是:先把每个主体的独立收益底线保住,剩下的合作增量三个人平分。带权重时也类似,每个人分到的增量等于总增量乘以自己的权重占比。

这条结论对写代码特别重要。它意味着收益分配问题根本不需要再调用一个复杂的优化求解器,直接用数学表达式就能算出结果。我之前见过不少同学一上来就把纳什积塞进YALMIP里当非线性目标硬啃,不仅求解慢,还经常因为数值问题报错。实际上两步走最干净:第一步用MILP求联盟总收益最大化的功率分配,第二步用解析公式计算三方的收益分配。

2.3 谈判破裂点怎么求

谈判破裂点 D_i 是各主体独立运行时的最优收益,而不是随便填一个数。求法很直接:把联盟模型拆开,每个主体单独建一个优化问题,不考虑其他主体的耦合约束,只追求自身收益最大化。

风电独立运行模型就是:给定预测的风电出力曲线,求最优上网功率,目标函数是售电收入减去运维成本,因为弃风没有任何惩罚,所以最优解一定是“出力等于预测值”或者“在电网限制出力范围内尽可能多出力”。

光伏独立运行模型同理。

氢能站独立运行模型稍微复杂一点:它只能从电网买电制氢,售氢收入减去购电成本减去运维成本就是目标,还要考虑电解槽功率约束、储氢罐容量约束。注意,独立运行时的最优策略不是每小时都满负荷制氢,而是在电价低谷时段多制氢,电价高峰时段少制氢甚至不制氢。

这三个独立优化问题各自跑一遍,得到的收益就是谈判破裂点。把这三个值代入前面增量均分公式,合作增量立刻算得出来。

2.4 系统约束与设备模型

联盟优化模型的约束条件可以分为四类。

第一类是风光出力上限约束。每个时段风电上网功率加送往电解槽的功率,等于该时段风电预测出力;光伏同理。实际上就是风电和光伏的功率流分配问题,功率不能凭空多出来,也不能浪费(除非允许弃风弃光,但合作模式下弃风弃光被氢能站吸收,目标函数会自然引导充分利用)。

第二类是氢能站设备约束。电解槽输入功率有上限,燃料电池输出功率有上限,储氢罐储量有上下限。电解槽制氢量和输入功率呈线性关系,燃料电池耗氢量和输出功率也呈线性关系,可以用效率常数把电和氢互相折算。

第三类是储氢罐的动态约束。这是整个模型里唯一带时间耦合的部分。第 t+1 时段的储氢量,等于第 t 时段储氢量,加上制氢量,减去燃料电池消耗量,减去对外售氢量。最后一个时段还要回到初始储氢量,保证调度的周期性,不然优化器会把初始储存的氢气全卖光,结果失真。

第四类是功率平衡约束。母线功率平衡方程把风光出力、燃料电池出力、电网购电、对外售电、电解槽用电这五部分耦合在一起。注意这里电网购电和对外售电不能同时为正,实际建模时要么加二进制变量互斥,要么利用电价机制让优化器自动避免同时买卖,后者实现起来更省事。

3. MATLAB环境搭建与仿真数据准备:跑通模型需要什么

3.1 为什么用YALMIP,求解器选哪个

MATLAB里做优化建模,最推荐的方式是YALMIP加一个商业求解器,比如CPLEX或Gurobi。YALMIP本身不是求解器,它是一层建模语言,负责把你写的约束和目标函数翻译成求解器能识别的标准格式。好处是语法简洁,写约束和写数学公式几乎一一对应,调试起来非常直观。

求解器方面,如果学校或课题组有授权,优先用Gurobi,性能在同类问题里是顶级水平;没有的话CPLEX也完全够用。风电、光伏、氢能这种规模的MILP,变量量和约束量最多几百个量级,两个求解器都能在几秒内出结果。有人问能不能用MATLAB自带的intlinprog,当然可以,但intlinprog输入麻烦,矩阵写起来头大,而且调试可视化不如YALMIP直观,所以我个人不推荐。

如果你的编译器环境配好的话,在MATLAB命令行输入yalmiptest,会反馈一系列可行性测试结果,看到所有测试项都通过,说明YALMIP已经能正常调用求解器了。

3.2 仿真数据从哪里来,怎么造典型日曲线

做博弈运行策略研究,输入数据主要是风电预测出力曲线、光伏预测出力曲线、分时电价曲线、氢价和购电价格。用真实数据最好,但要获得公开、连续、可复现的风光出力数据并不容易,实际做课题时常用典型日曲线代替。

风电典型日出力的生成方法,可以给定一个容量为100 MW的风电场,用一个满足Weibull分布的风速序列去模拟,但更简单的做法是直接定义一个24时段的功率曲线数组,比如:

Pwt_avail = [35 38 42 45 48 50 52 48 45 40 35 32 30 35 40 45 50 55 52 48 42 38 35 33]

除以100就是归一化的容量因子。这个曲线体现“夜间出力大、白天午后有一段爬坡”的特点,不考虑秒级波动,做小时级调度完全够。

光伏典型日曲线更简单,夜间为零,从早上6点开始爬升,中午12到14点达到峰值,下午逐渐降低到零:

Ppv_avail = [0 0 0 0 0 5 15 30 45 55 60 62 60 55 45 30 15 5 0 0 0 0 0 0]

分时电价可以设置为:峰时段10点到15点、18点到21点执行高价1.2元/千瓦时,平时段0.7元,谷时段23点到次日7点执行0.4元。氢价取35元/千克,电解槽效率约80%,燃料电池发电效率约50%。注意,价格量级和效率值直接决定了优化结果,不同论文里取值差异很大,你复现的时候可以结合自己系统的参考值调整,但模型结构完全兼容。

如果你想做得更精细,可以用LHS(拉丁超立方)采样生成多个典型日场景,再做蒙特卡洛仿真取期望收益,这个方向属于扩展玩法,本文不展开。

3.3 数据尺度注意:小技巧让求解更快更稳

MATLAB数值优化对变量量级比较敏感。假设电量单位选千瓦时,一天24小时,单时段风电出力上百千瓦时,氢价按千克计,收益数量级上万甚至更多,而储氢罐储量如果按立方米标况体积计,数值波动可能很小。两者差距过大时,求解器容易出现数值病态。

实际操作时我建议:功率统一用MW做单位,电价用元/千瓦时,时间步长取1小时,这样目标函数的数量级能控制在几百到几千,所有约束系数都在0.01到100之间,不需要额外归一化。氢气能量折算时,可以先用标准热值换算,比如1千克氢气低位热值33.3千瓦时,那么电解槽输入1千瓦时电对应产出约1/33.3/0.8 千克氢气,即0.0375千克;燃料电池发1千瓦时电需要消耗约1/33.3/0.5 千克氢气,即0.06千克。把这些换算系数提前算好写成常数,约束表达式就清爽得多。

4. 核心代码实现与关键步骤拆解:可以直接复用的MILP框架

4.1 决策变量定义与约束构建

以下是YALMIP框架下完整的联盟优化模型核心代码,我按模块拆开讲。首先定义决策变量:

T = 24; % 风电流向 Pwt_grid = sdpvar(1, T); % 风电上网功率 Pwt_h2 = sdpvar(1, T); % 风电送电解槽功率 % 光伏流向 Ppv_grid = sdpvar(1, T); % 光伏上网功率 Ppv_h2 = sdpvar(1, T); % 光伏送电解槽功率 % 氢能系统 Pel = sdpvar(1, T); % 电解槽输入功率 Pfc = sdpvar(1, T); % 燃料电池输出功率 Hstored = sdpvar(1, T+1); % 储氢罐储量 Hsell = sdpvar(1, T); % 对外售氢量(换算为功率当量) Pbuy = sdpvar(1, T); % 电网购电 Psell = sdpvar(1, T); % 对外售电

变量定义好了,接下来是约束。每一类约束本质上是变量的可行域限制。注意YALMIP里约束合并用的是中括号加逗号,最后统一拼成一个大的约束向量。

Constraints = []; % 风光出力平衡:上网 + 送氢 = 可用出力 Constraints = [Constraints, Pwt_grid + Pwt_h2 == Pwt_avail]; Constraints = [Constraints, Ppv_grid + Ppv_h2 == Ppv_avail]; % 母线功率平衡 % 风电上网 + 光伏上网 + 燃料电池发电 + 购电 = 对外售电 + 电解槽用电 Constraints = [Constraints, Pwt_grid + Ppv_grid + Pfc + Pbuy == Psell + Pel]; % 氢能站设备出力上下限 Constraints = [Constraints, 0 <= Pel <= Pel_max]; Constraints = [Constraints, 0 <= Pfc <= Pfc_max]; Constraints = [Constraints, 0 <= Pbuy <= Pbuy_max]; Constraints = [Constraints, 0 <= Psell <= Psell_max]; % 储氢罐动态平衡 % Hstored(t+1) = Hstored(t) + 制氢量 - 燃料电池耗氢量 - 售氢量 eta_el = 0.8; % 电解槽效率 eta_fc = 0.5; % 燃料电池效率 Hhv = 33.3; % 氢气热值 kWh/kg Constraints = [Constraints, Hstored(2:T+1) == Hstored(1:T) ... + Pel * eta_el / Hhv ... - Pfc / eta_fc / Hhv ... - Hsell]; % 储氢罐储量上下限与周期约束 Constraints = [Constraints, H_min <= Hstored <= H_max]; Constraints = [Constraints, Hstored(1) == Hstored(T+1)];

这段代码是联盟优化模型的骨架。模型里所有地方都用线性表达式,因为制氢量是输入功率乘以效率除以热值,线性关系;燃料电池耗氢量是输出功率除以效率除以热值,也是线性关系;储氢罐动态方程是标准的差分方程。目标函数也是线性组合,所以整个模型是纯MILP,换成线性规划也没有问题,求解效率非常高。

4.2 目标函数:联盟总收益最大化

联盟的收益来源有四个:对外售电收入、售氢收入,成本项是电网购电成本和设备运维成本。注意,风光送往电解槽的功率在联盟内部是“左手给右手”,不平账,因此目标函数里不涉及这个内部交易,收益分配环节再算账。

% 分时电价 price_buy = [0.4*ones(1,7), 0.7*ones(1,3), 1.2*ones(1,5), ... 0.7*ones(1,3), 1.2*ones(1,4), 0.7*ones(1,2)]; price_sell = price_buy * 1.05; % 上网售电价略高于购电价,模拟峰谷套利空间 price_h2 = 35; % 元/kg % 运维成本系数 c_wt = 0.02; c_pv = 0.02; c_el = 0.01; c_fc = 0.02; c_buy = 0.03; % 目标函数:收益 - 成本 Revenue_sell = sum(Psell .* price_sell); Revenue_h2 = sum(Hsell .* price_h2); Cost_buy = sum(Pbuy .* price_buy); Cost_om = sum(Pwt_avail * c_wt + Ppv_avail * c_pv + Pel * c_el + Pfc * c_fc); Objective = Revenue_sell + Revenue_h2 - Cost_buy - Cost_om; % 求解 ops = sdpsettings('solver', 'gurobi', 'verbose', 0); optimize(Constraints, -Objective, ops);

有人说为什么对外售电价格要比购电价格高。这里设定的price_sell比price_buy高5%,是为了体现电网的过网费或峰谷价差。实际系统里上网电价往往低于用户购电价,为了给燃料电池峰时发电留出套利空间,这里做了简化处理。你完全可以根据研究场景改成上网电价低于购电价的结构,结论方向不变,只是套利空间大小不同。

求解器跑完后,用value函数提取各个变量的值:

Pwt_grid_opt = value(Pwt_grid); Ppv_grid_opt = value(Ppv_grid); Pel_opt = value(Pel); Pfc_opt = value(Pfc); Hstored_opt = value(Hstored); R_total = value(Objective);

4.3 独立运行模型与收益分解

独立运行模型的代码更简单。以风电场为例,它不参与联盟,也没有氢能系统,目标函数只是上网售电收入减运维成本:

% 风电场独立运行 Pwt_solo = sdpvar(1, T); Constraints_wt = [0 <= Pwt_solo <= Pwt_avail]; Objective_wt = sum(Pwt_solo .* price_sell) - sum(Pwt_solo * c_wt); optimize(Constraints_wt, -Objective_wt); D_wt = value(Objective_wt); % 光伏独立运行 Ppv_solo = sdpvar(1, T); Constraints_pv = [0 <= Ppv_solo <= Ppv_avail]; Objective_pv = sum(Ppv_solo .* price_sell) - sum(Ppv_solo * c_pv); optimize(Constraints_pv, -Objective_pv); D_pv = value(Objective_pv); % 氢能站独立运行 Pel_solo = sdpvar(1, T); Hsell_solo = sdpvar(1, T); Hstored_solo = sdpvar(1, T+1); Constraints_h2 = [0 <= Pel_solo <= Pel_max]; Constraints_h2 = [Constraints_h2, 0 <= Hsell_solo <= Hsell_max]; Constraints_h2 = [Constraints_h2, Hstored_solo(2:T+1) == Hstored_solo(1:T) ... + Pel_solo * eta_el / Hhv - Hsell_solo]; Constraints_h2 = [Constraints_h2, H_min <= Hstored_solo <= H_max]; Constraints_h2 = [Constraints_h2, Hstored_solo(1) == Hstored_solo(T+1)]; Objective_h2_solo = sum(Hsell_solo * price_h2) ... - sum(Pel_solo .* price_buy) - sum(Pel_solo * c_el); optimize(Constraints_h2, -Objective_h2_solo); D_h2 = value(Objective_h2_solo);

这里氢能站独立运行的谈判破裂点算出来之后,D_wt、D_pv、D_h2 三个值就齐了。

4.4 纳什谈判分配:三步完成收益分配

联盟总收益和谈判破裂点求出来后,收益分配按三步走:

第一步,算联盟合作总增量:

R_increment = R_total - (D_wt + D_pv + D_h2);

第二步,在总增量确定的情况下,无权重纳什谈判解等于等增量分配:

R_wt = D_wt + R_increment / 3; R_pv = D_pv + R_increment / 3; R_h2 = D_h2 + R_increment / 3;

第三步,检查个体理性条件。正常情况下三个主体分到的收益都高于独立运行收益,因为整个联盟优化问题已经包含了独立运行策略作为可行解,R_total必然不低于三主体独立收益之和。如果因为目标函数系数问题出现了某个主体分到的收益低于独立收益,说明模型参数设置有问题,优先检查氢价、电价、效率系数的量纲是否一致。

4.5 完整运行流程

整个仿真流程可以封装成一个五分钟内跑完的脚本:第一步生成或者读取24时段的风光出力曲线、电价曲线和系统参数;第二步调用YALMIP求解独立运行模型,得到三个谈判破裂点;第三步求解联盟优化模型,得到联盟总收益和最优功率曲线;第四步用纳什谈判分配公式计算三方收益;第五步绘图展示合作前后收益柱状图、功率平衡曲线、储氢罐SOC变化曲线。这个流程适合写进论文第三章或第四章,五张图加一张收益对比表,基本就是一篇综合能源博弈方向小论文的核心内容了。

5. 仿真结果分析与收益分配验证:合作有没有价值一目了然

5.1 合作前后收益数值对比

我用一组典型数据跑完后的结果做一个概念性展示,具体数值取决于你的输入参数,但趋势是一致的。假设风电独立运行日收益3.2万元、光伏独立运行日收益1.1万元、氢能独立运行日收益0.4万元,三方独立收益合计4.7万元。

联盟优化后,风电因为弃风减少、部分电量以内部价格卖给氢能,日收益涨到3.5万元;光伏日收益涨到1.3万元;氢能因为买到低价绿电,售氢成本和发电成本双降,日收益涨到0.9万元。联盟总收益5.7万元,合作增量1.0万元。按纳什谈判解等增量分配后,风电最终收益3.53万元、光伏1.33万元、氢能0.83万元。三个主体都合作有收益增量,符合个体理性门槛。

这里的核心逻辑是:联盟总收益不是三方独立收益简单相加,而是通过内部功率流重构产生了“1 + 1 + 1 > 3”的协同效应。协同效应来自哪里?来自弃电的再利用、购电时段的优化、高峰售电的套利空间。

5.2 储氢罐运行曲线怎么看

储氢罐的储量变化是验证模型正确性的关键指标。合理的运行策略应该是:凌晨风电大发、电价低谷时,电解槽满负荷或者接近满负荷运行,储氢罐储量爬升;白天光照充足时,光伏除了直接售电也有一部分送电解槽,储氢罐保持在高位;傍晚电价进入高峰时段后,燃料电池启动放电,储氢罐储量下降,对外售电收入增加;夜间再次进入低谷时开始下一轮循环。

如果你跑出来的储氢罐曲线是一整条直线,基本没波动,说明模型有问题。常见原因是电解槽效率设置过低,制氢成本太高,优化器宁愿放弃制氢也不愿意储氢;或者售氢价格设置过低,氢气卖出还不如直接弃电划算;再就是储氢罐容量限制太宽松,导致优化器一开始就填满罐子然后一直捂到周期结束。遇到这种情况,优先调整电解槽效率和氢价,让制氢在经济上具有竞争力。

5.3 博弈解与单目标优化的区别

很多人第一次接触这个课题会有一个疑问:我都已经把联盟总收益最大化求出来了,为什么还要多算一步纳什谈判分配?直接把总收益按某个比例分给三方不就行了?

区别在于,联盟总收益最大化求出的是一组功率调度策略,这组策略保证联盟整体最优,但不保证每个成员都愿意接受。比如某套策略让风电收益大增,但氢能收益反而比独立运行时低了一个百分点,氢能站就不干了。纳什谈判分配的作用,是在“联盟整体最优”这个前提上,再叠加“每个个体都不吃亏”的合理性约束,它本质上寻找的是联盟的核,也就是所有成员都愿意接受的分配集合。总收益最大是效率问题,纳什谈判解是公平合理性问题,两者缺一不可。

5.4 带权重时的分配差异

实际研究中经常给三个主体加不同的谈判权重。权重 w_i 的含义是“谈判能力”或“贡献程度”。当权重相等时,增量均分;当某一方权重更高时,该方分到的增量比例更大。

w = [0.5, 0.3, 0.2]; % 风电、光伏、氢能权重 R_wt = D_wt + w(1) * R_increment; R_pv = D_pv + w(2) * R_increment; R_h2 = D_h2 + w(3) * R_increment;

权重的设定可以基于各主体独立运行收益占比,也可以基于投资额占比,或者根据碳减排贡献来定。这一点在写论文时是很好的讨论点:不同的权重分配方案会影响各主体参与合作的积极性,也影响整个联盟的稳定性。你可以做三组权重场景对比,分析各方收益的敏感度。

6. 常见报错与MATLAB实现避坑指南:个人实测经验整理

6.1 YALMIP报错Infeasible problem

这是新手最容易遇到的问题。模型不可行,意思是不存在一组变量同时满足所有约束。排查思路按优先级排序:先检查储氢罐周期约束与容量约束是否冲突。如果H_min设置成5、H_max设置成10、初始储量定成8,同时周期约束又要求最后一个时段回到8,而中间任何时段储量的变化幅度受制氢和放氢能力限制,完全可能无法满足,模型自然无解。

再检查功率平衡约束里购电和售电功率是否可能同时为正。如果设置上下限时没加互斥约束,理论上优化器会利用买卖价差做无限套利,这个影响的是目标函数合理性而不是可行性;但如果购电价高于售电价,模型会在买卖之间形成无界解,可能表现为求解时间过长或者数值警告。实际处理时我倾向于不加互斥二进制变量,因为好的电价结构下优化器自己不会同时买卖,加上互斥变量反而增加求解难度。

6.2 目标函数数量级差距过大导致求解精度差

前面提到储氢罐储量的数值可能从0.5到8之间波动,而售电收入是几千到上万,两者直接放在约束里,求解器的数值容差可能导致储量约束被不当松弛。解决办法有两个,一个是把单位统一化,比如所有功率单位用MW、氢气量用MW当量而不是千克,等式约束的系数就都是同数量级;另一个是给优化器设置更严格的数值容差,在sdpsettings里加一行:

ops = sdpsettings('solver', 'gurobi', 'verbose', 0, 'gurobi.MIPGap', 1e-4);

MIPGap设置成1e-4比较合适,太小会导致求解时间明显变长,对两阶段调度问题意义不大。

6.3 非线性项处理

有些同学会把售氢收益写成氢气价格乘以储氢量变化量,这样目标函数里会出现储量变量和价格变量的乘积,变成非线性项。标准做法是避免这种写法,售氢量定义成独立的非负变量,每一时段的售氢量在储氢罐动态约束中体现,同时设置售氢量上限,这样模型保持线性。

那如果确实需要用到功率与0-1变量的乘积,比如启停状态与出力的乘积,这种就是双线性项。处理办法是引入大M法线性化,用辅助变量替换乘积,并加上M约束。不过对于本文这个模型,电解槽和燃料电池的启停成本如果不重要,可以完全用连续变量建模,省去大量麻烦。

6.4 氢能站独立运行收益为负怎么办

氢能站的固定成本如果折算到日运维里,独立运行可能出现负收益。这并不影响模型逻辑,谈判破裂点D_h2是负数也没关系,纳什积里R_h2 - D_h2依然为正,说明合作后虽然还是在亏钱,但亏得少了,这也是一种收益改善。不过在论文里写负数观感不好,常见的处理方式是只计可变成本,不计固定投资折旧,或者把折旧年限拉长,让日折旧成本低于日收益。这个属于模型设定问题,没有绝对的对错,关键要在论文里说清楚边界。

6.5 绘图的小技巧

仿真结果画图时,我习惯用两张图配合展示:第一张是24小时功率分配堆叠图,把风电上网、光伏上网、燃料电池输出、购电和电解槽用电画在一起,能直观看到功率流的时间分布;第二张是储氢罐储量变化曲线,叠加电价曲线做副坐标,能解释为什么储氢罐在某个时段爬升或下降。收益对比用柱状图,三组柱子分别对应独立运行、联盟运行、纳什分配,每组三根柱子对应三个主体,一眼就能看出合作增量。导出图用exportgraphics函数设置300dpi分辨率,期刊投稿直接可用。

6.6 关于大规模扩展方向

这套模型做完之后,扩展性很强。一个方向是加碳交易机制,给各主体增加碳排放配额约束,让绿氢的降碳价值货币化;另一个方向是引入多场景随机规划,把风光出力的不确定性用典型场景描述;还有一个方向是把模型改成分布式求解,用ADMM交替方向乘子法把联盟优化分解成三个子问题,各主体只交换耦合变量的对偶乘子,可以保护各主体内部数据隐私。前两个方向在MATLAB里实现都不难,最后一个方向需要一些凸优化基础,但做出来论文档次会明显不一样。

我个人实测下来,这个课题最大的价值不是代码能跑通,而是通过纳什谈判解把“合作共赢”从一句口号变成一个可计算的数学结果。每次跑完仿真,看到三个主体分到的收益都高于独立运行,储氢罐在电价低谷爬升、高峰释放,心里还是有点小成就感。项目做完了,后续如果你想往分布式求解方向走,建议先读一下ADMM的经典论文,然后把本文的MILP改成两个子问题迭代求解,这个过程能加深对博弈论和优化理论的双重理解。最后提醒一点:仿真参数一定要记录清楚,风速、辐照度、电价、氢价、效率、容量这些参数换一组,合作增量可能完全不同,结论的适用性要以参数敏感性分析为准。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询