拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

冷热电联供系统多目标优化实战:NSGA-II建模与调参全记录

冷热电联供系统多目标优化实战:NSGA-II建模与调参全记录

做综合能源系统优化这几年,冷热电联供(CCHP)一直是我觉得最有嚼头的方向。单个设备的热力计算不难,但把燃气轮机、余热锅炉、吸收式制冷机、电制冷机、储能装置捏成一个整体,再让它同时满足冷、热、电三种负荷的需求,还要在运行成本、碳排放、一次能源利用率之间找一个最佳平衡点,这才是真正的硬骨头。网上讲CCHP原理的资料很多,但真正能把多目标算法落到工程算例上的分享很少。这篇东西不是教科书翻译,是我自己从建模、跑算法到调参、踩坑的完整记录,适合正在做微电网/综合能源调度、或者毕业论文选这个方向的同学参考,也欢迎有工程经验的朋友一起交流。

1. 冷热电联供系统的能量流与运行优化难点

1.1 系统的基本组成与能量耦合关系

先把这个系统的家底盘清楚。典型的冷热电联供型综合能源系统,核心发电设备是燃气轮机或者燃气内燃机,燃料一般是天然气。燃料进去之后,一部分变成高品位电能,直接供给电负荷或者卖给电网;剩下的余热从排气、缸套冷却水等地方跑出来,这部分低品位热能如果直接排掉,一次能源利用率撑死也就40%上下。所以联供系统的关键就是把余热捡回来:通过余热锅炉产生蒸汽或热水,冬天直接供暖,夏天驱动吸收式制冷机供冷,或者通过换热器供生活热水。

为了实现多能互补,系统里通常还会配一些辅助设备。电制冷机(压缩式制冷)用来补冷缺口,燃气锅炉用来补热缺口,蓄水罐或者蓄冰槽用来平抑冷热负荷波动,储能电池用来削峰填谷。这就形成了一个“输入侧多种能源、中间多能转换、输出侧冷热电台”的复杂能量流网络。我在做仿真时习惯先把能量流图画出来,核心节点就是母线:电母线、热母线、冷母线、天然气母线,所有设备的输入输出都挂在对应母线上,这样后面的建模会清晰很多。

这个系统的核心耦合点在天然气到电和热的转换比例上,燃气轮机的热电比基本是固定的(比如某型机额定热电比1.2),但实际负荷需求是波动的,因此会产生“以热定电”还是“以电定热”两种经典运行策略。前者优先满足热负荷,发电量作为副产品;后者反之。在真实的综合能源系统里,单纯用一种策略都太僵化,多目标优化就是要在不同运行模式下动态找最佳设备出力组合。

1.2 为什么要做多目标优化而不是单目标

很多初学者上来就问:直接让运行成本最小不就行了吗?问题是,只看钱会把系统带入一个极端工况:为了省钱,尽量多发电、多利用余热,但可能造成碳排放增加,或者为了满足峰值冷负荷把吸收式制冷机开得很大,结果高温季节余热不够用还得烧锅炉。反过来如果只追求碳排放最低,又可能过度依赖电制冷,导致运行电费非常高。这就是典型的多目标冲突。

以我跑过的算例为例,某园区一天的电负荷峰值约3.5MW,冷负荷峰值约2.8MW,热负荷峰值约1.2MW。如果单纯最小化运行成本,算法倾向于让燃气轮机全年满载发电,余热优先供冷,不够再用吸收式补,结果CO2排放量比纯网购电还高,因为天然气燃烧排碳不低。如果单纯最小化碳排放,算法又会倾向于低谷时段大量网购电,甚至牺牲余热利用,导致成本飙升。所以必须用帕累托最优的思路,找出成本、碳排放、能效之间的一组最优折中解,再由运营者根据自己的偏好去选。

多目标优化的另一个价值是能看到系统运行的“边界”。得到的Pareto前沿上每个解都对应一组设备出力方案,你可以观察前沿两端:成本最低解长什么样,碳排放最低解长什么样,中间折中解长什么样。这样就能为实际调度提供策略储备,比单目标一锤子买卖实用得多。

