做综合能源市场仿真的朋友应该都有同感:单独做电市场出清还好,单独做热网调度也不难,一旦把电、热通过能源集线器耦合起来,再放到市场框架里做双层出清,模型复杂度和求解难度都会上一个台阶。这篇文章就结合我最近在MATLAB里落地的一个算例,聊聊如何建立并求解考虑能源集线器参与的电热综合能源市场双层出清模型。文中会讲清楚建模逻辑、数学转换、MATLAB代码框架、求解器配置以及我踩过的坑,希望能给正在做相关课题的同学省点时间。需要说明的是,这里不会直接丢一个“一键运行”的完整程序,而是把思路和关键代码骨架讲透,你拿到之后可以按自己的算例往里填参数。
1. 双层出清要解决什么问题:从集中式优化到Stackelberg博弈
电热综合能源系统里有两类主体:一类是市场运营商,负责组织电力、热力交易并给出清价格;另一类是以能源集线器为代表的产消者,内部有CHP、电锅炉、燃气锅炉、储热罐等设备,可以根据市场价格调整购电、购气和热电产出。如果所有信息都集中到运营商手里,那本质上就是一个集中式最优能量流问题,单层优化就能解。但实际市场环境下,能源集线器有自己的运行目标和隐私边界,它不会把自己内部所有约束和成本曲线全部交给运营商,运营商只能通过市场机制去预测和引导它的行为。
这时候就需要用双层模型来描述。上层是市场出清问题,运营商以社会福利最大或系统购能成本最小为目标,决定常规机组出力、外购电量、热源出力和节点价格;下层是能源集线器运行优化问题,它把市场价格作为已知参数,以自身运行成本最小化为目标,决定从电网买多少电、从气网购多少气、内部各设备怎么出力。上下层通过价格和交易量耦合,形成典型的Stackelberg博弈结构。上层是领导者,先公布价格和出清方案;下层是跟随者,在给定价格下做最优响应。市场出清结果必须满足这样一个性质:在出清价格下,能源集线器没有单方面改变用能计划的动机,也就是下层一定处于最优状态。
单层优化和双层优化的本质区别就在这里。单层优化里,所有决策变量放在一起求系统总成本最小;双层优化里,下层主体的目标函数并不一定和上层完全一致,下层有独立利益,不能简单合并。举个例子,运营商希望系统总购电成本最低,所以想让能源集线器在某个时段多用电;但能源集线器自己还要权衡购气和购电的价格,如果电锅炉的用电成本比燃气锅炉的用气成本更贵,它就不会按运营商的意愿增加用电。这个博弈关系如果不显式建模,出清结果要么不可行,要么会让某个主体亏损退出市场。
我刚开始做这个题目的时候,也想过能不能用“上层出清-下层优化-再上层出清”的迭代法,类似不动点迭代。实际试下来,问题很大:价格和出清数量是同时决定的,迭代过程经常在两个解之间震荡,尤其当能源集线器容量占比高、价格弹性明显时,即使加了阻尼系数也很难收敛。后来老老实实把下层问题用KKT条件替换进上层模型,转成单层数学规划,再用商业求解器求解,这才稳定下来。这个“双层转单层”的过程,是整份代码最核心、也最花时间的部分,后面的章节我会专门展开。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 能源集线器建模:设备方程与耦合约束怎么写进MATLAB
能源集线器是整个模型的“心脏”,这一层建不好,上层出清再漂亮也没有用。建模的关键不是堆设备,而是把能量流关系、设备约束、储热动态这三件事用线性或可线性化的方程表达清楚,否则后面的MILP化会遇到大麻烦。
2.1 先画物理图,再写能量平衡方程
我在写代码前一定会先在草稿纸上画一张能源集线器能量流图:输入端是电网购电和天然气购买,输出端是电负荷和热负荷;内部设备至少包含CHP机组、燃气锅炉、电锅炉和储热罐。CHP消耗天然气,同时产电和产热;燃气锅炉消耗天然气只产热;电锅炉消耗电能产热;储热罐负责热功率的时段搬移。
以第h个能源集线器在时段t为例,简化后的能量平衡方程可以写成:
text复制电网购电Pbuy + CHP产电Pchp + 分布式光伏Ppv = 电负荷Dem_e + 电锅炉消耗Peb + 储热充电功率Hch - 储热放电功率Hdis
CHP产热Hchp + 燃气锅炉产热Hgb + 电锅炉产热Heb + 储热放电Hdis - 储热充电Hch = 热负荷Dem_h
CHP的产电、产热由天然气输入共同决定,写成效率形式:
text复制Pchp = eta_chp_e * Fchp
Hchp = eta_chp_h * Fchp
Hgb = eta_gb * Fgb
Heb = COP_eb * Peb
其中Fchp和Fgb分别是CHP和燃气锅炉的天然气输入功率,eta_chp_e、eta_chp_h分别是CHP的发电效率和余热回收效率,eta_gb是燃气锅炉热效率,COP_eb是电锅炉制热性能系数。
很多新手会在CHP的模型上翻车。CHP的产电和产热不是两个独立变量,它们来自同一个天然气输入,所以必须用效率比把两者耦合起来。实际代码里我习惯用Pchp作为主变量,Hchp用eta_chp_h / eta_chp_e乘以Pchp得到,这样变量数量少,数值尺度也一致。燃气锅炉和电锅炉则独立建模,它们之间通过热平衡发生竞争关系。
2.2 设备约束、爬坡约束和储热动态
设备不能无限出力,也不能瞬时改变出力。容量约束分别写:
text复制0 <= Pchp <= Pchp_max
0 <= Fgb <= Fgb_max
0 <= Peb <= Peb_max
0 <= Pbuy <= Pbuy_max
CHP和电锅炉还需要考虑爬坡约束,尤其当时间尺度是小时级时,爬坡约束对市场价格响应的影响非常明显:
text复制-Pchp_ramp <= Pchp(t+1) - Pchp(t) <= Pchp_ramp
-Peb_ramp <= Peb(t+1) - Peb(t) <= Peb_ramp
储热罐是能源集线器里最有意思的部分,它让热负荷在时间上有了弹性。状态量用SOC表示:
text复制SOC(t+1) = SOC(t) + eta_ch * Hc
