☰
需求响应与碳交易如何进入综合能源优化模型:24小时园区案例
2026/10/20 7:17:40 网站建设 项目流程

这两年做综合能源系统优化项目,最直观的感受是:如果优化模型里不带需求响应和碳交易,很多决策结论虽然能算出省了多少钱,但拿到实际业主面前会有一堆现实问题接不上。尤其碳中和这个大目标落到具体工程上,需求响应和碳交易已经不是概念,而是直接写进优化模型、直接影响设备出力曲线的约束条件。

这篇文章不谈宏观愿景,直接从代码角度拆一个典型的24小时园区综合能源优化问题,把需求响应(DR)和碳交易机制量化成目标函数里的费用项和约束条件,看看它们到底怎么改变能源供应决策。适合正在做综合能源、微电网、配网侧优化平台的朋友,也适合想弄懂这些机制如何落地的读者——有线性规划基础和一点Python基础就能跟上。

1. 综合能源系统优化:为什么“省钱最优”开始失效

1.1 从单一购能成本走向多能协同

综合能源系统(Integrated Energy System,简称IES)不是简单把光伏板、储能柜、燃气锅炉摆在一个园区里,而是让电、热、气、冷多种能量载体在运行层面互相配合。典型设备包括热电联产机组(CHP)、燃气锅炉、电锅炉、电化学储能、光伏等。过去做经济调度,目标函数就是一行字:最小化购电费加购气费,约束条件是设备容量和各级能量平衡。那时碳排放只是事后统计报表里的一个数字,不是优化模型的成员。

碳中和背景一压下来,情况变了。碳排放额度开始具备价格信号,电网侧对用户侧资源的调用越来越频繁,需求响应从“配合行政指令”变成了“市场化购买灵活性”。运营者手里的工具从“买卖能源”扩展到“买卖能源+买卖灵活性+买卖碳配额”。能源供应决策不再是一个纯成本问题,而是一个带排放约束和柔性资源调度的组合优化问题。

举个最直白的例子:以前一个园区晚上低谷电价两毛五,白天峰值电价九毛,优化逻辑就是让储能晚上充、白天放,再把电锅炉尽量安排在低谷时段。现在如果碳价每吨100元,外购电的隐含排放也要折算成成本,那么“低谷多充”和“高峰多放”的价差逻辑就要重新算一遍;用户侧还有一批准备响应调度的生产线,系统要在“调用需求响应付补偿”和“高峰期高价买电+付碳排放成本”之间做权衡。这才是当前项目里真正在优化的事。

1.2 优化模型的基本骨架

一个能落地的综合能源优化模型,通常包含以下几块:

  • 决策变量:各设备出力、储能充放电功率、购电购气量、需求响应调用量、碳交易量。
  • 目标函数:购能成本 + 需求响应补偿成本 + 碳交易支出/收益。
  • 约束条件:电/热功率平衡、设备容量上下限、储能SOC递推、需求响应资源边界、碳配额约束。

可以把它理解成:原来你只管“这个月水电燃气费最少”,现在多了一条“碳排放额度不能超,超了得花钱买”,还多了几个“允许你把用电任务从高峰期搬到低谷期”的选项。模型要一起回答:每个时刻从电网买多少电、从气网购多少气、CHP发多少电和热、储能充还是放、是否调用用户侧资源、碳配额要买还是要卖。

这种模型在数学上是线性规划(LP)或混合整数线性规划(MILP)问题。设备启停、储能同时充放互斥这类逻辑用整数变量表达,能量平衡、容量限制用连续变量表达。只要规模在几百个变量级别,用开源求解器几分钟内就能算完。

2. 需求响应:把“用户侧弹性”变成优化约束

2.1 价格型与激励型DR的差别

需求响应最常见的分法是价格型和激励型。价格型DR就是分时电价、实时电价这类信号,用户自己看着价格决定用不用电,优化中心不需要显式“请求”用户做什么,模型里只要分时电价设得合理,负荷自然会被引导到低谷时段。激励型DR则不同,系统运营商直接向用户购买“可调度权”:你允许我在某个时段把你的部分生产负荷挪走,我把补偿付给你。

