ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于纳什谈判的风-光-氢多主体能源系统合作运行MATLAB实现

基于纳什谈判的风-光-氢多主体能源系统合作运行MATLAB实现 做综合能源优化这几年合作博弈里最常用也最容易被问到的就是纳什谈判。手里这套风-光-氢多主体能源系统合作运行的MATLAB代码我从最初的理论推导到完整仿真前前后后改了三版才把结果跑稳定。这篇文章就把模型建立、MATLAB实现、结果分析和踩过的坑一次性讲清楚适合正在做综合能源系统调度、多主体协同优化或者电氢耦合方向的同学参考也适合打算把纳什谈判理论往工程模型里落地的读者看。先说明这个项目到底在解决什么问题。风电、光伏出力的随机性大家都懂单靠电网消纳要么弃风弃光要么需要额外调峰。如果把电解槽、储氢罐和燃料电池组成的氢能系统放进去让风光主体和氢能主体坐在一起谈合作就能把多余的电转化为氢气储存再在需要的时候发电或者卖氢。问题是各方都是独立利益主体谁都不想吃亏。纳什谈判理论就是给这类“既想合作、又谈不拢分成”的问题提供了一个数学上可求解、经济上可信的框架。下面我从建模、代码、案例和避坑四个方面展开。1. 项目要解决的问题与整体设计1.1 为什么多主体能源系统需要合作博弈传统综合能源优化里最常见的做法是把整个系统当成一个“大号单主体”目标函数写成总运行成本最小或者总收益最大然后交给优化器求最优解。这个思路在物理上没问题但在工程落地时会碰壁一座风电场、一个光伏电站和一个氢能公司大概率分属不同投资主体各有各的利润考核你没法要求某一方为了全局最优而牺牲自己的收益。这就是为什么要把问题从“单目标全局优化”改成“多主体合作博弈”。合作博弈的核心不是先定死一个总目标而是先让每个主体算清楚“我不跟你合作时能赚多少钱”这个值叫谈判破裂点也叫个体最优收益。然后各方坐下来商定一套合作运行方案让合作后的总收益大于各方单独运行收益之和最后把增量收益按某种公平原则分掉。纳什谈判理论在这个环节的优势在于它不靠拍脑袋分配而是通过最大化一组“纳什乘积”来同时得到运行方案和收益分配结果解满足帕累托最优、对称性、线性不变性和无关选择独立性这几条公理在工程上更有说服力。1.2 纳什谈判模型的适用性与前提条件用纳什谈判之前得先确认自己的问题是否满足它隐含的前提。最基础的一条是参与者之间没有强制指令关系每个主体可以自由选择“合作”还是“不合作”。如果某个主体在谈判后拿到的收益低于自己单独运行时的收益它完全可以退出谈判解就要保证这类情况不发生也就是满足个体理性。第二条是转移支付的可能性。纳什谈判通常假设合作的增量收益可以在主体之间进行经济补偿补偿可以体现为成本分摊、利润分成或者内部结算电价。我的这套风-光-氢系统里氢能主体向风、光主体购买低价绿电本质就是一种间接转移支付。如果系统里没有结算机制只是物理上连在一起、但账目上分不开那谈判模型就名存实亡了。第三条是主体成本函数要尽量可解析、可迭代。纯理论推导可以写得很漂亮但落到MATLAB代码里每个主体的收益函数、约束条件都必须在一套统一的时间序列上建模。我的做法是把问题拆成两层第一层求联盟总收益最大化第二层做收益分配。这个方法在工程上比直接求解非线性纳什乘积稳定得多也方便后面接ADMM分布式求解。2. 风-光-氢多主体系统的数学模型2.1 系统结构与主体模型这套系统由三个主体组成风电子系统、光电子系统和氢能子系统。风、光主体的设备是风机和光伏板产出全部进入公共母线氢能主体包括碱性电解槽、储氢罐和燃料电池。为了模拟真实工程我还给风、光主体各加了一个本地负荷和一条外送电网联络线这样风、光主体既可以把电卖给电网也可以卖给氢能主体的电解槽。每个主体的收益函数分开写。风电主体的收益是售电收入、售给电解槽的绿电收入之和减去运维成本和弃风惩罚。光伏主体同理。氢能主体的收益是售氢收入、燃料电池发电售电收入之和减去购电成本、电解槽与燃料电池维护成本和储氢罐折旧成本。为了突出合作价值我在目标里加了一个弃电惩罚项弃电越少系统收益越大。具体参数可以参考下面这张表这和项目代码里的init_parameters.m保持一致。时间分辨率为1小时调度周期24小时。参数数值说明风电装机容量400 MW出力上限光伏装机容量300 MW出力上限电解槽额定功率150 MW最大购电功率燃料电池额定功率80 MW最大发电功率储氢罐容量4500 kg氢气存储上限电解槽转换效率72%电转氢综合效率燃料电池发电效率50%氢转电综合效率售电电价固定部分 0.55 元/kWh峰谷分段售氢价格28 元/kg外售氢气价格2.2 非合作运行谈判破裂点的计算谈判破裂点是整个模型的地基不能随便拍一个数。我的做法是把每个主体分别建立独立运行优化模型风力主体只对自己局部约束求收益最大化光伏主体也一样。氢能主体在非合作状态下没有来自风、光主体的低价绿电只能按市场电价从电网买电制氢燃料电池是否发电取决于实时电价和氢价的经济比较。单独计算一轮之后会得到三组结果风电主体的非合作最大收益 $R_W^0$光伏主体的非合作最大收益 $R_P^0$氢能主体的非合作最大收益 $R_H^0$。这三个值将作为纳什谈判的谈判破裂点。也就是说合作后的任一方收益都不能低于这些值否则它宁可不谈。在MATLAB里我建议把这三个值作为全局变量保存第二步合作优化时直接引用。千万不要在合作模型里再算一次非合作目标否则两阶段的边界不一致结果会失真。我最初就是因为把两个问题混在一起建迭代了三十多次都不收敛后来拆成两个独立函数才正常。2.3 合作运行下的纳什谈判模型合作优化阶段我先把物理运行和收益分配拆成两阶段来写。第一阶段是在所有主体共享公共母线和储氢设施的前提下最大化联盟总收益[ \max R_{total} R_W R_P R_H ]约束包含母线功率平衡、风电光伏出力上下限、电解槽运行约束、燃料电池运行约束、储氢罐动态约束和电网联络线功率约束。这个阶段本质上还是一个集中式全局优化问题求解难度不大用YALMIP加Gurobi可以秒解。第二阶段是谈判收益分配。定义三个主体从合作中获得的净收益增量分别为[ \Delta_W R_W - R_W^0,\quad \Delta_P R_P - R_P^0,\quad \Delta_H R_H - R_H^0 ]纳什谈判解要做的是最大化[ \max \Delta_W \cdot \Delta_P \cdot \Delta_H ]并且满足合作后的任意一方收益不能低于谈判破裂点。更一般地有权重时三个增量可以写成 $\prod_i \Delta_i^{w_i}$权重越高谈判地位越强。这个乘积问题直接让Gurobi处理会比较勉强因为目标函数非凸我通常用交替方向乘子法把项目写成可分离拉格朗日形式在MATLAB里循环迭代。这个两阶段处理在理论上等价于一次性的纳什乘积最大化但在数值上稳定得多。第一阶段得到的是“蛋糕能做多大”第二阶段决定“蛋糕怎么分”工程上透明性好业主方也更容易接受。3. MATLAB代码实现与求解过程3.1 代码结构与数据准备整套代码我按功能拆成了四个文件main_nash.m、init_parameters.m、build_model.m和solve_admm.m。main_nash.m是入口负责读数据、调参数、跑非合作求解、跑合作求解最后画图init_parameters.m集中存放所有设备参数build_model.m里包含了风电主体、光伏主体和氢能主体的约束与收益函数solve_admm.m实现了分布式迭代。数据准备阶段要格外注意时间序列的对齐。风、光出力曲线、负荷曲线、分时电价曲线、氢价曲线全部按8760小时或者24小时统一索引。最容易出错的是把风电出力单位写成MW光伏出力写成kW到了目标函数里量纲不一致结果完全没法看。我在代码里统一把所有功率单位规定为MW收益单位规定为万元氢气单位规定为kg。下面这段是入口主程序和参数初始化的简化版本实际代码里还包括了边界检查和绘图输出% main_nash.m clear; clc; close all; init_parameters; % 读取风电、光伏和负荷数据单位MW Pw load(wind_data.txt); Pv load(pv_data.txt); Load load(load_data.txt); T 24; Pw Pw(1:T); Pv Pv(1:T); Load Load(1:T); % 先算非合作谈判破裂点 [RW0, RP0, RH0] non_cooperative_solution(Pw, Pv, Load); fprintf(非合作收益风电 %.2f 万元光伏 %.2f 万元氢能 %.2f 万元\n,... RW0, RP0, RH0); % 合作运行与收益分配 [result] cooperative_solution(Pw, Pv, Load, RW0, RP0, RH0); plot_result(result);3.2 用YALMIPGurobi搭建优化模型合作运行第一阶段的联盟收益最大化问题我用YALMIP建模求解器选Gurobi。这里有一个经验尽量把模型线性化别引入太多非线性项。电解槽的转换关系是线性的燃料电池的发电效率也是固定的常数所以整个模型可以建为线性规划如果后续加入启停状态变量和最小连续运行时间就升级成混合整数线性规划。公共母线的功率平衡是模型里最核心的一条约束写成[ P_{W,out} P_{V,out} P_{FC} P_{grid,buy} Load_{total} P_{EL} P_{grid,sell} ]风电光伏的外送功率、电解槽功率、燃料电池功率、电网购售电功率都是决策变量。储氢罐的动态方程写成离散形式[ E_{H2}(t1) E_{H2}(t) \eta_{EL} P_{EL}(t) - P_{FC}(t) / \eta_{FC} ]注意燃料电池是氢气转电力所以氢气消耗量是电功率除以发电效率不是直接乘效率。这个地方写反会让储氢罐越跑越满结果明显不真实。以下是YALMIP建模关键代码片段% build_model.m 中的核心约束 Cons []; % 功率平衡约束 Cons [Cons, P_w P_v P_fc P_grid_buy ... Load P_el P_grid_sell]; % 电解槽约束 Cons [Cons, 0 P_el P_el_max]; Cons [Cons, P_grid_buy 0, P_grid_sell 0]; % 储氢动态 Cons [Cons, E_h2(2:T1) E_h2(1:T) eta_el * P_el - P_fc / eta_fc]; Cons [Cons, E_h2(1:T1) H2_cap]; Cons [Cons, E_h2(1) H2_init, E_h2(T1) H2_init]; Obj sum(P_w * price_sell P_v * price_sell P_grid_sell * price_grid) ... - sum(P_el * price_buy_h2) - sum(P_fc * cost_fc) ... - sum(P_w_cur * penalty_w) - sum(P_v_cur * penalty_v);目标函数里我用了P_w_cur和P_v_cur表示弃风弃光惩罚量。真实设备不会让所有风光出力都进入系统超出母线消纳能力的部分就是弃电。经理性上惩罚系数取高一点优化器就会尽量让电解槽吸收多余电力从而体现“氢能消纳新能源”的价值。3.3 ADMM迭代实现与合作收益分配收益分配阶段采用ADMM有三个明显好处不需要将纳什乘积直接丢给全局非线性优化器避免了求解困难各主体可以保留各自的局部约束不用把全部信息交给中心调度迭代过程中如果某个主体不收敛可以单独定位问题。我的ADMM求解思路是这样的先由中心协调者计算联盟总收益和总增量然后每个主体计算自己理想的收益增量再通过一致性约束协调分配。目标函数写成[ \max \sum_{i} \ln(\Delta_i) ]约束[ \sum_i \Delta_i \Delta_{total} ]由于每个主体的成本收益函数互相关联直接并行不好解需要引入辅助变量局部复制原变量再用拉格朗日乘子协调。迭代到乘子残差小于阈值时认为达到纳什谈判解。下面是简化版的ADMM循环变量名和真实工程基本一致% solve_admm.m rho 0.1; lambda zeros(3, 1); delta zeros(3, 1); for k 1:max_iter delta_prev delta; % 主体1风电收益增量 delta(1) project_to_local(1, lambda(1), rho); % 主体2光伏收益增量 delta(2) project_to_local(2, lambda(2), rho); % 主体3氢能收益增量 delta(3) project_to_local(3, lambda(3), rho); % 中心协调者更新一致性乘子 lambda lambda rho * (delta - delta_target); r norm(delta - delta_prev); if r 1e-4 fprintf(ADMM收敛迭代次数 k%d\n, k); break; end end实际运行时rho不能设太大也不能设太小。太大会导致乘子更新剧烈目标值来回震荡太小会收敛极慢往往五十次迭代都压不到千分之一的残差。我自己用的经验区间是0.05到0.3具体值要结合目标函数量纲调整。如果收益单位是万元ADMM目标函数范围在几百到几千之间0.1左右通常比较稳定。3.4 结果输出与灵敏度分析做完优化不能只打印一个总收益数字工程上必须把关键变量曲线和表全部输出。我最常输出的有三张图第一张是24小时风电光伏出力与电解槽耗电曲线直观展示氢能对新能源的消纳作用第二张是储氢罐储量变化曲线验证动态约束没有越界第三张是三个主体在独立运行和合作运行下的收益柱状对比图。灵敏度分析方面我会选择两个关键参数售氢价格和电解槽容量。售氢价格直接影响氢能主体收益进而影响合作意愿电解槽容量决定系统能消纳多少盈余电力。我通常做一组“扫参”固定其他参数把售氢价格从20元/kg扫到40元/kg观察三个主体收益增量和总弃电率的变化输出成表格。这个结果对项目论证特别有用业主能一眼看出参数波动会造成多少收益波动。4. 综合能源应用场景与典型结果4.1 电氢耦合消纳弃风弃光在综合能源系统里电氢耦合最大的价值就是给新能源提供一条“不依赖电网并网容量”的消纳通道。风机和光伏大发时段电网接纳能力有限与其弃掉这部分绿电不如启动电解槽制氢哪怕制氢电价低一些也比白白弃掉强。我在典型日场景里测过风电光伏出力高峰出现在凌晨和午后电网负荷曲线高峰出现在早晚。不合作时风电主体凌晨时段大量弃电光伏主体午间也面临弃光合作运行时电解槽在凌晨和午间满功率运行把盈余电力转化为氢气。储氢罐在低谷时段充值在晚高峰通过燃料电池回放电力和出售氢气系统整体弃电率从14.7%降到2.1%效果非常明显。这只是24小时的经济调度结果。如果拉长到全年8760小时还要考虑储氢罐的跨日、跨周调度这时候储氢容量和电解槽容量之间的匹配就变得很关键。我建议先用典型日的代码把逻辑跑通再扩展到全年数据否则全年数据量较大且初始解设置不当会让ADMM很难收敛。4.2 合作收益与联盟稳定性分析纳什谈判得到的收益分配是否稳定最直接的检验标准是看每个主体的增量收益是否为正。只要增量收益大于零联盟就有存在基础如果某主体在纳什解下仍低于谈判破裂点模型就应当在约束层面直接排除这种分配方案。我用一个基准算例跑出来的增量收益分布大致如下主体非合作收益合作收益收益增量风电主体128.6 万元153.2 万元24.6 万元光伏主体86.4 万元108.7 万元22.3 万元氢能主体41.2 万元72.5 万元31.3 万元注意这里氢能主体的收益增量最大主要原因是它拿到了低价绿电制氢成本大幅下降。风、光主体的增量收益则来自弃电惩罚降低和卖电收入增加。三者增量都大于零说明这个联盟在利益层面是稳定的。还有一个经验值得单独说如果某个主体在合作后收益增量非常小只有几千块钱那这个联盟的真实稳定性其实很差。实际工程里几千块钱的增量覆盖不了通信改造和管理成本主体随时可能退出。遇到这种情况我会建议调整内部结算电价把收益增量再归一化而不是死盯着纳什乘积的解。5. 常见问题与MATLAB环境避坑5.1 求解器报错与参数设置用YALMIP加Gurobi跑合作模型我最常遇到的问题是“无法求解非凸二次约束”。这一般是因为目标函数或约束里出现了变量相乘比如把储能功率和氢价写成了两个变量相乘。纳什谈判原始的乘积目标就是非凸的所以第二阶段我不会直接塞给Gurobi而是先转化为对数形式再用ADMM迭代求解或者直接写解析分配公式。第二个高发问题是约束不可行。最常见的原因是储氢罐初末能量约束卡得太死。如果要求 $\ E(1)\ E(T1)$而电解槽和燃料电池容量又小无法平衡一天的净氢量模型就会无解。我一般先放开末值约束让储氢罐在调度周期结束时达到初始值的90%到110%等调试通过后再收紧到精确相等。另一个容易踩坑的地方是Gurobi许可证超时。在循环里反复调用optimize每次都要几秒钟如果数据量很大且循环次数超过一百次等待时间会让人很难受。我的做法是尽量减少循环内的建模次数把变量和约束对象定义好只更新常数项然后调用optimize能明显缩短求解时间。5.2 MATLAB安装、工具箱与运行效率问题MATLAB版本问题在团队协作里很容易踩坑。我自己用的是2026b版本遇到过装完新版本之后报MathWorks Licensing Error 8的情况。这个报错的本质是许可证文件的HostID和当前机器不匹配解决思路是打开许可证管理器重新核对主机ID再到学校的正版平台或MathWorks官网重新生成许可证文件激活不要自己手动改License文件。如果是公司账号让IT管理员重新绑定许可证后重启MATLAB基本就好了。工具箱方面这套代码主要依赖Optimization Toolbox和YALMIP。YALMIP不是MathWorks官方工具箱需要单独下载并加入路径。安装完成后可以跑一下yalmiptest如果输出里所有求解器的测试结果都有“solvertime”正常返回说明安装没问题。我在Gurobi和YALMIP的版本匹配上栽过一次跟头YALMIP版本太旧认不出新版Gurobi解决方案是到YALMIP的GitHub仓库拉最新版覆盖。运行效率方面24小时线性规划模型本身很小Gurobi求解只需不到一秒。但如果扩到8760小时并且加入ADMM循环内存和时间就会明显上升。建议把矩阵预分配、把常数向量提取到循环外、用稀疏矩阵描述约束。MATLAB里最影响速度的部分其实是动态变量叠加比如写Cons [Cons, new_constraint];这种写法在小模型里无所谓大模型里会导致矩阵不断复制改成预分配字段或者使用约束数组会快很多。5.3 常见问题速查表现象原因处理办法Gurobi提示模型不可行功率平衡约束与设备上下限矛盾检查负荷、弃电变量、联络线功率的关系加入松弛变量ADMM目标函数震荡rho太大减小到0.05观察20次迭代曲线收益分配出现负数谈判破裂点设置错误逐个单独验证非合作模型结果储氢罐电量越界动态方程忽略了效率方向氢转电要除以效率电转氢要乘效率MATLAB启动时报许可证错误HostID不匹配重新检查机器ID向管理员申请绑定合作收益低于非合作目标函数少计入了绿电销售检查内部结算电价是否进入双方收益6. 给后来者的几个实用建议代码可以先跑通再讲道理但参数一定要坚持“量纲统一、约束不互相打架”的原则。我第一版代码里把燃料电池效率写反导致储氢罐压力一直偏高花了整整一个晚上才排查出是除法和乘法的问题。类似这种低级错误在能源优化的代码里很常见建议每跑完一次结果就做一次“物理合理性检查”比如弃电率是否在合理区间、各主体收益是否为正、储氢罐曲线是否有异常锯齿。另外纳什谈判模型很容易陷入一种“数学上完美但工程上没法执行”的状态。最优解要求凌晨和午间频繁启动电解槽但如果实际电解槽的最小运行功率是额定功率的30%那么优化结果里出现小于30%的功率值就必须额外加约束。真实设备的启停寿命、爬坡速率和维护间隔这些约束可能不会出现在经典论文里但一定会出现在工程落地清单上。我建议在跑纳什谈判之前先和现场运行人员确认一套设备操作约束表再把这些硬约束补进模型。最后分享一个小习惯每轮仿真我都会把非合作收益、合作收益和收益增量保存成CSV文件并记录对应的参数配置和时间戳。这样做的好处是当你调整了某个参数导致收益异常变化时可以直接对比历史结果快速定位是电价、氢价还是储氢容量引起的。调试多主体模型最怕的就是“不知道哪次改动把哪里带偏了”保留实验记录能帮你省出大量排查时间。这套代码经过几轮迭代已经能稳定输出合适的结果后续如果再扩展可以考虑加入多能互补园区和碳交易机制逻辑结构不需要大的改动。
返回列表