做微网能量管理的人,迟早会碰到一个问题:当园区里不仅有运营商在统筹调度,还有一批各自算账的光伏用户、储能用户时,集中式优化那套“一个目标函数管到底”的思路就开始失灵了。我们课题组去年就是在这个背景下,用合作型Stackelberg博弈把整套微网能量管理重做了一遍,代码已经整理成可复用的工程。这篇博文就当作一份详细的功能说明来写,从模型落到代码的映射关系、目录结构和核心函数,到复现实验要改哪些参数、实际调试会遇到哪些坑,尽量一次讲透。如果你正在复现主从博弈相关的论文,或者想给自己的微网优化项目加一个多主体的对比基线,这篇文章应该能帮你省下不少时间。
1. 为什么微网能量管理场景里要用博弈而不是单纯集中优化
1.1 集中式优化在多主体共存的微网里为什么推不动
传统微网能量管理系统(EMS)的典型做法,是把整个微网的所有可调资源丢进同一个优化模型,目标函数通常是“全系统运行成本最小”或者“碳排放最小”,约束涵盖功率平衡、储能SOC、机组爬坡、联络线功率限制等等。只要微网的所有设备产权归属同一个运营主体,这套做法是没问题的,Gurobi一把梭,几分钟出结果,调度指令下发执行即可。
但分布式光伏和储能大规模铺开之后,场景变了。现在一个园区微网里,运营商和用户不再是“上下级”关系,而更像“平台和租户”的关系。用户装了光伏,白天想自用,余电想卖个好价钱;用户装了储能,更希望低充高放套利。运营商关心的则是峰时少从电网买高价电、尽量通过内部调度降低整体购电成本。这两个目标方向并不天然一致——你让用户在晚高峰多放电,用户会想“我凭什么牺牲自己的套利机会听你调度”。集中式优化缺少一个关键机制:激励相容性。它只能假设用户服从指令,却无法回答“用户为什么要服从”。
这个问题的本质是:能量管理从“单主体决策问题”变成了“多主体交互问题”。单主体优化只要找全局最优解,多主体交互则必须考虑每个主体的理性行为。一个很自然的建模工具就是博弈论,而Stackelberg博弈恰好对应“运营商先出价格、用户后做响应”的真实市场逻辑。
1.2 Stackelberg主从结构恰好匹配“运营商定价格、用户做响应”
Stackelberg博弈又叫主从博弈,核心结构是:领导者先行动,跟随者观察到领导者的行动后再做最优反应,领导者做决策时要把跟随者的反应函数考虑进去。放到微网里,领导者就是微网运营商或售电公司,它公布未来24小时的内部分时售电价/购电价;跟随者是各个用户,它们拿到电价之后,各自求解自己的用能优化问题,决定购电曲线、储能充放电曲线、可平移负荷的安排。
这种结构跟真实世界的价格引导机制是同构的:运营商不直接命令用户“你必须几点充几点放”,而是通过价格信号引导用户改变用电行为。用户有自主权,运营商有定价权,双方在均衡点达成一致。相比集中式优化,这套机制天然具备可落地性——因为每个用户确实是在自己的目标函数下做选择,不存在“指令不执行”的问题。
代码层面,这种结构也很清晰:上层循环由运营商的价格迭代驱动,下层循环是一组彼此独立的用户优化子问题,天然适合并行求解。这也是我选择用Stackelberg而不是单纯集中式做微网能量管理的原因之一:模型逻辑和代码结构能够严格对应,调试时非常直观。
1.3 “合作型”到底改了什么:从纳什均衡走向帕累托改进
但纯Stackelberg有一个短板:它假设跟随者之间各自独立、互不合作。这在用户数量少、彼此用电行为差异大的场景下问题不大,可一旦用户同质化程度高,就会出现集体次优。举个例子,运营商把凌晨低谷电价定得很低,结果10个用户全把储能安排在凌晨同一时段充电,形成一个新的负荷尖峰,运营商不仅没削峰,反而造了峰。
合作型Stackelberg的关键变化在于:在保持“运营商做领导者、用户做跟随者”这一主从结构的同时,允许跟随者群体内部形成合作联盟,共享部分资源(比如共享储能、P2P电量交易),并且把合作产生的额外收益按照一定规则分配给各用户。这样既保留了价格引导的主从机制,又让用户之间通过合作实现帕累托改进——整体成本下降的同时,每个用户的成本都不比独立时更差。
代码实现上,“合作”不是重新写一套博弈,而是在原Stackelberg迭代收敛后,增加一个收益分配模块:先算出“合作前各用户独立最优总成本”,再算出“合作后联盟最优总成本”,差值就是合作剩余,然后用Shapley值或Nash谈判把它分掉。下面两章就分别讲模型怎么映射到代码,以及这些模块具体长什么样。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 合作型Stackelberg模型从数学公式到代码映射
2.1 上层领导者模型与下层跟随者模型的变量和约束
先看上层。运营商的决策变量是24个时段的内部售电价 $\lambda_t^{sell}$ 和内部购电价 $\lambda_t^{buy}$,如果简化一点就只定一个净电价 $\lambda_t$。目标函数是运营商收益最大化:收益等于用户购电费收入,减去运营商从上级电网买电的成本,再减去向用户买电的支出。约束条件包括:电价不能超过政府目录电价上下限,避免运营商乱定价;如果运营商还运营共享储能,那还要加上储能的充放电约束和SOC递推约束。
代码里对应的是一个 MarketOperator 类的核心逻辑。它内部保存电价上下限、购电成本曲线、共享储能参数这些字段,核心方法就是 update_price() 和 compute_revenue()。这里有个很多人容易忽略的细节:上层模型的目标函数里会出现“电价乘以用户购电量”这种双线性项,如果直接套数学公式写进Gurobi,会得到一个非凸二次约束,求解很痛苦。迭代法之所以好实现,就是因为每一轮电价是固定值,用户购电量是求解回来的常数,相乘之后只是普通算术,不存在非线性求解问题。
下层就是每个用户的用能优化问题。给
