☰
微电网日前优化调度:需求响应与电动汽车协同建模与工程实践
2026/10/11 4:33:54 网站建设 项目流程

我最早接触这个方向,是因为要给某个园区级微电网做可行性探索。当时平台侧已经能采集到负荷、光伏和储能数据,但调度策略还停留在“固定负荷曲线加人工经验”的阶段。真正把多种需求响应和电动汽车放进日前优化调度模型里跑起来之后,我才发现这件事比预想的复杂不少:需求响应要区分价格型和激励型,电动汽车又不能当普通负荷处理,每辆车的入网时间、离网SOC、是否允许V2G都会改变调度结果。这篇笔记就是把这轮“探索”从头到尾梳理一遍,从建模取舍、求解器选择到算例结果和踩坑记录都摆出来,给同样在做微网/虚拟电厂优化调度的朋友一个可参考的起点。

1. 多个变量进来之后,原来的调度思路为什么不灵了

1.1 传统经济调度假设里,用户侧是被动的

传统微网经济调度的思路很直接:预测明天的负荷曲线,再根据光伏出力和储能状态,决定每个时段从主网购多少电、储能充放多少。这个逻辑在用户侧完全被动的前提下是成立的,负荷就是一条给定的曲线,储能的SOC变化用一组线性约束就能描述,整个问题本质上是一个线性规划,求解器几秒钟就能给出结果。

但现实环境变化之后,这条老路走不太通了。各类用户侧资源开始具备“可调度性”:工业用户愿意在电价尖峰时段削减一部分负荷换取补偿;商业楼宇的空调、冷机可以提前蓄冷;停车场里的电动汽车既能充电,也能在V2G模式下向微网放电。用户侧资源一旦从“常数”变成“变量”,负荷就不再是一条固定曲线,而是一堆由价格信号、补偿机制和用户意愿共同决定的决策变量。

1.2 三种需求响应、电动汽车,分别是模型里的三类“新增量”

我把它们按建模特征分成了三类,因为它们在优化模型里扮演的角色完全不同:

连续型响应资源,比如可削减负荷。它们的响应量可以看成连续变量,只要给定上限和补偿单价,优化器会自己决定每个时段削减多少。这类资源最容易处理,本质上是给原问题加了一个可调节的“负负荷”。

离散型响应资源,比如可中断负荷合同。用户一旦签约,要么整段中断、要么不中断,会有最小中断时段数、最大中断次数这些约束。这类资源必须引入0-1整数变量,问题从LP变成MILP,求解难度立刻上一个台阶。

能量型响应资源,就是电动汽车集群。EV不是简单的一个可调功率,而是“充进去的电量可以存起来再放出来”的移动储能。单看一辆车,有SOC状态、充放电功率上限、入网/离网时间约束;放在集群层面看,还要考虑不同车辆的在网时段重叠情况。它的调度价值在于“时空转移”——把充电需求从晚高峰挪到光伏大发的中午,再把储存的电量在晚高峰反送回来。

这三类资源同时进入一个模型之后,功率平衡方程不再是一对一的供需匹配,而是一个多资源参与的多时段耦合优化问题。这也是为什么原来的经济调度代码改不动:不是加一行乘数的问题,而是整个问题结构都变了。

1.3 我采用的基础边界:并网模式、1小时步长、确定性日前预测

开始建模之前,必须先把边界定清楚。这次探索我做了三个简化设定:

  • 并网运行模式:微电网与主网保持联络,允许买卖电,联络线功率有限制。孤岛模式需要额外考虑频率稳定和更严格的安全约束,复杂度会高很多,不适合作为第一版探索。
  • 时间粒度取1小时:日前优化调度常用的就是24点或96点。我选了24点起步,先把模型逻辑跑通。15分钟粒度虽然更精细,但整数变量直接乘以4,求解压力和数据精度要求都上来了,后面需要再单独处理。
  • 确定性预测:假设光伏出力、负荷水平、EV用户行程都已知(取预测值),暂不考虑随机场景。不确定性建模放到下一步再做,否则很难判断模型本身对不对。

提示:如果你的目标是做工程化落地,建议也从这三个边界出发。先把确定性模型跑透,再逐步放开到随机优化或鲁棒优化,不要一上来就追求高复杂度。

2. 需求响应建模不是越精细越好:价格型、可中断、可平移的取舍

2.1 价格型响应:分时电价已经是最好的“简化入口”

