资讯动态

微电网多产消者非合作博弈能量共享的分布式优化Matlab仿真实现

发布时间:2026/10/16 15:19:06 来源:尧图企业网站定制
几个月前我实际构建并跑通了一套“基于分布式优化的多产消者非合作博弈能量共享研究Matlab代码实现”仿真系统。这类课题在微电网、虚拟电厂、园区能源管理方向特别常见每个产消者既可以用自己的光伏和储能满足本地产能也可以把剩余电力卖给邻居但各主体之间没有从属关系谁都不会乖乖听中央指挥只关心自己账单上的数字变少。这种“各怀心思”的局面用非合作博弈来描述非常自然而真实场景中又不希望把所有私有数据交给单一决策中心所以分布式优化就是一个必须走的路。这篇文章不讲虚的理论框架直接把我从建模、算法选取、Matlab编码到调参避坑的完整过程摊开写适合正在做相似仿真、需要一套能落地代码方案的读者。1. 问题模型与博弈结构1.1 产消者与微电网场景建模先把场景固定下来。我这里假设园区里有 N 个产消者各自屋顶装光伏、配有电池储能负载曲线各不相同。每个产消者都可以走三条路来平衡电力向电网购电或卖电、用本地电池充放电、与其他产消者通过共享母线交易。这里最关键的一个物理约束是同一时刻全体产消者相互交易的总功率必须守恒也就是有人额外送了 100 kW 进去就必须有人实际消纳掉 100 kW否则共享母线在物理上就无法成立。对第 i 个产消者功率平衡方程写成PV_i(t) P_grid_in_i(t) - P_grid_out_i(t) P_bat_discharge_i(t) - P_bat_charge_i(t) P_share_i(t) L_i(t)其中P_share_i(t) 0表示该主体往共享母线注入功率P_share_i(t) 0表示从共享母线吸收功率。电池要有状态约束比如用简化模型SOC_i(t1) SOC_i(t) η_ch * P_ch_i(t) - (1/η_dis) * P_dis_i(t) - σ_i(t)SOC还要限制在某个范围比如 0.2 到 0.95充放电功率也有上下限。这是几乎所有微电网仿真的公共底座我一开始的教训是不要一上来就搞非常复杂的电池寿命模型先把功率平衡和 SOC 递推关系写对后面再按需升级。系统整体要优化的是运行成本和交易成本之和。电网购电价格通常设计成阶梯或二次形式C_grid_i(P_grid_i) a_i * P_grid_i^2 b_i * P_grid_i二次项的作用非常现实它模拟了线路损耗和负荷水平升高后边际成本上升的物理特征也让目标函数变成强凸后续用标准求解器处理起来非常省事。电池部分一般加一个退化惩罚项C_bat_i(P_bat_i) β_i * P_bat_i^2 γ_i * |P_bat_i|这里|P_bat_i|可以用绝对值建模也可以用 SOC 偏离目标值的平方来近似。这套模型从数学上看是二次凸规划结构简单却足以反映产消者之间互相影响、彼此博弈的机制。1.2 非合作博弈与纳什均衡“非合作博弈”不是说要互相使坏而是强调每个产消者都独立做决策没有一个主体能替别人做主。在这个前提下每个产消者以最小化自己的运行成本为目标其他产消者的功率计划对它来讲是“环境参数”。如果所有产消者同时给出一个策略集合且任何单独改变自己策略都没办法让自己成本更低这个策略集合就叫纳什均衡。实际建模时会碰到一个细节如果纯粹让各主体各自优化本地变量它们之间唯一的耦合就是全网共享功率守恒约束Σ P_share_i(t) 0。这个约束没有落到任何单个人手里所以必须通过某种协调机制来传递。常见做法是给共享功率附加一个影子价格或乘子λ(t)每个产消者看到同一个共享价格后决定自己是买还是卖而价格调整又反过来改变所有产消者的决策直到市场出清。这正是“分布式优化 非合作博弈”最自然的结合点。集中式优化是拿全局收益最大化的而这里每个主体目标函数只是自己的局部成本纳什均衡对应的结果不一定等于全局最优这是课题的核心也是审稿人反复问的点。我在编码前把这些关系在公式层面理清楚后面每一步才能在代码里对号入座。2. 分布式优化算法设计与选型2.1 集中式与分布式方案取舍一开始我确实动过“干脆全部托付给一个中心优化器”的念头。集中式方案最大的优点是代码好写一个全局目标函数扔给求解器就完事。但它有三个现实痛点隐私短板所有产消者的负载曲线、电池参数、光伏出力都要上报现实中谁也不愿意把家里的数据交出去。单点故障中心计算机一旦出问题整个交易系统直接瘫痪。扩展成本节点数量增加后求解规模和通信量快速增长计算压力全压在中心侧。分布式方案把问题按产消者拆开每个主体只维护本地数据通过少量协调信息——通常是共享价格或乘子——完成全局平衡。这样既保留博弈的非合作特征又具备实际工程部署价值。两套方案的对比我做了个表维度集中式优化分布式优化数据需求所有主体全部私有数据上报中心各主体仅交换价格、功率等协调量信息暴露完整暴露部分暴露有隐私优势计算压力集中在中心节点分散到各产消者本地通信依赖单向上报通信失败影响大迭代通信对短暂中断容忍度较高全局最优性容易得到全局最优通常收敛到博弈均衡非全局最优工程可扩展性较差较好这个表基本就是我在开题阶段最常用的素材。研究员或者做方案评审时直接拿它解释“为什么不用集中式”。2.2 用ADMM把耦合约束撕开分布式求解方法我选了交替方向乘子法也就是ADMM。ADMM能很好地处理“本地独立目标 全局耦合约束”这类结构。原问题可以写成min Σ_i J_i(x_i)s.t. Σ_i P_share_i 0其中x_i表示第 i 个产消者的全部决策变量。引入拉格朗日乘子λ和罚参数ρ后构造增广拉格朗日函数L Σ_i [ J_i(x_i) λ * P_share_i (ρ/2) * P_share_i^2 ]接下来是三步交替迭代第 1 步每个产消者独立求解自己的子问题x_i^{k1} arg min_{x_i ∈ Ω_i} J_i(x_i) λ^k * P_share_i (ρ/2) * P_share_i^2第 2 步计算全网共享功率残差r^k Σ_i P_share_i^{k1}第 3 步更新乘子λ^{k1} λ^k ρ * r^k这里把(ρ/2) * P_share_i^2加到目标函数中相当于每个产消者在决策时不仅看到当前共享价格还看到交易量的平方成本物理含义是交易越猛额外增加的线路损耗或市场风险越大。这种近端正则项正是 ADMM 收敛性的核心保障。需要注意的是实际实现时λ可以是标量全局乘子也可以是对每个产消者单独的λ_i如果要做成完全点对点通信则需要在邻居之间做乘子一致性协商这次我用的是协调者模式下单一乘子传参更简单先跑通机制再说。2.3 收敛条件、罚参数与停止准则ADMM 用起来并不复杂但它最考人的地方在于罚参数ρ和停止准则。我实际调试时发现ρ太小共享功率残差容易反复振荡乘子更新幅度不够修正太慢。ρ太大稳定性上去了收敛速度却肉眼可见地变慢迭代几百步都压不到精度。收敛判断我习惯同时看原始残差和对偶残差。原始残差就是共享功率的累计不平衡量r_prim^k |Σ_i P_share_i^k|对偶残差反映乘子更新幅度和决策变化量之间的联系r_dual^k ρ * max_i |P_share_i^k - P_share_i^{k-1}|当r_prim和r_dual同时小于阈值比如 1e-3 或 1e-4我就判定达到收敛。停止阈值不能拍脑袋定要跟功率数量级匹配。我的电池和负载数据都是 kW 级所以取 1e-3 就已经非常严格硬取 1e-8 反而会让程序陷入无穷无尽的微小修正循环。3. Matlab代码实现与关键模块3.1 工程文件结构与数据生成我习惯把仿真拆成四个文件模块边界清楚调试时能快速定位问题main.m % 主程序负责参数设置、迭代调度、结果汇总 data_gen.m % 生成负载、光伏、电池参数 subproblem_solve.m % 单个产消者的局部优化子问题 admm_update.m % 乘子更新、残差计算与收敛判断数据生成这一步绝不能随便拍脑袋。先要给 N 个产消者设置不同的电力特征A 类主体光伏富裕白天发电远大于负载B 类主体是商业负载用电高峰在白天C 类主体储能容量较大适合削峰填谷。我用典型日曲线加随机抖动的办法生成 24 小时数据共 24 个时段每时段做一次静态交易决策这样电池 SOC 跨时段约束就退化为逐时段约束模型更简单也更适合作为第一版仿真的验证对象。%% data_gen.m 关键片段 function data data_gen(N) for i 1:N % 基础负载双峰曲线叠加随机偏移 base_load 0.6 0.4 * sin(2*pi*(0:23)/24 i); data(i).load base_load * (40 20*rand); % 光伏输出白天有出力夜晚为0 data(i).pv max(0, sin(2*pi*(8:31)/24 - 1.2)) * (30 25*rand); % 电池参数 data(i).soc_min 0.2; data(i).soc_max 0.95; data(i).p_bat_max 15 10*rand; end end初版可以先用恒定随机曲线测试算法等分布式迭代收敛稳定之后再替换成真实气象数据和负载曲线避免一开始就把问题复杂度拉满。3.2 单产消者子问题的标准二次规划建模每个产消者的子问题是一个带线性等式约束和上下界约束的凸二次规划Matlab 里直接调quadprog就行。关键在于把目标函数和约束写成标准矩阵形式。我习惯把每个时段的决策变量排成一个向量y_i [P_grid_i; P_bat_ch_i; P_bat_dis_i; P_share_i]目标函数J_i λ * P_share_i (ρ/2) * P_share_i^2对应的二次项矩阵H和一次项向量f这样构造H 2 * diag([a_grid, beta_ch, beta_dis, rho/2]); f [b_grid; 0; 0; lambda];功率平衡方程写成等式约束PV_i P_grid_i P_bat_dis_i - P_bat_ch_i P_share_i L_i对应的Aeq矩阵就是[1 1 -1 1]beq是L_i - PV_i。电池充放电上下界、购售电上限全部放到lb和ub。有一个特别容易踩的坑quadprog默认只接受凸二次规划如果你在目标函数里误加了一次项符号搞反或者H矩阵没有保持半正定求解器会警告甚至直接罢工。我在代码里加了检查eig(H)的最小特征值小于 0 就提示报错避免连锁问题。3.3 分布式迭代与乘子更新实现主程序的核心循环长这样%% main.m 核心迭代段 lambda 0; rho 0.5; maxIter 200; tol 1e-3; P_share_old zeros(1, N); for k 1:maxIter for i 1:N [y(:,i), ~] subproblem_solve(data(i), lambda, rho); end P_share y(4,:); r_prim abs(sum(P_share)); r_dual rho * max(abs(P_share - P_share_old)); lambda lambda rho * sum(P_share); P_share_old P_share; record_residual(k,1) r_prim; record_residual(k,2) r_dual; if r_prim tol r_dual tol break; end end每次迭代时各个产消者先后调用subproblem_solve如果追求更严格意义上的分布式并行可以用parfor把循环做成并行但需要注意每个 worker 里都要能读取lambda并且共享功率的汇总要在并行结束后统一处理。我在第一版用的是串行循环先确保逻辑正确再看性能需求决定要不要改并行。3.4 协调者通信机制与代码封装代码层面我采用了“轻量协调者”模式协调者只维护一个乘子lambda每轮向所有产消者广播产消者求解完本地问题后把P_share_i回报给协调者协调者汇总残差后更新lambda。这个架构在仿真中非常好实现也确实符合微电网能量管理系统的常见运营方式。如果你想做成真正无中心的点对点模式代码就要复杂不少因为每个产消者只能跟自己通信范围内的邻居交换信息乘子更新变成图上的平均一致性迭代。两种模式我都试过建议时间不充裕的读者先按协调者模式实现这个版本跑出来的结论已经能支撑论文和项目报告中“分布式优化”的核心论述点对点模式可以作为后续扩展方向。4. 仿真结果与实用分析4.1 迭代收敛动态分析我做的基准场景是 5 个产消者、24 个时段rho 0.5停止阈值 1e-3。收敛曲线最明显的特点是前 15 轮原始残差快速下降从量级接近 50 kW 一路掉到 0.5 kW 以下之后进入一个稳定的渐进收敛段大约在第 60 轮左右两个残差同时满足停止条件。整个计算时间在普通笔记本上不到 3 秒大部分时间其实花在反复调用quadprog上算法本身的计算量并不大。我还专门对比过rho 0.05和rho 5两组参数。rho 0.05时前 30 轮残差曲线呈现明显锯齿形说明乘子更新步子太小原始约束残差很难快速消除rho 5时虽然不振荡但残差下降速度慢还需要额外增加最大迭代次数才够。实测下来 0.5 这个量级在我的数据规模下是比较均衡的选择这也验证了rho本质上是在“响应速度”和“修正稳定性”之间做权衡。4.2 各产消者经济性对比评估博弈共享机制的价值我最常用的是三方案对照方案 A全部产消者独立运行不从共享母线获取任何功率。方案 B所有产出者参与非合作博弈共享交易用我实现的分布式算法求解。方案 C集中式全局优化作为理想化基准。以我那个 5 主体场景为样本方案 B 相对方案 A 的总运行成本下降了大约 12.7%。成本下降主要来自光伏富余主体不再低价卖给电网而是直接供给白天商业负载较高的主体减少了高电价时段的电网购电。方案 B 的总成本比方案 C 高约 2.3%这个差距就是非合作博弈均衡与全局最优之间的“无谓损失”也是课题里非常有价值的分析点。需要特别说明的是每个产消者个体的收益并不均匀。光伏出力大的 A 类主体收益最明显电池容量大的 C 类主体收益略低。这种分配不均在非合作博弈里面非常常见如果你想让共享机制更公平可以考虑把纯粹的价格协调改成带收益分摊系数的双层机制这通常可以作为论文的延伸研究方向。4.3 参数灵敏度与场景扩展灵敏度分析方面我做了三组测试提高光伏装机容量共享交易量上升整体成本下降幅度加大但边际收益递减因为光伏出力曲线与负载峰值不完全重合。加大电池退化惩罚系数主体倾向于减少电池充放电转而通过共享交易来平衡功率共享功率量可能上升但总收益受电池约束限制。改变电网购电价格曲线的峰谷差峰谷差越大共享交易的套利空间越大分布式算法得到的成本下降比越明显。这些测试的结论对课题论证很重要因为单看一组收敛曲线并不能说明博弈共享机制在什么条件下有效灵敏度分析能明确给出适用范围。5. 常见问题与避坑指南5.1 残差不收敛与振荡问题在别的地方我看到很多人把 ADMM 跑出毛刺后第一反应是增加迭代次数但实际往往没用。我踩的坑基本集中在三类原因rho不匹配导致振荡优先调rho而不是加迭代。局部子问题的约束没有包含共享功率范围导致每轮解出来的P_share超出合理物理量级。乘子初始值设置太离谱比如直接给lambda 10000会迫使主体在迭代初期做出非常激进的交易决策残差曲线要花很长时间才拉回来。对策是先把残差曲线打印出来看看是锯齿持续振荡还是单调不下降。振荡就朝增大rho的方向调单调不降则优先检查模型约束和初值。5.2 初值敏感性与收敛提速lambda的初值可以取 0也可以取电网购电价和售电价的中值。我发现取中值会显著减少迭代初期的尖峰尤其是在 24 时段同步仿真的场景里各个时段同时开始迭代初始乘子如果全部为 0前几轮共享功率残差会出现一次明显凸起。提速还有一个实用技巧上一时段的收敛乘子作为下一时段的乘子初值。因为相邻时段的负载和光伏曲线变化不大这样做通常能把总迭代次数压缩 30% 到 40%。我在主循环外面套了一层时段循环每个时段保留自己的lambda_final效果非常显著。5.3 代码调试与可视化技巧调试分布式程序最怕的是不知道问题出在哪个主体身上。我在每个子问题求解后都会短暂检查quadprog的返回状态如果某个主体出现exitflag 0立刻打印该主体的数据索引和当前lambda这样定位问题从小时级压缩到分钟级。可视化方面除了画残差收敛曲线我强烈建议把每个时段的P_share_i画成堆叠柱状图。某段出现正负相互抵消但数值特别大时说明交易在两边绕路某个主体持续被压在最底部说明它的边界约束一直在起作用。这些画面在论文里也很有说服力胜过单纯的文字描述。我自己实际的体会是这套系统最花时间的永远不在算法理论而在于把每个主体的数据、约束和求解器状态调到一个“既数学上严谨、又物理上说得通”的状态。先小规模调通再扩展节点数量最后补灵敏度分析这是最稳的路线。如果后续还想往深做把静态时段模型改成带储能跨时段耦合的滚动时域模型再把点对点通信模式补上整个课题的完整度立刻会上一个台阶。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