ARTICLE DETAIL

资讯详情

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

非对称纳什谈判求解微电网P2P电能交易:两阶段优化与MATLAB实现

非对称纳什谈判求解微电网P2P电能交易:两阶段优化与MATLAB实现 1. 先把这个课题翻译成人话它在解决什么做微电网优化研究或者相关工程项目的人这两年基本都会撞上同一个话题P2P电能交易。评审意见、课题需求、毕业设计的题目里到处都在问“微网之间除了各买各的电还能怎么互济”。我之前完整复现并改造过一套“基于非对称纳什谈判的P2P电能交易共享优化策略”今天把这套东西的数学模型、MATLAB代码组织、两阶段求解思路和踩坑过程一次讲清楚。这套方法的核心就一句话几个有光伏、有储能、有负荷的微电网组成一个合作联盟通过内部P2P交易减少向配电网高价购电再用合作博弈里的纳什谈判解来确定“联盟收益该怎么分”。它解决的典型痛点是单个微网受自身光伏出力和负荷曲线不匹配的限制要么光伏白白上网廉价出售要么高峰期承受高价购电而几个微网联合起来之后通过电量互济可以把这部分价差空间吃下来。代码层面落地的难点则在于纳什谈判并不是拍脑袋分账而是要解一个带约束的非线性优化问题并且还要保证每个微网都能接受最终分配结果。为了把这个课题聊透我先假定一个基本场景区域配电网下面挂了3个微网每个微网自带分布式光伏、负荷和储能电池各有一条与配电网的联络线微网与微网之间通过公共联络线进行P2P交易。系统调度周期是24小时时间间隔取1小时。在这个场景下代码要算两件事第一每个微网各时段的储能充放电、向配电网购售电、P2P交易电量分别是多少第二P2P交易后联盟多出来的收益怎么分配才能让大家都愿意参与合作。1.1 P2P电能交易到底是什么意思先给完全刚接触的读者打个底。所谓P2P电能交易就是把传统“用户只跟电网公司交易”的单边模式改成用户与用户之间的直接交易。放到微网场景下就是几个微网之间可以直接互相买卖电而不是各自把剩余电量卖给配电网、再把缺额从配电网买回来。为什么这件事值得做因为配电网的购电价和售电价之间存在明显价差。举个常见设定从配电网购电约0.8元/kWh向配电网售电只有0.4元/kWh。A微网中午光伏多到用不完硬卖给配电网只能拿0.4元同一时刻B微网负荷正高从配网购电要花0.8元。这时A直接卖给B哪怕内部成交价取中间值0.6元A比卖给电网多赚0.2元B比从电网买省0.2元双方总福利都提升。这就是P2P电能交易产生经济价值的根本来源整个优化模型都是围绕怎么把握住这个价差空间来搭建的。如果光有价差直接按固定中间价交易就行没必要上升到优化。但实际系统里每个微网都有储能有充放电效率损耗有联络线容量约束还有各自独立的光伏波动曲线和负荷曲线。某个时段该卖还是该充、该买还是该放不是一眼能看出来的。这就要靠优化来统一决策。P2P交易电量本身也成为优化变量不能事先固定。加上“储能可以在光伏富余时充电、在负荷高峰时放电”问题的耦合关系就更复杂了。1.2 为什么“谈判”不是比喻而是数学问题我经常被问纳什谈判不是一个博弈论概念吗怎么落到代码里就变成一个优化模型了这里的关键在于谈判在数学上可以被抽象成一个带公理约束的收益分配问题。纳什在1950年提出的讨价还价问题描述的是几个理性参与者在存在合作剩余时如何达成一致分配方案。他证明满足帕累托最优、个体理性、线性变换不变性和无关选择独立性这四条公理的唯一解是最大化所有参与者效用的乘积。后人把这种解称为Nash议价解NBS。如果参与者的议价能力不一样就把乘积形式修改为带权重的形式也就是非对称纳什谈判解。它求的是最大化各参与者收益增量的加权乘积权重用来反映各方的议价力、贡献度或者主观优先级。放到微网P2P场景里“谈判”就是各微网商量内部交易电价和电量分配的过程。每个微网都有自己的底线收益也就是不参与联盟时单独跟配电网交易能拿到的最大收益。只有联盟分配后收益高于底线微网才愿意合作。优化模型要做的事情恰恰是找一个帕累托最优的分配方案没有任何一个微网比现状更差同时整体收益已经达到最高任何人都无法在不损害他人的情况下过得更好。1.3 对称与非对称的区别分账时谁的份量更重对称纳什谈判和非对称纳什谈判的区别类似“五五开分账”和“按贡献/按话语权分账”的区别。几个微网组成联盟后如果A的光伏装机大、对联盟贡献多B的负荷弹性小、议价能力弱还硬按完全平等的方式分则贡献大的一方会觉得吃亏而退出联盟。非对称纳什谈判给每个微网配置一个权重χ_i权重越大的微网在分配中越有话语权最后的结算结果就越向它倾斜。这个权重怎么来是模型设置里最灵活也最容易引起争议的部分。常见做法有三种第一种由上级调度或运行方直接给定体现管理意图第二种按照各微网的峰值负荷、光伏装机容量、储能容量等物理指标归一化取值第三种通过Shapley值计算各微网在联盟中的边际贡献再把边际贡献归一化作为权重。第三种理论上最“公平”但要多次计算子联盟的优化结果计算代价明显偏高。我实际用的比较多的是第二种物理指标明确、可解释性强也能避免代码里反复求解多个子问题带来的时间开销。2. 数学建模从NBS到可求解的优化问题搞清楚逻辑之后接下来是最核心的部分怎么把“非对称纳什谈判”变成一个MATLAB能直接求解的优化问题。这里推导思路比公式本身更重要理解了推导顺序代码基本就是顺着公式一行行翻译的事。2.1 每个微网的运行收益怎么算先定义单微网的收益模型。以常见日运行成本最小化的等价形式为例微网i在时段t的收益可以写成[ U_i \sum_{t1}^{T} \left( p_t^{sell}P_{i,t}^{sell} - p_t^{buy}P_{i,t}^{buy} \right) \sum_{t1}^{T} \rho_{t} P_{i,t}^{p2p} - C_i^{ess} ]其中 (p_t^{sell}) 和 (p_t^{buy}) 是t时段向配电网售电和购电的电价(P_{i,t}^{sell}) 和 (P_{i,t}^{buy}) 是对应的功率(\rho_t) 是t时段P2P交易内部结算价(P_{i,t}^{p2p}) 是微网i在t时段通过P2P净买入的功率买入为正、卖出为负。(C_i^{ess}) 是储能运行损耗成本可以用电池充放电成本的线性近似来刻画。真正在代码里跑的时候我习惯把储能损耗成本写成固定损耗系数的线性项比如 (C_i^{ess} \sum_t(c_{ch}P_{i,t}^{ch} c_{dis}P_{i,t}^{dis})\Delta T)即每次充电或放电都按功率大小支付一点“磨损费”。这样做的好处是目标函数保持线性第一阶段优化可以直接用线性规划或二次规划求解速度和稳定性都有保障。若把储能寿命损耗建模成非线性函数整个问题的复杂度会上升分布式求解时更容易出现收敛问题。P2P内部结算价 (\rho_t) 是模型里最有意思的变量。真实物理世界中微网之间的交易只要约定在购电价和售电价之间即可大于售电价、小于购电价就不会有人吃亏。但 (\rho_t) 同时还是收益分配的手段它的取值直接决定每个微网从P2P交易中赚到多少差价。在纳什谈判框架下(\rho_t) 不能随便定必须是第二阶段分配问题的解。2.2 谈判破裂点不合作的底线收益谈判破裂点在纳什谈判模型里记为 (d_i)表示微网i退出联盟、单独运行时的最优收益。这个值非常重要它是后面所有个体理性约束的基准。如果最终分配出来的收益低于 (d_i)微网i完全有理由拒绝合作模型给出的解也就不成立。计算 (d_i) 的方式很简单把每个微网单独扔进优化问题里允许它跟配电网交易但不开放P2P交易通道。求出来这个单微网日运行最优收益就是它的底线。代码实现上只需要跑一个简化版的单主体优化问题约束里去掉P2P交易耦合项即可。这里有两点经验值得说。第一(d_i) 大多数情况下是负值因为微网向配电网购电的支出通常大于光伏上网收益尤其当负荷较重时。所以后面检查个体理性约束不要看到收益是负数就以为模型错了应该把眼光放在“联盟分配收益是否大于底线收益”上。第二底线收益会受到分时电价影响。如果某微网的底线被算得特别高说明它单独运行本来就不差那么它在联盟分配中就应当获得更多盈余否则没有合作动机。2.3 两阶段求解法先做大蛋糕再谈分蛋糕直接求解非对称纳什谈判问题在数学上可以做到但在工程实践中大家更常用的其实是个两步走的技巧这也是很多已发表论文和开源代码里使用的方法。第一阶段先忽略P2P结算价格的具体分配单纯求解联盟整体总收益最大化问题。这相当于把所有微网当成一个整体让内部P2P电量自由流动配电网只作为兜底交易对象。这个阶段得到的最优总收益 (U_\Sigma^{\star}) 就是“蛋糕做大”后的尺寸。第二阶段在保证总收益不降低的前提下确定P2P结算价格 (\rho_t)使得每个微网最终收益 (U_i) 满足非对称纳什谈判的目标[ \max \prod_{i1}^{N} \left( U_i - d_i \right)^{\chi_i} ]等价于[ \max \sum_{i1}^{N} \chi_i \ln \left( U_i - d_i \right) ]约束条件是每个微网的 (U_i) 不低于 (d_i)且联盟总收益保持 (U_\Sigma^{\star})。为什么能这样拆因为NBS本身的特性决定了它对应的最优解一定处在帕累托前沿上而帕累托前沿正好对应第一阶段总收益最大的那些解。所以先把前沿找出来再在前沿上选一个点满足公平性要求。两阶段的思路和“先创造价值再分配价值”完全一致也让代码结构变得清晰第一阶段是一组线性约束下的线性目标第二阶段是一组线性约束下的对数目标。实际操作中第二阶段目标函数里的对数项在 (U_i - d_i) 接近0时梯度会急剧增大这会迫使求解器把每个微网的收益都拉开底线一点距离。我们从物理角度理解就是不能把任何一家微网压榨到刚好跟单独运行一样必须给一点甜头否则人家凭什么参与联盟。2.4 约束条件清单一览把完整约束列出来方便直接对着写代码。以下都为混合整数线性规划或二次规划可处理的线性/二阶锥约束形式。功率平衡约束。每个微网每个时段必须满足能量守恒[ P_{i,t}^{buy} P_{i,t}^{dis}\eta_{dis} P_{i,t}^{p2p} P_{i,t}^{pv} P_{i,t}^{load} P_{i,t}^{ch}/\eta_{ch} ]注意我这里把 (P_{i,t}^{p2p}) 定义成买入为正卖出为负这样的话 (P_{i,t}^{p2p}) 可以为正也可以为负代码里对应sdpvar变量不需要额外加非负约束。P2P交易耦合约束。每时段所有微网的P2P净买入之和必须等于0[ \sum_{i1}^{N} P_{i,t}^{p2p} 0, \quad \forall t ]联络线功率约束。向配电网购电和售电不能同时进行P2P交易量也不能超过联络线容量[ 0 \le P_{i,t}^{buy} \le P_{buy,\max}, \quad 0 \le P_{i,t}^{sell} \le P_{sell,\max} ]如果是线性模型用一个很小的惩罚项让两者不同时为正即可或者用二进制变量严格互斥。我一般建议加上购售互斥约束因为真实物理上同时和电网买卖是毫无意义的而且会浪费交易空间。储能系统约束。包括SOC动态递推、SOC上下限、充放电功率上下限以及充放电互斥约束[ SOC_{i,t} SOC_{i,t-1} \frac{P_{i,t}^{ch}\eta_{ch}}{E_i}\Delta T - \frac{P_{i,t}^{dis}}{E_i\eta_{dis}}\Delta T ][ SOC_{i,\min} \le SOC_{i,t} \le SOC_{i,\max}, \quad 0 \le P_{i,t}^{ch} \le P_{ch,\max}, \quad 0 \le P_{i,t}^{dis} \le P_{dis,\max} ]P2P结算价范围约束。内部交易价必须在售电价和购电价之间否则经济上无意义[ p_t^{sell} \le \rho_t \le p_t^{buy} ]这两组约束大家都容易漏我在踩坑阶段没少被提醒。特别是SOC的初值和末值约束很多新手只写了初值忘记末值归位导致求解器利用储能的“作弊”把日收益算得很高。正确的做法是令 (SOC_{i,0} SOC_{i,T} SOC_{init})保证储能只是平移电量不是无中生有。3. MATLAB代码架构与求解答配置这部分是大家最容易关心的也是标题里最吸引人的地方。一个完整可跑通的项目代码文件怎么组织YALMIP模型怎么写求解器怎么配分布式ADMM怎么落地我分成几块讲。3.1 工程文件怎么分拿到一个课题先别急着写优化目标函数先把文件结构规划好。我推荐的目录结构是project/ ├─ main_nonNBS_P2P.m % 主程序总入口 ├─ config_params.m % 参数配置电价、负荷、光伏、储能参数 ├─ load_data.m % 读取或生成24小时负荷和光伏数据 ├─ calc_disagreement.m % 计算各微网谈判破裂点收益 ├─ stage1_total_opt.m % 第一阶段联盟总收益最大化 ├─ stage2_nbs_alloc.m % 第二阶段非对称NBS收益分配 ├─ plot_results.m % 结果绘图 └─ data/ ├─ PV_data.csv % 光伏出力的标幺曲线 └─ Load_data.csv % 负荷标幺曲线这样拆分的最大好处是每个求解问题之间天然解耦。调试时如果第一阶段跑出离谱结果不需要怀疑第二阶段如果P2P价格范围有问题也只改stage2那个函数。我见过很多人把所有代码堆在同一个脚本里变量互相覆盖排查问题时非常痛苦。主程序的基本逻辑用伪代码写出来大致是clear; clc; close all run config_params.m; [PV, Load] load_data(); % 阶段零各微网单独运行求谈判破裂点 d_i calc_disagreement(); % 第一阶段联盟整体收益最大 [P_buy, P_sell, P_p2p, P_ch, P_dis, SOC, obj_star] stage1_total_opt(); % 第二阶段非对称NBS分配 [rho_t, U_i, chi] stage2_nbs_alloc(); % 绘图 plot_results();3.2 用YALMIP建模的关键代码建模工具我用得最多的是YALMIP加求解器的组合。YALMIP本身不是求解器它是一个建模接口可以把你写的sdpvar变量和约束自动翻译成求解器能吃的标准形式。好处是换求解器不需要重写模型代码。下面是一段简化的第一阶段模型代码可以直接参考。T 24; n 3; dt 1; P_buy sdpvar(n, T, full); P_sell sdpvar(n, T, full); P_p2p sdpvar(n, T, full); P_ch sdpvar(n, T, full); P_dis sdpvar(n, T, full); SOC sdpvar(n, T1, full); rho sdpvar(T, 1, full); F []; % 功率平衡约束 for i 1:n for t 1:T F [F, P_buy(i,t) - P_sell(i,t) P_p2p(i,t) ... P_dis(i,t)*eta_dis - P_ch(i,t)/eta_ch ... PV(i,t) - Load(i,t) 0]; end end % P2P功率互济约束每个时段所有微网购售之和为0 F [F, sum(P_p2p,1) 0]; % 储能SOC递推与边界 for i 1:n for t 1:T F [F, SOC(i,t1) SOC(i,t) ... (P_ch(i,t)*eta_ch - P_dis(i,t)/eta_dis)*dt/E_cap(i)]; end F [F, SOC(i,1) SOC_init(i)]; F [F, SOC(i,T1) SOC_init(i)]; F [F, SOC_min(i) SOC(i,:) SOC_max(i)]; F [F, 0 P_ch(i,:) P_chmax(i)]; F [F, 0 P_dis(i,:) P_dismax(i)]; end % 购售电功率边界 F [F, 0 P_buy P_grid_max]; F [F, 0 P_sell P_grid_max]; % P2P交易价格范围 F [F, repmat(price_sell,1,1) rho repmat(price_buy,1,1)]; % 目标函数联盟总净收益最大化 obj sum(sum(P_sell .* repmat(price_sell, n, 1))) ... - sum(sum(P_buy .* repmat(price_buy, n, 1))) ... - sum(sum(P_ch P_dis)) * c_ess * dt; ops sdpsettings(solver, gurobi, verbose, 2, dualize, 0); optimize(F, -obj, ops);这段代码里有几个细节值得解释清楚。第一购售互斥没有强制用二进制变量而是靠经济性自然排除因为购电价一定大于售电价同时购售必然增加成本、降低总收益所以最优解中不会出现同一微网同一时段又买又卖。这个处理在纯优化上没问题比混合整数规划快得多。第二P2P价格 rho 的维度是 T×1但 P_buy 是 n×T如果要算每个微网的支出需要把 rho 复制扩展成 n×T。第三优化目标是最大化总收益所以传给optimize的目标函数取负号。3.3 第二阶段NBS分配的代码实现第二阶段的目标换成加权对数盈余这是整个代码里最容易出现数值警告的地方。% chi 是非对称权重需满足 chi_i 0, sum(chi) 1 chi [0.45, 0.35, 0.20]; % U_i_total 由第一阶段的结果和P2P电量计算得到 % profit_p2p_i sum(P_p2p(i,:) .* rho, 2) % 所以总收益与 rho 是线性关系 d_i [d1; d2; d3]; % 从 calc_disagreement 获得 % 第二阶段优化变量只有 rho U_i zeros(3,1); for i 1:n U_i(i) base_profit_without_p2p(i) sum(P_p2p(i,:) .* rho); end obj2 -sum(chi .* log(U_i - d_i)); F2 []; F2 [F2, repmat(price_sell, T,1) rho repmat(price_buy, T,1)]; F2 [F2, U_i d_i eps]; ops2 sdpsettings(solver, gurobi, verbose, 2); optimize(F2, obj2, ops2);这里的目标函数带有log如果收益增量小于等于0就会直接出问题。求解器在数值上需要目标函数在定义域内有意义所以必须确保 (U_i - d_i) 严格大于0代码里加eps就是为了防止出现0。第二阶段的问题规模很小只有T个变量跑起来非常快通常不到一秒就能出结果。需要注意第二阶段我没有显式写 (\sum U_i U_\Sigma^{\star}) 的约束。因为优化变量的变化只会通过P2P价格重新分配联盟收益而P2P总量已经固定联盟总收益从数学上已经锁死再写这条约束既冗余又容易引发数值问题。检验这个推理是否成立可以跑完后打印所有U_i的总和跟第一阶段目标值比对误差在1e-6以内就算正常。3.4 分布式ADMM从课题报告到真正可用如果你做的是仿真研究集中式两阶段法已经完全够用。但如果你要交付一个真正能部署的多主体系统会面临一个隐私问题各微网不愿意把自己的负荷和光伏数据全部上报给中心计算节点。这时候就要做分布式求解ADMM是目前最主流的选择。ADMM把P2P交易耦合约束拆开。以两个微网之间的交易为例原始约束 (P_{i,j} P_{j,i} 0) 被改写成每个微网自己声明一个交易计划再通过一个全局变量 (z) 来达成一致[ P_{i,j} z, \quad P_{j,i} -z ]每次迭代每个微网只求解自己的本地问题然后交换交易功率和拉格朗日乘子更新对偶变量。由于每个微网只需要向邻居传递交易功率和价格信号不需要暴露内部负荷曲线隐私就得到了初步保护。我在MATLAB里实现的基本结构是for k 1:max_iter for i 1:n [P_local{i}, lam{i}] local_opt(i, z_last, rho, d_i); end z_next update_global(P_local, lam); if norm(z_next - z_last, inf) tol break; end lam_update(); endADMM的两个核心参数是惩罚系数 (\rho) 和收敛容忍度 (\text{tol})。(\rho) 取太小的话原始残差下降慢迭代次数多取太大则对偶残差容易震荡。实际调参下来(\rho) 设在0.01到0.1之间比较稳但最优值跟电价量级强相关建议按目标函数量级归一化后再选。要注意的是ADMM收敛性在目标函数强凸的前提下能得到保证。如果模型里P2P价格 rho 也是优化变量且目标函数带log整个问题是非凸的此时ADMM可能会发散。我的经验是分布式版本先把P2P价格从本地优化变量里拿掉改为“按第一阶段求得的边界价离散化”或“由上层按协商规则更新”这样才能保留ADMM的凸分解特性。3.5 参数初始化与数据生成建议参数初始化是新手最容易忽视但影响最大的环节。我遇到过好多次模型本身没问题纯粹是参数给得太离谱导致找不到可行解的情况。电价建议这样设购电分时电价在0.6到1.0元/kWh区间内波动售电固定为0.35到0.45元/kWh这样就有0.3到0.5元/kWh的P2P交易空间。注意售电价必须低于低谷购电价否则某些时段失去P2P动力模型会退化。储能参数方面容量200到500 kWh之间额定功率50到100 kW充放电效率取0.95SOC范围0.1到0.9。光伏和负荷曲线可以直接用标幺值再乘容量系数生成但最好加一点随机扰动避免多个微网曲线完全相同导致P2P交易量为0。关于初始值SOC初值设为0.5末值强制等于初值。联络线功率上限如果不设系统可能会通过配电网无限购电完成所有负荷这不符合实际场景。通常取微网峰值负荷的80%到100%。P2P交易功率上限可以比联络线上限高一些因为微网之间的线路容量通常更充裕。4. 仿真结果解读这些曲线在说什么模型跑通之后真正的工作才刚刚开始因为仿真结果背后的物理含义直接决定论文能不能写圆、项目方案能不能说清楚。这一节我用典型算例讲解怎么看结果图怎么设计对比实验以及怎么验证非对称权重的作用。4.1 一个典型的P2P交易曲线长什么样假设3个微网的典型日场景如下微网1光伏容量大白天有大量盈余微网2没有光伏但有储能白天负荷平稳微网3负荷集中在傍晚晚上没有光伏。跑完模型后你基本会看到这样的结果白天10点到15点微网1的 (P_{p2p}) 为负也就是大量输出电量给微网2和微网3傍晚17点到20点微网2和微网3的负荷上升微网1光伏归零此时微网2的储能开始放电并通过P2P卖给微网3同时微网1可能也要从电网买电。这个交易模式的宏观表现就是光伏出力被内部消化储能的放电时段避开电价的最高峰各微网的购电总量相比独立运行明显下降。画图时把各微网的P2P交易功率画成柱状图再把配电网购电功率曲线用虚线叠加一眼就能看出哪些时段发生了“内部替代外部”的交易。我自己看结果图时习惯先关注两个指标。第一个是P2P总交易电量它反映了模型对价差空间的利用程度第二个是各微网从配电网的净购电量峰值它直接关系到联络线扩容需求工程上非常重要。如果P2P总交易量偏小往往是价差设置太小或者P2P功率上限约束太紧。4.2 对比实验无P2P、对称NBS、非对称NBS一篇合格的论文或者项目报告单看一组结果没有说服力必须做对比。最常见也最有效的是三组对照。第一组是无P2P合作场景也就是每个微网独立运行、只与配电网交易。这组实验给出谈判破裂点集合也是合作后收益增量的“零刻度”。第二组是对称纳什谈判场景权重全部取1/N。这个组反映的是“收益平均分配给各方”的谈判结果。第三组是非对称纳什谈判场景权重差异化。我把三组的总收益和单微网收益整理成一张表比用文字描述要直观得多场景联盟总收益微网1收益微网2收益微网3收益P2P总交易量无P2P823.5342.1251.8229.60对称NBS941.2386.4287.7267.1486.5非对称NBS941.2410.8278.9251.5486.5注意联盟总收益在第一阶段就已经定死所以对称和非对称的总收益是同一个值差异在分配上。非对称权重让微网1得到更多收益代价是微网2和微网3拿得略少但依然高于无P2P场景下的底线收益。4.3 非对称权重敏感性测试怎么做项目要交付时通常还要求做敏感性分析。我最常做的是扫描权重矩阵中的关键元素观察单个微网收益的变化路径。比如把微网1的权重从0.2逐步调到0.6同时保持另外两个微网权重等比缩放观察微网1收益是否单调上升、微网2和微网3是否承受更多的收益压缩。这个测试在代码上非常简单外面套一层for循环即可chi1_list 0.10:0.05:0.70; for k 1:length(chi1_list) chi(1) chi1_list(k); chi(2) (1 - chi1_list(k)) * 0.6; chi(3) (1 - chi1_list(k)) * 0.4; U_save(k,:) run_stage2(chi); end跑完之后画各微网收益随微网1权重变化的曲线。如果是一条平滑的单调曲线说明模型对权重变化的响应稳定如果出现拐点或跳变多半是第二阶段优化中个体理性约束起作用导致的需要仔细检查是否在某个权重区间内某个微网的收益被压到了底线附近。还有一个细节值得提权重敏感性的结果和P2P交易量的对比密切相关。如果非对称权重大幅改变分配方向但P2P交易总量并没有发生变化说明第一阶段后联盟总收益是固定的权重只能影响分配不能影响“蛋糕大小”。这个结论经常被写错成“非对称权重提升联盟收益”本质上是两阶段模型的天然结果不是权重带来的提升。5. 实际运行中你会踩的坑这套代码我跑过很多版本期间踩过的坑远比看论文时想象的要多。挑几个最有代表性的问题按排查思路记录下来希望能帮你少走弯路。5.1 YALMIP建模与求解器相关报错第一个高频问题“No suitable solver for the problem detected”或者“Failed to find a solver”。原因是YALMIP只会调用已安装并获得许可的求解器而且不同求解器能够处理的模型类型不同。如果你的模型里有二进制变量基本只能靠Gurobi、Cplex这类混合整数求解器如果只有连续变量则可以用linprog、fmincon或者quadprog。我的建议是直接装Gurobi学术许可免费性能稳定。如果环境里没有Gurobi也可以用MATLAB自带的linprog跑第一阶段第二阶段用fminunc或者fmincon。代价是速度慢一些且容易碰到局部最优但对于规模很小的3微网系统问题不大。第二个高频问题“Index exceeds array dimensions”。这个基本都是yalmip变量的维度写错了。sdpvar(n, T, full)生成的变量是n行T列操作过程中需要注意向量方向。用sum函数时sum(P_p2p, 1)是按列求和结果是一个行向量如果要用它拼约束维度对不上会直接报错。我习惯在所有需要按列求和的地方写清第二个维度参数而不是依赖默认行为。5.2 ADMM收敛性问题分布式ADMM跑出来的目标值往往在一开始猛涨然后陷入缓慢震荡。我在3微网系统上遇到过错过收敛点后目标函数反复波动的案例。排查优先级建议是先检查P2P交易变量符号方向是否一致一个微网卖出的功率是负数另一个买入是正数两者相加应该等于0再检查惩罚系数 (\rho)判断是否过大导致对偶变量更新过猛最后看本地子问题是否还有二进制变量只要有二进制变量在循环内ADMM的收敛理论就不成立了实践中会很难稳定。还有一个非常隐蔽的问题每个本地微网优化时把储能的SOC初始值设成共享常量但各微网迭代不同步时SOC边界处理不一致造成对偶乘子被不断“推高”。解决方法是每个迭代轮次内统一先固定SOC初值轮次间再更新。这相当于在分布式实现里加了一个“异步修正”步骤。5.3 非对称权重设置容易犯的错设置非对称权重时最容易犯的错误是权重和个体理性约束冲突。比如把权重全部分给一个微网最终分配结果可能让另一个微网收益低于底线此时第二阶段优化无解。代码上的现象是MATLAB直接给你一个NaN的rho或者Gurobi报infeasible。当第二阶段无解时不要急着调求解器参数应该先检查权重矩阵是否合理以及底线收益d_i是否计算正确。如果单独运行某个微网时没有给它足够的储能用它的底线看起来特别低这会导致它“愿意接受”极差的分账比例对应到现实里就是弱势微网被拿走几乎所有盈余模型虽然可解但结果可信度低。我通常会额外加一个约束比如每个微网的收益至少比底线高出5%作为个体理性约束的加强版。另一个常见问题是权重和议事权不是一回事。很多人直接把权重设成和负荷大小相关结果发现高负荷微网占大头但高负荷微网本身在联盟里的贡献可能主要来自“买电”这种理解需要从合作博弈的边际贡献出发而不是简单套用负荷比例。5.4 结果合理性检验与绘图技巧模型跑完先别急着截图先做两个合理性检验。第一在P2P价格序列里每个时段价格是否落在售电价和购电价之间如果出现越界说明约束没加全或数值有问题。第二检查每个微网的SOC曲线是否平滑是否出现频繁的充放电切换。如果SOC一天内来回跳动十几轮大概率是充放电互斥没处理好或者是储能损耗系数设置太小导致求解器利用“零成本充放电”进行套利。绘图方面有几个小技巧。把3个微网的P2P交易功率画在同一张图上用正负柱状图表达“卖”和“买”观感很好。P2P价格曲线和分时电价画在同一个坐标系能直观看出内部价格贴着购电还是售电走。最后一张图画对比柱状图把无P2P、对称NBS、非对称NBS三组的总收益和各微网收益并列展示所有核心结论一张图说清。从我可以长期使用的个人经验出发这套方法最大的价值其实不是代码本身而是把一个原本要靠“拍脑袋定价”或者“平均分摊”的合作问题变成了一个数学上可验证、决策上可解释的优化过程。我自己复现完这套代码后最大的收获是理解了“合作收益的来源必须由物理网络结构决定而合作收益的分配必须由博弈规则决定”这句话的分量。如果后续有机会我会再补一篇关于多微网与配电网协同运行的文章那里面这套非对称NBS框架同样能继续复用。
返回列表