最常被误解的一点是:价格型需求响应不一定要在模型里显式建一套“用户对价格的弹性函数”。实际工程里最常见的做法是直接利用分时电价(TOU)。电价本身就是需求响应的驱动信号——所有资源都会在低谷时段多用电、高峰时段少用电,这已经构成了事实上的价格型响应。

更精细的做法是引入需求价格弹性矩阵,用自弹性系数和交叉弹性系数描述“当前时段电价变化对当前及相邻时段负荷的影响”。但问题在于:弹性矩阵一旦进优化模型,容易出现非线性项,而且弹性系数本身很难标定——不同行业、不同温度、不同季节,系数差异很大。

我的取舍是:第一版模型不把弹性矩阵放进约束里,而是作为电价场景的输入参数。先给定一版分时电价,让优化器自己去安排各类柔性资源的用电时段。等模型稳定之后,再考虑从历史数据里回归弹性系数,作为灵敏度分析工具使用,而不是直接嵌入主模型。

这样做的原因很实际:优化调度需要的是一个“可执行”的决策,不是经济学推导。你给用户发一套价格信号,用户怎么响应用户会自己决定,微网要做的是在价格信号之下安排好自己可控资源的响应策略,而不是替用户做经济学建模。

2.2 可中断负荷:0-1变量让问题从LP变成MILP

可中断负荷是需求响应里最有合同色彩的一类。工业用户、大型商业用户和微网运营方签订协议:在某个约定时段内,如果运营方提前通知,可以中断一定量的电负荷,运营方按照实际中断电量支付补偿。

建模上有三组核心约束:

  • 单时段中断上限:每个时段最多中断多少,取决于用户可接受范围。
  • 总中断电量上限:一天累计中断多少有合同上限,避免优化器为了省钱把用户往死里削。
  • 连续中断时段约束:部分用户要求“要么连续中断至少X小时,要么不中断”,这就引入了0-1状态变量和启动变量。

具体约束可以写成:

0 ≤ P_IL(t) ≤ u_IL(t) * P_IL_max(t) sum(u_IL(t) for t in 1..24) ≤ N_IL_max

其中u_IL(t)是0-1变量,N_IL_max是最大中断时段数。目标函数里增加一项c_IL * P_IL(t) * Δt,表示补偿成本。

这里容易踩的坑是:如果把中断补偿单价定得太低,优化器会把所有可中断负荷全砍掉来省钱,导致用户侧实际不可接受;定得太高,优化器又永远不会用这个资源。合理范围一般参考“高峰时段购电价与低谷时段购电价的差”来标定,补偿单价要高于用户自己调整生产安排的成本,但低于微网从主网购高价电的边际成本,两边都有利,合同才成立。

2.3 可平移负荷:用“用电量守恒”做整体时段搬移

可平移负荷和可削减负荷有本质区别:削减是“少用电”,平移是“换个时间用一样的电”。典型的可平移负荷包括:电动汽车充电、工业破碎机、注塑机、洗衣机等生产工艺不要求精确时刻、但在某个窗口期内必须完成指定工作量的设备。

简化建模方式是把同一类可平移负荷聚合成一个总负荷块,约束条件是:

  • 总用电量在调度周期内守恒,即所有时段平移后的总用电量等于原总用电量;
  • 每小时用电量有上下限;
  • 如果要求连续运行,则还需要额外的整数变量表达“开启/关闭”状态。

平移负荷的价值在于削峰填谷:把高峰时段的用电挪到低谷或者光伏大发时段,既降低购电成本,又减少弃光。但它会引入跨时段耦合,让功率平衡不只是同一时段内的事,还牵涉“电量守恒”。

我的建议:不要把平移负荷的颗粒度做得太小。把同质负荷合并成一个聚合块,否则几十种平移负荷会直接撑爆求解器。

3. 电动汽车别一辆一辆建模:集群聚合才是工程做法

3.1 单体EV的约束长什么样

单辆电动汽车的调度模型并不复杂,核心约束就三块:

  • SOC递推:SOC(t+1) = SOC(t) + (η_ch * P_ch(t) - P_dch(t) / η_dch) * Δt / Cap
  • 充放电功率约束:0 ≤ P_ch(t) ≤ P_ch_max * y_ch(t)、0 ≤ P_dch(t) ≤ P_dch_max * y_dch(t),且 y_ch(t) + y_dch(t) ≤ 1,避免同时充放。
  • 离网SOC约束:用户离开时必须达到约定SOC,比如90%,否则用户下次就不配合了。

