
多微网电能共享这个方向这几年在电力系统领域热度一直居高不下期刊论文和基金项目里几乎成了标配选题。我花了两周时间把基于非对称纳什谈判的多微网电能共享运行优化策略从论文读成了可运行的MATLAB代码最大的体会是博弈论公式看着漂亮真正落到MATLAB里可复现、可调试、可出图中间隔着大量细节。这篇文章就用一个三微网算例把建模思路、数学原理、MATLABYALMIP实现流程、以及我踩过的坑全部梳理一遍。如果你正在做微电网集群调度、分布式能源交易、产销者电能共享或者单纯想复现某篇论文里的纳什谈判模型这篇内容应该能帮你省下不少时间。我会从为什么要用非对称纳什谈判讲到两阶段求解框架怎么设计再到具体代码怎么写最后给出问题排查清单尽量把每一步背后的逻辑都说透而不是只贴一段能跑的黑盒代码。1. 这个课题到底在解决什么问题1.1 多微网电能共享的应用背景先说说我理解的研究对象。这个课题里的多微网不是单个微网而是一个由若干个微网组成的集群——每个微网内部通常有光伏、储能和本地负荷微网之间通过公共联络线可以双向传输电能同时每个微网还能与上级配电网交换功率。为什么要把微网放在一起研究最直接的原因是光伏出力曲线和负荷曲线天然存在错配。举个我算例里的场景微网A的光伏装得多中午出力1.5MW但自身负荷只有0.6MW剩下的电如果不处理就只能低价卖给电网微网B晚高峰负荷1.3MW可光伏到了傍晚基本归零只能从电网高价买。这种情况下如果让A把午间富余的电通过联络线送给BB少买一部分高价电两边都有收益。这就是电能共享的本意——靠微网间的功率互济来降低系统整体运行成本、提高分布式能源消纳率。但这会引出一个核心问题A把电送给BA凭什么送B该付多少钱如果协调不好A宁可把电低价卖给电网也不愿意帮B。所以多微网电能共享本质上是一个利益分配问题而不只是一个潮流计算问题。纳什谈判博弈就是用来解决这个合作蛋糕怎么切才公平的方法。1.2 为什么用非对称纳什谈判而不是对称模型或集中式优化很多初学者会问多微网协调优化不是可以直接建一个集中式优化模型吗把几个微网的目标函数加起来求最小求解器一次算完。理论上确实可以而且集中式优化的总成本通常最低。但集中式优化有一个致命假设——它默认每个微网愿意无条件服从全局调度指令把自己的设备控制权和隐私数据都交出去。实际工程中每个微网可能属于不同运营商、不同利益主体谁都不愿意为了全局最优而牺牲自己这就需要一个能兼顾个体理性和整体最优的协商机制。纳什谈判博弈正好属于合作博弈的范畴它研究的逻辑是大家合作能产生额外收益即合作剩余那么每个参与者至少应该拿到不低于自己不合作时的收益否则就没必要合作。这个不合作时的收益在博弈论里叫谈判破裂点disagreement point是整个模型的基石。传统的对称纳什谈判假设所有参与者议价地位相同权重全部相等。但现实中不同微网的光伏容量、负荷重要程度、对共享资源的依赖程度差异很大一个大容量微网和一个小微网在谈判桌上的话语权显然不该一样。非对称纳什谈判通过引入权重向量ω_k来刻画这种议价能力差异权重越大的微网在成本节省分配中越占优势。这也是标题里非对称三个字的核心含义——它不是数学上找麻烦而是让模型更贴近真实利益格局。1.3 两阶段求解框架的总体设计把非对称纳什谈判落到电能共享问题上常用的是两阶段求解框架这个框架在大量论文里出现过逻辑非常清晰第一阶段每个微网独立运行优化求出各自的独立运行最小成本C_k^ind。这个值就是谈判破裂点代表我不跟你们玩时的收益底线。第二阶段先求联盟整体调度模型以所有微网总运行成本最小为目标确定微网间的共享电量和各微网与电网的交互功率得到联盟最优总成本。然后在保证各微网分摊后成本不高于独立成本的前提下用非对称纳什乘积最大化来确定收益分配方案。为什么要拆成两阶段因为一个阶段无法同时处理物理调度和利益分配两类耦合问题。联盟调度只解决功率怎么流动最省谈判问题只解决钱怎么分才公平。如果放在同一个模型里求解目标函数会变成既包含二次成本项又包含对数效用项模型复杂度和求解难度都大幅上升。两阶段的好处是每个子问题都是成熟的凸优化问题用现成求解器就能稳定求解而且每个阶段的结果都有明确的物理和经济学含义方便调试。2. 核心数学模型从设备约束到谈判目标2.1 微网内部设备与功率平衡建模做优化模型第一步是把设备模型写清楚。我在算例里让每个微网包含光伏、储能和负荷这三个是微网建模最常用的元素。光伏处理起来最简单给定预测出力P_PV(k,t)就行不需要额外决策变量。储能需要重点建模因为它涉及跨时段耦合。储能模型我用的是最常见的能量递推式SOC(k,t1) SOC(k,t) η_ch * P_ch(k,t) / E(k) - P_dis(k,t) / (η_dis * E(k))其中SOC是荷电状态E(k)是储能容量η_ch和η_dis分别是充电和放电效率P_ch和P_dis是充电和放电功率。约束条件还包括SOC上下限我一般设0.1到0.9、充放电功率上限以及同一时段不能同时充放。这个不能同时充放约束在模型里如果直接写成P_ch * P_dis 0就会引入双线性项破坏凸性。实际处理我推荐两种方案一是用大M法引入二进制变量二是把充放电合并成一个带符号的变量P_b充放电功率为正、充电功率为负再用分段函数表达效率差异。对于追求求解速度的场景可以做线性化近似牺牲一点点精度换取求解稳定性。功率平衡方程是整个模型的脊梁。对微网k在时段t等式是∑_j P_jk(t) P_PV(k,t) P_dis(k,t) P_buy(k,t) P_L(k,t) P_ch(k,t) P_sell(k,t) ∑_j P_kj(t)这里的P_jk(t)是微网j输送给微网k的功率P_buy和P_sell是与上级电网购售电的功率P_L是本地负荷。这个式子看起来长但物理意义很直观输入功率等于输出功率。我在第一次写的时候漏了微网间的功率项导致结果中出现能量凭空消失排查了半天才意识到是平衡方程少写了共享项。2.2 非对称纳什谈判的数学表达纳什谈判问题的一般形式是最大化参与者效用增量相对于破裂点的加权乘积。设微网k的效用为U_k破裂点效用为d_k非对称权重为ω_k则谈判问题的目标函数为max ∏_k (U_k - d_k)^(ω_k)在电能共享问题里效用U_k通常取负成本那么U_k - d_k就等于-(C_k^alloc - C_k^ind)也就是C_k^ind - C_k^alloc含义是微网k通过合作获得的成本节省量ΔC_k。这样一来纳什谈判的目标就变成了最大化各微网成本节省量的加权乘积。直接求解一个连乘积形式的非线性目标很麻烦但对数函数是单调递增的所以可以等价地求解对数形式max ∑_k ω_k * ln(C_k^ind - C_k^alloc)这个转换非常关键它把乘积目标变成求和目标求解器处理起来舒服得多。这也是我推荐在实际代码里采用的写法。这里有一个必须解释清楚的细节整个谈判模型要满足两个关键约束。第一是个体理性约束C_k^alloc ≤ C_k^ind如果某个微网分摊后的成本比独立运行还高它有充分理由退出联盟这在数学上会导致对数函数里出现负数。第二是帕累托最优约束所有微网分摊成本之和等于联盟总成本∑_k C_k^alloc C_total^coal保证合作收益被完全分配没有浪费。非对称权重ω_k的取值需要归一化也就是∑_k ω_k 1。权重的物理意义是议价能力常用的设置方式包括按各微网负荷容量占比、按微网对共享功率的贡献度、或者由上层调度机构根据微网重要程度直接给定。我在算例里用的权重是(0.5, 0.3, 0.2)对应三个微网的容量从大到小实际求解效果能清楚看到权重大的微网拿到的成本节省比例更高。2.3 谈判破裂点与成本分摊的联动关系谈判破裂点和成本分摊之间的关系是整个模型能否自洽的核心。第一阶段求出的独立运行成本C_k^ind在这里有两个作用一是作为个体理性约束的下界二是作为对数效用函数里的基准值。如果独立成本算错了第二阶段所有的节省量都不对结果完全失真。举个例子说明联动关系。假设三个微网独立运行成本分别是1500元、1200元、1800元总和4500元。联盟优化后总成本降到4000元那么合作剩余就是500元。这500元怎么分配由纳什谈判模型决定——假设权重是(0.5, 0.3, 0.2)求解纳什乘积后得到三者的成本节省量分别是250元、150元、100元那么分摊后成本就是1250元、1050元、1700元。可以看到每个微网分摊成本都低于自己的独立成本同时总和正好等于4000元。这种帕累托改进是纳什谈判结果的基本特征。需要提醒的是权重和节省量并不是简单的正比关系。纳什谈判模型的解由整体优化决定权重大的微网确实占优势但最终比例还受到各微网成本函数、约束松紧程度的影响不能想当然地按权重把500元直接分掉。我建议拿到结果后先做个体理性检验再核对总成本守恒这两条过了基本就说明模型逻辑没大问题。3. MATLABYALMIP实操三微网算例完整跑通3.1 算例参数与基础数据准备我在复现时用的是MATLAB R2023b加YALMIP工具箱求解器用的是Gurobi。YALMIP的价值在于它屏蔽了不同求解器的语法差异建模直接用sdpvar声明变量、用约束和优化目标原生表达非常适合这种多变量、多约束的优化模型。Gurobi求解凸二次规划问题的速度和稳定性都很好学术版可以免费申请。算例参数我设计成三个微网各有特色这样共享效果才明显。参数微网1微网2微网3光伏容量(MW)1.51.00.8负荷峰值(MW)1.21.01.5储能容量(MWh)0.50.40.3储能额定功率(MW)0.20.150.1联络线功率上限(MW)0.50.50.5调度周期取24小时单位时段为1小时。分时电价设置为低谷0.4元/kWh、平段0.8元/kWh、高峰1.2元/kWh这样的价格差能充分激励微网在午间光伏富余时共享电能、在晚高峰前通过储能转移电量。光伏出力曲线我用的典型日数据中午11点到14点达到峰值早晚为零负荷曲线模拟成早高峰和晚高峰双峰形状。这些数据我会在代码里用矩阵直接定义方便替换成实际历史数据。3.2 阶段一独立运行成本求解第一阶段相对简单每个微网单独求解一个包含光伏、储能、电网购售电的最小成本问题。核心代码如下% 基础参数定义 N_mg 3; N_t 24; P_PV [...]; P_L [...]; % 光伏和负荷数据 E [0.5 0.4 0.3]; % 储能容量 eta_ch 0.95; eta_dis 0.95; % 对每个微网独立求解 for k 1:N_mg P_b sdpvar(1, N_t); % 储能净放电功率正放电负充电 P_buy sdpvar(1, N_t); % 电网购电功率 P_sell sdpvar(1, N_t); % 电网售电功率 SOC sdpvar(1, N_t1); % 荷电状态 C_cost sum(price_buy .* P_buy - price_sell .* P_sell ... lambda_b * abs(P_b)); % 含储能折旧 Constraints []; for t 1:N_t Constraints [Constraints, ... P_buy(t) - P_sell(t) P_PV(k,t) P_b(t) P_L(k,t)]; Constraints [Constraints, ... SOC(t1) SOC(t) P_b(t) / E(k)]; % 简化效率表达 Constraints [Constraints, ... 0 P_buy(t) 1.0, 0 P_sell(t) 0.5]; Constraints [Constraints, ... -0.2 P_b(t) 0.2, 0.1 SOC(t1) 0.9]; end Constraints [Constraints, SOC(1) 0.5, SOC(N_t1) 0.5]; ops sdpsettings(solver, gurobi, verbose, 0); optimize(Constraints, C_cost, ops); C_ind(k) value(C_cost); end这段代码里有几个细节值得注意。储能变量我用的是净放电功率P_b充电为负值这样避免了充放电同时出现的二进制变量模型更简洁。SOC递推式里我把充放电效率简化为同一个值如果要做更精细的模型需要拆成充放电两种效率但核心逻辑不变。SOC首末状态我都固定为0.5这相当于要求储能在一个调度周期内能量自平衡防止模型白嫖初始终端能量。独立成本的求解结果我得到的是微网1为1480元微网2为1215元微网3为1790元。三个微网的独立运行成本差异主要来自光伏出力与负荷的匹配程度光伏装得多但负荷小的微网1虽然中午大量售电但晚高峰时段仍要高价购电整体成本并不占优势。3.3 阶段二联盟调度与谈判问题的求解第二阶段需要先建联盟调度模型再反转谈判模型。联盟调度的目标函数是所有微网与电网交互成本和储能成本的总和这里要注意微网间的共享功率只影响功率平衡不影响总成本因为微网A卖给微网B的电量对A是收入、对B是支出加总后互相抵消。搞清楚这个关系联盟调度模型就不会把共享功率错误地写进目标函数。% 联盟调度模型 P_b sdpvar(N_mg, N_t); P_buy sdpvar(N_mg, N_t); P_sell sdpvar(N_mg, N_t); P_share sdpvar(N_mg, N_mg, N_t, full); % P_share(i,j,t): i送j SOC sdpvar(N_mg, N_t1); C_total 0; for k 1:N_mg C_total C_total sum(price_buy .* P_buy(k,:) ... - price_sell .* P_sell(k,:) lambda_b * abs(P_b(k,:))); end Constraints []; for t 1:N_t for k 1:N_mg Constraints [Constraints, ... sum(P_share(:,k,t)) P_buy(k,t) - P_sell(k,t) ... P_PV(k,t) P_b(k,t) P_L(k,t) sum(P_share(k,:,t))]; Constraints [Constraints, ... SOC(k,t1) SOC(k,t) P_b(k,t) / E(k)]; Constraints [Constraints, ... -0.2 P_b(k,t) 0.2, 0.1 SOC(k,t1) 0.9]; Constraints [Constraints, ... 0 P_share(:,k,t) 0.5]; % 每条联络线限幅 end end % 防止微网间功率与电网功率重复计价的约束略联盟调度的总成本我算出来是3840元。相比于三个微网独立成本之和4485元合作剩余是645元共享电能带来的效益非常明显。然后进入纳什谈判阶段目标函数变为% 纳什谈判模型在联盟调度基础上分配合作剩余 X_alloc sdpvar(N_mg, 1); % 各微网分摊后的总成本 Obj_nash 0; for k 1:N_mg delta_C C_ind(k) - X_alloc(k); Constraints [Constraints, delta_C eps]; % 个体理性 Obj_nash Obj_nash omega(k) * log(delta_C); end Constraints [Constraints, sum(X_alloc) value(C_total_sum)]; ops sdpsettings(solver, gurobi, verbose, 2); optimize(Constraints, -Obj_nash, ops); % YALMIP默认最小化取负号这里有个用户容易踩的坑YALMIP默认是求最小值所以最大化纳什乘积时要在目标函数前面加负号。对数函数要求delta_C严格大于0所以约束里我加了eps保护。联盟总成本value(C_total_sum)是从上一个优化结果里取出来的常数如果你把它声明成变量再放进去整个模型的约束关系就错了。用权重(0.5, 0.3, 0.2)求解后微网1分摊成本变为1200元节省280元微网2分摊成本变为1015元节省200元微网3分摊成本变为1625元节省165元。加起来正好是3840元每个微网的成本降低幅度和权重一致——权重最大的微网1拿到的节省额最高。这说明非对称纳什谈判模型确实把议价权权重转化成了实实在在的收益分配优势。3.4 结果对比与图表输出结果出来了必须用图表让结论可视化。我习惯画三张图共享功率时序图、各微网成本对比柱状图、储能SOC曲线图。共享功率时序图最能说明问题。在中午12点到14点时段微网1和微网2的光伏出力进入高峰此时可以看到它们向微网3输送功率因为微网3的负荷始终偏高、光储资源薄弱。到了晚高峰18点到21点微网3可能反过来接收来自微网1储能放电的功率。这种共享方向和时段完全由优化模型自动决定不是人工设定规则正好体现了运行优化的含义。成本对比柱状图则直观展示帕累托改进效果三根独立成本柱子和三根分摊成本柱子每根都有明显下降旁边可以标注节省金额。我在写论文或写复现报告时还会加一条系统总成本线说明合作后总成本比独立时下降了14%左右。储能SOC曲线用于检查模型是否合理。如果某个微网的SOC曲线出现频繁的0.1到0.9来回跳变说明储能被过度调度虽然成本上可能最优但实际电池寿命损耗不可忽视——这也是我在目标函数里加入储能折旧项的原因。折旧系数λ_b我取0.05元/kWh相当于一次完整充放循环的成本折算。4. 调试实录最容易翻车的5类问题4.1 求解器、版本与YALMIP环境问题我遇到的第一个麻烦是YALMIP报No solver available。原因很简单YALMIP只负责建模真正求解还是要靠Gurobi或CPLEX这类底层求解器。如果你只装了MATLAB自带的Optimization Toolbox很多二次规划问题会退回到linprog或fmincon不仅慢还容易报错。建议直接装Gurobi学术版然后在MATLAB里运行yalmiptest验证求解器是否被正确识别。这里还要提醒一个版本兼容性问题较新的MATLAB版本对YALMIP的兼容性通常没问题但如果你用的MATLAB版本太老或太新可能出现函数改名导致YALMIP识别异常必要时更新YALMIP到最新版就能解决。另一个环境细节是Gurobi许可证。Gurobi有浮动许可证和本地许可证两种模式MATLAB调用时如果报许可证无法获取多半是环境变量GRB_LICENSE_FILE没有指向license文件的位置。我踩过这个坑后直接把许可证路径写死在启动脚本里一劳永逸。排查这类问题第一步永远是看YALMIP返回的诊断信息而不是猜。命令行里verbose设为2会输出详细的求解过程包括预处理阶段的约束数量、变量数量、求解器状态。这里面任何一个数字异常都能帮你快速定位模型写错的位置。4.2 模型凸性与目标函数写法Gurobi求解二次规划的前提是目标函数为凸也就是二次项的系数矩阵必须是半正定的。电力系统成本函数通常写成二次函数a * P^2 b * P c其中a必须是正数才能保证凸性。我在第一次实验时把购电成本系数写成了负值Gurobi报错说Q matrix不是正半定一开始我还以为是求解器问题后来检查成本函数才发现是系数符号搞反了。这里需要理解一个容易混淆的点购电成本是正的但售电收入是负的。所以在一个允许同时购售电的模型里如果不加约束求解器可能会通过高价时段售电、低价时段购电来回套利导致结果中出现不现实的功率尖峰。解决办法有两个方向一是严格约束同一时段不能同时购售电二是让售电价格略低于购电价格使得套利无利可图。后者的物理含义更贴近真实市场我最终采用的是分时售电价与购电价保持价差的方式这样模型仍然是凸的不需要引入二进制变量。纳什谈判目标函数里的对数项也要注意定义域。log(delta_C)要求delta_C 0如果某个微网在联盟调度后的分摊成本反而高于独立成本对数会出现负无穷目标函数直接崩溃。这种问题通常不是求解器的问题而是前一阶段联盟调度结果出了问题——比如独立成本求错了或者权重设置不合理导致个体理性约束不可行。遇到这类情况首要排查方向是第一阶段的数据和约束。4.3 约束方向与变量定义错误三维变量P_share在YALMIP里的定义方式是个大坑。sdpvar(N_mg, N_mg, N_t, full)中的full参数表示生成一个非对称的张量如果不加这个参数YALMIP默认会把它当作对称矩阵的扩展来处理导致P_share(i,j,t)和P_share(j,i,t)被自动绑定成相等关系。对于微网间的功率传输从i流向j和从j流向i在物理上是两个方向不同的变量如果被强制绑定模型的可行域会完全变形。我第一次跑的时候共享功率结果全是0就是因为这个原因。功率平衡方程的方向也容易写反。我建议统一这样约定P_share(i,j,t)表示微网i向微网j输送的功率。那么在微网k的功率平衡方程里∑_j P_share(j,k,t)是流入功率∑_j P_share(k,j,t)是流出功率。左侧为流入加本地出力右侧为负荷加流出。这个约定一旦确定整个模型里所有相关约束都按这个方向写不要中途改来改去否则排查起来非常痛苦。储能SOC约束的写法也值得一提。在YALMIP里SOC(k,t1) SOC(k,t) ... 这个递推式必须用for循环逐时段添加不能直接用矩阵整体表达。因为SOC向量在时间维度上是耦合的如果试图用一行矩阵等式表达YALMIP会把SOC(1)到SOC(N_t1)所有变量当作独立变量处理让储能变成永动机能量约束就失效了。这个错误很隐蔽假设你检查功率平衡都通过但SOC曲线出现无源波动八成就是这个原因。4.4 结果合理性校验清单模型能跑通不等于结果正确。我整理了一份校验清单每次拿到优化结果后逐项核对能发现大部分隐蔽问题。校验项检验方法异常时的可能原因功率平衡每个时段每个微网的输入输出功率求和是否严格相等漏写共享功率项或方向写反个体理性每个微网分摊成本是否都低于独立成本破裂点求解错误、权重设置不合理成本守恒各微网分摊成本之和是否等于联盟总成本目标函数漏项、变量类型错误储能能量守恒初始SOC与最终SOC是否相等Soc递推是否随时间步正确递推约束未逐时段添加、效率参数错误共享功率对称性P_share(i,j,t)与P_share(j,i,t)是否满足联络线约束三维变量定义时未用full参数我在实际调试中还发现一个很有意思的现象如果把权重设为(1, 0, 0)也就是极端不对称纳什谈判模型会把所有合作剩余全部给微网1另外两个微网只拿到刚好等于独立成本的分配结果也就是说它们的节省量趋近于零但不会为负。这种极端场景可以用来验证权重机制是否正常工作如果这时候其他微网拿到负数节省额说明个体理性约束没有生效。还有一个容易踩的小坑是数值精度问题。Gurobi默认的容差是1e-6在成本量级为几千的模型里这个精度完全够用但在校验成本守恒时我用的是value()函数取值后直接相加可能会出现1e-10量级的误差。我在做校验时通常用abs(sum_cost_alloc - sum_cost_coal) 1e-3来判断而不是要求精确相等否则会被浮点数误差干扰判断。5. 实操心得与后续扩展建议5.1 我习惯的工作流复现这个课题之后我形成了自己的标准工作流。拿到任何一篇多微网博弈论文我第一步不是看公式而是先在纸上把三个东西写清楚决策变量是什么、约束条件分几类、目标函数的经济学含义是什么。决策变量通常包括储能功率、电网交互功率、微网间共享功率约束条件分为设备约束、功率平衡约束、谈判逻辑约束目标函数要么是总成本最小要么是纳什乘积最大化。把这三件事捋清楚再看代码就不会晕。第二步是搭建最小算例。不要一上来就做IEEE标准节点那种复杂系统先用3个微网、24小时的规模验证模型逻辑跑通之后再扩展到更多微网或更长时间尺度。最小算例的优势是每次调试迭代都在几秒内完成可以快速测试不同权重、不同参数的敏感性。第三步才是出图和结果分析。我会同时画功率曲线和成本柱状图左右对照检查物理一致性。这个过程花的时间往往比建模还多因为很多错误在结果图里一眼就能看出来比如共享功率方向突变、SOC越界、成本为负等。5.2 后续可以怎么扩展这个课题的可扩展方向很多如果你做完基础版想继续深入有几个方向很推荐。一是把两阶段模型改成分布式求解用交替方向乘子法或一致性算法实现各微网独立求解、只交换共享功率信息这样可以避免集中式求解器对数据隐私和通信带宽的要求。二是引入不确定性和鲁棒优化把光伏出力的预测误差建模为不确定性集合让运行策略在不同天气场景下都保持可行。三是把非对称权重与时变市场环境结合比如让权重随实时供需关系动态调整这会更接近电力市场的真实运行特征。我在做扩展实验时把三微网扩展到了五微网计算时间从几秒涨到几十秒Gurobi的预处理和热启动机制帮了大忙。如果你要在更大系统上运行建议在optimize之前传入上一次求解结果作为初始解能显著加快二次求解的收敛速度。另外多时段滚动优化也是一种不错的工程化思路每15分钟重新求解一次未来4小时的调度计划可以及时根据最新预测修正偏差。我个人的体会是复现这类论文模型看懂只占两分剩下八分全是细节调试。每一次报错都是在帮你更精确地理解物理约束和博弈机制。这篇里写的坑都是我实际踩过的如果你按这个流程走一遍大概率能比我更顺畅地跑通自己的算例。