2. 多目标优化建模:目标函数、决策变量与约束条件

2.1 目标函数怎么设计才不跑偏

建模型的第一步是定目标函数。冷热电联供系统的目标函数常见有三个:运行成本、CO2排放量、一次能源利用率(或者一次能源消耗量)。我个人不建议把能效直接当最大化目标,因为它跟成本和排放往往是强耦合的,容易让算法把解全部堆到一个区域,所以我一般用成本和排放两个目标作为主目标,能效作为后处理指标来分析。

运行成本模型要包含四块:天然气购气费用、向电网购电费用、售电收益(如果有余电上网)、设备运行维护费用。表达式各区域电价结构差异很大,我用的典型分时电价是峰段1.1元/kWh、平段0.7元/kWh、谷段0.4元/kWh,天然气价按2.5元/m3(低位热值按9.7kWh/m3折算)。设备维护成本按出力比例系数估算,燃气轮机取0.03元/kWh,吸收式制冷机取0.01元/kWh,电制冷机0.008元/kWh,储能电池充放电损耗按0.05元/kWh折算。

碳排放模型要分清“直接排放”和“间接排放”。燃气轮机烧天然气是直接排放,按天然气含碳量计算,1m3天然气完全燃烧产生约2.1kg CO2;购电是间接排放,取决于电网排放因子,华东地区我习惯取0.6kg CO2/kWh。需要注意的是,这里面有个陷阱:如果系统在谷电时段购电,电网排放因子其实更低,但很多论文都用固定值,实际做工程测算时最好按分时段排放因子。

一次能源利用率(PEE)的定义是输出的总冷热电能量除以输入的化石能源总能量(折合一次能源)。电制冷机的能效比(COP)通常在3.0~5.5之间,但它消耗的电如果是来自天然气发电,那一次能源折算系数得默认电厂效率约0.4左右,千万别直接用COP去比。我在写文章时就吃过这个亏,后来统一按“一次能源折算系数”处理,电的折算系数取1/0.4=2.5,天然气的折算系数取1,这样才公平。

2.2 决策变量与约束条件的处理技巧

决策变量是智能优化算法直接操控的东西,选得好不好,直接决定求解速度和解质量。对于CCHP系统,常见的决策变量集合包括:

  • 燃气轮机各时段的发电功率Pgt(t)
  • 燃气锅炉产热功率Pgb(t)
  • 吸收式制冷机供冷功率Pac(t)
  • 电制冷机供冷功率Pec(t)
  • 储能电池充电/放电功率Pess_in(t)、Pess_out(t)
  • 蓄水罐/蓄冰槽蓄能/放能功率Pst_in(t)、Pst_out(t)
  • 与电网的交互功率Pgrid(t)(正为购电,负为售电)

如果时段数是24,变量数就是7×24=168个。对于遗传算法种群里的每个个体来说,这个维数不算高,但如果你把每个变量都直接用浮点数编码,搜索空间会巨大。我习惯做“分时优化”,把一天分成96个15分钟时段(更贴近实际调度),或者干脆24小时,但变量编码时用“运行模式”辅助降维:比如燃气轮机在峰段有满载/半载/待机三种离散档位,先把档位确定,再细化到连续功率。

约束条件分三类。第一类是功率平衡约束,包括电平衡(燃气轮机发电+储放电+购电 = 电负荷+电制冷耗电+储充电+售电)、热平衡(燃气轮机余热+燃气锅炉产热+储热放热 = 热负荷+热储充热)、冷平衡(吸收式制冷+电制冷+蓄冷放冷 = 冷负荷+蓄冷充冷)。第二类是设备出力上下限和爬坡约束,比如燃气轮机爬坡速率限制在额定功率的5%/分钟,储能电池SOC范围0.1~0.9,蓄水罐容量不能超限。第三类是逻辑约束,比如吸收式制冷机必须在有余热时才允许运行,储能不能同时充放。