但如果一个100辆EV的小区,每辆车都建一套上述约束,再乘以24个时段,可用的离散变量就会瞬间膨胀。而且最麻烦的是:每辆车的入网、离网时间都不一样,用户到达时间、出发时间、充电需求都有不确定性。车辆多了之后,这种“时空差异化”信息会让模型变得非常笨重。

网上很多教程喜欢教你怎么精细化建模每一辆车,学术论文里也常见复杂的EV行为模拟。但工程实践里,虚拟电厂运营商根本不可能实时知道每辆车的行程细节,即便知道也不应该让优化器针对每辆车做决策——太多变量了,求解效率不可接受。

3.2 聚合建模的经典做法:把EV集群看成“可变功率的可调度储能”

工程上更实用的方式是把整个EV集群聚合为一个“虚拟储能”资源,用几个聚合参数描述:

  • t时段集群最大充电功率:该时段所有在网车辆的充电功率上限之和。
  • t时段集群最大放电功率:该时段所有在网车辆的放电功率上限之和。
  • t时段集群能量上界/下界:根据在网车辆的SOC范围、入网/离网时间推算出来的聚合能量约束。

聚合之后,模型里的EV集群从“几百辆车、几万个变量”变成“一个虚拟储能、几十个约束”,求解规模大幅下降。这就相当于把整个停车场当成一块大号电池:有充电功率上限、放电功率上限、能量上下限,只不过这些参数会随时间变化。

3.3 如何确定聚合边界:统计、抽样、再打折

聚合边界的精确程度,决定了调度结果的可执行性。我见过有人直接拍脑袋定“充电功率500kW、容量2000kWh”,结果调度方案下发后根本无法执行,因为夜间半数车辆根本不在停车场,那500kW根本凑不出来。

实际可取的做法分三步:

第一步,统计车辆行为特征。通过历史数据统计每天各时段的在网车辆数、平均入网SOC、平均离网SOC需求。不需要精确到每辆车,聚合层面看分布就够了。

第二步,蒙特卡洛抽样生成典型场景。从入网时间分布、离网时间分布、初始SOC分布中抽样,生成几百组可能的“EV集群状态”,然后取这些场景下可调度功率和能量的包络线,或者取某个保守百分位数(比如5%分位数)作为优化模型的边界参数。

第三步,打折扣留裕度。实际调度时还要再乘一个系数,比如把可调度功率按80%计入。原因是用户可能临时取消行程、SOC比预期低、部分车不支持V2G。折扣系数在学术界叫“鲁棒裕度”,在工程上叫“别把用户的配合度当理所当然”。

3.4 V2G要不要开:电池损耗惩罚必须进目标函数

V2G其实就是放电方向。不开V2G,EV集群只能是“充电负荷”,顶多做到有序充电;开了V2G,EV集群还能反哺微网,在高峰时段放电,价值更大。

但V2G有一个绕不开的问题:电池循环寿命损耗。用户把电池能量卖回给微网,等价于用自己电池的寿命换取系统收益。如果调度模型里不对放电行为做惩罚,优化器可能会为了省一毛钱电费让EV满充满放,实际对电池寿命的损伤远超省下的那点钱。

我通常会在目标函数里给EV放电加一项损耗成本,单位约0.1~0.2元/kWh。这个数值不是拍出来的,是根据“电池循环寿命约3000~5000次、更换成本约每千瓦时几百元”反算出来的近似值。加了这一项之后,优化器会自然倾向于“非必要不放电”——只在高峰高价时段放电,而不是任意时段瞎放。

4. 把模型拼起来:目标函数、约束骨架与求解器选择

4.1 目标函数:哪些成本进模型,哪些先进不了

日前优化调度的目标函数,我采用如下形式:

min 总成本 = 购电成本 - 售电收益 + 需求响应补偿成本 + 储能/EV损耗成本 + 弃光惩罚
  • 购电成本:每个时段从主网购电量 × 购电价 × Δt。
  • 售电收益:每个时段向主网售电量 × 售电价 × Δt。一般售电价低于购电价,所以优化器不会没事卖电。
  • 需求响应补偿成本:可中断负荷、可平移负荷的调度量和补偿单价。
  • EV放电损耗:前面提到的电池损耗惩罚。
  • 弃光惩罚:一个较大的正系数乘以弃光电量。光伏大发时段如果消纳不了,宁可花钱惩罚也不要让它变成无解问题。

