☰
微网日前调度中的源荷不确定性建模:蒙特卡洛场景生成与快概率距离削减实战
2026/9/26 13:40:20 网站建设 项目流程

做微网日前调度的同行应该都有同感:风电、光伏的预测曲线看着挺光鲜,真正并网之后就会发现实际出力和预测完全是两回事;负荷预测更是只能看个趋势,碰上电动汽车集中充电、天气突变,偏差能让你哭笑不得。早几年我按确定性方法做日前调度,第二天执行下来经常不是弃风就是切负荷,偏差一大就得靠配网功率兜底。后来把“源荷双重不确定性”显式搬进优化模型,用蒙特卡洛算法做场景生成,再用快概率距离削减把几千个场景压缩成几十个有代表性的场景,最后做随机优化调度,情况才真正稳定下来。

这套流程说白了就是:对不确定的东西不要只给一个“点预测”,而是给出一簇可能发生的“情景”,再让优化模型在所有情景下都尽量做对。本文就结合我实际做的一个虚拟电厂微网算例,把从场景生成、场景削减到日前随机优化调度的完整链路拆开讲清楚,包括每一步为什么这么做、参数怎么定、以及我踩过的坑。适合正在做微网能量管理、虚拟电厂聚合调度、以及想从确定性调度转向随机优化的同学参考。

1. 虚拟电厂微网的日前调度:为什么说不确定性是“双重”的

虚拟电厂微网和普通微网最大的区别,在于它不仅要管好自己“这一亩三分地”的源荷平衡,还要以聚合商的角色跟外部配网互动,甚至参与辅助服务或现货市场。GB/T 44260-2024《虚拟电厂资源配置与评估技术规范》发布之后,VPP的资源评估、配置比例、响应能力都有了更明确的衡量口径,分布式光伏、风电、储能、柔性负荷都在聚合范围内。这样一来,日前调度就不只是“预测一下明天风光发多少、负荷用多少”,而是要在源侧和荷侧都存在随机波动的情况下,提前一天定好储能充放电计划、联络线购售电计划和可调负荷的调节方案。

1.1 源侧不确定性到底来自哪里

源侧不确定性,主要来自风电和光伏。

风电出力的随机性本质上是风速的随机性。风速一般用威布尔分布拟合,形状参数和尺度参数随季节、地形变化。但仅仅用分布还不够,风速还有很强的时序相关性,比如夜晚风大、白天风小,阵风和爬坡事件可能让出力在半小时内从20%冲到80%。光伏出力主要受辐照度影响,Beta分布是常用的辐照度拟合分布,但云层遮挡带来的分钟级波动很难用单一分布刻画,阴雨天和晴天的分布参数完全不同,所以分场景、分时段建模是必要的。

我之前见过不少团队直接拿“明天预测最大概率出力”当成确定性输入,结果在风光大发且负荷低谷的时段严重弃电,在风光骤减又碰上晚高峰的时段不得不高价购电。问题的根子不在预测算法精度,而在于把随机变量当成了确定值。

1.2 荷侧不确定性为什么不能简单地“乘系数”

荷侧不确定性很多人容易轻视,觉得负荷波动范围不大,乘个1.1的安全系数就够了。但在虚拟电厂微网里,负荷构成比传统台区复杂得多。普通居民负荷本身的随机性已经不小,工商业负荷受生产计划影响会呈现明显的日类型差异,更要命的是电动汽车充电——无序充电的功率需求叠加在一起,可能让负荷曲线在某个时段突然高出平均水平50%以上。

如果源侧和荷侧各自单独处理,比如源侧考虑波动、荷侧取预测值,或者反过来,都属于没有面对“双重不确定性”。不定性会耦合:比如傍晚时段光伏出力快速下降,正好碰上居家负荷和充电负荷抬升,这时候源侧的下行风险和荷侧的上行风险叠加,只建立单侧随机模型必然导致调度方案低估风险。因此,我的做法是把源、荷都作为随机变量,统一生成联合场景,再交给优化模型。

2. 蒙特卡洛场景生成:用随机抽样把不确定性的“形状”刻画出来

场景生成是整套随机优化的地基。它的目标不是预测“明天光伏发多少度电”,而是回答一个问题:基于历史统计特征,明天可能出现的源荷出力组合有哪些,各自概率多大。

蒙特卡洛方法在这个问题上是最直观也最常用的选择:根据随机变量的概率分布大量抽样,生成成千上万条完整日的出力场景。这个方法要说精巧并不精巧,但胜在概念清晰、实现简单、可解释性强——工程落地时大家可以理解、可以审计、可以复现。

