含多微电网租赁共享储能的配电网博弈优化调度全解析 先给个定心丸这个方向并不是什么天马行空的科研难题而是近些年在电网调度里被反复讨论的真实工程需求。多微电网接入配电网之后每个微电网都有自己的一套负荷、光伏或者风机谁都想着“储能必须得有”但真让每家都按峰值功率去自建储能那投资成本直接劝退。于是“共享储能租赁模式”就出现了储能资产集中建设、集中运营微电网按需租容量、租功率用多少付多少钱。这个模式听着简单真做调度的时候各方利益纠缠在一起传统集中式优化又很难办于是博弈论就被请了进来。这篇文章我会把“含多微电网租赁共享储能的配电网博弈优化调度”拆开讲清楚从模型怎么建、博弈的结构怎么搭、为什么用Matlab做仿真到代码框架怎么组织、调试会遇到哪些坑一次性说透。适合电力系统方向的研究生、做园区微电网或综合能源系统设计的工程师以及正在复现相关论文、被博弈迭代搞到失眠的同学参考。1. 先想清楚这个问题到底在优化什么为什么要用博弈1.1 从“每家建储能”到“租赁共享储能”的现实逻辑先说储能自建和共享的区别。假设一个配电网下面挂了3个微电网A微电网白天负荷高峰在上午B微电网高峰在晚上C微电网光伏特别多、中午发出来的电自己根本用不完。如果每家各买一套储能那么每套储能的利用时段其实都很短大部分时间在闲置投资回报率很低。而且电池是有循环寿命的闲置不代表没成本那种“买了不用”的状态才是最亏的。共享储能的思路很直接把一大块储能集中放在配电网侧的某个节点由配电网运营商或者专门的储能运营商统一充放电管理微电网按自己的需求去“租”。你用白天、我用晚上错峰使用之后储能整体的利用率比分散自建高出一大截。对微电网来说不用一次性掏大笔建设费变成按需付费的运营成本财务上压力小得多。这个逻辑在工程上已经很成熟很多园区的共享储能试点就是照着这个思路走的。但问题也随之而来共享意味着容量有限功率也有限。几个微电网如果都挤在同一时段想充电或者放电给谁用按什么价格给这个问题一旦落到调度层面靠“拍脑袋分配”是不行的必须有一个能让各方都认账的机制。1.2 多主体各自算盘博弈模型出现的必然性博弈论在这里出现根本原因是各参与方都有自己的目标函数而且互相冲突。微电网A的目标是让自己一天的运行费用最低它希望储能租赁价格越低越好、可用容量越多越好储能运营商的目标是让储能资产收益最大它希望价格合理且利用率高配电网的目标是保证潮流不过载、电压不越限希望微电网们别在同一个时段集体充电或者集体倒送功率。如果做集中式优化理论上能求出一个全局最优的运行方案但前提是你要把每个微电网的负荷、光伏出力、设备参数、运行成本全部收上来放到一个模型里统一算。这在工程上很难落地——微电网之间的信息往往是独立的谁也不愿意把自己内部的真实成本函数和预测数据完完整整交给别人。而且不同投资主体的诉求不一样集中式优化给出的“全局最优解”很可能让某个微电网利益受损它根本不接受。非合作博弈和主从博弈解决的就是这个问题每个微电网在给定价格信号的条件下独立优化自己内部的调度计划只需向外界提交需求或购售电计划不暴露内部完整数据。大家通过价格这个“信号灯”来回试探、调整最终收敛到一个谁都不愿意单方面改变策略的状态。这个状态就是纳什均衡。这是博弈调度模型比集中式优化更贴近工程现实的原因。1.3 参与方边界谁在上层谁在下层具体到这个题目里博弈的结构通常是主从递阶的。配电网和共享储能运营商处于上层微电网处于下层。可以这么理解上层定规则下层做反应。上层拥有共享储能资产还掌握配电网的网络拓扑和潮流安全约束它制定储能租赁价格、容量分配策略甚至可以让配电网的购售电价参与调节。下层各微电网拿到价格信息后独立求解自己的日前优化调度决定向电网买多少电、卖多少电、租多大容量、什么时段充放电再把结果返回上层。上层的目标通常是综合性的既要让共享储能的运营收益最大化又要保证配电网运行安全可能还要兼顾网络损耗。下层的目标就单纯多了自己一天的总成本最小。双方经过多轮迭代最后达到谁都不想再改的状态。这里有一个容易混淆的点有的文章把共享储能运营商当成一个独立主体有的把它和配电网运营商合在一起建模。两种做法都有道理区别在于储能是不是单独盈利的实体。做代码实现的时候一开始建议把储能运营商和配电网合并成“上层主体”这样模型简单、迭代更容易收敛等基础版本跑通了再拆成两层也不迟。2. 博弈优化调度模型上下层到底怎么搭2.1 上层模型定价、容量分配与网络约束上层做决策的时候手里有两个关键工具租赁价格和容量分配。租赁价格可以按租用容量收费也可以按充放电电量收费工程上常做的是“容量租金电量租金”结合类似电话套餐的“月租通话费”。论文复现为了简洁可以先只做容量租金也就是微电网报一个“我租多少容量”上层根据总需求和储能额定容量之间的关系动态调整每单位容量的租金。上层决策还需要满足配电网安全约束。最常用的是DistFlow潮流模型通过二阶锥松弛把非线性的潮流方程转成可求解的凸优化形式。约束包括节点电压上下限、支路电流上限、联络线传输功率限制等。如果只做稳态日前调度这些约束处理起来并不复杂担心抄代码抄不明白的可以先忽略电压的详细潮流简化成“联络线功率约束储能容量约束”等思路理清了再加复杂网络约束。上层的目标函数一般包含三项共享储能的租赁收益减去运行维护成本再减去网络损耗成本。用数学语言表达就是max: 租赁收益 - 储能运维成本 - 配电网网损成本在这个目标函数里租赁收益由价格和分配容量共同决定运维成本可以简化成与充放电电量线性相关的成本系数网损可以通过潮流计算得到。需要注意的是上层在迭代过程中并不直接控制微电网的负荷和分布式电源它只能通过价格间接影响下层的决策这正好体现了主从博弈的特点。2.2 下层模型微电网自己先算明白下层的每个微电网本质上是做一个经济调度问题。它的目标函数是让一天内的总成本最小主要包含与配电网的购电费用购电电量的正值、售电收益售电电量的负值、储能租赁费用可能还包括微型燃气轮机的燃料成本。具体约束包括微电网内部的功率平衡负荷 充电功率 光伏出力 风机出力 购电 放电功率符号约定按充放电习惯调整、储能SOC递推关系、SOC上下限、充放电功率上下限、同一时刻不能既充又放这是0-1变量来源、联络线功率上下限等。因为存在“同时充放”互斥约束下层问题是一个混合整数线性规划如果考虑网络潮流还可能变成混合整数二阶锥规划。这里特别提一下储能模型的书写这是新手最容易翻车的地方。SOC递推关系建议这样写SOC(t1) SOC(t) eta_ch * P_ch(t) * dt / E_rated - P_dis(t) * dt / (eta_dis * E_rated);其中 eta_ch 和 eta_dis 分别是充电效率和放电效率dt 是调度步长E_rated 是共享储能分配给该微电网的额定容量。注意充放电效率的位置不一样充进去要打折放出来也要打折两个效率不能写反。而且 SOC 一般给一个范围比如0.1到0.9这既是电池本身的保护需要也是给调度留出调节余地。2.3 迭代博弈信息交换内容与收敛判据整个博弈调度的计算流程可以概括成四步上层给定一个初始租赁价格或者初始储能分配方案。各微电网根据价格独立求解自己的优化调度问题得到购售电计划、储能充放电计划和需要的租赁容量。上层汇总所有微电网的需求计算总租赁容量需求是否超过共享储能额定容量校验配电网安全约束如果超限或者不满足约束就调整价格让价格往“抑制需求”的方向走。重复第2、3步直到相邻两次迭代的价格变化和调度结果变化小于给定阈值视为收敛。价格更新公式常用的是次梯度法lambda(k1) lambda(k) alpha * (总需求容量 - 共享储能额定容量)其中 alpha 是一个正的步长因子。如果总需求大于额定容量说明储能稀缺价格应该上涨反之需求小于额定容量价格应该下调。这个逻辑和市场经济里的供需关系完全一致。收敛判据建议用两个条件同时判断一是价格向量的无穷范数变化小于阈值二是每个微电网的调度方案在连续两轮迭代中基本不再变化。只判断价格有时候会“假收敛”——价格不动了但微电网内部结果还没稳定。3. Matlab代码实现从模型到跑出结果的完整思路3.1 先解决工具链Yalmip加求解器怎么配做这类优化调度直接在Matlab里手写矩阵约束当然可以但非常容易把自己绕晕。我强烈建议用Yalmip建模再配合Cplex或Gurobi求解。Yalmip的作用是把数学约束用接近自然语言的方式写出来Cplex/Gurobi负责真正求解混合整数规划两者配合起来效率很高。安装上只需要注意几点Yalmip只要把文件夹加入Matlab路径即可不需要额外安装什么插件Cplex或者Gurobi需要下载对应版本并配置许可证如果用学校或者企业许可证到期了也可以先用Matlab自带的intlinprog跑小算例验证模型逻辑正确后再换商业求解器。代码不需要最新的Matlab版本R2020b以上基本都能跑通很多老版本也完全没问题。3.2 代码架构文件怎么分函数怎么拆我把这类代码建议按功能拆成五个部分调试和排查问题会轻松很多参数设置脚本定义微电网个数、节点参数、负荷曲线、风光出力、储能参数、电价、收敛阈值等微电网子问题函数输入价格和上限信息输出该微电网的调度结果上层决策函数汇总全体微电网需求更新租赁价格校核配电网约束主循环脚本负责迭代调用上下层函数判断收敛记录每次迭代结果结果分析脚本画功率曲线、SOC曲线、迭代收敛曲线输出对比表格用一个函数封装一个微电网的优化问题可以避免在迭代循环中重复写一大段约束。函数内部用Yalmip建模大概长这样function [P_buy, P_sell, P_ch, P_dis, SOC, obj] solve_mg(price_rent, E_max, P_max, ...) % 变量定义 P_buy sdpvar(1, T, full); % 购电功率 P_sell sdpvar(1, T, full); % 售电功率 P_ch sdpvar(1, T, full); % 充电功率 P_dis sdpvar(1, T, full); % 放电功率 SOC sdpvar(1, T1, full); % 荷电状态 u_ch binvar(1, T, full); % 充电状态标志 u_dis binvar(1, T, full); % 放电状态标志 Constraints []; % 功率平衡、SOC递推、充放电互斥等约束... % 目标函数... ops sdpsettings(solver, cplex, verbose, 0); optimize(Constraints, objective, ops); % 取值返回... end写这个函数的时候有几个细节十分关键。第一所有变量定义最好在函数开头集中写不要散落在循环里。第二约束要用中括号慢慢拼起来不要试图在一个表达式里塞太复杂的条件否则报错时很难定位。第三Yalmip对二进制变量和连续变量混用的表达式支持很好但要注意“0-1变量乘以连续变量”这类双线性项要尽量线性化否则模型会变成非凸问题Cplex就算不动。主循环的代码逻辑其实很少核心就是价格更新和收敛判断。价格更新部分可以参考这个模式for iter 1:max_iter % 各微电网独立求解 for i 1:N_mg [result_mg(i)] solve_mg(lambda_rent, E_sso_max, P_sso_max, mg_data(i)); end % 统计总需求 total_demand sum([result_mg.E_demand]); % 更新租赁价格 lambda_new lambda_rent alpha * (total_demand - E_sso_rated) / E_sso_rated; % 收敛判断 if norm(lambda_new - lambda_rent, inf) tol break; end lambda_rent lambda_new; end代码里把总需求和额定容量的差值除以额定容量是为了归一化让价格更新的步长不容易因为数值量级问题而震荡。3.3 收敛性调参步长和初值的经验值博弈迭代最折磨人的就是不收敛——价格上下震荡微电网调度结果也跟着来回跳。这个时候首先要检查的就是价格更新步长。步长alpha取太大价格会来回过冲取太小迭代几百轮也磨叽不动。我的经验是先从0.01开始试如果前20轮收敛曲线呈明显振荡就减半如果收敛非常慢就翻倍。实际代码里可以设定一个自适应步长比如连续三轮变化方向相同就略微加大步长出现振荡就减小步长。初值的选择也很影响收敛速度。把租赁价格的初值设成接近边际成本或历史电价水平通常最稳妥。比如储能运营成本加上合理利润率大概在每千瓦时零点幾元到1元的水平就直接从0.3元/kWh起步试。如果你是复现论文论文参数里一般会给出基准价格照着取即可。还有一个容易被忽略的点边界条件的松紧。比如SOC范围设成0.1到0.9比0到1更容易收敛联络线功率上限如果设置得太接近实际需求微电网问题可能无解博弈一开始就崩了。做初版的时候可以先把约束放松一点保证每个微电网都有可行解再逐渐收紧验证结果。这个技巧对排查“迭代发散”问题非常有用。4. 算例设计几种方案放在一起比一比4.1 算例系统怎么选节点和微电网参数算例建议用一个中等规模的配电网IEEE 33节点系统是最常见的选项节点少、参数齐全、研究案例多很适合做这类博弈调度的验证平台。把3到5个微电网分别接入不同节点每个微电网包含自己的日负荷曲线、光伏出力和风机出力再在某个节点接入共享储能系统。数据来源可以这样安排负荷曲线用一个典型工业园区的日负荷曲线加一些随机波动模拟实际光伏出力用典型晴天的出力曲线中午峰值、早晚为零风机出力戴一个夜间相对较高、白天相对较低的曲线因为夜里风通常大一些。储能参数按市面上的磷酸铁锂电池水平设置额定容量比如2MWh额定功率0.5MW充放电效率按95%考虑SOC限值0.1到0.9。4.2 对比方案怎么设置三组对照就够用虽然本文主题是博弈调度但光看一个结果没有说服力。建议至少设置三组对照方案A每个微电网自建储能各自优化运行不做共享。方案B采用共享储能但租赁价格固定不调整微电网按固定价格申报需求不做博弈迭代。方案C本文的博弈优化调度价格由上层根据需求动态调整。这三种方案放在一个表里对比文章的说服力会强很多。对比指标建议包括微电网总运行成本、共享储能利用率实际充放电电量与额定最大充放电电量之比、配电网日峰谷差、线路日网损量。我实际跑下来典型结果大致是方案A因为每家储能的投资折旧和运维成本高总运行成本最高方案B因为价格固定容易造成多个微电网同一时段抢储能实际利用率不高部分时段储能闲置部分时段又不够用方案C通过价格信号主动引导微电网错峰充放总运行成本比方案B低8%到15%比方案A低20%左右储能利用率明显提高。这个结论并不夸张它来源于“价格杠杆调节供需”的基本经济学逻辑。4.3 从结果里应该读出什么重要的不只是成本下降看结果别只盯着总成本数字。我建议把每个微电网的SOC曲线画在一张图上仔细观察它们的充放电时段是否形成错峰。如果博弈机制设计得当SOC曲线应该表现出“你充我放、我充你放”的错开趋势而不是所有人挤在同一个时段充电。这说明价格信号已经起到了调节作用储能容量紧张时价格升高对储能需求弹性大的微电网会主动减少租用容量需求刚性的微电网则愿意支付更高价格保住自己的充电时段。这种资源配置效果正是集中式优化难以在不暴露隐私的前提下实现的。迭代收敛曲线也很值得画出来。横轴是迭代次数纵轴是价格或者总成本变化量一般30轮以内就应该收敛。如果画出来的曲线像心电图上上下下飘个没完说明步长或者初值有问题回到上一节的调参方法去处理。5. 调试心得这些坑我一次一次踩出来的经验5.1 博弈迭代不收敛先查价格更新再查模型病态不收敛的原因排在第一位的就是价格更新步长不合适。价格连涨好几轮然后突然暴跌典型是步长过大价格半天不动但微电网内部调度结果还在来回变化往往是因为价格变化太小微电网对价格不敏感得加大价格刺激力度。还有一种情况是目标函数里费用项数量级差太多比如租赁费用是几千元量级购电费用是几万元量级价格微调对微电网决策的影响被购电成本淹没了。解决办法是对目标函数各项做归一化或者把租赁价格的初值和变化幅度调到购电成本的同量级。另一个不收敛的隐含原因是储能容量分配规则不明确。如果上层只更新价格但不明确“按什么规则分配容量”微电网之间可能出现竞价混乱。实际工程里一般先让微电网按需求申报如果总需求超限再按“愿意出价从高到低”依次分配或者按各微电网申报需求的占比硬性配比。论文复现时建议先处理成按比例分配简单稳定。5.2 Yalmip建模的报错大部分是索引和维度问题Yalmip报错最常见的问题就是维度不匹配。比如把1×24的变量和一个24×1的变量放在同一个约束里乘报错会很莫名其妙。解决方法是统一使用行向量也就是1×T所有参数也保证是1×T涉及常数时用ones(1,T)乘一个标量不要用标量直接参与矩阵运算。用矩阵乘法还是点乘也要分清变量和变量相乘要用点乘变量和系数矩阵相乘要用乘号或按你的矩阵维度写清楚。还有一类报错是“Nonlinear constraint”或者“Nonconvex model”说明约束里有非线性项。常见原因是在同一个约束里写了两组0-1变量与连续变量相乘比如 u_ch .* P_ch这在线性化处理不当的时候就会触发。解决办法是借助“大M法”把双线性项拆成一组线性不等式。别慌着改求解器先把非线性项找出来。5.3 结果不合理先做单元测试再做整体联调我在调试这类代码时有个习惯先只跑单微电网且只跑一天24个时段不给博弈迭代手动设定一个价格检查SOC曲线是否合理、功率平衡是否成立。单个微电网跑通了再测试两个微电网的博弈最后扩展到三五微电网。不要直接一上来就全系统联调不然报错了都不知道是储能模型的锅还是配电网约束的锅还是博弈迭代的锅。结果里还有一个非常容易踩的坑买电和卖电的价格如果设置不合理微电网会产生“低买高卖套利”的假象调度。比如购电电价0.8元/kWh售电电价却设成1.0元/kWh微电网就会不管自己实际需不需要拼命买电再卖电来“盈利”。实际电网里售电电价一定低于购电电价前者通常是后者的80%或更少这个约束要刻意在代码里保证否则结果虽然数值上很漂亮但工程上完全不可行。表格总结几个典型问题和排查方向现象可能原因排查与修复方法价格震荡发散价格更新步长过大前一轮和后一轮价格差悬殊步长减半或做归一化处理收敛很慢步长过小或初值偏离最优解太远加大步长用历史最优价格作为初值微电网问题无解联络线上限设置过紧或储能容量不足先放松约束确认可行后再收紧Yalmip提示非线性模型双线性项未线性化用大M法把0-1变量与连续变量乘积拆分成线性约束结果出现无意义充放电购售电价倒挂保证售电电价明显低于购电电价最后再分享一个做这类多主体博弈调度项目时我个人最推荐的路线先把“集中式单目标优化”的版本完整跑通再拆成“主从博弈迭代”版本。这样你能清楚看到博弈分布式求解和集中式全局最优解之间的差距也能理解为什么实际工程必须接受这种“次优但可落地”的解。别急着一步到位模型复杂度循序渐进代码调试的体验会好非常多。多微电网和共享储能这个方向还远没到天花板后续把不确定性、需求响应、多时间尺度加进来都是很有价值的扩展点但愿上面这些经验能帮你少熬几个夜。