弃光惩罚系数要远大于购电成本,但不能大到离谱,否则会破坏数值稳定性。一般取该时段购电价上限的3~5倍即可。

4.2 功率平衡与联络线约束的骨架写法

功率平衡方程是每时段的“总决算表”:

P_buy(t) + P_pv(t) + P_ess_dch(t) + P_ev_dch(t) = P_base_load(t) - P_IL(t) - P_shift_load(t) + P_ess_ch(t) + P_ev_ch(t) + P_sell(t)

翻译成人话:左侧是“所有来电”,右侧是“所有去处”。可中断负荷、平移后的负荷调整都体现在右侧。联络线约束需要限制购售电不能同时发生,引入一个0-1变量u_tie(t):

0 ≤ P_buy(t) ≤ P_tie_max * u_tie(t) 0 ≤ P_sell(t) ≤ P_tie_max * (1 - u_tie(t))

储能SOC递推和EV聚合SOC递推的写法类似,注意功率、能量、时间步长的单位一致性——功率用MW、时间用h、能量用MWh,才能直接相乘。

4.3 求解器选型:我用什么工具、为什么

这个模型是一个典型的混合整数线性规划(MILP),可选工具非常多。我自己的选择经历是:早期用MATLAB + YALMIP + CPLEX,验证模型逻辑;后面改写Python + Pyomo + HiGHS,方便对接数据预处理和结果可视化。这里有几个对比供参考:

方案优点缺点适合场景
MATLAB + YALMIP + CPLEX建模语句简洁,调试直观需要商业许可证,数据接口稍弱学术验证、教学演示
Python + Pyomo + HiGHS免费开源,生态完整建模代码略啰嗦工程落地、数据集规模较大
Python + Gurobi求解性能最强需要商业许可大规模场景、要求高性能时

用Pyomo写一个简化骨架大概是这样的:

import pyomo.environ as pyo m = pyo.ConcreteModel() m.T = pyo.RangeSet(24) m.Pbuy = pyo.Var(m.T, within=pyo.NonNegativeReals) m.Pess_ch= pyo.Var(m.T, within=pyo.NonNegativeReals) m.Pess_dch=pyo.Var(m.T, within=pyo.NonNegativeReals) m.u_il = pyo.Var(m.T, within=pyo.Binary) m.P_il = pyo.Var(m.T, within=pyo.NonNegativeReals) def balance(m, t): return (m.Pbuy[t] + Ppv[t] + m.Pess_dch[t] + Pev_dch[t] == Pload[t] - m.P_il[t] + m.Pess_ch[t] + Pev_ch[t]) m.balance_con = pyo.Constraint(m.T, rule=balance) m.cost = pyo.Objective( expr=sum(m.Pbuy[t]*Price[t] + c_il*m.P_il[t] for t in m.T), sense=pyo.minimize )

实际模型会比这个骨架长很多,但结构就是如此:变量定义、功率平衡、SOC递推、联络线约束、目标函数。

5. 不跑算例永远发现不了的事:五组场景的结果对比与解读

5.1 场景设计:单一资源优先试,最后再协调

设计算例是有讲究的。不要一上来就跑“所有资源全开”的大模型,那是给自己挖坑——出了问题不知道是哪个模块导致的。我按这个顺序设计场景:

场景说明
S1无需求响应、无EV,只有储能和光伏
S2只加需求响应(可中断+可平移)
S3只加EV、但EV无序充电(固定18:00-22:00充满)
S4只加EV、EV有序充电(由优化器决策充电时段)
S5需求响应 + EV有序充电 + V2G全部接入,协调优化

系统参数大致取了一个中等规模的园区微网:基础负荷峰值约720kW,光伏装机400kWp,储能500kWh/200kW,EV聚合体约40辆车、可调度功率240kW、日充电总需求约1000kWh。

系统运行后得到的结果如下表(具体数值与该系统数据强相关,看相对趋势更有意义):

场景日购电成本(元)峰谷差(kW)说明
S1约6180约320只有储能削峰,能力有限
S2约5820约230DR削峰效果明显
S3约7200约410无序充电,晚峰被叠高
S4约5580约250有序充电降低总成本
S5约5120约170协调优化,成本最低、峰谷差最小

5.2 最意外的发现:无序充电EV比没有EV更糟