处理约束最笨也最可靠的方法是惩罚函数法。但要注意惩罚系数不能设得太小,否则算法会大量产出不可行解。我的经验值是:功率平衡偏差每1kWh罚100元(相比目标函数里动辄几千上万的数值,这个量级能压住),SOC越界罚200元。这样算法前中期会主动避开不可行解,后期能快速收敛到可行域边界。

3. 算法选型与实现细节:NSGA-II与MOPSO的对比和调参实操

3.1 为什么NSGA-II依旧是首选

多目标优化算法很多,NSGA-II(带精英策略的非支配排序遗传算法)我强烈推荐作为第一个上手实现的对象。原因很现实:它代码成熟、资料多、可控性好,而且对CCHP这种中等规模、非线性、有约束的问题表现很稳。相比MODE(多目标差分进化)、MOPSO(多目标粒子群),NSGA-II的“拥挤度距离”机制能很好地维持Pareto前沿的均匀性,不会出现解扎堆的现象。

MOPSO训练速度确实快,但在CCHP这种强约束问题上容易陷入不可行域,因为它更新粒子时不太容易感知约束边界。我自己试过,MOPSO在某些时段功率平衡约束上反复越界,需要加额外的约束处理机制。NSGA-II因为有锦标赛选择和模拟二进制交叉(SBX),种群多样性保持得更好,更容易覆盖整个Pareto前沿。你要是追求论文丰富度,两个都写也没问题,但主线用NSGA-II,MOPSO作为对比算法,效果最稳妥。

3.2 关键参数设置与代码骨架

直接给一组我试过很多遍、效果稳定的参数。种群大小NP=100,迭代次数GEN=200,交叉概率pc=0.9,变异概率pm=0.1,模拟二进制交叉的分布指数eta_c=15,多项式变异的分布指数eta_m=20。这个组合在24时段的CCHP算例上,大约跑50次实验,Pareto前沿的覆盖率能稳定达到90%以上。注意,遗传算法的随机性很强,每跑一次结果都不一样,所以正式实验必须至少重复10次,取最好结果或者平均指标。

下面是一段核心流程的Python伪代码,我尽量保持简洁:

import random import numpy as np # 定义个体:每个个体是决策变量向量,长度为 n_var # 这里 n_var = 24 * 7(小时数 × 设备数) def evaluate(individual): # 返回目标向量 [cost, emission],内部需要做约束判断 cost = calc_cost(individual) emission = calc_emission(individual) constraint_violation = calc_violation(individual) return [cost, emission], constraint_violation def init_population(NP, n_var): pop = [] for _ in range(NP): # 每个变量在合理范围内随机初始化 ind = [random.uniform(low[i], high[i]) for i in range(n_var)] pop.append(ind) return pop def sbx_crossover(parent1, parent2, eta_c=15): # 模拟二进制交叉,返回两个子代 pass def polynomial_mutation(child, eta_m=20, pm=0.1): # 多项式变异 pass def fast_non_dominated_sort(population, objectives): # 非支配排序 pass def crowding_distance(front): # 计算拥挤度距离 pass # 主循环 pop = init_population(100, 168) for gen in range(200): # 选择、交叉、变异生成子代 # 合并父子代,快速非支配排序 + 拥挤度选择 pass

这个骨架跑通之后,后面最重要的是目标函数和约束的实现,因为算法本身都是现成的,工程问题才是灵魂。

3.3 NSGA-II与MOPSO的对比实验心得

我做过一组对比:同一套CCHP系统参数,NSGA-II跑200代和MOPSO跑200代,三个性能指标:世代距离(GD)、反世代距离(IGD)、超体积(HV)。NSGA-II的IGD均值是0.032,MOPSO是0.057;HV方面NSGA-II约0.78,MOPSO约0.66。这说明NSGA-II在收敛性和分布性上整体优于MOPSO,但代价是运行时间多了约40%(100个体×200代,NSGA-II约8分钟,MOPSO约5分钟,都是普通笔记本环境)。

不过MOPSO不是没有优点,它在目标函数计算量小的时候,迭代速度优势很明显。如果你用的是简化模型(比如设备效率为常数、不考虑爬坡约束),MOPSO完全够用。从论文写作角度,建议把两种算法的Pareto前沿画在同一张图里,标注HV和IGD,直接用数据证明选型合理性,审稿人挑不出毛病。

