ARTICLE DETAIL

资讯详情

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

冷热电联供系统运行优化:MOPSO如何平衡成本与碳排放

冷热电联供系统运行优化:MOPSO如何平衡成本与碳排放 做冷热电联供型综合能源系统的运行优化最容易栽在“看起来简单”的坑上。去年我接到一个园区能源站的项目需求提得很直白每天运行成本压下来碳排放也要尽量少。听起来就两个目标可真开始建模就会发现它们在很多时段是打架的——多发电可以少买电、甚至上网卖钱但机组负荷率一低单位电量的燃气耗量和排放反而更难看少从电网买电听起来低碳可本地机组一旦顶着上限跑多余的热和冷又没地方去照样是浪费。这套项目最后是用多目标粒子群算法MOPSO解决的对24小时逐时出力寻优目标函数里同时放进运行成本和CO₂排放约束条件覆盖电、热、冷三种负荷平衡和各设备的运行区间。跑完多组典型日数据得到的不是单个“最优解”而是一整条帕累托前沿。成本和排放的真实折衷关系摆在桌面上决策层终于可以按自己的偏好挑方案而不是被一个权重值绑架。这篇文章会把整个建模过程、算法实现细节、实测对比和踩坑经验完整写出来希望给正在做综合能源调度、又不太清楚多目标优化怎么落地的朋友一些够直接、能上手的东西。1. 冷热电联供系统的优化调度先拆清楚要优化什么CCHP系统说穿了就是一套设备同时出电、热、冷三种能量。常见的园区级配置里燃气轮机或燃气内燃机先发电燃烧产生的高温烟气进余热锅炉变成蒸汽或热水一部分直接送采暖一部分进吸收式制冷机制冷发电不够就并网购电电多了还能上网卖冷负荷不够时电制冷机顶上来。如果再配蓄热水箱、蓄冷罐那灵活性还会再上一个台阶。1.1 联供系统的能量流与设备关系能量流具体是这样走的天然气进入燃气轮机发电发电后的乏气、缸套水余热进入余热回收装置。余热优先满足采暖热负荷和吸收式制冷机组的驱动力。吸收式制冷机组把热量转成冷水供冷电制冷机组则直接耗电制冷冷水。电网侧负责兜底本地发电不足就购电本地发电富余就尝试上网售电。这套系统里最关键的耦合点在“余热”和“温度品位”。燃气轮机一开机电和热几乎是同时出来的用户要的电越多产生的余热也越多但余热总量和热负荷需求并不能总是对上。供热需求低的时候大量余热只能通过散热器白白放掉这就造成“发电多反而浪费大”的怪圈。供热需求高的时候余热不够还要补燃锅炉额外烧燃料排放又上去了。所以运行优化的核心其实是在这种刚性耦合里把每一时段的设备出力安排到最合理的位置。1.2 调度问题的变量、目标与约束把一天划成T个时段常见是24点或者96点再定义决策变量燃气轮机/内燃机每个时段的电出力P_gt(t)。补燃锅炉的热出力Q_boiler(t)。吸收式制冷机的制冷量Q_ac(t)电制冷机的制冷量Q_ec(t)。从电网购电/售电的功率P_grid(t)。目标函数是两个运行成本最小燃气费用加上购电费用再减去售电收益。CO₂排放最小本地燃气燃烧直接排放加上外购电折合的间接排放。约束条件则是这套系统的“物理边界”电功率平衡机组发电 购电 - 售电 电负荷 电制冷耗电 其他自用电。热功率平衡余热回收 补燃锅炉出力 热负荷 吸收式制冷机耗热。冷功率平衡吸收式制冷 电制冷 冷负荷。设备出力的上下限和爬坡率约束。机组最小启停时间如果模型精度要求更高还要加上这个。为什么要拆得这么细因为只有把每个时段的能量平衡写成等式约束才能把“调电就会连带着调热”这个本质耦合暴露出来。燃气轮机的热电比不是固定的负荷率高的时候单位发电量的烟气和余热更充足负荷率低的时候余热总量少单位电量的热耗反而升高。如果在模型里把这个关联简化掉优化结果交给运行人员基本没法用。2. 为什么我在这个项目里放弃了单目标加权改用MOPSO最早我用的方法也是大多数论文里常见的那套把成本和排放分别归一化然后乘以权重变成一个目标函数再丢给粒子群或者遗传算法去跑。跑了一段时间后发现这条路在工程决策上根本走不通。2.1 单目标加权法的两个致命问题第一个问题是要权重怎么定。成本和排放两个量纲完全不同不归一化直接加权没有意义归一化之后权重还是拍脑袋定的。决策者说“成本和排放各占一半”听着很公平但算出来的“最优解”其实什么都不代表。你只要把权重从0.5换成0.6方案就可能从“多用电网电”跳变到“多用本地气电”这种不连续非常让人头疼。第二个问题是目标之间的矛盾被掩盖了。举个项目里遇到的实际例子某个午间时段电负荷60kW热负荷只有30kW燃气轮机刚好落在低效区间。单看成本最优策略很可能是不开机直接从电网买电单看排放如果外购电的排放因子很高反而应该顶着低效运转开机。两个策略都有道理但哪个“更优”取决于电价、气价、排放因子这些外部条件。加权法只能告诉你“按这个权重A比B好”却没法告诉决策层“你们每多减排一公斤CO₂要额外付出多少钱”。这个“换汇率”信息只能从帕累托前沿上读出来。2.2 MOPSO相比NSGA-II等算法的选择理由可能有人会问为什么不直接用NSGA-IINSGA-II在学术界应用非常广多样性保持机制也成熟但我这边最后选了MOPSO主要原因是CCHP调度问题的决策变量绝大多数是连续功率值粒子群在这种连续搜索空间上天然友好。两者对比下来差异大致是这样对比维度MOPSONSGA-II实现复杂度较低核心算子少中等需要非支配排序和拥挤度计算收敛速度在连续变量问题上通常更快相对慢一点需要更多代数多样性保持需要额外设计外部档案和网格策略自带拥挤度距离机制对离散变量的处理需要通过取整或映射处理二进制编码时更自然参数敏感性惯性权重和加速系数需要调交叉变异概率相对不敏感我实测下来500个粒子跑500代MOPSO处理24时段的典型日调度只要几分钟得到的帕累托前沿在分布均匀性上并不输给同运算量下的NSGA-II。做工程项目迭代速度很关键因为你可能要反复跟决策者讨论“这个解为什么是这样”每次讨论都要重新跑模型。后面相关内容里我会重点讲外部档案怎么维护、多样性怎么保持这些都是MOPSO能不能用好的关键。3. 建模与目标函数设计把成本和排放算清楚再动手很多算法文章喜欢一上来就写优化方程但真正决定结果靠谱程度的是设备模型。设备模型偏了算法再好也是白搭。3.1 设备特性与运行区间怎么建模我当时项目里用的一套典型参数是这样燃气轮机额定功率300kW发电效率曲线近似为二次多项式低负荷40%时效率大约0.24满负荷时效率能到0.32。余热回收系统按燃气轮机烟气余热与发电出力的关系建立曲线热电比大致在0.9到1.1之间波动。补燃锅炉效率取0.85出力范围0到500kW。吸收式制冷机组COP取1.3电制冷机COP取4.0。天然气低热值按9.7kWh/Nm³单价3.2元/Nm³。电网分时电价峰时1.0元/kWh平时0.65元/kWh谷时0.35元/kWh上网电价固定0.4元/kWh。外购电排放因子按当地电网公开数据取0.85 kg CO₂/kWh。这些数字看起来琐碎其实每一个都直接影响优化结果。比如燃气轮机效率曲线很多简化模型把它当常数这会导致低负荷时段的调度方案严重失真。实际机组在低负荷下效率掉得很快如果模型里不体现算法就会倾向于让机组频繁在低出力运行而真实运行里这会带来很高的单位发电燃料成本。3.2 成本、排放两个目标如何量化运行成本目标可以写成C C_gas C_buy - C_sell燃气费用按每个时段的耗气量乘以天然气单价来计算购电费用按购电量和分时电价相乘售电收益则按上网电量乘以上网电价。排放目标写成E E_gas E_grid燃气燃烧排放按实际燃气消耗量乘以排放因子电网间接排放按外购电量乘以电网排放因子。这里要注意联供系统的燃气排放如何分摊到电和热上在学术上有不同的方法可以简单把总排放都算在发电头上也可以用热焓分摊法还有按收益分摊的。不同的分摊方法会改变帕累托前沿的形状但不会改变优化框架。我项目里用的是“总排放直接汇总”的方式因为决策者要的是整个能源站对外部环境的净影响。3.3 为什么成本和排放总是“打架”算一笔简单的账就明白了。按燃气轮机效率0.32算每发1kWh电需要消耗约3.125kWh燃料折合的天然气量大概是0.322Nm³成本约1.03元/kWh直接排放约0.625kg CO₂/kWh。如果这台机组的余热还能被利用比如同时带出约1kWh热量那这部分经济性和环保效益就不一样了。这时候和电网购电对比一下电网电价谷时只要0.35元但排放因子是0.85。所以“成本最优”和“排放最优”经常给出相反的指令电价低谷且热负荷低时低成本方案会倾向停掉机组、直接买电但低排放方案可能会因为本地气电排放更低而坚持开机。电价高峰且热负荷高时两个目标罕见地达成一致——本地联供机组既便宜又低碳这时候优化算法会毫不犹豫地让机组满负荷跑同时把余热全部利用起来。换句话说成本与排放的冲突不是模型造出来的而是外部电价、气价和电网排放因子之间关系造成的。这个认知非常重要因为后面你观察帕累托前沿时如果某个区域前沿特别稀疏往往不是因为算法没搜索到而是这个时段目标方向天然一致。4. 多目标粒子群算法的实现细节框架大家都懂真正区分一个项目能不能落地的是实现细节。我把我最后采用的方案完整写出来供参考。4.1 粒子编码、初始化与约束处理首先是编码。我的做法是只把真正需要寻优并且互相之间没有直接关联的变量放进粒子剩下的变量由能量平衡方程反推。这样能大幅降低搜索维度也避免大量不可行粒子。粒子的每个维度由以下变量组成每个时段燃气轮机电出力。每个时段吸收式制冷机制冷量。每个时段电制冷机制冷量。至于电网购电功率是由电平衡方程推出来的补燃锅炉的热出力是由热平衡方程推出来的。这种“变量消元”的办法等于把等式约束自动满足掉了。比如先给定P_gt电平衡里其余都是已知量或已决策量那么P_grid就唯一确定不需要再专门作为粒子维度去搜索。不等式约束比如设备出力上下限我用的是最朴素的钳位处理粒子越界就拉回边界。对热平衡里出现的“余热过剩”问题我加一个松弛量代表散热损失并且在目标函数里给这个松弛量一个很小的惩罚。这样物理上说得通算法也不会被逼到死胡同。初始化采用随机生成加局部校正先随机生成燃气轮机的初始出力如果超出技术出力范围就钳位到范围边界然后校验补燃锅炉反推是否越界越界则重新随机。这块逻辑虽然不起眼但非常影响粒子群前期的收敛速度。4.2 外部档案维护与多样性保持MOPSO和单目标粒子群最大的区别就是需要一个外部档案保存历史上找到的所有非支配解。档案容量不可能无限大所以多样性保持是核心。我用的是网格法实现很直接把两个目标值分别归一化到[0,1]。在每个目标维度上划分20个等宽网格。每个粒子根据目标值找到自己落在哪个网格。档案里的解如果超过容量上限就优先删除“人多”的网格里的解。选择全局最优引导时先按概率挑一个稀疏网格再从网格里随机选一个解。这个“稀疏网格优先”的策略非常关键。如果总是选目标值最小的解当全局最优粒子群很快就收敛到帕累托前沿的某一段另一区域的解永远不会被发现。用网格稀疏度来引导等于逼着粒子往还没探索过的地方跑。伪代码大概是这样# 多目标粒子群算法主循环伪代码 初始化粒子位置X、速度V 评估每个粒子的目标值和约束 把非支配解存入外部档案A for gen in range(MAXGEN): for i in range(N): # 从A的低拥挤度网格中随机选全局最优 gbest_i select_low_density_member(A) # 速度更新 V[i] w*V[i] c1*r1*(pbest[i]-X[i]) c2*r2*(gbest_i-X[i]) X[i] X[i] V[i] # 边界钳位 约束校验 X[i] clamp(X[i]) # 评估 fitness_i evaluate(X[i]) # 更新个体最优支配则替换互不支配则比较拥挤度 if dominates(fitness_i, pbest_fitness[i]): pbest[i] X[i] elif not dominated_by(fitness_i, pbest_fitness[i]): pbest[i] X[i] # 随机更新或按拥挤度 # 更新外部档案 A update_archive(A, X[i], fitness_i) # 网格维护 A prune_archive(A) # 惯性权重线性递减 w w_max - (w_max - w_min) * gen / MAXGEN惯性权重w从0.9线性降到0.4加速系数c1、c2都是1.8。这个参数组合在多组测试里表现很稳。w取太高粒子容易在边界附近震荡取太低前期搜索范围不够后期又容易陷入局部。如果要做更精细的调节可以考虑非线性递减或者自适应但对CCHP调度这种规模的问题线性递减已经够用。4.3 帕累托解集的最终决策算完一遍外部档案里可能有几十上百个非支配解运行人员不可能一个个看。怎么挑我用的方法是模糊隶属度法也叫“折衷解选择”。对每个解k分别计算它在每个目标上的隶属度μ_m(k) (f_m_max - f_m(k)) / (f_m_max - f_m_min)这里f_m_max和f_m_min是指帕累托前沿上第m个目标的最大值和最小值。然后对每个解求平均隶属度S(k) (1/M) * Σμ_m(k)S(k)越大说明这个解在多个目标之间整体越均衡我最后给决策者看的默认推荐方案就是S最大的那个解。当然如果决策者明确说“多花20%成本可以排放必须压到最低”那就直接看帕累托前沿靠排放端的解。整个项目的优势正在这里——不是替决策者做选择而是把所有可选项摆出来让他把自己的偏好量化进去。5. 典型日仿真结果帕累托前沿带来的选择空间只讲算法不讲结果是耍流氓。我挑了冬季典型日来说因为这个场景最能体现热电联供的耦合。5.1 测试场景与参数设置冬季典型日负荷大致有这些特点早晚电采暖负荷高白天略低热负荷全天都很高尤其是清晨冷负荷接近零吸收式制冷机可以不开只靠余热供热。负荷数据按24时段给出我就不贴整张表了这里列几个有代表性的时段时段电负荷kW热负荷kW冷负荷kW0:004521008:00160220014:00120140020:001752100可以看到热负荷非常大而且要命的是有些时段电负荷并不高机组如果只满足电需求热就不够如果为了追热让机组高负荷运行电又会过剩只能往电网上卖。粒子数量取500迭代500代外部档案容量100网格划分数目20。整个仿真在我们一台普通工作站上跑大约3分钟。5.2 三组解的结果对比我跑完后从帕累托前沿里挑了三组有代表性的解方案运行成本元/天CO₂排放kg/天机组平均负荷率购电比例成本最优解421526500.6838%排放最优解483018100.8612%折衷解446821900.7922%这组数据本身就是很好的决策材料。成本最优解在中午和夜间电价低谷时段大量购电燃气轮机只在电价高峰时段跑低负荷率导致单位发电效率下降排放自然高。排放最优解则尽量让燃气轮机承担基荷即使电价低谷也少从电网买电机组平均负荷率上去了单位电量排放降下来了代价是燃气费明显增加。折衷解相当于每多花约1.6元就能比成本最优解少排约1公斤CO₂。决策者看到这个数比看到一堆权重参数有用得多。5.3 几个值得注意的运行规律第一目标方向一致时段和冲突时段强烈分化。电价高峰和热负荷高峰重合时寻优结果几乎只有一个选择燃气轮机满负荷运行余热全部吸收补燃锅炉尽量少开。帕累托前沿在这些时段几乎没有分支说明目标不冲突算法怎么跑都是同一个方向。真正让前沿发散开的是电价低谷和热负荷偏低的时段。第二排放目标会显著改变电网交互行为。排放最优解在谷时段的购电比例只有12%因为外购电的排放因子0.85高于本地气电在低负荷时的排放。这个结论依赖当地电网的清洁能源比例如果未来电网排放因子降下来帕累托前沿会整体往左下方移动到时候可能连排放最优解都会变成“多用网电”。第三如果把蓄热装置加进去成本还能进一步压降。蓄热水箱可以在机组高负荷放电时把多余的热存下来等机组停机时再释放。加了蓄热后成本折衷解从4468降到了约4100降幅相当可观。代价是决策变量多了一个时段的蓄放热功率搜索空间变大MOPSO的收敛时间也略有增加但仍在可接受范围内。6. 实测中的坑与工程化改造建议最后把实际项目里踩过的坑和改动思路整理出来这些是最容易让“论文算法”变成“废纸算法”的地方。6.1 等式约束的惩罚与修复策略如果直接用惩罚函数处理平衡等式会遇到一个很恶心的问题惩罚系数小了粒子可以靠着违反平衡来拉低目标值档案里全是不可行解惩罚系数大了可行域之外的目标梯度非常陡粒子搜起来像在爬悬崖。我最后的做法是“变量消元为主修复为辅”前面已经提到过让P_grid、Q_boiler由平衡方程直接算出来等式约束理论上恒成立。但实际操作里还是会出现“补燃锅炉计算值为负”的情况这时候我会做一个两步处理如果Q_boiler算出来是负的就把所有多余余热标记为散热损失并在这个时段的成本里加一笔散热惩罚代表物理上要开散热器。散热损失过大时说明粒子给出的机组出力组合不合理这个粒子大概率会在下一轮被支配解淘汰。对不等式约束动态惩罚系数也是好用的技巧初始阶段惩罚系数取小值让粒子大胆探索后期逐步加大逼着所有粒子收敛到可行域。这样既保证了多样性又保证了最终档案里所有解都是工程可用的。6.2 目标冲突最严重的时段怎么处理实测里会发现有些时段帕累托前沿非常薄甚至几乎没有。最容易出现这种情况的是平电价、中负荷时段燃气轮机的成本和外购电价接近排放又和电网排放因子接近两个目标基本不冲突所以无论怎么选都差不多。不要试图靠调整算法来解决这种“瘦前沿”。更关键的是要检查是不是模型里少了某些实际约束。比如很多园区实际情况是燃气轮机不能频繁启停或者有最低日运行时间要求。如果没有把这些约束加进去算法给出的解可能在每个时段看都合理但连起来就是“白天开机、夜里停机、早上再开”这种运行人员完全无法接受的方案。加上最小启停时间约束后帕累托前沿会自动变化一些原来看似可能的调度组合会消失留下来的才真正可执行。6.3 从离线优化走向滚动时域调度离线优化的结果再漂亮也不能直接交给运行系统。真实负荷一直在波动光伏如果并网了出力也是随时变化的。我们的最终落地方式是在项目环境里做滚动时域优化每15分钟触发一次重计算。用最新预测数据替换最近24小时的电、热、冷负荷序列。只执行第一个时段的调度指令到下一个15分钟再重新优化。滚动优化的好处是误差不会累积因为每15分钟都会拿真实值重新校准。但代价是计算必须在几分钟内完成。MOPSO在这种场景下的优势很明显500粒子×500代对24时段的算例我用向量化处理基本能在3分钟以内跑完留出足够的时间做预测和数据质量控制。如果现场控制器算力有限还可以先离线把典型场景的帕累托前沿全部算好存成指令表在线时按当前负荷和电价在表里做最近邻匹配。这个思路特别适合那些不能接受任何延迟的场合。最后再分享一个排查收敛问题的小技巧。很多人看算法收敛只看帕累托前沿画出来的两条曲线是不是差不多这个判断非常不靠谱因为前沿形状往往看不出微小变化。我建议跟踪超体积指标HV也就是帕累托解集与参考点之间围成的目标空间体积。HV从第400代到第500代的变化小于0.5%同时极值点不再明显移动这时候基本可以认为收敛了。如果HV根本稳不下来别急着加迭代代数先回头检查惩罚系数和网格划分数多半是多样性保持的参数出了问题。这也是MOPSO这套方案最后能够稳定落地而不是停在仿真报告里的重要原因。
返回列表