2.1 随机变量的分布假设与参数估计

以我用的微网算例为例,微网额定配置为一个600kW的风电场、400kW的光伏阵列、300kWh/150kW的储能系统,基础负荷峰值约500kW。

源侧和荷侧的随机变量我做了这样的假设:

  • 风速:威布尔分布,形状参数k=2.1,尺度参数c=8.5(按当地全年测风数据用极大似然估计得到)
  • 辐照度:Beta分布,形状参数α、β按月分时段标定,晴天时段α=2.5、β=2.0,阴雨时段α=2.0、β=4.5
  • 负荷:正态分布,均值取预测负荷曲线,标准差取历史同期负荷标准差的15%

需要强调的是,分布假设不是拍脑袋定的。如果有条件,最好先用历史数据做分布拟合优度检验。我见过有同学直接假设负荷服从正态分布,但实际负荷在极端天气下有明显厚尾,导致抽样场景里缺少极端高负荷情景,调度结果在真正遇上极端日时就会出问题。

参数估计的方法不必多高级,极大似然估计已经够用。关键是数据清洗,剔除检修日、通信故障日和节假日等异常样本,不然拟合出来的分布参数会整体偏移。

2.2 从抽样到场景:时序相关性与完整场景构造

光有边际分布还不够,蒙特卡洛抽样要生成的是“一条完整的日曲线”,而不是各时段互相独立的散点。早上10点的光伏出力和下午2点的光伏出力有强正相关,21点的负荷和23点的负荷也有相关性。如果忽略时序相关性,生成出来的场景曲线会剧烈跳变,完全不像真实的源荷出力。

我的处理方式是用协方差矩阵刻画时序相关性,再通过Cholesky分解做相关性抽样。具体步骤是:

  1. 对每个时段的历史出力数据标准化,计算时段间相关系数矩阵R
  2. 对R做Cholesky分解得到下三角矩阵L
  3. 生成独立标准正态随机向量Z
  4. 通过X=μ+σ·L·Z得到满足相关性的正态分布样本
  5. 再把标准正态样本通过逆变换法转换到目标分布(如威布尔、Beta)

这样生成出来的场景,在统计特征上既保持了各时段的边际分布,又保留了时序上的相关性。辐照度和风速之间的跨变量相关性,我简单采用Copula函数做联合抽样;如果不想上复杂工具,一个近似做法是让源侧各随机变量共用部分随机数种子,也能保证中低相关性的效果,但要注意不要人为引入过强的伪相关。

抽样规模方面,我一般取2000到5000个场景。太少的话尾部极端情景可能没有被覆盖到,太多的话后续削减和求解的计算负担会翻倍。我的算例里先抽了2000个场景试算,剔除明显不合理样本(比如光伏夜间出力为0的场景与辐照度为正但风电场出力异常跳变的场景)后,保留约1900个有效场景进入削减环节。

注意:抽样时一定要固定随机数种子。随机优化流程跑通后,如果每次重新抽样,调度结果波动会让人怀疑程序出了bug,实际上只是随机性在捣乱。固定种子之后,削减和求解结果可复现,后续调参也才有的放矢。

3. 快概率距离削减:上千场景怎么浓缩成几十个“典型日”

2000个场景直接丢进优化模型,理论上没问题,但实际上很痛苦。每个场景都对应一组二阶决策变量,场景数翻十倍,求解规模粗暴地跟着翻十倍。我一个中等规模的微网算例,2000场景的MILP模型用普通电脑跑,动辄几个小时起步,根本无法用于“日前”调度——日前调度是要在每天下午出结果的,不是用来过夜的。

所以场景削减是必须的。但削减不能随便抽几个场景了事,否则会破坏概率分布的结构。标题里的“快概率距离削减”,指的就是用概率距离指标衡量“削减后的场景集”和“原始场景集”之间的分布差异,并最小化这个差异来挑选保留场景和调整概率。

3.1 概率距离是什么:Kantorovich距离的思想

概率距离这个概念,简单讲就是衡量两个概率分布之间“有多不一样”。场景削减里最常用的是Kantorovich距离(也叫Wasserstein距离的1阶形式)。它有个很直观的解释:把两个分布想象成两堆土,搬动土堆使其形状一致,搬土的最小工作量就是距离。对场景削减来说,原始场景集是一个离散分布,削减后的场景集是另一个离散分布,Kantorovich距离越小,说明两个分布的统计特征越接近。