4. 完整算例实现:从负荷数据到Pareto前沿

4.1 典型园区24小时负荷曲线设定

我以某类工业园区为背景,设置一个典型的夏季工作日场景。电负荷曲线在早8点后开始爬升,14点达到峰值为3.5MW,凌晨低谷为1.1MW;冷负荷因为太阳辐射和机器散热,在13点到16点达到峰值2.8MW,夜间几乎为零;热负荷主要是生活热水和部分工艺用热,夏季相对平坦,维持在1.0~1.2MW。储能电池容量为1.5MWh,初始SOC为0.5,最大充放电功率0.5MW;蓄水罐容量为6m³(等效冷/热容量约12kWh),蓄热/蓄冷功率上限为0.3MW。

燃气轮机选择一型典型机组:额定发电功率2MW,热电比1.3,调节范围0.3~1.0额定功率,效率按负载率拟合:η_e = 0.25 + 0.15 * λ(λ为负载率)。余热回收系数取0.8,吸收式制冷机COP为1.2,电制冷机COP为4.0,燃气锅炉效率0.9。电网交互功率上限1MW,允许余电上网,上网电价为0.35元/kWh。

这里要提醒一个关键点:负荷曲线的数据颗粒度直接影响优化结果。如果用24小时整点数据,冷负荷峰值可能被平滑掉,导致制冷设备选型偏小。我建议至少用15分钟数据,或者一天96点,虽然计算量会增大,但结果更可信。

4.2 结果分析:Pareto前沿长什么样

跑完200代之后,得到的Pareto前沿是一组大约15~20个非支配解。横轴是运行成本(元/日),纵轴是CO2排放量(kg/日)。前沿形状通常是倒L形,左下角是理想点,但实际最优解位于曲线上。

以其中一个折中解为例:当日运行成本约1.38万元,CO2排放量约8.6吨。设备调度特征如下:燃气轮机在8点到20点保持高负载运行,其余时段部分负载;电制冷在14点到17点与吸收式制冷共同供冷,电制冷承担约40%冷负荷;储能电池在凌晨低谷充电、上午和晚间放电;蓄水罐在夜间蓄冷,下午释放。这种调度方案既利用了天然气的低价优势,又避免了峰段高价购电,同时由于燃气轮机效率在高负载区较高,碳排放也控制在了可接受范围。

成本最低解则完全“以电定热”:燃气轮机全天满载上网卖电,成本降到1.2万元/日,但排放升到9.8吨/日;碳排放最低解则减少燃气轮机出力,多用谷段电,排放降到7.9吨/日,成本却涨到1.56万元/日。这个对比就非常直观地呈现了多目标之间的冲突。

4.3 从Pareto前沿到单一决策:TOPSIS选解

实际项目里最终只能执行一个方案,这时候不能拍脑袋从中挑一个点。我常用TOPSIS(逼近理想解排序法)做决策。具体做法是:先把Pareto前沿上每个解的各个目标值做归一化处理,然后确定正理想解(成本最小且排放最小,通常不存在)和负理想解,再计算每个解到正理想解和负理想解的欧氏距离,按照接近度排序,选最接近正理想解的那个点。

举个例子,上述三个典型解的TOPSIS打分结果,折中解0.72最高,成本最低解0.51,排放最低解0.49。也就是说折中解是最贴合“同时压低成本和排放”这个偏好的。如果你更看重成本,可以给成本目标赋权重0.7,排放0.3,重新计算;更看重环保就把权重反过来。这就是多目标优化真正落地到决策的过程,比简单加权单目标更科学。

5. 常见问题与排查技巧实录

5.1 冷热电负荷匹配严重失衡怎么办

这是我遇到最多的问题:算法跑出来的解,燃气轮机余热在夏天根本不够供冷,导致吸收式制冷机利用率极低,系统退化成了“燃气轮机+电制冷”,完全失去联供的意义。根源在于冷负荷峰值和电负荷峰值可能不在同一时刻,而燃气轮机额定热电比是固定的,导致余热供应曲线和冷负荷曲线对不上。