工程项目的实际优化模型里,激励型DR更容易量化,因为合约上有明确的调用容量、补偿单价和响应窗口。本文代码案例就以激励型DR为主,把需求响应当作“负向功率”或“可平移功率”放进电功率平衡约束中。

用大白话说:需求响应就是把“用户侧的时间弹性”变成系统侧的可调度资源。峰的时段负荷太高,就从用户那里借走一部分;低谷时段系统有能力,就把借走的负荷还回去。

2.2 可平移、可削减负荷的建模要点

需求响应资源按响应方式可以分成两大类,建模姿势完全不同。

类型典型场景本质建模关键
可平移负荷喷涂线、充电桩、消毒设备把某时段的用电量搬到其他时段总量守恒、平移窗口限制
可削减负荷照明、空调、非关键工艺直接减少用电量单时段削减上限、补偿单价

可平移负荷有两个铁律:第一,总用电能量不能凭空多出来,移出去的量和移进来的量必须相等;第二,不是所有时段都能接收移入,比如深夜低谷可以接收,中午尖峰就不能接收,这是“平移窗口”约束。

可削减负荷相对简单,就是用户允许系统在某个时刻砍掉一部分用电,砍多少有上限,每砍一度电给固定补偿。在优化模型里,它直接减少该时段的电负荷需求。

这两类DR资源进入模型后,系统会自发地在“峰时购电成本+碳排放成本”和“DR补偿成本”之间比价。如果高峰买电的综合成本比补偿费还高,模型就会调用DR。

3. 碳交易:把“排放结余”变成调度收益

3.1 配额、实测排放、交易量三本账

碳交易进入优化模型,逻辑链条并不复杂。每个控排主体会拿到一个免费配额,这是允许你排多少吨二氧化碳的额度;实际运行后根据购电量、购气量乘以对应排放因子,算出实测排放;实测排放高于配额的部分必须去市场购买,低于配额的部分可以卖出获利。

在单周期优化里,这三本账可以全部量化成约束和费用项。外购电力的排放因子反映电网平均碳排放水平,天然气则按热值燃烧的碳排放系数折算。这两类排放源基本覆盖综合能源系统的主要排放渠道。

一个关键认知是:碳排放不是“限制死了不许排”,而是“超排要花多少钱”。碳价如果很低,优化器可能宁愿超排也不改变购电结构;碳价如果高到一定程度,系统自然会减少高排放的能源输入,比如减少高峰外购电,或让高能效的热电联产机组替代效率偏低的燃气锅炉。

3.2 碳交易成本进目标函数的线性化技巧

实测排放减配额,可能是正也可能是负。如果直接在目标函数里写碳价 * max(0, 排放-配额),就会出现一个不可导的max项,损害线性规划结构。工程里常用一个标准线性化技巧:引入两个非负变量,分别表示“买入碳配额量”和“卖出碳配额量”,再加一条等式约束。

核心就三行:

  • 变量碳买入量 >= 0
  • 变量碳卖出量 >= 0
  • 约束:实测排放 - 免费配额 = 碳买入量 - 碳卖出量

这样无论排放超了还是配额有富余,都映射到两个连续变量上。目标函数只需加上碳价 * (碳买入量 - 碳卖出量),减排结余就自然变成了收益。这套写法在碳排放约束类模型中非常常见,属于看一次就能记住的固定套路。

4. 完整模型与代码级实现:一个24小时园区案例

4.1 场景设定与假设参数

下面用一个虚拟园区案例把整套模型跑起来。园区包含一台燃气热电联产机组(CHP)、一台燃气锅炉、一台电锅炉、一套电化学储能和一组光伏。电负荷白天高、夜间低,热负荷相对平稳。设备参数基于常见工程范围设定,代表一套典型的分布式供能配置。