这个思想很关键,因为它把“削减后能不能代表原始不确定性”变成了一件可量化的事。常规的随机抽样缩减,比如直接均匀抽稀,看起来省事,但稀少了极端场景的概率权重,而概率距离削减能保证在期望意义上新旧分布的差距最小。

3.2 同步回代削减的步骤与“快”在哪里

严格意义的同步回代削减(Simultaneous Backward Reduction)是这样操作的:

  1. 初始给每个场景赋相等概率π_i=1/N
  2. 计算所有场景对之间的Kantorovich距离矩阵(通常用场景向量间的某种范数距离乘以场景概率)
  3. 找到与其他场景距离最近、删除后对整体概率距离影响最小的场景j
  4. 删除场景j,把它的概率累加到离它最近的保留场景上
  5. 更新场景集,重复第2步,直到达到目标场景数

这个算法的理论性质很好,但复杂度高。N个场景时,每轮都要更新距离矩阵,总计算量接近O(N^3),两千个场景跑下来也要很长时间。所谓“快”,就是在工程实现上做了加速处理。我常用的方案有两种:

第一种是“快速前代选择(Fast Forward Selection)”,不是每次寻找对整体距离贡献最小的被删场景,而是按每个场景到其他场景的最小距离做预排序,优先删除“周围密集度高”的场景,然后用回代方式更新剩余场景概率。这个方法在N=2000时能把削减耗时从半小时压到一两分钟。

第二种是“分块并行计算距离矩阵 + 近似最近邻”,在场景数上万时用KD树找最近邻,避免全矩阵计算。注意这只是近似加速,严格概率距离最优性会被打破,工程上通常可以接受。

我建议的顺序是:先用快速前代选择把场景从2000削减到200,再用严格的同步回代从200削减到目标数量。这样既保证了大批量削减的效率,又在小规模阶段保证了最优性,工程上的性价比最高。

3.3 削减多少合适:场景数量、计算时间与误差的权衡

削减数量不能拍脑袋,我一般会做一组敏感性分析。下表是我在算例里得到的典型结果(目标函数为次日期望运行成本):

保留场景数削减耗时(秒)求解耗时(秒)期望运行成本(元)成本偏差
1900(不削减)-约800012036基准
5096326122051.40%
2061145123902.94%
104088127836.21%

可以看到,从1900削到50个场景,期望成本偏差只有1.4%,而求解耗时从8000秒降到326秒,这是质变级的提升。继续从50削到20,偏差扩大到2.9%,还在可接受范围;削到10个场景时,偏差超过6%,这就有点危险了——尤其在极端天气日,尾部风险会明显低估。

所以我的经验是:对于典型的VPP微网,20到50个代表场景是比较甜的区间;如果日内还要做滚动修正,可以取20个,因为日内还有纠正机会;如果只依赖日前调度且可调资源有限,宁可取50个。削减完记得把各场景概率做归一化,并且要保留原始场景集中重要事件的发生频率特征,而不是只保留数学期望。

4. 随机优化日前调度模型的构建与求解

场景削减完成之后,真正进入“重头戏”——随机优化调度模型。与确定性优化最大的不同,是决策变量分为两个阶段:第一阶段变量在第二天开始前就要敲定,不随场景变化;第二阶段变量可以在场景实现后进行适应性调整。

4.1 目标函数怎么设置才“真实”

目标函数不是越复杂越好,但要尽可能真实地反映运行诉求。我的微网算例采用期望运行成本最小化,包括这些成本项:

  • 向配网购电费用(分时电价)
  • 向配网售电收入(一般按上网电价计,但要设约束防止低买高卖套利)
  • 储能充放电的损耗成本与寿命折算成本
  • 弃风弃光惩罚成本
  • 失负荷惩罚成本

其中储能寿命折算这一项很多人会漏掉,但反复深度充放电对电池寿命影响很大,如果不把折算成本放进目标函数,优化结果往往会让储能频繁以最大功率充放。我按循环寿命和全生命周期成本折算得到的损耗系数大约是0.12元/kWh,放进去之后储能动作明显温和了。

目标函数的场景期望形式如下:

min Σ_s π_s · [ Σ_t ( p_buy(t)·P_buy(s,t) - p_sell(t)·P_sell(s,t) + C_es·(P_ch(s,t)+P_dis(s,t)) + C_curt·P_curt(s,t) + C_ll·P_ll(s,t) ) ]

其中π_s是场景s的概率,P_buy和P_sell是联络线购售电功率,C_es是储能损耗成本系数,C_curt是弃能惩罚系数,C_ll是失负荷惩罚系数。惩罚系数设置的关键是让惩罚量值足够大,确保模型只有在万不得已的情况下才会弃能或失负荷,同时又要防止过大的惩罚系数导致数值病态。

