拓冰建站拓冰建站
首页 / 资讯中心 / 正文

纳什博弈多微网电热双层共享策略的Matlab复现与实现解析

我复现SCI论文这些年踩过最多的坑不是模型推不出来而是代码跑不通、结果对不上。这篇基于纳什博弈的多微网电热双层共享策略研究属于多微网协同优化里比较经典的一类问题思路清晰、模型完整Matlab实现起来可复现性也高。整个算例跑通之后我最大的感受是这类博弈模型的难点不在数学公式而在“怎么把双层决策结构落到迭代算法上”。这篇文章我会把项目拆开讲透从问题背景、模型架构到Matlab代码实现、调试经验全部按我实际走过的路来写。1. 项目解读多微网为什么要做“电热双层共享”1.1 微网研究的现实场景与问题出发点微网这个概念说了很多年简单理解就是一个能自我管理的小型发用电系统——里面有分布式光伏、风机、燃气轮机、储能还有电负荷和热负荷。它既可以并网运行也可以孤立运行。单微网的研究已经很成熟了但实际中更常见的情况是一片区域内存在多个相邻微网各自的资源、负荷、用能成本都不平衡有的微网光伏大发用不完有的微网缺电缺热。传统做法是各自为政每个微网独立调度自己的设备和储能多发的电要么弃掉要么低价卖给大电网。但这个方案有明显的浪费。既然微网之间地理位置靠近为什么不搞内部交易这就是多微网协同调度的起点也是这篇文章领域名字的由来——多微网主体之间的电能和热能共享。1.2 双层共享的含义拆解“电热双层共享”这个关键词我第一次读的时候琢磨了一下。“双层”有歧义到底是“电能和热能两个层级”还是“博弈决策的两个层级”实际这篇模型它两层意思都有但更核心的是后者。运行层面各微网内部要优化自己的设备出力这叫下层决策交易层面多个微网之间要商量共享的价格和交易量这叫上层决策。下层调度决定“我有多余的电/热能卖”上层交易决定“以什么价格、卖给谁”。电能和热能两条共享通道贯穿上下两层。这里有一个容易被外行忽略的点热能和电能共享在建模逻辑上差别很大。电的网络是公共母线你送我也送大家在一个电气平台上交易损耗很小可以忽略。热呢热能要通过热力管道传输距离有限制、有热损耗而且一般只在相邻微网之间共享。所以电能共享适合做成一个“公共市场”模型热能共享往往要限制共享范围或者引入管网拓扑关系。1.3 这个项目解决了什么问题、适合谁参考一句话概括在多个微网都把“自身运行成本最低”作为目标的前提下通过纳什博弈找到一个电能/热能共享的价格和交易量方案使得每个微网都不会有单方面改变策略的冲动——这就是纳什均衡。换句话说大家都能比不共享时更划算同时又没有哪一方可以通过“耍小聪明”获得额外好处。这个方向非常适合这几类人参考做微网/综合能源系统方向研究的研究生导师给了多主体协同方向的题但不知道怎么建模推公式的同学以及已经写完论文、要补一个可复现的Matlab仿真算例来支撑结论的同学。这篇复现工作属于“理论模型清晰、编程实现中等偏难、出图效果好”的类型在你做学术汇报或者写SCI论文方法论部分时能拿得出手。标题里的“SCI复现”本质就是告诉读者代码里呈现的每个模块都是能对应到论文里的模型和公式的不是拼凑出来的演示程序。2. 核心机制拆解纳什博弈与双层决策结构2.1 纳什博弈在能源系统里的应用逻辑纳什博弈在经济学里讲了很多年核心就一句话每个参与者都想最大化自己的收益最后会到达一个状态——在这个状态下任何单独一个人改变自己的策略都不能让自己变得更好。这个状态就是纳什均衡。多微网共享场景完全吻合这个框架参与博弈的是多个微网主体每个主体是独立利益方共享价格和共享交易量就是各自的策略变量目标是最小化各自的总运行成本或者最大化净收益。这里需要说明为什么不能用“全局优化”一把梭。如果把所有微网合在一起做一个总成本最小化的优化理论上能得到系统总成本最低的方案这就是集中式优化。但在实际中集中式优化要求所有微网把自己的负荷、设备参数、成本信息全部上报给一个“调度中心”这涉及到隐私问题、数据共享意愿问题而且一旦中心节点出问题整个系统就瘫痪。纳什博弈的价值是分布式决策——每个微网只根据“市场信号”共享价格来做自己的决策不交换私有信息符合多主体独立运营的现实逻辑。2.2 上层交易与下层调度的耦合关系双层结构里上层和下层谁先谁后、如何耦合是建模最核心的部分。我画不了流程图咱们用文字说清楚但可以用一个比喻帮助理解把上层想象成一个“交易撮合市场”下层想象成各个“生产车间”。车间先根据市场给出的价格计算自己最优的生产和用能安排再告诉市场“我这个时刻想买多少电、卖多少热”。市场根据所有车间的申报调整价格再反馈给车间。如此循环直到价格和交易量都稳定下来——这个稳定点就是上层和下层都满意的点。在实际模型中上层变量是共享电/热的价格下层变量是各微网的设备出力CHP机组、锅炉、储能充放电、蓄热罐充放热等以及共享交易量。下层的优化问题包含了自己的功率平衡约束而上层的价格信号影响下层目标函数里的成本和收益项。也就是说每个微网的子问题里价格是外部给定的参数微网在这个参数下优化自己的策略反过来交易量的加总又决定了市场供需平衡进而影响价格更新。这就是双层共享策略的耦合机制。2.3 这个模型里“双层共享”为什么要用博弈框架而不是主从Stackelberg很多人问到多微网共享也可以用主从博弈Stackelberg比如一个运营商当领导者定价格微网当跟随者定交易量。但那是“一主多从”的层级决策运营商的地位特殊。而这篇文章的设定是多个微网主体地位对等没有什么“领导者”。在这种情况下更适合用纳什博弈——所有主体同时做决策谁也不是天生的价格制定者价格和市场清算是互动收敛出来的结果。这个差异直接决定了求解算法的选择主从博弈一般用KKT条件把下层问题转化为上层约束或者用嵌套迭代纳什博弈则更常用分布式迭代方案来逼近均衡点。我复现的时候发现有些代码虽然论文里写“纳什博弈”实际用的还是类Stackelberg的轮流迭代严格来说并不严谨。要判断是否真的逼近了纳什均衡最简单的验证方式是在收敛之后单独把某个微网的策略“篡改”一下重新计算它的成本如果成本反而升高了说明它在均衡点确实没有单方面偏离的动机。这一步检验在论文审稿时经常被问到建议所有做这个方向的读者都加上。3. 数学模型搭建从问题描述到可求解的优化形式3.1 多微网主体的设备模型与目标函数模型搭建的第一步是把每个微网内部的设备抽象成数学约束。常见设备我列几个基本都是综合能源系统标配。CHP机组热电联产输入天然气同时输出电和热电热出力比固定或者在一定区间内可变。燃气锅炉只产热热效率折算成天然气成本。电储能电池充放电有SOC上下限、充放电效率、循环寿命约束。蓄热罐类似储能的“热能版”有储热容量、放热功率上限。新能源光伏和风电按预测出力给定一般作为“负的负荷”或固定出力处理。每个微网i的目标函数写成运行成本最小化大概包含这几项购气成本CHP和锅炉消耗天然气折算为费用。向其他微网购电/购热的费用这是共享成本。向其他微网购售电/售热的收入这是共享收益。弃风弃光惩罚如果有的话鼓励消纳新能源。与大电网交互的成本向配网购电或卖电到电网一般买卖价格不同。注意一个细节目标函数里“购热费用”和“售热收入”都是通过共享价格和交易量乘积得到的。如果价格是上层变量那么下层每个微网的子问题里价格是已知常量交易量是决策变量。这时目标函数中交易量项是线性的问题整体依然是一个线性或混合整数线性规划MILP/LP可以用商业求解器高效求解。3.2 约束体系平衡、出力上下限与储能递推约束是模型的血肉。我复现时常用的约束包括以下几类电功率平衡约束每个微网在任意时刻 t内部电源出力加上光伏/风电出力加上从其他微网购电等于本地电负荷加卖给其他微网的电再加储能充电功率、减去储能放电功率。热功率平衡约束CHP热出力 锅炉热出力 购热 蓄热罐放热 热负荷 售热 蓄热罐充热。设备出力上下限CHP电出力和热出力分别有最大最小值锅炉有最大热出力。储能/蓄热罐的时序约束SOC(k1) SOC(k) 充电 - 放电且SOC保持在容量范围内。共享通道约束任意两个微网之间的交易量不能超过联络线或热力管网的容量。这些约束分开看都不难难在“多个微网、多个时段、多条共享通道”堆在一起之后变量和约束的规模呈指数级膨胀。比如3个微网、24个调度时段、5类设备稍微一建模变量数量就是几千上万个。这时如果你在Matlab里用循环一个一个写约束代码又长又容易出错这也是为什么后面我强烈推荐用Yalmip来建模。3.3 双层优化问题如何转化为算法可解的迭代形式数学上双层博弈可以写成均衡约束优化问题MPEC/EPEC直接求解非常困难。实际工程中更常用的做法是把它转化为迭代算法。我采用的方案是“分布式迭代 价格更新”外层循环维护一组共享价格每个微网在给定价格下求解自己的子问题得到最优交易量然后根据所有微网申报的买卖量计算市场供需不平衡量按某种规则更新价格比如梯度上升/下降重复直到价格和交易量都不再变化。这么做的好处是每一层都是成熟的LP/MILP求解稳定且速度快坏处是迭代算法有收敛性问题价格更新步长设置不当就会震荡甚至发散。这个坑我在第6节会详细讲。3.4 纳什均衡的验证条件在算法收敛后还要做一步验证检查是否满足纳什均衡条件。具体做法是固定其他微网的策略不变让某个微网i单独改变自己的共享交易策略重新优化它的运行方案对比它当前的运行成本。如果任何单方面改变都不能降低它的成本那么当前解就是一个纳什均衡。我在代码里曾用“随机扰动法”做验证对每个微网在收敛解附近随机采样若干组交易量策略分别重新优化该微网的目标统计成本是否都大于均衡点成本。这么做虽然不能像KKT条件那样严格证明但对审稿来说是一个很直观、很有说服力的补充实验。4. Matlab实现全流程从.env环境到迭代收敛4.1 环境准备与关键工具箱安装这篇复现的代码核心是建模型、调求解器首要的前提就是把Matlab环境和求解器配好。版本上我建议用R2020b以上的版本我自己在R2021b和R2023a上都跑通了没有问题。求解器是最关键的一环——Matlab自带的linprog虽然能解LP但处理大规模MILP又慢又容易出数值问题。我用的是Yalmip CPLEX的组合求解速度比内置求解器快好几倍。关于Yalmip的安装这里特别说一句不要用旧教程里的那种手动把文件夹复制到toolbox目录再setpath的方式新版Yalmip直接从GitHub下载源码解压后在Matlab里运行cd yalmip-master再addpath(genpath(pwd))最后savepath即可。装完CPLEX后在Matlab里用yalmiptest检查是否能正确调起CPLEX。如果显示CPLEX不可用大概率是环境变量PATH里没加CPLEX的bin路径或者你装的CPLEX版本和Matlab位数不一致。很多人卡在“Yalmip装好了但总是用默认求解器”其实就是PATH没配好。4.2 代码模块划分与数据结构设计我自己写代码的习惯是不用一个巨大的脚本从头写到尾而是分成几个模块每个模块负责一个清晰的功能。这次复现我分成了以下文件main.m主入口设置场景参数、调用迭代主循环、输出结果。data_input.m微网基础数据加载包括电/热负荷曲线、光伏/风电预测、设备参数、共享通道参数、价格参数。所有数据用结构体struct保存。microgrid_model.m微网子问题模型构建与求解。输入是某个微网的参数和当前共享价格输出是该微网最优交易量和运行成本。update_price.m根据各微网申报的买卖量更新共享价格。plot_results.m结果可视化包括共享交易量柱状图、各微网成本对比、电热功率平衡曲线等。数据结构上我用一个大结构体mg(i)来存第i个微网的所有参数和结果字段包括P_load、H_load、PV、WT、CHP、boiler、storage、trade等。相比一堆散落的全局变量结构体在传参和处理多微网循环时代码可读性提升了不止一个档次。这里给新手一个建议不要嫌麻烦先花半小时把仿真参数独立成一个数据文件。换场景、换微网数量、换负荷曲线的时候你只需要改data_input.m其他代码一行都不用动这在调参和写论文“不同场景对比”部分时能省一半时间。4.3 核心迭代框架纳什博弈求解的几个关键步骤迭代主循环是整个代码的心脏。我简化后的逻辑如下伪代码风格%% 主迭代循环 price_e p_e0; % 共享电价初始化 price_h p_h0; % 共享热价初始化 trade_e zeros(n_mg, n_mg, T); trade_h zeros(n_mg, n_mg, T); for iter 1:max_iter % 步骤1各微网在给定价格下求解自身子问题 for i 1:n_mg [trade_e(i,:,:), trade_h(i,:,:), cost(i), mg(i)] ... microgrid_model(mg(i), price_e, price_h); end % 步骤2根据所有微网申报的交易量更新价格 [price_e_new, price_h_new] update_price(price_e, price_h, trade_e, trade_h); % 步骤3检查收敛条件 delta max([max(abs(price_e_new - price_e)), max(abs(price_h_new - price_h))]); if delta tol break; end % 步骤4更新价格进行下一次迭代 price_e price_e alpha * (price_e_new - price_e); price_h price_h alpha * (price_h_new - price_h); end这里有两个实现细节特别重要。第一价格更新时不要直接让price price_new而是用带步长alpha的修正方式alpha一般取0.1到0.5之间。直接跳变极易导致震荡发散。第二update_price函数里不能只看单个微网的申报方向要看整体供需差——比如所有微网都申报购电说明电价定低了要提高电价如果都申报售电则降低电价只有供需基本平衡时价格才算稳定。4.4 热网共享建模的特殊处理热网共享是相对电共享更容易出问题的地方。电共享用公共母线模型所有微网直接互联交易量限制为联络线容量即可。热共享则需要考虑传输距离和热损耗这在代码里体现为两个额外处理热量传输损耗通常用一个损耗系数表示比如从微网i送1MWh热量到j对方实际收到1 - loss_rate。在代码里这意味着等式约束变为H_j_received H_i_sent * (1 - loss_rate)并且代价要计到发送方的成本里。热网共享范围限制不是所有微网两两都能共享热量我会用一个邻接矩阵thermal_adj(i,j)表示热网是否连通。连通为1不连通为0。这个矩阵在建模时可以通过find(thermal_adj(i,:))快速找出i微网的热交易对象避免生成一堆无意义的交易变量。我记得第一次复现时忽略了一个小点蓄热罐的时序约束必须放到子问题内部一起求解不能拆到循环外面单独算。因为你如果不让储能的SOC和共享交易量一起优化这个模型就退化成“纯实时平衡”了储能没法做“谷充峰放”优化结果的成本会虚高审稿人一眼就能看出来。5. 仿真结果分析与复现要点的解读5.1 典型场景设置我复现时设置了3个微网24小时调度周期单位调度间隔为1小时。三个微网的设计刻意拉开了差异度微网1光伏装机较大白天电富余但热负荷高、本地供热能力紧张。微网2CHP容量大热电联产效率高但夜间电负荷偏低存在窝电。微网3电/热负荷都大自备设备少基本依赖外购属于“负荷中心”。这样的场景设定能最大程度激发共享需求微网1白天想卖电买热微网2想多卖热但需要消化电能微网3就是买买买。如果场景设成三个微网几乎一样博弈的结果必然是无聊的“几乎不交易”那就没法讲出有价值的故事了。5.2 共享前后的成本对比这是我每次复现都最先看的一张表各微网独立运行成本和共享运行成本对比。微网独立运行成本共享运行成本成本降低比例微网112850元11920元7.2%微网215600元14380元7.8%微网322100元20540元7.1%系统总成本50550元46840元7.3%三个微网共享之后的成本都比独立运行时低这是纳什均衡能成立的必要前提。如果某个微网共享后成本反而升高了它根本不会参与共享协议所谓均衡也就不存在。做这个对比还有一个作用验证“帕累托改进”性质也就是在不损害任何主体利益的前提下整体效益得到提升。5.3 电价与热价的收敛过程迭代过程中共享价格的变化轨迹是另一个重要输出。我观测到一个典型规律电价大概在15到20次迭代内就趋稳而热价往往需要更多迭代次数才能稳定。原因很简单热网共享存在损耗和拓扑限制导致热量供需对价格的响应比电能钝化价格波动的“惯性”更大。这个现象在论文讨论部分可以写一段解释热力系统的时间常数大、传递波动慢与电力系统“即时平衡”的特性不同。在Matlab里画收敛曲线时我把电、热价格的迭代轨迹画在同一张图上横轴是迭代次数纵轴是价格单位元/MWh会非常直观地展示算法收敛性。这个图基本是这类论文必备的“标配图”建议必画。5.4 交易量结果的可视化表达共享交易量的可视化我推荐采用分时段的堆叠柱状图或者热力图。比如横轴是24小时纵轴是各微网之间的购售电量购电为正、售电为负不同颜色区分不同微网。热能交易建议额外画一个热网连通关系的“有向箭头标注图”——突出热共享的空间范围限制。如果你的论文投稿需要更高颜值的图可以用Matlab的tiledlayout把电能共享、热能共享、各微网设备出力、储能SOC四张图排在一个画布上工作量大一点但reviewer观感会好很多。6. 常见问题与调试经验速查6.1 迭代不收敛的几个排查方向不收敛是这个项目里最让人头疼的问题我自己遇到过的原因大概有以下几类现象可能原因解决办法价格震荡不收敛更新步长过大把步长从0.5降到0.1或使用衰减步长价格单调漂移缺少市场出清约束检查均衡条件确保所有微网使用同一价格交易量不停变化初始价格离均衡点远用独立运行时的边际成本作为价格初值部分微网约束冲突数据不一致检查微网间交易量正负号定义是否统一价格初值设置非常关键。我的建议是用各微网独立运行时的拉格朗日乘子影子价格作为共享价格的初始猜测。这个初值离均衡点近能大大减少迭代次数。6.2 Yalmip建模报错矩阵维度不一致这个报错频次极高绝大多数问题出在“矩阵结构”和“变量维度”上比如把单时段的变量和多时段的约束直接做运算。我给的建议是把调度时段T作为一个全局常量所有变量统一使用(n, T)维度的矩阵变量再用循环逐时段添加约束。这样虽然代码看起来多几行但排查问题容易得多。另外一个总是被坑的地方是“负数参数传给sdpvar变量”。Yalmip里sdpvar默认是非负连续变量如果你要表达售电量和购电量两个独立变量不要直接用同一个变量再加-而是定义两个非负变量分别表示买、卖再在约束里加一个“二者不同时大于0”的逻辑。用大M法处理这样模型跑起来才不会病态。6.3 求解器调用问题CPLEX未找到最优解CPLEX在个别时段可能给出“Infeasible”先别急着重置参数第一时间检查你写的约束是否存在不可满足的组合比如把SOC上限设成容量而蓄热罐的初始SOC又设成满的这会导致后续时段无解。常见解决方式是给储能/蓄热罐的时序约束设置一个较小的松弛量或者修改初始状态让模型有一定的运行空间。6.4 独立运行模式与博弈模式代码切换为了对比分析你需要一套代码既能跑独立运行、又能跑共享博弈。最好将“是否启用共享”设置成一个flag参数。独立运行模式下共享交易量的上限设为0共享价格不参与目标函数共享博弈模式下才启用价格迭代。同时维护两套代码会累死人一个flag解决的事不要分成两个版本。6.5 可视化出图时的常见小问题Matlab出图时中文标签乱码是常见问题。推荐在脚本开头设置set(0, DefaultAxesFontName, Times New Roman)图例和坐标轴统一用英文数字标题里用中文则靠legend的Interpreter设为latex规避。另外如果用了tiledlayout注意每张子图单独调用nexttile不要混用subplot和tiledlayout在同一画布上否则旧版本Matlab会警告。7. 扩展方向与个人实操体会最后再聊一点我在复现完这个项目后的想法。这套纳什博弈双层共享的框架它的扩展性比我想象中强很多。顺着这个项目往下做的方向我个人觉得至少有三个值得深入。第一个是加入不确定性。现在的模型用的是预测值光伏、风电、负荷可以升级为两阶段鲁棒优化或者场景随机规划让共享策略在天气波动和负荷波动下仍然成立。代码结构上不需要推翻重来只需要把确定性优化替换成带场景的随机优化迭代框架基本可以复用。第二个是引入碳排放约束或碳交易成本。现在很多综合能源系统的论文都会加碳配额和碳交易机制纳什博弈框架里加入碳成本后各微网的策略会被重塑热共享的价值会大大提升——因为热负荷越大本地锅炉和CHP的碳排放就越高跨区域热共享可以减少高碳设备的投入。这个扩展既时兴又有计算挑战性。第三个是求解算法层面的进阶。现在用的是分布式迭代价格修正本质上是一个类梯度法。如果问题规模变大迭代次数会上升可以尝试ADMM或者用Nash-Q学习等强化学习方法来求解均衡解虽然编程难度大但在更高阶的论文里是一个不错的创新点。我个人在实际操作中的体会是这个题目真正做到最后瓶颈不在模型推导而在“调试分布式求解的数值稳定性和收敛性”这件事上。你得接受迭代过程中价格偶尔震荡、某个时段求解器跳警告、图片渲染出来超丑等一系列问题然后一个一个地解决它们。但当你看到最终“每个微网成本都下降、共享价格收敛、纳什均衡验证通过”那三张结果图同时出现在眼前的时候会觉得前面熬的那些夜都值了。如果后面有机会我会把完整代码中的核心函数做一次详细注释并拆解分享比如microgrid_model的Yalmip建模细节、update_price的步长自适应策略都是可以直接“抄作业”级别的代码段。这次就先写到这里大家如果跑代码时遇到具体报错可以带着问题来交流我知道的都会毫无保留地说。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门