你有没有接过这样的仿真任务:一个园区里既有电负荷,又有冬季供暖和夏季制冷需求,燃气轮机烧天然气发电,排出的高温烟气不舍得扔,经过余热锅炉回收变成蒸汽,一部分直接供热,另一部分送给吸收式制冷机制冷水,再配上燃气锅炉和电制冷机兜底,末端还有一套电转热设备用来消纳多余电力。整个系统怎么分配出力,才能又省成本又满足负荷?这就是冷热电综合能源系统优化调度要解决的核心问题。
这个标题里的配置非常典型,几乎是国内高校课题组和设计院里最常见的CCHP(冷热电三联供)系统架构。燃气轮机、燃气锅炉、余热锅炉、电制冷机、吸收式制冷机、电转热,一个都不少。我做过的几个项目里,至少有三次拿到的是几乎一模一样的设备清单,只是负荷数据、能源价格和算例场景不同。这篇文章我就把这类系统的优化调度从建模到求解完整拆一遍,讲清楚每一台设备的数学表达、目标函数怎么设计、约束怎么列、用什么方法求解,以及我在实际调试中踩过的那些坑。
如果你正在做类似的仿真、写论文或者从零搭一个园区级优化调度Demo,这篇文章可以作为一份直接抄作业的参考。文章里不会贴大段完整代码,但会把建模思路、线性化技巧、求解器选型和排错经验讲透,照着这个思路写代码,基本不会走大弯路。
1. 冷热电综合能源系统优化调度,到底在解决什么问题
先把系统结构捋清楚。燃气轮机是整条能量链条的起点,它烧天然气发电,同时产生高温烟气。烟气直接排掉是巨大浪费,于是经过余热锅炉回收,把烟气热变成蒸汽或热水,这些热能一部分送到供热管网,另一部分驱动吸收式制冷机产出冷水。这样发电、供热、制冷就全部挂到了燃气轮机的余热回收链条上。
但只有燃气轮机这条主线还不够。园区负荷是随时波动的,夏天傍晚冷负荷可能突然升高,冬天清晨热负荷也经常顶上来,单靠余热回收的热量不一定够用,也不一定匹配电负荷的比例。所以系统里还会配置燃气锅炉作为补热来源,电制冷机作为冷负荷的兜底手段,电转热设备则负责在电力充裕时把电变成热,起到灵活调节和新能源消纳的作用。
设备一多,调度问题就来了。燃气轮机的发电量和产热量是耦合的,多发电往往伴随更多余热,但园区电负荷和热负荷又不总是同步变化。电价在不同的时段有峰谷差,天然气价格基本固定,这就意味着同样的负荷曲线,按照不同的设备出力分配方案运行,一天下来的运行成本可能差不少。我们要做的优化调度,就是在满足冷热电负荷、设备出力上下限、爬坡速率等一系列约束的前提下,决定每个时段每台设备“开多少出力”,让总运行成本最低,或者在引入低碳目标后让综合经济性最好。
这个问题的本质是一个带连续变量和0-1整数变量的混合整数规划问题。连续变量是每台设备的出力大小,整数变量是设备的启停状态。时间粒度一般取1小时,一天24个时段,这样一个典型的园区算例大概会包含数百个连续变量和上百个整数变量。问题规模不算大,但对于刚上手的人来说,真正的门槛不在求解器能不能算出结果,而在模型本身能不能建得对、约束写全了没有、线性化处理是不是足够精确。
这类优化调度从应用角度讲,既适合做园区级的能量管理策略研究,也是综合能源系统规划设计阶段的基础工具。你可以在同一个模型框架下,通过调整设备参数和价格参数,对比“三联供+燃气锅炉+吸收式制冷”和“纯电制冷+燃气锅炉”哪种配置更划算,也可以把它扩展成带储能、带光伏、带碳交易约束的复杂系统。所以花时间把基础模型啃下来,后面扩展就是加变量、加约束的事,不会推翻重来。
2. 设备建模:把每一台机组写进数学里
设备建模是整个优化调度的地基。模型太粗,调度结果参考价值低;模型太细,非线性项太多,求解器直接被拖垮。我在实际建模时遵循一个原则:用“准确说得清楚、线性化起来不难”的精度去刻画每台设备,不追求连燃烧室的燃烧效率曲线都复现出来。
2.1 燃气轮机:整个系统的心脏
燃气轮机的核心关系是燃料消耗、发电出力与余热产出之间的转换。通常建模时先给定发电出力P_GT,然后按发电效率算出燃料消耗:
F_GT = P_GT / η_GT,e
其中F_GT是单位时间的天然气消耗量(单位可按kW或MW热值表达),η_GT,e是发电效率。这个效率在额定工况下最高,部分负载时效率会下降。如果建模精度要求不高,可以取一个恒定效率;想做准一点,就把负载率区间切成几段,每段用一条线性关系拟合效率,也就是分段线性化。
余热产出部分,我用的是“热电比”的思路。燃气轮机生成的热量Q_GT,余和发电量P_GT之间有关系,很多型号的热电比在0.5到1.2之间波动。简单模型写成:
Q_GT= r_GT × P_GT
其中r_GT热电比。更严格的做法是把余热写成发电量和燃料消耗量的函数,但那样会增加非线性项。对于常规调度算例,固定热电比再加一个小范围波动上下界,已经足够指导运行策略了。
燃气轮机的约束我一般列四类:出力上下限、爬坡约束、最小启停时间约束、以及启停状态与出力大小的互补约束。出力上下限和爬坡约束都是线性的,直接用线性不等式表达。最小启停时间约束写起来稍微烦一点,但本质上是用0-1变量约束连续几个时段的启停变量取值,属于混合整数线性规划里的标准写法。
实际操作中还有一个容易被忽略的地方:燃气轮机发电时,余热是“跟着排出来”的,即使热负荷很小,只要你发电,就必须产生那么多热量。这股热量要么被吸收式制冷机用掉,要么被余热锅炉制出的蒸汽供到热网,要么直接通过散热设备排掉,总之不能凭空消失。所以建模时必须加一条约束,让余热产出的去向被完全平衡掉,否则求解器会给你一个“只发电不产热”的假结果。
2.2 燃气锅炉和余热锅炉:补热和回收热
燃气锅炉是独立于燃气轮机的一条供热支路,天然气直接燃烧产热,模型最简单:
Q_GB = η_GB × F_GB
η_GB是锅炉热效率,可取0.85到0.95。约束就是供热出力上下限和爬坡限制,启停可以用整数变量控制。燃气锅炉没有“产热伴随发电”的耦合关系,灵活性比燃气轮机高很多,所以在热负荷高峰、而燃气轮机余热不够用的时段,由它顶上。
余热锅炉的逻辑在数学上和燃气锅炉是两回事。它不是独立“烧燃料”的设备,而是回收燃气轮机排出的高温烟气。模型写成:
Q_WHB = η_WHB × Q_GT,余
也就是说,余热锅炉的产热直接受制于燃气轮机的运行出力,是燃气轮机余热的一部分。它的效果是把烟气中的热“搬运”到蒸汽或热水系统中,效率η_WHB一般在0.75到0.85之间。
我见过不少新手把燃气锅炉和余热锅炉的模型写得一模一样,然后发现优化结果很不合理。原因是余热锅炉必须跟随燃气轮机走,它自己的出力上限可以设一个较大范围,但实际产出受上游烟气量限制,你必须在约束里把这条链条传递下去:燃气轮机发电 → 产生烟气热 → 烟气的一部分进入余热锅炉 → 余热锅炉产热 → 进入热网或吸收式制冷机。这一步传递关系漏掉,就等于默认余热是免费的、无限的,调度的结果当然是拼命开燃气轮机发电赚电费,然后热随便扔,成本核算完全失真。
2.3 电制冷机和吸收式制冷机:冷负荷的两条供应路线
制冷设备里,电制冷机用的是电能,吸收式制冷机用的是热能。两者的模型都是“输入能量 × 能效比 = 制冷量”:
Q_EC = COP_EC × P_EC
Q_AC = COP_AC × Q_H,AC
电制冷的COP(制冷性能系数)通常在3到5之间,吸收式制冷的COP则在0.6到1.2之间。单看数值,电制冷明显更高效,但它消耗的是高品位电能;吸收式制冷用的是系统里现成的余热,如果这部分热本来就是发电的副产品,那使用它的边际成本接近零。
所以两条制冷路线的调度优先级不是固定不变的,而是取决于系统状态。燃气轮机高负载运行时段,余热充足,吸收式制冷多出力;电价低谷时段,电制冷机多开,把电转化成冷,同时减少燃气轮机出力;电价高峰时段,又回到吸收式制冷的低成本路线。这个切换逻辑正是优化模型的价值所在,也是我在算例分析里最喜欢拿来讲解的部分。
制冷机组还有一个共性问题:COP不是恒定的。尤其是吸收式制冷机,在部分负载率很低时COP会明显下降,在60%到80%负载区间效率最高。论文里如果直接在COP上乘一个常数,结果会偏乐观。我的做法是给COP乘以一个分段线性修正系数,或者直接在制冷量上下限上收紧范围,不建议为了简化把COP设成函数形式,因为那会引入非线性,给求解增加不必要的负担。
2.4 电转热设备:灵活消纳的电热转换器
标题里的“电转”,按常见园区配置指的通常是电转热设备,最典型的就是电锅炉,也可能包含热泵。电锅炉的模型更简单:
Q_EB = η_EB × P_EB
电锅炉效率很高,普遍在0.95到0.99之间,几乎可以把输入的电能全部变成热。它最值得建模的点在于给系统提供了“用电产热”的通道,这个通道在两种时刻特别有用:一是电价低谷时段,用便宜电制热,比燃气锅炉烧气更经济;二是系统里如果接入了光伏或风电,在电负荷低而新能源出力高的时段,电锅炉可以消纳富余电力,避免弃风弃光。
扩展一步,有些研究把“电转”写到电转气(P2G),也就是电解水制氢,再把氢和二氧化碳合成甲烷。P2G的模型就不是简单的电热转换了,它涉及电解槽效率、储氢罐、甲烷化反应等多个环节,变量和约束都会成倍增加。如果标题限定在冷热电联供场景,我建议先把电锅炉这种电转热设备建好,P2G作为扩展方向保留即可,别一上来就把问题复杂度拉满。
3. 优化调度模型:目标函数、功率平衡与运行约束
设备模型处理好之后,下一步是把它们组装成一个完整的优化问题。这里的关键是目标函数怎么设计、平衡约束怎么列、设备约束怎么和启停变量衔接。组装顺序一旦错了,后续排查会非常痛苦。
3.1 目标函数怎么定:经济性优先,碳成本作扩展
最经典的运行调度目标函数是日运行总成本最小,成本项包括:
- 燃料成本:所有燃烧天然气的设备,折算成天然气耗量乘气价
- 购电成本:从电网买电的费用,按分时电价计算
- 设备启停成本:燃气轮机每次启动要花燃料、设备寿命损耗,按单次启停成本计入
- 运行维护成本:按出力大小线性计费,一般取一个小系数
把这些项写成数学形式,目标就是:
min C_total = Σ_t ( C_gas × F_total,t + C_grid,t × P_buy,t + Σ_i (C_start,i × y_start,i,t + C_maint,i × P_i,t) )
其中t是时段索引,i是设备索引,y_start是启停0-1变量。写目标函数时要注意单位的统一,天然气消耗量、电量和热量都统一折算到同一个能量基准,购电功率和站内功率也最好都用kW或MW表示。
如果项目背景里需要体现碳排放约束,我会在目标函数里加上碳成本项:把外购电折算成间接碳排放,把天然气消耗折算成直接碳排放,乘以单位碳价。碳价参数化之后,你可以直接对比不同碳价水平下系统应该多自发电还是多购电,这个分析做出来挺有说服力,适合写在论文或者项目报告里。
3.2 冷热电功率平衡约束:三条平衡线必须同时满足
综合能源系统里,功率平衡是按能量类型分别建立的,三个独立的平衡方程,每个时段各写一次。
电功率平衡:
P_GT,t + P_buy,t = P_EC,t + P_EB,t + P_load,e,t
左边是供电量,右边是耗电量加上电负荷。如果你还考虑了售电到电网的场景,右边再加一项P_sell,t,同时目标函数里增加卖电收入。是允许向电网倒送电还是只允许单向购电,取决于你设定的并网模式,这个要在建模之前就定下来,不然后面约束条件会写得打架。
热功率平衡:
Q_GB,t + Q_WHB,t + Q_EB,t = Q_load,h,t + Q_H,AC,t
左边是产热方,右边是热负荷加上吸收式制冷机消耗的热量。注意吸收式制冷机消耗热量不是小数目,夏季制冷高峰时,它消耗的热量可能比建筑供暖热负荷还高,这条约束写漏了,冷负荷就凭空消失了。
冷功率平衡:
Q_EC,t + Q_AC,t = Q_load,c,t
左侧是制冷侧,右侧是冷负荷。三条平衡线在时间维度上逐时段耦合,所以整个模型是同时含有时间和能量类型两个维度的调度问题。
3.3 设备运行约束:别让优化算出“幻觉参数”
除了功率平衡,每台设备还需要加上自身的运行约束。出力上下限是显然要写的,比如燃气轮机的出力区间是[P_GT,min, P_GT,max],燃气锅炉是[0, Q_GB,max],电制冷机是[0, Q_EC,max]等。这里注意一个问题:设备的出力上下限并不是固定不变的,实际运行中存在“最小技术出力”的概念,尤其是燃气轮机,低负载率下燃烧稳定性差,调度模型中如果不给它设一个最小出力,优化器很可能让它运行在10%负载率,这在现实中根本做不到。
爬坡约束用于限制设备在相邻时段内出力的变化速度。写法是:
|P_i,t - P_i,t-1| ≤ R_i × Δt
R_i是该设备的爬坡速率,Δt是时间粒度,一般1小时。爬坡约束对燃气轮机比较重要,锅炉和制冷机响应速度快,爬坡限制可以放宽甚至不加。
启停约束方面,每台可调度的设备对应一个运行状态变量z_i,t。启停切换成本用y_start_i,t表示,需要满足y_start_i,t ≥ z_i,t - z_i,t-1。为了不让求解器在无意义时机频繁启停,我还会加最小开机时间和最小停机时间约束,比如燃气轮机开机后至少连续运行2小时,停机后至少停1小时。这类约束让调度结果更贴近实际运行规则,代价是增加了一些整数变量,但值得。
所有约束写完之后,检查一遍“变量维度一致性”非常重要。我在第一次做这类模型时,把热电比的单位搞错了,余热锅炉的产热量比燃气轮机的总燃料热量还大,求解器依然能跑出一个结果,但结果完全不能用。后来习惯养成了:每个约束写完,先手动代一个数进去验算一次量级是否正确,再丢给求解器。
4. 求解实现:从非线性模型到MILP落地
设备建模和约束组装完成之后,下一步就是怎么求解。这里绕不开两个问题:模型里所有表达式必须能被求解器处理,以及怎么选择合适的求解方案。
4.1 非线性项怎么处理:分段线性化是主力手段
仔细检查你会发现,燃气轮机的燃料消耗和发电效率如果写成了负载率函数,就会出现F_GT = P_GT / η_GT(P_GT)这样的非线性关系。目标函数里的效率分母上带着变量,这已经不是线性表达式了,求解器没法直接优化。
常规解法的第一步是“常量效率近似”,就是把η_GT当作固定值,直接用线性表达式F_GT = P_GT / η_GT_const。这种做法在负载率变化不大时误差很小,适合做方案对比。
如果要做更精细的研究,则用分段线性化:把P_GT的可行区间切成三段或四段,每段范围里用一条斜线拟合燃料消耗曲线。这个分段线性模型仍然是线性的,只是引入了额外的辅助变量和约束。与之类似,厂用电率、COP部分负载修正、储能充放电效率等非线性项,都是同一套处理逻辑。
还有一个容易踩坑的细节是“避免0-1变量和连续变量相乘”。比如想要表达“设备开机状态下出力才允许大于0”,新手容易写成P_i,t ≤ z_i,t × P_max,这个式子本身是线性的,没问题。但如果写成P_i,t = z_i,t × P_operating_i,t,把整数变量和连续变量直接相乘,就变成非线性的双线性项了,需要重构。能不用双线性项就不用,实在要用的话,引入大M法和辅助变量把它线性化。
4.2 求解器与建模框架选择:MATLAB还是Python
这类模型最成熟的求解分类是混合整数线性规划(MILP),所以求解器选择上,几款主流商业求解器或者开源求解器都可以胜任。我对新手的建议是:先不要纠结用哪款求解器,最重要的是把模型结构写清楚,变量、约束、目标函数逐段组织好,然后丢给求解器跑。
我自己常用的建模框架有两类。一类是MATLAB里的优化建模工具箱,把约束以矩阵形式拼装,调用商业求解器求解,适合已有MATLAB基础、团队里也熟悉这套工具的场景。另一类是Python环境下的优化建模库,配合开源求解器或者商业求解器内核使用。Python的好处是数据处理方便,负荷预测、结果可视化和主程序可以一条龙做下来,我现在新做项目时更喜欢这一套。
无论用哪种框架,代码组织都可以按这个模块化顺序来写:
- 数据模块:设备参数、负荷曲线、能源价格、碳排放系数
- 决策变量模块:连续变量和0-1变量声明
- 目标函数模块:按成本类型分项相加
- 约束模块:平衡约束、设备约束、逻辑约束分别成段
- 求解与结果输出模块:调用求解器、提取结果、画图
调试时我习惯逐模块打开、逐个约束注释掉来找问题。最开始时把目标函数先设成一个常量,只求解可行解,确认模型有解且量级合理后,再慢慢把目标函数加回来,这样定位问题会快很多。
4.3 求解慢怎么办:问题规模的三个关键控制点
求解性能方面,这类模型的主要压力来自整数变量。时间粒度越细、设备数量越多、最小启停时间越长,整数变量规模就越大。三个最有效的降规模手段是:
- 时间聚合:非尖峰时段把时间粒度从1小时扩展为2小时或4小时,对于日调度来说精度损失很小。
- 启动决策合并:如果当天只有一个明显的热峰和电峰,可以在目标函数里加一个软约束,避免设备频繁启停导致的变量膨胀。
- 求解精度设置:给求解器设置一个合理的MIP Gap,比如1%或0.5%,不追求全局最优证明,工程调度场景完全够用。
我做过一个包含四台机组、24小时、逐时约束的项目,最早MIP Gap设置到默认值,跑到一百多秒才收敛。后来把时间粒度在深夜时段合并、启动约束放宽,求解时间直接降到十秒以内,调度结果差异不到0.1%,工程上完全可以接受。
5. 一个典型算例:调度结果长什么样
理论讲完,用一个简化的典型夏日负荷场景把模型转起来。某园区场景的冷负荷峰值约2000 kW,电负荷峰值约1800 kW,系统配置为一台额定发电功率1200 kW的燃气轮机、一台额定热功率800 kW的燃气锅炉、一台余热锅炉、一台额定制冷量1500 kW的吸收式制冷机、一台额定制冷量1200 kW的电制冷机,以及一台额定热功率500 kW的电锅炉。电价采用峰谷平三段式,天然气价格按常见工业气价设定。
热负荷在夏季主要体现为生活热水和小部分工业用热,低谷在凌晨,峰值出现在早上和傍晚。冷负荷则从中午开始攀升,下午三四点达到峰值。这种情况下,优化调度给出的典型运行策略是:早上冷负荷还小的时候,燃气轮机维持较高负载,余热一部分供热、一部分驱动吸收式制冷,电制冷机低负载运行;到了下午冷负荷峰值,燃气轮机火力全开,吸收式制冷机尽量顶着上,电制冷机作为补充;晚间电负荷降下来、电价进入低谷时段,燃气轮机降低出力,电锅炉和燃气锅炉顶上供热,电制冷机承担更多冷负荷。
把这个运行曲线跟“燃气轮机恒功率运行加电制冷兜底”的常规策略对比,一天下来运行成本能低8%到12%,如果把峰时电价差再拉大,节省比例还会更高。所以这套模型的价值不只是理论上“优化”,而是真正能把分时电价、余热回收这些因素变成量化的省钱策略。
算例运行完之后,我还会做一次“热负荷敏感性分析”:把热负荷整体上浮20%,观察燃气轮机和燃气锅炉的出力变化,这能帮助判断系统里哪台设备的容量是瓶颈。这种分析写到项目报告里,会比单纯贴一张调度出力图更有说服力。
6. 常见问题与排查技巧实录
做这类模型十次有八次要跟各种莫名其妙的问题搏斗。下面这几类是我遇到最多、也最让新手头疼的情况。
6.1 模型提示不可行,怎么定位
模型无解在调试初期几乎天天发生。最常见的三个原因分别是:功率平衡约束两边写反、设备出力上限跟负荷量级不匹配、以及启停约束出现逻辑矛盾。比如燃气轮机的启动状态和出力上限约束写成了“开机才能出力,但停机也允许出力”,求解器会给出一个无解的模型。
我的排查方法是先用惩罚变量法:在每一条平衡约束的等式里都加一个“松弛变量”,目标函数里给松弛变量加上很大的惩罚系数。模型重新求解后,哪个松弛变量被赋值不为零,问题就出在哪一条约束上。这一步几乎是秒级定位效率,强烈推荐。定位之后把松弛变量删掉,把具体参数改对即可。
6.2 优化结果出现“设备空转”
有时候求解器给出的结果里,燃气轮机在热负荷为零的时段仍然开着,吸热机也在低负载运行,看着很傻。这种情况通常不是模型写错了,而是约束里漏了最小技术出力或者启停状态与出力范围的耦合。设备一旦开机,出力下限是额定容量的30%或者40%,所以哪怕热负荷很低,系统也不得不产那么多热。
还有一种可能是没有计散热阀。燃气轮机产生的余热如果实在用不完,在真实系统里可以走散热器排掉,这部分损失在模型里要有对应的约束或者成本项。如果不允许散热,优化器就把所有余热硬塞给吸收式制冷机和热负荷,结果看起来像“系统自己需要那么多冷”,实际上只是在满足平衡约束而已。我的做法是单独列一个“余热未利用”的冗余变量,并给它加上一个很小的成本系数,这样既保证模型可解,又不会扭曲主要目标。
6.3 负荷预测不准导致调度结果偏差
优化调度是在“给定的负荷曲线”上做的,如果负荷预测误差大,那调度方案跑出来也只是理论上最优,实际运行时会失衡。这方面我一般用滚动调度来解决:不是一次性求解全天24小时,而是每1小时或每2小时滚动一次,每次只取前一个到两个时段的调度结果下发执行。这样可以把负荷预测更新得更频繁,让调度方案始终跟随实际负荷变化走。
冷负荷预测尤其难做,它跟气象温度、太阳辐射、建筑围护结构热惰性都有关系。如果项目里有历史冷负荷数据,可以先做一个简单的线性回归模型预测当天冷负荷,再用滚动调度做修正,比直接拍一个恒定冷负荷靠谱得多。
6.4 求解器给出的结果跟论文数据差异大
你要是拿自己的结果跟论文里的结果对比,发现成本差挺多,先别急着怀疑模型错。很可能是参数基准不同:天然气低位热值取值、电价曲线、设备效率、负荷曲线形状,每一项都对结果影响很大。我遇到过同样一套模型,只是把天然气热值从42 MJ/kg改成35 MJ/kg,运行成本直接涨了十几个百分点。
所以项目交付时,一定要把所有参数基准写清楚。天然气热值、能源价格、设备效率、负荷数据来源,这些哪怕只在报告里占半页,也足够让后来者复现你的结果。这既是对读者负责,也是对自己负责。
结尾
最后说点我个人的体会。这类冷热电综合能源系统优化调度项目,数学上并不高深,核心就是设备建模、约束组装、线性化处理和求解器调用这一套流程。它的真正难点在于两点:一是对系统“能量流”的理解,你得清楚燃气轮机的余热去了哪、吸收式制冷机消耗的热从哪里来,链条断了任何一环,模型都会失真;二是排查问题的耐心,不可行、结果怪异、性能慢,这些问题90%都能靠前面说的松弛变量法和模块化调试解决。
另外我建议新手别急着加储能、加碳交易、加不确定性,先把最基础的CCHP模型做通,跑出一个合理的调度结果,理解每个成本项是怎么变化的,再一步步往上扩展。地基打好了,后面加光伏、加储能、加电转气设备,都是在既有框架上增加变量和约束的事。这套思路我用了很多年,每次拿到新的仿真项目都是这么推进的,希望对你也有用。