4.2 约束条件的层次与细节

约束条件需要分几层来搭:

第一层是功率平衡约束。每个场景、每个时段的源荷功率必须平衡,包含风电、光伏、储能放电、购电、可调负荷下调量之和等于负荷、储能充电、售电、弃电、失负荷之和。这是所有调度模型的底线约束。

第二层是储能约束。SOC递推方程、SOC上下限(我设的是10%~90%)、充放电功率上下限、以及充放电互斥约束。充放电互斥在连续变量下无法表达,必须引入0-1变量,这也是模型变成MILP的原因。

第三层是联络线约束。与配网的交互功率要设上限(我的算例是±400kW),同时购售电不能同时发生,避免模型通过买卖套利制造出虚假的经济收益。

第四层是可调负荷约束。可调负荷的调节量有上下限,且一天的累计调节量要有限制,不能让人家工厂或者用户一天被频繁调整多次。

4.3 两阶段结构与非预期性约束

这个结构值得单独说明一下。第一阶段决策包括:储能各时段充放电计划(计划值)、联络线购电计划(计划值)、可调负荷基准调节量。这些变量不带上标s,也就是不论第二天实际来的是哪个场景,这些计划都得按部就班执行。

第二阶段变量包括各场景下的弃电量、失负荷量、储能实际充放电偏差、购电偏差修正。它们带上标s,可以在场景实现后调整,用来模拟“实际运行中的实时平衡手段”。

这里最关键的是非预期性约束:第一阶段变量必须对所有场景保持一致,不能“提前知道”明天是晴天还是阴天。初学者最容易犯的错误就是让决策变量带上场景下标,导致模型可以针对每个场景分别做完美决策,产生“旁观者效应”——结果期望成本好看得吓人,实际执行时根本无法复现。

求解方面,我用的求解器是Gurobi,MILP模型大概有2万多个变量、4万多个约束,50个场景下求解时间约5分钟,完全能接受。如果预算有限,可以考虑开源的HiGHS,但求解速度和数值稳定性会差一些,尤其是大规模场景时需要多留意。

5. 算例验证:削减效果与调度结果到底怎么评价

模型搭完、求解跑通,还不能说工作结束了。真正的挑战是回答两个问题:随机优化比确定性优化到底好在哪?削减后的场景能不能代表真实不确定性?

5.1 基准设置与对比结果

为了说明随机优化的价值,我设置了三组对比:

  • 确定性调度:用预测的“最大概率场景”作为唯一输入
  • 随机优化(50场景):用削减后的50个场景做期望优化
  • 随机优化(20场景):用削减后的20个场景做期望优化

评价指标包括期望运行成本、实际执行时的失负荷概率(LOLP)、弃风弃光率、联络线功率越限次数。

算例结果显示,确定性调度的期望成本虽然名义上最低,但实际执行时一旦风光出力偏离预测值,失负荷概率高达8%左右,弃电率也接近10%。而随机优化把失负荷概率压到了1%以下,弃电率降到3%左右,期望成本比确定性方案高出约2.5%,但这多出来的成本相当于“保险费”——换来的是大幅降低的断电风险和计划不可行风险。具体数值如下表:

方案期望成本(元)失负荷概率弃电率联络线越限次数/日
确定性调度114308.2%9.8%3
随机优化(50场景)122050.6%2.1%0
随机优化(20场景)123901.2%3.3%0

从表中可以看出,50场景的随机优化方案虽然成本比确定性高约6.8%,但运行可靠性指标发生了质的改善。20场景方案在可靠性和成本之间取得了一个更均衡的位置,适合日内有修正手段的场景。

5.2 削减前后调度结果的差异与原因

这里我想特别讲讲20场景方案和50场景方案的差别。表面看成本只差1.8%,但我做了逐场景回代检验后发现,20场景方案在某些极端场景下的失负荷量明显偏大。原因是当场景数太少时,那些概率虽小但后果严重的尾部场景在削减过程中被合并到了邻近的正常场景里,相当于把“黑天鹅”事件给平均掉了。

这给我们的启示是:评价场景削减效果,不能只看期望成本的偏差,还要看削减后场景集对极端分位数的保真度。我的做法是计算削减前后场景集在5%分位数和95%分位数处的出力值偏差,如果偏差超过10%,就需要增加保留场景数。

5.3 我的校验流程:用历史日做“影子运行”