参数数值说明
电负荷峰值5400 kW出现在晚间用电高峰
热负荷1900~3500 kW白天工业用热偏高
光伏容量800 kW峰值出力约720 kW
CHP电效率/热效率35% / 50%输入燃气按低位热值折算
燃气锅炉效率90%用于补足热负荷缺口
电锅炉COP3.0谷电时段可参与供热
储能500 kW / 2000 kWh充放效率分别取0.95/0.9
外购电排放因子0.58 tCO2/MWh电网平均排放水平
天然气排放因子0.19 tCO2/MWh按燃气输入能量折算
日免费配额60 tCO2低于基线排放,形成约束

分时电价采用三费率:峰段0.9元/kWh、平段0.55元/kWh、谷段0.25元/kWh。天然气价取0.3元/kWh(按低位热值折算)。需求响应补偿设置为:可平移负荷每度0.6元,可削减负荷每度1.2元,上限分别为全天2000 kWh平移量和800 kWh削减量。碳价取100元/吨。

4.2 核心建模代码:变量、约束、目标

代码用Python实现,求解器采用开源线性规划库,核心代码框架如下。

from pulp import LpProblem, LpMinimize, LpVariable, LpStatus, lpSum hours = range(24) # 设备与价格参数(示例值,实际项目按实测数据替换) price_e = [0.25,0.25,0.25,0.25,0.25,0.25,0.35,0.5,0.7,0.8,0.9,0.9, 0.8,0.7,0.6,0.6,0.7,0.9,0.9,0.8,0.7,0.5,0.35,0.25] price_gas = 0.30 carbon_price = 100.0 grid_ef = 0.58 gas_ef = 0.19 quota = 60.0 # 决策变量 p_buy = LpVariable.dicts("p_buy", hours, lowBound=0, upBound=8000) # 购电功率 g_chp = LpVariable.dicts("g_chp", hours, lowBound=0, upBound=2000) # CHP燃气输入 g_boiler = LpVariable.dicts("g_boiler", hours, lowBound=0, upBound=1500) # 燃气锅炉输入 q_eb = LpVariable.dicts("q_eb", hours, lowBound=0, upBound=800) # 电锅炉热出力 p_chg = LpVariable.dicts("p_chg", hours, lowBound=0, upBound=500) # 储能充电 p_dis = LpVariable.dicts("p_dis", hours, lowBound=0, upBound=500) # 储能放电 soc = LpVariable.dicts("soc", hours, lowBound=400, upBound=1800) # 储能电量 kWh d_out = LpVariable.dicts("d_out", hours, lowBound=0, upBound=300) # 可平移移出 d_in = LpVariable.dicts("d_in", hours, lowBound=0, upBound=300) # 可平移移入 d_cut = LpVariable.dicts("d_cut", hours, lowBound=0, upBound=150) # 可削减 c_buy = LpVariable("c_buy", lowBound=0) c_sell = LpVariable("c_sell", lowBound=0) prob = LpProblem("IES_Dispatch", LpMinimize) # 目标:购能成本 + DR补偿 + 碳交易成本 prob += ( lpSum(price_e[t] * p_buy[t] for t in hours) + price_gas * lpSum(g_chp[t] + g_boiler[t] for t in hours) + 0.6 * lpSum(d_out[t] for t in hours) + 1.2 * lpSum(d_cut[t] for t in hours) + carbon_price * (c_buy - c_sell) )

电功率平衡是核心约束。供给侧为购电、光伏、CHP发电、储能放电;需求侧为基础电负荷、电锅炉耗电、储能充电,再减去需求响应带来的净变化。

# CHP与燃气锅炉、电锅炉的能量转换关系 for t in hours: prob += e_chp[t] == 0.35 * g_chp[t] # CHP电出力 prob += q_chp[t] == 0.50 * g_chp[t] # CHP热出力 prob += q_gb[t] == 0.90 * g_boiler[t] # 燃气锅炉热出力 # 电功率平衡:供给 = 需求 for t in hours: prob += ( p_buy[t] + pv[t] + e_chp[t] + p_dis[t] == load_elec[t] + q_eb[t] / 3.0 + p_chg[t] - d_out[t] + d_in[t] - d_cut[t] ) # 热功率平衡 for t in hours: prob += q_chp[t] + q_gb[t] + q_eb[t] == load_heat[t]

储能和需求响应的特殊约束需要单独处理。储能要防止同时充放,还要满足SOC递推;需求响应则要保证移入移出总量守恒。