S3这个结果值得单独说一下。很多人直觉上认为“电动车的电总是要充的,反正充电需求跑不了,对调度影响不大”。但实测数据很打脸:无序充电的EV在18:00到22:00扎堆开始充电,恰好撞上负荷晚高峰,结果是峰谷差从320kW直接抬高到410kW,购电成本也从6180元涨到7200元。

这个结果说明,EV接入微网不是天然友好的。电动汽车本身是“能量型负荷”,它对电网的影响高度取决于充电时段和充电功率的分布。无序接入会把峰谷差拉大、推高成本;有序充电或V2G则能把劣势转成优势。这个取舍必须靠优化模型算出来,不能靠拍脑袋说“EV是柔性负荷,肯定有利于电网”。

5.3 需求响应和EV为什么能互相成就

S2和S4分别单独验证了DR和EV有序充电的价值,但S5才是真正让我觉得“这个探索值得做”的场景。

S5里,需求响应负责削掉负荷峰值尖角,EV有序充电负责把充电需求搬到光伏大发时段,V2G在夜间高价时段峰值开始前放电,储能则填补两者结合后剩下的波动。多个资源之间形成了时间上的互补:DR削尖峰,EV移电量,储能填剩余缺口。

峰谷差从S1的320kW降到S5的170kW,降低了将近47%;购电成本从6180元降到5120元,下降了约17%。这就是多种需求响应加上EV协调优化的核心价值。

6. 从离散变量到求解超时:这轮探索踩过的坑和最终建议

6.1 big-M取值:取大了数值崩,取小了削可行域

建模初期我犯了个典型错误:为了让“购电和售电不能同时发生”的约束生效,我取了一个特别大的M,比如10000。结果求解器开始出现数值警告,部分约束形同虚设,求解结果看起来合理但细看会发现有购售电同时存在的“影子时段”。

后来把系统内所有功率统一归一到MW级别,M值取联络线功率上限的1.2~2倍,问题立刻稳定下来。这个经验是:M不是越大越好,能表达“两件事互斥”的最小量级就是最优值。凡是看到求解器报numerical issues,第一件事检查所有常数项的尺度是否一致。

6.2 单位不统一是最隐蔽的错误来源

SOC递推公式本身没错,但如果你用的是kW和kWh,Δt用的是小时,就要小心功率乘以时间得到的是kWh,不是MWh。很多人在储能SOC约束里忘记除以容量,或者功率和能量单位混用,导致SOC曲线越跑越离谱,看起来“像”但实际错得离谱。

我的习惯是:所有功率统一为MW、能量统一为MWh、电价统一为元/MWh,时间步长是小时。任何异构单位进入模型之前,先做一次换算。这个习惯让我少排了很多错。

6.3 求解超时的实用退路,而不是硬扛

模型规模一大,求解器经常会跑几分钟还没到最优。这时候不要干等,有几个实用方案:

方案一:设置合理的MIP Gap。学术论文里动不动追求10^-4甚至10^-6的gap,工程场景1%的gap完全够用。把mipgap设为0.01,求解时间往往能缩短一个数量级。

方案二:先解LP松弛定位问题。如果连LP松弛都很慢,说明问题本身可能不是离散变量的问题,而是数值病态——把连续变量的边界问题先修好,再加回整数变量。

方案三:时段聚合。先用24点模型验证逻辑,再用96点模型跑精细方案。在探索阶段不要一开始就上96点,否则调试周期会成倍拉长。

方案四:固定部分状态变量。比如某些时段储能显然不会充放电、某些时段显然不会发生倒送,可以先用简单规则固定这些状态变量的值。这样整数变量个数大幅减少,然后再放开精确求解。这个方法不严谨,但很实用。

6.4 最后的一点个人建议

这轮探索跑完之后,我最大的感受是:微网/虚拟电厂的日前优化调度,难点从来不在“把目标函数写出来”,而在于搞清楚每个资源在模型里的角色、边界条件和实际可执行性。需求响应不只是一个“负负荷”,EV也不只是“一辆车”,它们的价值要靠协调优化才能显现。

下一步我打算把确定性模型扩展到两阶段随机规划:第一阶段定联络线购电计划和DR合约,第二阶段根据光伏和负荷场景调节储能和EV出力。不过在此之前,先把确定性模型的结果、参数灵敏度分析做成一个可复用的模块,后面扩展就不必从零开始了。这个探索方向我会持续跟进,有新结果再继续写。

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

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

立即咨询