模型参数全部整定后,我还做了一件很重要的事:取出历史记录中几个典型日(比如大风日、阴雨日、极端高温日),把当天的真实风光和负荷曲线喂给已经确定的日前计划,仿真各时段功率平衡情况。

这个方法我称之为“影子运行”,相当于让调度计划在历史上先“演习”一遍。结果发现,随机优化方案在阴雨叠加高温的极端日表现尤其好,而确定性方案在高负荷日容易出现联络线越限,因为它的备用容量完全基于预测精度来设置,一旦预测偏差超过预期,物理上就兜不住。

通过“影子运行”,还能发现模型参数的一些不合理设定。比如我最初把失负荷惩罚系数设成50元/kWh,结果模型在高温日宁可高比例弃风也要把可调负荷留作备用,这个行为明显不符合运营倾向。后来我把弃风惩罚提高到80元/kWh,失负荷惩罚保持50元/kWh,模型的行为才变得合理。参数整定不能靠公式,必须结合实际调度倾向反复试。

6. 实操中容易踩的坑与经验总结

走到这一步,整套流程算跑通了。但我回过头去复盘,发现真正耗时间的不是模型推导和编程,而是各种看似不起眼的细节。下面按实操顺序梳理几个容易踩的坑。

6.1 数据准备阶段:历史数据的“脏”完全会传导到场景里

我建议不要直接拿原始数据拟合分布。历史数据里常混着检修日、通信中断日、限电日等非正常运行日的数据,这些样本会严重污染分布参数。比如某天因为配网检修导致风电全场停机,出力恒为0,如果把这个样本放进威布尔拟合,尺度参数会被明显拉低,之后生成的场景整体都会偏保守。

我的处理流程是:先做数据清洗,删除出力或负荷恒为0且持续时间超过2小时的异常日;再按季节和天气类型分桶,每个桶单独拟合分布参数;最后做归一化处理。这步工作量不小,但省了后面所有环节的返工。

6.2 场景削减阶段:概率归一化与相关性保持

同步回代削减过程中,由于被删除场景的概率要累加到最近保留场景上,削减后各场景概率会出现微小偏差。一定要在削减结束时重新归一化,否则优化模型的目标函数期望值会存在系统偏差,场景数越少偏差越明显。

还有一个容易忽略的点:削减是按“场景向量距离”来合并的,所以两个在空间上很接近但时间分布截然相反的场景可能被合并(比如一个场景是上午光伏强、下午弱,另一个是上午弱、下午强,如果整体能量相近,欧氏距离可能很小)。这会造成调度结果在时序上失真。解决办法是削减前在场景向量里加入时段权重,或者分时段各减一次再接起来,让时间分布特征被保留。

6.3 模型求解阶段:注意数值规模与求解器参数

MILP模型里既有kW级别的功率变量,也有百分数级别的SOC变量,数值尺度差异很大,求解器默认的容差可能会导致“虚假可行解”。我习惯把功率变量统一换算成MW(比如0.4MW而不是400kW),SOC用0到1之间的标幺值,这样模型数值尺度统一,求解速度能提升20%以上,解的质量也更稳定。

求解器参数方面,MIPGap我一般设为0.5%,RN(随机数扰动)和MIPFocus参数也会根据模型规模调整。小规模模型用默认参数问题不大,但上千变量模型如果直接默认参数跑,很有可能陷入长时间的“涌现式”搜索。

6.4 工程落地:策略不是越复杂越好

最后说一点我想强调的体会。随机优化调度在学术上是成熟方法,但工程落地时一定要考虑运行人员的接受度和系统的可维护性。我见过有的团队把模型加得非常复杂,源侧Copula、荷侧深度学习预测、市场电价随机场景全部塞进去,结果模型参数有几百个,运行调度员根本不敢用,最后又退回简单规则调度。

我的习惯是:先跑通“蒙特卡洛生成 + 距离削减 + 期望优化”的基础链路,确认每个环节的输入输出都能解释、可审计,再逐步增加复杂度。比如先只做源侧随机,验证无误后再加入荷侧随机;先做日前单次优化,稳定后再接日内滚动修正。每一步都在实际数据上看到收益,才保留这个复杂度。

另外,随机优化给出的“最优计划”本质上是一个期望意义上的计划,不代表当天一定完美,但它一定比确定性计划更不容易被现实打脸。配合日内15分钟级的滚动修正,整体运行效果才会非常稳。这些年我实际运行微网和聚合虚拟电厂的经验是:日前随机优化定骨架,日内滚动修正调细节,这套组合基本能扛住绝大部分天气突变和市场波动,比单纯堆高预测算法或者扩大备用容量都经济得多。

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

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

立即咨询