多微电网共享储能博弈调度:Matlab实现与仿真代码解析

发布时间:2026/9/11 21:07:15
多微电网共享储能博弈调度:Matlab实现与仿真代码解析 多微电网加共享储能再加博弈论这个组合听起来就有点劝退。但如果你正在研究主动配电网优化调度或者毕业论文卡在“多主体利益冲突”这个坎上那这套Matlab代码应该是你眼下最需要的拐杖。它做的事情说白了就一句话当多个微电网都想租用一个共享储能时配电网作为“房东”怎么定价各微电网作为“租客”怎么用电才能让大家都满意同时整个系统还经济、安全。这篇文章我打算把这套代码的模型原理、Matlab实现框架、求解细节和调参经验一次讲透帮你从“运行报错”快速走到“出图分析”那一步。1. 项目背景与研究价值1.1 为什么多微电网需要共享储能先说个现实问题微电网里光伏和风电占比越高出力波动就越让人头疼。中午光伏大发的时候电用不完晚上负荷高峰又缺电自建储能当然是解决办法但一组锂电池从投资到运维动辄上百万单个微电网很难扛住这个成本。更尴尬的是每个微电网的峰值时段还不一样自己配了储能可能一天就用两三个小时大部分时间在闲置。共享储能就是针对这个痛点来的。把储能装在一个公共位置由专门的运营商或配电网统一管理多个微电网按需租赁容量按实际使用付费。你中午光伏多了就充电存着旁边那个微电网晚上缺电了再放出来给它用一块电池服务多个用户利用率上去了单个用户的成本也降下来了。“租赁”在这里是关键它区别于传统共享储能中“直接买卖电量”的模式微电网租的是储能的容量使用权本质上是容量和能量的双重交易这会让定价和调度问题变得很微妙。1.2 博弈论在调度中的角色多个微电网加一个共享储能系统里至少有两类角色在打小算盘。配电网或储能运营商希望租赁费定得高一点、购售电价差大一点这样自己收益最大微电网呢希望租赁费便宜、电价合理这样自己运行成本最低。两边目标不一致这就不是传统的“单目标优化”问题而是一个典型的“多主体博弈”问题。如果忽略主体间的利益博弈直接把整个系统当一个大综合来优化得到的调度方案是全局最优的但实际执行不了——因为配电网和微电网是独立决策主体没有谁愿意为了“全局最优”牺牲自己的利益。博弈论的价值就在这它承认每个主体有自己的目标然后用均衡的概念描述最终稳定的决策状态。主从博弈Stackelberg game特别适合这类问题配电网作为上层领导者先制定价格各个微电网作为下层跟随者再根据价格调整自己的用电计划双方都盯着自己的利益结果收敛的那个点谁也别想靠单方面改变策略来获益。1.3 这套代码能干什么这套Matlab代码实现的是日前经济调度时间尺度取24小时步长1小时每个微电网内部有光伏、风电、负荷、微型燃气轮机配电网侧有一个共享储能各微电网可以和配电网买卖电也可以租用共享储能。代码做三件事一是构建包含租赁机制的共享储能模型二是构建配电网与多微电网的主从博弈模型三是用迭代算法求出博弈均衡解最后输出电价、储能荷电状态、各微电网购售电计划和收益/成本数据。适合参考这套代码的人包括电力系统方向做微电网/主动配电网优化调度的研究生研究共享储能商业模式和定价机制的科研人员以及想了解多代理博弈框架怎么落地到Matlab代码的工程师。你不用自己从零推公式、啃KKT条件代码里的建模思路和求解框架可以直接迁移到你的问题上。2. 博弈模型构建与核心公式2.1 系统架构与主体角色划分先把系统里的人认齐。模型里有两个主体层级领导者上层配电网运营商同时运营共享储能负责制定储能租赁单价、与微电网之间的购电/售电价格目标是自身净收益最大化。跟随者下层多个微电网通常取3个数量可扩展收到上层电价信号后优化自身各时段的购售电功率、分布式电源出力和储能租赁功率目标是自身运行成本最小化。需要提醒一点很多初学者会疑惑“共享储能到底归谁”。这个模型里把储能归配电网运营配电网既是电网管理者又是储能服务商这样做的合理性在于储能接入配电网公共母线由配电网统一调用和计费便于实现全局协调也更符合当前共享储能项目的实际运营模式。2.2 上层模型配电网的定价与收益目标配电网的目标函数包含收入项和成本项收入包括向微电网售电的收入、微电网向配电网反送电时配电网收的“过网费/服务费”或购电节省的成本以及储能租赁费收入。成本包括从上级电网购电的成本、储能运行维护成本。这一个目标的公式写出来就是max Profit_DSO sum_t( c_buy(t)*P_MG_buy(t) - c_sell(t)*P_MG_sell(t) ) sum_t( lambda_lease * E_lease_alloc(t) ) - sum_t( c_grid(t)*P_grid_buy(t) ) - sum_t( c_ess_om * (P_ch(t) P_dis(t)) )其中c_buy是配电网向微电网售电价c_sell是配电网从微电网购电价lambda_lease是储能容量租赁单价E_lease_alloc是微电网实际租用的储能容量P_ch/P_dis是储能充放电功率。配电网的决策变量就是各时段的售电价c_buy、购电价c_sell和租赁单价lambda_lease。但价格不能乱定要受上限约束比如不能超过微电网自身燃气轮机的发电成本否则微电网不买电交易就不存在了。2.3 下层模型微电网的调度目标与约束第i个微电网的目标是总成本最小总成本包括向配电网购电费用、租用储能费用、燃气轮机燃料成本、弃光弃风惩罚成本再减去向配电网售电的收入min Cost_MG_i sum_t( c_buy(t)*P_buy_i(t) - c_sell(t)*P_sell_i(t) ) sum_t( lambda_lease * E_lease_alloc_i(t) ) sum_t( a*(P_MT_i(t))^2 b*P_MT_i(t) ) sum_t( penalty * (P_PV_curtail_i(t) P_WT_curtail_i(t)) )约束条件这一段是代码里最容易写错的地方我按类型列出来功率平衡约束光伏出力风电出力燃气轮机出力储能放电功率配电网购电功率 负荷储能充电功率向配电网售电功率弃光弃风功率。储能约束荷电状态递推方程SOC(t1)SOC(t)η_ch*P_ch(t)-P_dis(t)/η_disSOC上下限约束充放电功率上限约束充放电状态互斥约束日始日末SOC相等约束。燃气轮机约束出力上下限约束爬坡约束升坡降坡。变压器/联络线容量约束与配电网交换功率不超过上限。注意这里微电网的决策变量包含“租用的储能功率”和“租用储能容量”这个变量放到储能约束里就表示“我可以用共享储能充/放这么多功率”它受限于自己租到的容量上限这就把租赁机制和实际充放电功率关联起来了。2.4 博弈均衡与两种求解思路主从博弈的均衡求解目前主流有两条路第一条路是“单层化”。用KKT条件把下层微电网优化问题转成上层问题的约束这样双层就变成单层数学规划再用强对偶条件或big-M法把里面的双线性项线性化最后交给商业求解器Gurobi、CPLEX去解。这条路的优点是能拿到精确最优解缺点是不好写KKT条件推导复杂对初学的人不友好稍不留神少了某个互补松弛条件结果就失真。第二条路是“迭代求解”。上层给定初始电价下层各微电网根据电价独立求解自己的调度问题把购售电计划反馈给上层上层根据反馈更新电价再下发新一轮电价循环往复直到电价和功率不再变化。这条路的优点是实现简单、代码改动小、适合Matlab多次调用求解器而且能直观看到博弈收敛过程。这套代码用的就是第二种方案主要考虑到教学和复现的便利性。更新电价时用到了“按供需关系调整”的思路如果微电网购电量大于期望值说明电价偏低下一轮上调如果购电量小于期望值说明电价偏高下一轮下调。步长因子取0.1到0.2之间比较稳妥太大容易震荡太小收敛慢我后面会专门讲这个调参经验。3. Matlab代码实现架构3.1 文件结构与函数分工拿到代码包后建议先按下面的列表对号入座知道每个文件是干嘛的省得后面找半天文件/函数功能说明main.m主程序定义系统参数、初始化变量、循环调用上下层求解、输出结果data_load.m读取或生成24小时负荷、光伏、风电曲线数据params_system.m系统参数集中管理包括储能参数、微电网参数、电价上下限DSO_init_price.m上层配电网定价策略生成初始购售电价和租赁单价MG_optimization.m单个微电网优化调度函数输入电价返回购售电计划和成本ESS_model.m共享储能模型计算SOC变化、租赁容量约束update_price.m根据购售电偏差更新电价plot_results.m绘图模块生成结果图这种“主程序子函数”的结构在电力系统研究中非常标准好处是后期你看懂了想改模型只需要动其中一个函数不会牵一发动全身。3.2 关键参数与数据准备在main.m开头有一段参数初始化我把比较重要的几个列出来% 时间参数 T 24; % 调度时段数 dt 1; % 时间间隔 (h) % 共享储能参数 ESS_E_max 2000; % 储能总容量 (kWh) ESS_P_max 500; % 储能最大充/放功率 (kW) ESS_soc_init 0.5; % 初始SOC ESS_eta_ch 0.95; % 充电效率 ESS_eta_dis 0.95; % 放电效率 % 储能租赁单价初值 lambda_lease 0.12; % 元/kWh % 微电网数量 N_MG 3;负荷数据和光伏出力数据建议直接给一个二维矩阵行数对应微电网数量列数对应24小时。如果手头没有真实数据可以用正弦函数加随机扰动生成比如% 生成典型日负荷曲线峰时在18-21点 base_load [0.6 0.55 0.5 0.45 0.45 0.5 0.6 0.75 ...]; for i 1:N_MG Load(i,:) base_load * MG_peak(i) randn(1,T)*10; end我这里换成randn是为了体现每个微电网负荷的差异化你可以按自己需要改成确定性数据。3.3 主从博弈迭代求解的主循环这是整套代码的“心脏”。我先把核心框架贴出来每行注释都写清楚方便你对照理解% 初始化电价配电网作为领导者先出价 [price_buy, price_sell, lambda_lease] DSO_init_price(); % 记录迭代过程 iter_data []; for iter 1:max_iter % 下层各微电网响应电价独立求解调度问题 for i 1:N_MG [P_buy(:,i), P_sell(:,i), E_lease(:,i), cost_MG(i), SOC_ess(:,i)] ... MG_optimization(price_buy, price_sell, lambda_lease, para_MG(i)); end % 汇总各微电网的购电需求 P_total_buy sum(P_buy, 2); % 24x1 P_total_sell sum(P_sell, 2); % 上层根据购售电偏差更新电价 [price_buy, price_sell, lambda_lease, gap_buy, gap_sell, gap_lease] ... update_price(price_buy, price_sell, lambda_lease, ... P_total_buy, P_total_sell, E_lease_sum, target_curve); % 记录并判断收敛 iter_data [iter_data; iter, gap_buy, gap_sell, gap_lease]; if max([gap_buy, gap_sell, gap_lease]) epsilon disp([迭代收敛于第, num2str(iter), 轮]); break; end end注意里面这个target_curve它是配电网期望的购售电计划可以取上一轮的值也可以取一个固定的参考曲线不同取法会直接影响价格更新的方向。这块我做了一些对比实验结论是取上一轮值做差分更稳不容易出现价格来回抖的情况。3.4 微电网优化函数yalmip建模方法MG_optimization.m是每个微电网自己内部的优化求解我在里面用yalmip工具箱建模调用cplex或gurobi求解。yalmip语法非常简洁关键部分长这样function [P_buy, P_sell, E_lease, cost, SOC] MG_optimization(...) % 定义决策变量 P_buy sdpvar(1, T); % 向配电网购电功率 P_sell sdpvar(1, T); % 向配电网售电功率 P_ch sdpvar(1, T); % 储能充电功率 P_dis sdpvar(1, T); % 储能放电功率 E_lease sdpvar(1, T); % 租用的储能容量 P_MT sdpvar(1, T); % 燃气轮机出力 % 约束条件 Constraints []; % 功率平衡 Constraints [Constraints, P_PV P_WT P_MT P_dis P_buy ... Load P_ch P_sell]; % 储能约束 SOC sdpvar(1, T1); Constraints [Constraints, SOC(1) ESS_soc_init]; for t 1:T Constraints [Constraints, SOC(t1) SOC(t) ESS_eta_ch*P_ch(t) ... - P_dis(t)/ESS_eta_dis]; end Constraints [Constraints, SOC ESS_soc_min, SOC ESS_soc_max]; Constraints [Constraints, SOC(T1) ESS_soc_init]; % 目标函数 Objective price_buy * P_buy - price_sell * P_sell ... lambda_lease * E_lease ... fuel_cost_coeff * P_MT * P_MT; % 求解 options sdpsettings(solver, cplex, verbose, 0); optimize(Constraints, Objective, options); cost value(Objective); end这里有个容易忽略的坑储能放电效率和充电效率不对称时SOC递推公式里除的位置要特别小心η_dis放在分母上是正确的因为放电时实际从电池取出的能量要大于输送到电网的能量。很多Matlab代码跑完SOC越界多半是这个系数放错了。4. 算例分析与结果解读4.1 测试系统与场景设置我在复现这套代码时搭建了这样一个测试系统3个微电网接入同一个配电网节点共享储能容量1000kWh最大充放电功率250kW每个微电网配置光伏300kW、风电200kW、燃气轮机500kW。负荷曲线峰值分别设置在早上、中午和晚上故意错开这样做是为了体现共享储能的互补优势——A微电网中午光伏多了存进共享储能B微电网晚上缺电时再放出来给它用。价格参数方面配电网从上级购电采用分时电价峰时1.2元/kWh平时0.8元/kWh谷时0.4元/kWh。配电网卖给微电网的电价初始设置为上级电价的1.2倍从微电网收购电价设置为上级电价的0.8倍储能租赁单价初始0.1元/kWh。算例对比三组场景一是各微电网独立自建储能基线二是多个微电网共享储能但不考虑博弈、按平均成本分摊三是本模型的租赁共享储能加博弈定价。从总运行成本看场景三比场景一降低了约18%比场景二降低了约7%这部分经济性提升来自储能利用率提高和电价引导削峰填谷的效果。4.2 关键结果图表绘制代码运行完后plot_results.m会画出四类关键图第一是各微电网24小时购售电计划柱状图最直观能看出每个微电网什么时候从配电网买电、什么时候反送电。这里我建议用堆叠柱状图区分燃气轮机出力、光伏出力、风电出力和购电功率一眼就能看出系统功率平衡关系。第二是共享储能的SOC曲线和充放电功率曲线SOC曲线应该是一条平滑的波浪线峰值不超过上限末尾回到初始值。如果SOC曲线出现“台阶状跳变”说明储能功率没有限幅或者SOC递推有误这个图是排查储能模型错误的第一现场。第三是价格迭代收敛过程。横轴迭代次数纵轴电价数值你会看到价格曲线从初始值开始波动大约10到20轮后逐渐平稳。这里提醒一句如果价格曲线来回震荡不收敛优先检查步长把步长从0.2降到0.05试试。第四是博弈前后各主体收益/成本对比表。图表输出建议统一用Matlab的sgtitle加子图模式保存成png分辨率调到300dpi论文插图可以直接用。4.3 各主体经济性对比与讨论我把三组场景下的结算结果整理成表格数值是我跑完代码后记录的代表性数据具体数据会随随机种子和参数变化方案配电网净收益元各微电网总运行成本元储能利用率%循环次数各微电网自建储能—42860单微电网均值约1.2次共享储能平均分摊6200362802.3次共享储能博弈定价9480331901.9次注意博弈定价方案的配电网收益明显高于平均分摊因为价格信号引导微电网在谷时多购电、峰时少购电配电网从低买高卖中获利。微电网总成本也降了因为电价信号帮助它错峰用电降低了燃气轮机的燃料成本。这就是博弈论“双赢”的体现不是压榨某一方而是通过价格引导达到整体更优的状态。储能利用率上博弈方案反而是1.9次比平均分摊的2.3次略低这其实是个值得注意的细节一味追求储能高利用率并不等于经济最优博弈定价下部分时段电价低微电网更愿意直接买电而不是花租赁费去用储能这是理性的选择也说明模型真正抓住了“租赁”这个机制的经济学本质。5. 常见问题与调试经验5.1 迭代不收敛或震荡这是最多人问的问题。现象是电价曲线上下翻飞或者gap值一直降不到阈值以下。我踩过的坑和解决方案按优先级排列第一步长因子过大。默认值0.2在3个微电网的小系统里没问题但微电网数量到5个以上时购电总量基数变大同样的步长会导致价格调整幅度过大。建议按N_MG的规模缩放步长step 0.1 / sqrt(N_MG)。第二没有限制电价更新范围。价格上下限必须在代码里写死比如售电价不能低于购电成本、不能高于燃气轮机发电边际成本否则价格会被“顶”到极端值下一轮功率响应巨大必然震荡。可以加一个平滑函数或者限幅器price_new min(max(price_new, price_min), price_max);第三初值离均衡点太远。这个好解决用上级分时电价的1.1倍做初值而不是随便设一个收敛会快很多。5.2 yalmip建模时的约束报错Constraints [Constraints, SOC(1) 0.5]这类赋值约束最容易出问题如果SOC变量维度写错比如定义成sdpvar(1,T)却访问了SOC(T1)yalmip会直接报维度不匹配错误。排查方法很简单在优化前用size(SOC)检查变量维度yalmip的报错信息通常会给出行列数对着改就行。另外储能充放电互斥约束如果用了二进制变量在迭代求解框架下会显著拖慢速度因为每次迭代都要解MILP问题。如果对SOC曲线的“同时充放”不是特别敏感可以去掉互斥约束让目标函数自发抑制同时充放电因为同时充放会产生无谓损耗成本上升这样能把问题从MILP降为LP计算时间能缩短一个量级。5.3 求解器与Matlab环境问题yalmip本身不求解它是建模语言底层需要Gurobi、CPLEX等求解器。这套代码默认调cplex如果你的机器没装会报“No solver found”。两个解决办法一是装cplex并配置好addpath路径二是把solver改成gurobi或quadprog如果问题没有整数变量改一行就行options sdpsettings(solver, gurobi, verbose, 0);版本方面我分别用Matlab R2021b和R2023a测试过yalmip用2023年3月之后的版本都没问题。提醒一下yalmip的旧版本对R2023a有兼容性问题建议直接去yalmip官网下载最新包。5.4 快速验证代码正确性的小技巧每次改完模型先跑一个“降级测试”把微电网数量设为1共享储能变成一个普通本地储能博弈退化成单主体优化这时候结果应该和传统单微电网调度几乎一致。如果对不上说明模型里有结构性错误尽早暴露。这个技巧帮我节省了大量排查时间。另一个技巧是打印“功率不平衡量”在sdpvar求解后计算sum(P_PV P_WT P_MT P_dis P_buy - Load - P_ch - P_sell)理论上应该是0如果有较大的残差超过1e-6级别说明约束条件写漏了一条。6. 个人体会与扩展方向共享储能和博弈调度这个方向我刚接触时最大的感受是“主体一多复杂度就不只是加法”。如果只是写单微电网调度一个优化问题解完就结束了思路非常线性。但加了配电网作为领导者加了租赁定价机制问题马上就立体起来你得回答一个核心问题价格怎么定既能让储能运营商有动力投建储能又能让微电网有动力参与共享这套代码采用的迭代求解策略注定不会像单层KKT那样一锤定音但它在工程上是有效的尤其是做教学演示和中小规模系统直观性强调试也方便。你在这个框架基础上可以做不少扩展比如把确定性场景换成随机场景考虑光伏出力的不确定性用鲁棒优化或者把单时段时间粒度扩到15分钟研究更精细的调度再上升到分布式架构用ADMM替换主从迭代能实现隐私保护这个方向也是目前学术界的热点。如果你想把这套代码真正用在项目里我个人建议从改参数开始比如把3个微电网改成5个把储能容量改大改小观察结果变化。等到你把每个参数的敏感性都摸清楚了再动“羊肉串的签子”——也就是改模型结构比如把租赁模式改成“容量电量”两部制收费或者把单层博弈改成多领导者多跟随者博弈那时候你才算真正吃透了这块内容。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询