# 储能SOC递推与充放互斥 for i, t in enumerate(hours): if i == 0: prob += soc[t] == 1000 + 0.95 * p_chg[t] - p_dis[t] / 0.9 else: prev = hours[i - 1] prob += soc[t] == soc[prev] + 0.95 * p_chg[t] - p_dis[t] / 0.9 prob += p_chg[t] <= 500 * y_chg[t] prob += p_dis[t] <= 500 * (1 - y_chg[t]) # 可平移负荷总量守恒 prob += lpSum(d_out[t] for t in hours) == lpSum(d_in[t] for t in hours) # 碳排放与碳交易 emission = ( grid_ef * lpSum(p_buy[t] for t in hours) / 1000.0 + gas_ef * lpSum(g_chp[t] + g_boiler[t] for t in hours) / 1000.0 ) prob += emission - quota == c_buy - c_sell

代码中所有单位统一为kW和kWh,排放因子按吨/MWh换算,所以在算总排放时把kWh除以1000转成MWh。求解完成后,直接读决策变量结果做分析。

4.3 结果解读:DR和碳交易分别改变了什么

为了看清机制,我跑了三个场景:A是纯成本调度,不接入DR也不引入碳价;B只接入DR,碳价置零;C同时接入DR和碳交易。仿真结果大致如下。

场景总成本(万元/日)碳排放(吨/日)峰值购电(kW)DR移出电量(kWh)碳净买入(吨)
A 纯成本7.2074.854000-
B 仅DR6.8871.250002600-
C DR+碳7.3661.5460032004.8

对比A和B,需求响应的作用一目了然:峰值购电从5400kW降到5000kW,负荷曲线被削平了一块,同时总成本还下降了。这是因为模型把白天高峰的部分负荷搬到低谷时段,减少了高价电购买量,付出的DR补偿低于节省的电费,整体划算。

对比B和C,碳交易进入模型后,系统开始主动压缩碳排放。排放从71.2吨降到61.5吨,已经压到配额附近,峰值购电进一步降低到4600kW。代价是总成本上升到7.36万元,这笔多出来的成本相当于为减少碳排放支付的“碳账单”。如果业主的配额进一步收紧,这个成本信号会更加明显。

这个结果说明一个关键结论:碳交易改变的不是设备本身,而是设备的调度次序。高碳价让系统更倾向于在高峰时段压低购电、增加CHP热电联产的运行小时数、加大储能谷充峰放的力度,必要时再调用更多需求响应资源。

5. 碳价与电价的敏感性:谁在真正改变能源供应

5.1 碳价涨跌如何传导到设备出力

把碳价从0一直扫到200元/吨,你会看到一个典型的边际减排成本曲线。碳价低的时候,系统只做最便宜的小调整,比如顺带优化一下储能时段;碳价升高以后,系统才会付出更高成本去调用DR、压低高峰购电、调整CHP与锅炉的出力分配。

我试过几组数据,趋势是这样的:碳价从0涨到50元/吨,碳排放会小幅下降;从50涨到100,排放继续下降但仍高于配额;到150到200元/吨时,系统会把可用的DR和储能资源基本用满,排放压到接近配额下限。再往上,减排速度明显放缓,说明便宜的减排手段已经被用尽了。

这个曲线对项目决策很有用。你可以提前算清楚自己的边际减排成本是多少,再对照碳价判断哪些运行策略值得做。如果碳价是50元,就不用强求把排放压到配额以内;如果碳价涨到150,就要认真跟用户签DR协议了。

5.2 电价与碳价的耦合:储能成了“自动搬运工”

单独看电价,储能的充放逻辑很简单——低充高放。但引入碳价后,低谷充电虽然电价便宜,如果外购电排放因子高,低谷多充的电在生命周期里也携带碳成本;高峰放电替代的是高峰时段的高价高碳电力,两头都要算。实际结果通常是碳价越高,储能在高峰放电的价值越大,因为它在替代对外购电的边际成本时,同时替代了电费和碳排放。