解决思路有三条。一是在建模中引入“补燃”环节,允许在余热不足时用燃气锅炉直接产热驱动吸收式制冷,扩大热源灵活性;二是配置蓄冷罐,在夜间负荷低谷时段用吸收式制冷蓄冷,白天峰值时段释冷,时间解耦;三是在目标函数中加入“联供收益率”或“余热利用率”作为软约束,鼓励算法优先利用余热。我实际试下来,加蓄冷罐的效果最明显,冷负荷满足率能从78%提升到96%。

5.2 算法过早收敛,Pareto前沿分布性差

如果跑完200代,Pareto前沿上的点只集中在一条狭长区域,说明种群多样性出了问题。原因通常是交叉概率太低或者选择压力过大。我踩过的一个坑是:为了加速收敛,把锦标赛选择人数从2改成4,结果种群快速同质化,到第50代左右就完全收敛了,前沿极度稀疏。

排查技巧是先看每一代的种群多样性指标(比如平均拥挤度距离),如果它在不到一半迭代次数时就跌到接近零,说明参数设置不合理。修复方法:把锦标赛人数调回2,交叉概率提至0.9,并且对变异概率做自适应调整——迭代初期变异概率0.15,后期降到0.05,保证前期充分探索、后期精细开发。另外,初始化种群时可以有意加入一些“极端解”,比如全购电解、全自发电解,让种群一开始就覆盖搜索空间两端。

5.3 约束处理导致解不可行的疑难杂症

功率平衡约束的惩罚函数,最怕出现“所有解都不可行”的局面。有一次我把惩罚系数调得过高,结果算法宁可产出功率严重不平衡的解(因为目标函数值小)也不愿意违反设备上下限,实际算下来电量平衡误差达到几百千瓦。后来我改成“按违反了几个约束分别记惩罚”,并且对每个约束单独设阈值,比如功率不平衡允许±50kW软区间,在这个区间内不罚,超出才按比例罚。这样算法有了缓冲区,收敛稳定性明显提升。

还有一个细节:SOC的终值约束。储能电池调度一天后SOC如果和初始值不一致,在长期运行中会累积偏差。我通常加一个“SOC日终恢复约束”,要求最终SOC在0.48~0.52之间,否则罚200元。这个约束很有效,能避免算法把储能当成免费能量来源。

6. 个人经验与后续扩展方向

6.1 一个容易被忽略的数据陷阱

所有优化结果都建立在负荷预测数据上,但负荷预测不可能100%准。我在实际项目中习惯在优化后做“滚动修正”:把24小时优化变成4小时滚动优化,每跑一次只执行未来4小时的前1小时指令,然后重新用实时负荷数据更新模型。这种模型预测控制(MPC)思路比一次性离线优化更抗扰动,尤其在冷热负荷突变时,系统能及时调整设备出力。

6.2 设备寿命和维护成本要不要进模型

很多文章把维护成本当作常数系数,但真实燃气轮机的维护周期和高负载运行强相关。如果你想更精细,可以把维护成本建模成出力的二次函数,或者引入启停次数惩罚。我做的一个算例中,加入启停惩罚后,燃气轮机的启停次数从每天6次降到了3次,运行成本只增加了2.3%,但设备寿命预期明显延长,从全生命周期看更划算。这个维度对业主非常有吸引力,写论文也是个不错的创新点。

6.3 后续可以怎么扩展

多目标算法不是万能的,但在这个问题上还有不少可延伸的空间。一是目标函数可以加入“可再生能源消纳率”或“负荷预测误差最小化”,如果你的系统里还有风机和光伏的话。二是在算法层面,可以用改进的NSGA-III或基于分解的多目标进化算法(MOEA/D)处理高维目标。三是我最近在尝试把强化学习引入到这里面的日常调度里,用多目标视角做奖励函数设计,比传统元启发式算法更快。以后如果跑出有意思的结果,再来和大家分享。

返回列表