非对称纳什谈判多微网电能共享优化:博弈建模与ADMM求解实践

发布时间:2026/10/8 9:14:35
非对称纳什谈判多微网电能共享优化:博弈建模与ADMM求解实践
从拿到一篇《电网技术》上的多微网电能共享论文到把模型拆成能跑的 MATLAB 程序中间隔着不少论文里没写清楚的细节。尤其是基于非对称纳什谈判的合作博弈模型表面看只用把纳什积最大化写出来就行真正落地时却涉及决策变量的分解、谈判破裂点的计算、共享电价的内生形成机制还有 ADMM 迭代的收敛问题。这篇文章围绕“基于非对称纳什谈判的多微网电能共享运行优化策略”这个主题把我复现经典电网技术文献代码时的完整思路、模型推导和 MATLAB 实现要点拆开讲一遍适合正在做微电网/多微网优化调度、博弈论相关方向的研究生以及需要把这类文献复现成可运行代码的工程师参考。1. 多微网电能共享要解决的实际问题为什么要引入博弈模型多微网系统并不新鲜但大多数初读这类文献的人会先问一句每个微网自己独立调度不是挺好的吗为什么非要搞共享、搞谈判我先从实际场景说说这个问题后面的模型理解起来会顺很多。1.1 单微网独立运行的三个痛感假设你手上有三个微网分别靠近一片工业园区微网A屋顶光伏装了很多白天发电量远大于自身负荷但晚上负荷上来后只能高价从配网购电微网B基本上是个工业负荷中心自有的风电出力不稳定缺电的时候经常要买高价电微网C有一个功率还算够用的储能系统但因为没有和其他微网联动的机制储能的利用策略非常保守很多时候“有劲使不上”。三个微网各自独立运行时典型的矛盾是A中午有大量富余光伏被迫限功率弃光B和C的负荷午间高峰期照样从外部电网买电。从整个系统去看这不是资源不够而是资源错配。共享电能最本质的收益就是把A的富余出力通过联络线送到B和C减少向外部电网购电的总量同时降低弃光率这就是多微网电能共享要解决的资源配置问题。但这里有一个隐藏的问题A凭什么要把电共享给B和C如果只是行政命令让A低价送电A的积极性会很差。如果让A自己定价B和C又不一定接受。于是需要一个能公平决定“共享多少电、以什么电价共享”的机制——这就是博弈论模型介入的原因。1.2 合作博弈与纳什谈判的分界线在电力系统文献里“多微网电能共享”建模方式大致有三类集中式优化假设存在一个中心调度者对所有微网的运行做统一优化。这种方法数学上最简单全局最优性强但它忽略了各微网属于不同利益主体这一事实——现实中园区里的几个微网很可能归不同公司所有谁也不希望自己的运行数据完全暴露给中心。非合作博弈每个微网基于其他微网的行为做最优反应迭代。这种模型能体现主体自利性但最后结果往往是纳什均衡均衡点可能远偏离系统全局最优而且迭代格式容易不收敛。合作博弈/纳什谈判先让所有微网结成联盟得到联盟总成本最小的运行方案也就是做一次集中式优化再通过谈判机制把联盟产生的合作收益分配给各成员让每个成员实际承担的成本都不高于其独立运行时的成本。第三类模型的吸引力在于它既保留了集中式优化的全局最优性又通过谈判机制解决了利益分配问题保证了每个微网“有动力参与”。非对称纳什谈判在对称纳什谈判基础上的改进是把各微网的“谈判力”差异显式建模进去——这个细节后面细说但方向是对的现实中资源多的微网和资源少的微网在谈判桌上的话语权确实不一样的。1.3 复现文献前必须建立的目标预期不少人在复现这类代码时上来就埋头写 YALMIP 模型结果跑了半天不知道自己在什么。我建议动手之前先明确这个优化模型最终要输出什么每个微网内部各时段的储能充放电功率、向外部电网的购售电功率微网之间联络线上的交换功率谁供谁、供多少微网之间的共享电价内生变量不是给定的输入参数每个微网的成本/效益变化用来验证谈判结果是否优于独立运行。换句话说整个模型不是一个纯粹的“运行调度”问题它同时包含调度决策和定价决策。这个双重性质决定了它的求解不能只用单层优化而是要分层迭代。理解了这一点你再看文献里的两阶段算法框架就不会觉得绕了。2. 非对称纳什谈判的数学本质从纳什积到谈判破裂点这一节是整个复现工作里最核心的部分。如果只把目标函数抄下来不理解纳什谈判的公理体系代码里很多取舍你会看不明白。我用最直接的方式过一遍。2.1 纳什谈判模型的四个基本元素任何谈判问题都可以抽象成四个元素参与人集合这里是 N 个微网谈判破裂点disagreement point谈判如果没有达成协议各微网退回到独立运行时的收益向量通常记为 (d_i)在电能共享场景里可以定义为微网独立运行时能获得的最大收益或者说最小成本(d_i -C_i^{ind})可行收益集合所有通过某种合作方式能够实现的收益向量组成的集合这个集合约束了谈判结果的空间每个参与人的效用函数在电能共享文献中通常用成本节省额作效用更直观(U_i C_i^{ind} - C_i^{coal})表示参与合作后相比独立运行节省了多少成本。纳什谈判解的定义是在可行收益集合中找一个点使得所有参与人的效用相对谈判破裂点的超额乘积最大。对称情形下的表达式是[ \max \prod_{i1}^{N} (U_i - U_i^0) ]其中 (U_i^0) 是谈判破裂点对应的效用值。这个目标函数看起来很朴素但它背后是纳什在1950年提出的公理体系帕累托最优性、对称性、线性变换不变性和无关选择独立性。满足这四条公理的解恰好就是使纳什积最大的那个点。这也是为什么电力系统的合作博弈文献普遍采用纳什谈判模型——它有严格的博弈论基础。2.2 非对称权重怎么进入纳什积说到“非对称”很多读者会误以为只是给目标函数加个权重系数。数学形式上确实如此——非对称纳什谈判就是在纳什积里给每个参与人的效用差值加上一个指数权重[ \max \prod_{i1}^{N} (U_i - U_i^0)^{w_i}, \quad \sum_{i1}^{N} w_i 1 ]但背后的含义完全不同。(w_i) 刻画的是每个参与人的谈判力。谈判力大的主体对最终收益分配的影响权重更大它能获得更多的合作剩余。这里的谈判力在物理网架中可以体现为几种因素谁的资源更稀缺边际供电成本高的一方往往有更强的要价能力、谁对联盟成功的贡献更大比如提供了更多调峰容量、谁的退出会给联盟造成更大损失。在具体文献里非对称权重的设置有些是提前给定的例如按各微网容量比例折算有些是和“边际贡献”挂钩需要做一个 Shapley 值或 Aumann-Shapley 值的前置计算。复现代码的时候最省事的做法是先用固定的 (w) 数组做敏感性分析观察不同权重分配对共享利益分配的影响。我实际跑下来的经验是权重差异对最终物理调度结果影响并不大但对成本节省的分配结构影响非常明显——这就对了因为它本质上改变的是“分蛋糕”的比例而不是蛋糕本身的大小。2.3 谈判破裂点计算的误区很多复现代码跑出来的结果“好得过分”往往是在谈判破裂点上做了手脚。谈判破裂点应该是如果联盟没有形成每个微网在不依赖其他微网的前提下仅靠自己内部的分布式电源和储能配合和外部电网的交易能达到的最大效用水平。这里常见两个错误把破裂点算成了包含共享电能的成本。这等于把所有收益都算进谈判的基础里合作剩余被重复计算纳什谈判解会失真破裂点用了确定性负荷和确定性新能源出力。实际场景中如果考虑不确定性破裂点应当定义为预期效用但文献复现阶段通常先做确定性模型这个简化可以接受需要在文章里说明。代码层面破裂点其实是一次独立的优化求解。每个微网跑一遍自己内部的优化问题目标是最小化自身总成本约束包括功率平衡、储能SOC约束、与外部电网的购售电约束。因为各微网之间没有耦合约束这个计算可以并行求解N个微网就是N次相互独立的optimize()调用。记住这一步的结果要保存下来后面第二阶段谈判目标函数里要反复用到。3. 两阶段求解框架先做大蛋糕再谈分蛋糕把非对称纳什谈判模型直接扔给求解器是不现实的因为目标函数里的 ((U_i - U_i^0)^{w_i}) 是非线性函数而且决策变量同时包含功率调度量和共享电价实际上构成一个非线性耦合问题。文献里标准的处理方法是转化为两阶段求解3.1 第一阶段联盟总运行成本最小化第一阶段要做的事一句话概括在所有微网结成联盟、共享电能的前提下最小化整个联盟的总运营成本。这个模型本质上就是多微网集中式优化调度目标函数是[ \min \sum_{i1}^{N} C_i^{coal} ]其中每个微网的成本包括从外部电网购电成本、售电收入相对于购电成本是负项、储能退化成本、分布式电源发电成本。约束条件包含各微网内部功率平衡光伏风电储能放电购电 负荷储能充电向其他微网输出联络线功率约束任意两微网之间的交换功率不超过线路容量储能约束SOC 递推方程、充放电功率上下限、SOC 上下限微网间交换功率耦合约束A流向B的功率必须等于B接收自A的功率在建模时用镜像变量或统一的交换变量来表示。这个阶段的求解在 MATLAB 里比较直接YALMIP 建模Gurobi或者你手头有的任何一个 LP/QP 求解器求解。因为它本质上是一个线性规划或凸二次规划只要约束线性、储能退化成本函数建模为线性/凸二次形式求解没有任何困难。第一阶段的目标是得到联盟最优总成本和最优功率调度方案 (P_{i,t}^{sch})。这里有一个容易被忽略的点联盟总成本虽然求出来了但我们还不知道每个微网各自承担多少成本。共享电价还没有决定所以每个微网的购售电费用还不是最终值。3.2 第二阶段通过非对称纳什谈判确定共享电价第二阶段的目标在联盟总成本已确定蛋糕大小已定的前提下通过纳什谈判解出共享电价从而确定各微网的成本分摊和收益分配。具体来说联盟调度的总成本 (C^{coal}) 是各微网成本之和。每个微网在合作中的实际成本可以写成[ C_i^{final} C_i^{local} \sum_{j \in \mathcal{N}, j \neq i} \pi_{ij,t} P_{ij,t} ]其中 (C_i^{local}) 是微网i在联盟调度方案下的本地运行成本(\pi_{ij,t}) 是从i流向j的共享电价(P_{ij,t}) 是t时段i向j输送的功率。如果i是送电方(P_{ij,t}0)它从共享交易中获得收入如果i是受电方(P_{ij,t}0)它需要支付费用。纳什谈判的目标函数是[ \max \prod_{i1}^{N} \left( C_i^{ind} - C_i^{final} \right)^{w_i} ]这里用了成本形式所以差值是成本节省量。取对数之后目标变成[ \max \sum_{i1}^{N} w_i \ln \left( C_i^{ind} - C_i^{final} \right) ]这个转化很重要第一对数函数是凹的最大化一个凹函数在线性约束下是一个凸优化问题可以用标准求解器处理第二通过对数变换纳什积的连乘形式被转换成了求和形式数值稳定性大幅改善。很多代码直接在原纳什积上跑非线性优化反复出现unsuccessful的求解状态改用对数形式后就没有这个问题了。3.3 为什么需要 ADMM共享电价带来的耦合难题表面看第二阶段有了目标函数和约束直接交给求解器就行。但问题在于(\pi_{ij,t}) 和 (P_{ij,t}) 的乘积项产生了变量耦合——送电方的收入取决于受电方的支付金额而受电方的支付金额又取决于共享电价。这是一个包含双线性项的优化问题直接全局求解非常困难。文献中常用的破解办法是 ADMM交替方向乘子法。核心思想是引入一致性变量把关联的耦合约束分解开让每个微网只需要跟一个虚拟协调者交换信息而不需要知道其他微网的具体运行数据。这个特性在机理上也很符合多微网系统的实际情况——微网之间本来就不希望暴露太多私有信息。ADMM 在代码层面的实现大致是这样一个循环初始化共享电价 (\pi_{ij,t}^{(0)})一般用外部电网分时电价作为初值固定电价对每个微网独立求解其局部优化问题得到该电价下自己的最优成本收集各微网的局部解更新全局一致性变量调整共享电价更新拉格朗日乘子和罚参数检查原始残差和对偶残差是否满足收敛阈值不满足就回到步骤2。这里每个微网的局部优化问题规模很小求解速度快。但 ADMM 的收敛性受罚参数 (\rho) 影响很大。我后面专门讲这个调参经验这里先记住一个判断基准原始残差和对偶残差应该同时下降如果只降其中一个模型大概率有问题。4. MATLAB代码架构与YALMIP建模细节现在进入代码层面。我先给出整体文件架构再拆开讲每个模块的建模陷阱。这套架构参考了多篇电网技术文献复现代码的常见组织方式适合二次开发。4.1 代码目录结构multi_microgrid_nash/ ├── main.m % 主程序串联两阶段求解 ├── data_system.m % 系统参数负荷、新能源、网络拓扑 ├── data_price.m % 外部电网分时电价、权重配置 ├── solve_baseline.m % 独立运行模式计算谈判破裂点 ├── solve_coalition.m % 联盟集中优化第一阶段 ├── solve_nash_admm.m % 纳什谈判ADMM第二阶段 ├── update_price.m % ADMM子函数电价更新规则 ├── plot_results.m % 结果可视化 └── params.m % 公共参数常量定义实测下来把params.m单独放一个文件很重要。文献复现的代码最怕的就是参数散落在各个脚本里改一个数值要找半天。把所有可调参数集中在一个文件里调算例的时候效率提升非常明显。4.2 决策变量定义的核心选择用净购电还是双变量这是写 YALMIP 模型时第一个要决策的点。外部购电和售电可以用一个可以有正负的变量表示也可以用两个非负变量表示。在集中式联盟模型里用净购电变量 (P_{grid,i,t}) 更简洁P_grid sdpvar(n_mg, T, full); % 从外部电网的净购电功率 P_ex sdpvar(n_mg, T, full); % 微网间净注入功率出为正 SOC sdpvar(n_mg, T1, full); % 储能SOC多一列存初值对应功率平衡约束写成Constraints []; for i 1:n_mg for t 1:T Constraints [Constraints, ... P_pv(i,t) P_wt(i,t) P_dis(i,t) P_grid(i,t) P_ex(i,t) ... P_load(i,t) P_ch(i,t)]; end end有一个细节容易错(P_ex) 这个变量是整个系统层面的交换功率在给每个微网单独建模时同一对微网之间的交换功率有两个方向相反的表达如果不加约束优化器会“凭空创造能量”。最简单的处理是定义交换功率变量 (P_{ij,t})然后约束 (P_{ji,t} -P_{ij,t})。在全局模型里可以统一用一个变量矩阵表示但要保证每对微网只定义一次方向。4.3 储能约束的建模细节储能是造成模型不收敛的常见原因之一。SOC 递推方程eta_ch 0.95; eta_dis 0.95; dt 1; % 时间间隔小时 Constraints [Constraints, ... SOC(:, 2:T1) SOC(:, 1:T) eta_ch * P_ch - P_dis / eta_dis];这里必须注意单位一致性。如果功率单位是 kW、时间步长是小时那么 SOC 的单位是 kWh储能容量的单位也必须对应。我遇到过一份代码储能容量写成 300能量约束写成 300 kW·h但功率上限按 300 kW 配置导致 SOC 在几个时段内就冲满又放空优化器怎么调都找不到可行解。充放电不能同时发生的约束在文献复现中常见写法是引入二进制变量u_ch binvar(n_mg, T, full); u_dis binvar(n_mg, T, full); Constraints [Constraints, u_ch u_dis 1]; Constraints [Constraints, P_ch P_ch_max .* u_ch]; Constraints [Constraints, P_dis P_dis_max .* u_dis];引入整数变量后模型变成混合整数线性规划求解速度会慢一些但在十几节点规模的多微网系统里完全能接受。如果你的目的是快速复现核心机理也可以接受“充电和放电不同时进行”这个约束稍微放松——通过设定充放电效率不对称让优化器自动不会同时充放但不建议默认这么做因为储能损耗会因此虚高。4.4 第二阶段 ADMM 迭代的 MATLAB 实现骨架为了让你有个直观的实现参照给出第二阶段的核心循环框架。这里省略了局部约束的具体展开重心放在 ADMM 的迭代结构上% 初始化 rho 0.1; lambda zeros(n_mg, T); % 拉格朗日乘子 z_price price_grid; % 一致性变量共享电价的参考值 P_ex_local zeros(n_mg, T); % 各微网局部交换功率 P_ex_global zeros(n_mg, T); % 全局平均 tol_pri 1e-4; tol_dual 1e-4; max_iter 200; for k 1:max_iter for i 1:n_mg % 每个微网在给定 z_price 和 lambda 下独立优化 [P_ex_local(i,:), cost_local(i)] solve_local_problem(i, z_price, lambda(i,:), rho); end % 更新全局一致性变量取所有微网交换功率的投影平均 P_ex_global project_consistency(P_ex_local); % 更新共享电价参考值 z_price z_price lambda ./ rho (P_ex_local - P_ex_global); % 更新拉格朗日乘子 lambda lambda rho * (P_ex_local - P_ex_global); % 计算残差 r_pri norm(P_ex_local - P_ex_global, fro); r_dual rho * norm(P_ex_global - previous_P_ex_global, fro); if r_pri tol_pri r_dual tol_dual break; end end写下这段代码的时候我已经提前声明这是一个高度简化的骨架真实文献中的变量映射和约束投影要复杂得多。但结构足够让你理解——每个微网只需要在自己的 “local problem” 里做一次独立优化协调者的作用只是更新价格参考值这个信息交互模式非常符合多主体系统的实际需求。4.5 求解器选型Gurobi、Cplex 还是 OSQPYALMIP 的好处是对底层求解器做了隔离同一套建模代码可以切换不同求解器。但不同求解器对问题的适配差异很大问题类型推荐求解器说明纯线性规划 / 混合整数线性规划Gurobi / Cplex闭源但学术免费速度和稳定性最好凸二次规划对数纳什积目标Gurobi / Mosek / OSQP注意目标函数的形式YALMIP 会自动识别非线性规划Ipopt / fmincon一般不建议ADMM 已把主问题拆成子问题教学演示 / 无商业求解器sedumi / SDPT3慢但能处理小规模凸问题我的建议是装 Gurobi。学术授权申请很快YALMIP 对它的兼容性最完善很多“为什么我的代码一跑就报求解器 not found”的问题都来自求解器没有配置好。5. 数值算例设计与复现中的验证思路代码写完后至少还得有一个说得通的算例验证两阶段算法的效果。下面给出一个我实测过的三微网算例设计思路你可以直接照搬参数跑。5.1 系统参数配置设计三个微网让它们各有长短处这样共享收益才足够明显微网1光伏300kW储能200kW/400kWh负荷峰值200kW白天出力严重过剩微网2负荷峰值350kW自有新能源只有100kW风机负荷中心型电力缺口大微网3光伏150kW小型燃气轮机50kW储能100kW/200kWh偏自平衡型。仿真周期取24小时步长1小时。外部电网采用分时电价峰值时段10:00-15:0018:00-21:001.2元/kWh谷段0.4元/kWh平段0.8元/kWh售电价格统一按购电的70%计算。非对称权重这里设置成(w_10.4, w_20.2, w_30.4)。这个设置的逻辑是微网1是主要送电方联盟的成功离不开它的富余电力所以谈判力强微网3有燃气轮机和储能调节能力强谈判力也强微网2是受电方缺电时它从联盟获得的好处很大但本身话语权弱。5.2 三个关键输出指标的验证逻辑跑完代码后不能只看一张图就说“成功了”。我一般按三个层面核验结果第一层联盟总成本必须小于独立运行总成本之和。这个差值就是“合作剩余”如果结果不是这样说明模型约束写错了或者破裂点计算有误。第二层每个微网的最终成本必须不高于其独立运行成本。这是参与约束individual rationality如果某个微网参与合作反而更亏它没有理由加入联盟。纳什谈判解应当自动保证这一点但如果你的模型参数设置不合适或权重极端化可能某个微网成本反而增加这时候要回溯检查约束和权重。第三层共享电价应该落在合理区间内。在我这个算例中共享电价的合理范围是送电方的边际发电成本约0.2-0.4元/kWh到受电方的替代成本即外部电网购电价0.4-1.2元/kWh之间。如果跑出来的共享电价低于送电方成本说明保护送电方利益的约束没建对如果高于外部电网购电价受电方会直接选择从外部购电合作就没有意义。按照上面的参数我实测的典型结果是联盟总成本比独立运行之和低约12%-18%微网1作为送电方节省成本约8%微网2节省约20%微网3节省约10%。不同权重组合下绝对值有波动但方向一致。5.3 收敛性复现时的判断标准ADMM 的收敛曲线是判断代码正确性的重要依据。正常情况是原始残差和对偶残差都呈阶梯式下降一般在几十步内降到阈值以下。如果你遇到下面两种情况要优先检查模型本身残差震荡不降罚参数 (\rho) 太大或太小但更多时候是耦合约束写错了导致每次迭代子问题之间的可行域不一致残差快速降到很低但目标值异常很可能是初始化把变量设置到了某个退化点或者某个局部约束没有包含进ADMM循环里。调 (\rho) 的经验值是初值 0.1如果残差振荡按 1.618 倍黄金分割比倍增如果收敛太慢按 0.618 倍递减。这个经验在多个算例上都有效算是 ADMM 实际调试的技巧。6. 复现过程中最容易踩的坑和排查方法这一节的价值我个人觉得是最大的。把这些坑提前列出来能让读者少走至少两周弯路。6.1 坑一YALMIP 目标函数里的非线性导致求解器罢工有次复现时我在第二阶段直接把纳什积写成prod(...)形式YALMIP 告诉我找不到求解器因为问题是非线性非凸的。后来把目标函数两边取对数变成求和形式Gurobi 直接秒解。这不是模型错而是建模技巧的问题——纳什谈判目标函数一定要做对数变换不要在原始乘积形式上硬跑。6.2 坑二谈判破裂点的“重复计算”陷阱还有一个我在别人代码里看到的经典错误先算了独立运行成本 (C_i^{ind})然后又在第二阶段目标函数里用联盟调度的方案但忽略共享电价计算了一遍“独立成本”导致超额收益被重复计入。正确做法是(C_i^{ind}) 必须来自一次独立的、没有微网间功率交互的优化求解并保存为一个固定常量不允许在后续迭代中改变。6.3 坑三SOC初值没有对应到正确时段储能SOC的初值不是写一个SOC_0 0.5就能了事。SOC序列的第一列和时刻1的充放电决策是同一批次变量赋值时很容易把初值错放到时刻1结束后的SOC上。表现出来就是第二天初始SOC漂移或者总能量不守恒。建议给 SOC 变量定义T1列第1列写初值从第2列开始才是每个时段结束后的SOC状态约束严格对齐。6.4 坑四联络线交换功率“凭空创造能量”如果没有对每对微网之间的交换功率做方向一致性约束优化器会在两个微网的功率平衡方程里同时把交换功率设为正值造成“能量凭空产生”联盟成本大幅偏低。检查方法是看优化结果的能量平衡全网所有微网的交换功率之和必须为零。如果这个和不为零说明耦合约束失效了。加入交换功率对偶约束后再跑一次检查这个指标。6.5 坑五权重归一化被忽略非对称权重的设置要求 (\sum w_i 1)但不少复现代码直接给 ([0.4, 0.2, 0.4]) 就忘了归一化。如果权重不归一化对数纳什积目标的尺度会偏不同权重组合的比较就没有意义。写代码时最好加一个断言assert(abs(sum(w) - 1) 1e-6, 非对称权重之和必须等于1);这类防御性检查看起来多余实际上能在上游拦截很多传参错误。复现这类文献我个人的经验是先把独立运行模型写对再写联盟集中优化模型最后加 ADMM。每一步都先用理想参数验证结果合理性再往下一步走。很多同学一上来就整个大模型猛跑报错了都不知道是哪个模块的问题排错成本反而更高。这套路径我已经在多份电网技术类文献复现中验证过希望对你有用。