需求响应补偿单价的设定也有讲究。补偿定太低,用户没有动力响应;定太高,模型会滥用DR,比如强制削减大量不影响电价的负荷。工程上通常把补偿设在实际用能损失和系统节约成本之间,让优化器自然选择最优调用深度。

6. 实战避坑:模型能跑但结果没法用的五个原因

6.1 解不可行先别怀疑求解器

模型一跑就报infeasible是常有的事。多数时候不是求解器坏了,而是约束写矛盾了。最常见的是可平移负荷设定得过猛,比如你规定某时段最多移出300kW,又要求该时段负荷保持不变,两个条件直接冲突。排查办法是在关键平衡约束上加一个松驰变量,谁不为零就说明谁最紧张。先用这套方法定位,再去检查参数,比自己盯着等式看快得多。

6.2 可平移负荷守恒约束不能马马虎虎

可平移负荷的守恒约束是这套模型最容易写出逻辑漏洞的地方。如果你写sum(d_in) - sum(d_out) >= 0,优化器就会看到套利机会:凭空给某时段多增加负荷,在低谷移入,再谎称高峰时段有移出需求,最后白拿DR补偿。正确写法一定是严格等于,数值上就算有浮点误差,也要设置合理的求解容差,而不是放宽成不等式。

6.3 别把碳排放成本和电价里的环境成本重复计算

有些地区的外购电价里已经包含绿色电力溢价或碳排放附加成本,如果再在目标函数里按碳价全额计算外购电排放,就会出现双重计费。建模开工前必须跟数据提供方确认:电价是市场出清价还是含环境成本的电价。如果是后者,碳价应该取“市场碳价-隐含碳价”的差额,或者干脆把碳交易只作用于配额缺口部分,不重复累加。

6.4 单位换算是隐藏的大杀器

kW、kWh、MWh、吨、元,这几个单位混在一起,很容易算错。我见过比较多的问题是排放因子的单位换算:电网排放因子是吨/MWh,负荷数据和设备容量是kW,一小时产生kWh,要除以1000才和排放因子对齐。天然气排放因子如果按公斤/立方米给,还要先按热值折算成输入功率。建议所有模型统一使用kW、kWh、元、吨四类单位,做完一步换算就在旁边注清楚,避免整个模型做完了才发现量纲差了一个数量级。

6.5 连续解太“精准”,落地需要工程圆整

线性规划给出的需求响应结果可能是“第14时段削减3.7kW”,这种数字在真实用户面前就是笑话。真实的DR资源通常按块分配,一条生产线要么响应100kW要么不响应。我习惯的做法是:第一轮用连续模型算出经济性最优区域,然后按实际负荷的可调配粒度做圆整,把圆整后的DR调用量固定下来,再重新求解一轮,得到可执行方案。牺牲一点理论最优性,换取方案的工程可行性,这笔账是划算的。

7. 从单园区到多主体市场:扩展方向

单园区模型跑通之后,再往深走,就是多主体博弈问题。需求响应资源不再只有一个用户,而是多个用户各有响应成本和窗口限制;碳配额也不再是单一主体的预算,而是多个用能主体之间的交易价格信号。此时单层优化模型会变成市场出清模型,或者用双层规划描述“运营商定价-用户响应”的博弈关系。

我的建议是:先别急着上双层。把单园区模型的数据、边界条件、参数敏感性摸透,尤其把碳价和DR补偿对购电曲线的影响搞清楚,再扩展成多代理仿真。很多实际项目里,脚本越简单越容易被业务团队接受,复杂的博弈模型在数据和算力不支持时反而不如一个清晰的单层模型好用。

我个人在实际操作中的体会是:需求响应和碳交易带来的变化,本质上不是让某个设备少跑或者多跑,而是让所有设备的运行优先级被重新排序。碳价给每一种能源输入标了价,DR给负荷曲线的时间维度标了价,优化器就在这些价格信号下自动做取舍。所以做这类项目最有趣的部分,反而不是求解过程本身,而是看着碳价从50调到150,系统的购电曲线一层一层地变平、变干净。先把这套单园区模型跑通,你就已经掌握了理解综合能源系统优化最核心的那把钥匙。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询