做微网动态经济调度的人几乎都要和“场景”这两个字打交道。注意这里说的场景跟最近很火的那种“上传一段视频生成对应的三维场景”完全不是一回事。在电力系统的语境里场景是指对风电、光伏、负荷这些不确定量未来可能呈现的“典型样子”的采样描述——说白了就是把“未来可能发生什么”这件事用一组带概率的时间序列表达出来。而场景生成与削减就是这套流程里最核心、也最容易被忽视的两个环节。这篇文章面向正在做微网调度建模的研究生、工程师或者刚接手随机优化项目、被一堆分布函数和聚类算法搞得头疼的同行。我会把这套东西从原理到实操拆开讲清楚为什么要用场景场景怎么生成生成完为什么还要削减削减到什么程度才合适以及我在实际项目中踩过的坑。全程不堆公式但关键的流程和参数逻辑都会给到方便你回去直接改造成自己的方案。1. 先想明白动态经济调度为什么非要“场景”不可1.1 动态调度和静态调度的本质差异传统经济调度很多时候只关心“某一个时段”怎么把发电成本压到最低。但微网里的动态经济调度是另外一回事它要在一个调度周期内常见的是一天24小时、96个时段每个时段15分钟做出连贯的决策。这里的关键是“连贯”上一时段的储能充放电决定了当前时段的荷电状态当前时段的机组出力又受到爬坡速率的限制而负荷和新能源出力时刻在波动。任何一个时段的决策错了后面的时段都会被拖累。这就带来一个很头疼的问题你没法用一个“确定性的未来”来做决策。光伏出力受云层遮挡影响风电场出力跟着风速波动负荷更是随着人们的生产生活节奏起起伏伏。如果调度模型把这些都当成确定值处理那算出来的方案在真实运行中往往会出问题——要么备用容量不足关键时刻顶不上要么过于保守白白弃掉不少清洁能源。场景生成的意义就在于此它把“未来有很多种可能”这件事显式地放进优化模型里让决策在统计意义上更稳健。1.2 不确定性到底长什么样搞场景之前得先知道自己面对的不确定性是怎么分布的。不同源荷特性的差别非常大这也是许多新手上来就套正态分布然后翻车的原因。光伏出力在时间上高度集中在白天而且受云层影响呈现出“多云天出力大幅波动”的厚尾特性很多文献用Beta分布来描述光照强度的随机性。风速则更经典双参数Weibull分布是行业标配它能够很好地刻画“大多数时候风速不高、偶尔来一场大风”的偏态特性。负荷的随机性相对温和但一天内早晚高峰的结构性波动很强常用的建模方式是在预测曲线附近叠加正态分布或t分布的扰动项。除了单变量分布还得注意时间相关性。相邻时段的天气不是独立的——如果下午三点起了云这团云大概率四点钟还在。用独立采样生成场景会得到一条剧烈抖动的伪风速曲线这种场景送入调度模型只会让优化器疲于奔命算出来的储能充放电策略完全没有参考价值。所以场景生成不是说“抽样就行”而是要尽量保留时序自相关性。1.3 场景在动态经济调度中的“生态位”如果你接触过两阶段随机优化应该对场景在其中的位置有印象。随机动态经济调度一般写成这样的形式外层决策是“今天开机哪些机组、储能初始状态怎么设定”这些决策在一开始就要定下来内层决策是“在每个可能出现的场景下各时段怎么调出力、怎么充放电”这些决策要等到场景观测到之后再调整。场景集就是这个模型的核心输入它决定了期望成本怎么算也决定了约束条件要对哪些情况满足。这里有个两难。场景数太少不足以覆盖真实情况优化的结果对不确定性不敏感跟确定性调度区别不大场景数太多比如一次性生成5000个场景、每个场景96个时段优化模型的变量规模直接飙升到几十万甚至上百万普通商用求解器跑起来非常吃力项目迭代效率也受不了。所以就有了“场景削减”这个环节在尽量不损失分布信息的前提下把场景集压缩到可计算的规模。这本质上是精度和算力之间的博弈而削减算法的好坏直接决定这场博弈的平衡点落在哪里。2. 场景生成从概率分布到可计算的“未来切片”2.1 蒙特卡洛采样的底层逻辑与适用边界场景生成最常见的人门方法就是蒙特卡洛采样。思路很简单先根据历史数据估计出不确定量的概率分布然后从分布里反复抽样每一组抽样结果就构成一个场景。以风速为例如果假设它服从双参数Weibull分布那么只需要从历史风速里用极大似然法估计出形状参数和尺度参数就能用随机数发生器生成大量风速序列。但这里有个细节直接独立抽样得到的是“一堆没有时间记忆的点”不是一条合理的风速曲线。我在实际项目中处理这个问题时常用的做法是先估计相邻时段风速的自相关系数然后用一阶自回归模型来生成时序序列也就是在上一时段风速的基础上加上一个服从条件分布的随机扰动项。这样生成的场景曲线既有统计分布上的正确性又保留了“下午的风和上午的风有关联”这个基本物理常识。同样地辐照度、负荷也可以按这个思路改造。蒙特卡洛方法的优点就是灵活、实现简单不管分布多奇怪只要采样次数足够多统计特征总能逼近真实分布。缺点也很明显如果想要覆盖小概率但高影响的事件比如极端寒潮导致的负荷尖峰纯随机采样得抽很多次才可能碰到一次。如果只是做常规调度分析这个缺点一般还可以接受但如果你要做极端工况下的校核就得上重要性采样或者后面会提到的针对性场景生成方法了。2.2 时间序列模型让场景带“记忆”前面提到自回归思想再往前走一步就是ARIMA这类经典时间序列模型。ARIMA的核心是把一个时间序列看成“过去值的线性组合白噪声”差分项负责处理趋势和非平稳性。在微网场景生成的场景里ARIMA通常用来给负荷或风速的“波动序列”建模而不是直接对出力本身建模。我自己更常用的做法是先用历史数据训练ARIMA模型得到一个预测值和残差的标准差估计然后蒙特卡洛采样残差序列来生成备选场景。这样生成的场景天然具备正确的时序相关性并且因为残差一般近似服从正态分布采样和实现都比较顺手。不过ARIMA也有局限它对非线性特征和突变事件的刻画能力一般遇到天气过程性突变比如冷锋过境时模型的预测区间会明显偏窄——换句话说它给出的场景集可能会系统性低估极端事件的概率。用ARIMA生成场景时有几个参数需要反复调阶数p和q的选择一般用AIC/BIC准则帮忙筛选但也不能全信信息准则还得结合业务需求做人工校验差分的阶数d要谨慎差分过多会把有用的长期信息也差掉导致生成的场景虽然平稳但失去了本来应有的季节特征。我遇到过最典型的问题就是把光伏出力序列强行做了二阶差分结果生成出来的场景全是围绕0波动的白噪声完全看不出一天之内日出日落的形状后来改成按日类型分别建模才解决问题。2.3 相关性问题用Copula表达变量间的“默契”微网里很少只有一个随机量往往是光伏、风电、负荷同时存在而且它们之间彼此相关。比如同一个微网内的光伏和负荷在夏季往往有正相关性——太阳越大空调负荷越高风电和负荷之间的相关性又在不同季节呈现完全不同的模式。如果只对每个变量单独建模、独立采样生成的场景集就丢失了变量之间的“默契”调度结果自然失真。处理多维相关性业界最成熟的方法就是Copula。Copula的通俗理解是把每个变量的边缘分布各自长什么样和变量之间的连接结构彼此怎么联动拆开建模。边缘分布可以用前面提到的Beta、Weibull或者非参数法来拟合连接结构则用Copula函数来描述常见的有Gaussian Copula和t-Copula。把这个思路翻译到具体操作里大致是三步第一步把每个变量的历史观测值转化为对应的均匀分布分位数第二步用这些分位数估计Copula函数的参数第三步从Copula中联合采样再反变换回各变量原始分布。这套方法我实测下来最关键的收益不是相关系数更精确而是生成场景时能保持变量间的尾部相关性——尤其是极端天气下“大风和低负荷同时出现”这类情况。这种场景看起来冷门但对微网是否需要在夜里保留备用容量、储能要不要留底电影响非常大。要是用独立采样这类场景出现的概率会明显偏低导致调度策略在真正的恶劣天气面前缺乏抵抗力。2.4 场景生成阶段最容易翻车的三个细节场景生成看起来就是“抽样”但实际操作中翻车率极高。我梳理一下最常踩的坑基本都是项目里真实遇到过的。第一个是数据泄漏。有人直接把全部历史数据拿去拟合分布又用同一段数据的均值曲线来生成场景结果评估出来误差极低到了线上立刻“现原形”。正确做法是把历史数据严格切成训练段和测试段生成场景时只用训练段的信息测试段只用来做评估。第二个是样本外极端事件被平滑掉。概率分布建模天然会把低频极端事件当成“离群点”处理拟合时它们的贡献很小导致生成场景集里几乎没有极端天气的影子。这种情况下我一般会单独构造一个“极端场景库”把历史上有记录的新能源停机、负荷尖峰等现象做成固定场景按一个小概率附加到场景集里而不是指望纯随机采样能自然覆盖。第三个是季节混淆。冬天的负荷形态和夏天的完全不一样把一年的数据混在一起拟合一个分布生成出来的场景一定是四不像。我的习惯是按季节甚至在过渡季节按月分别建立模型宁可多维护几套参数也要保证场景的物理意义是清晰的。3. 场景削减在“精度”和“算力”之间找平衡3.1 削减的本质不是“删数据”而是概率测度的近似不少人第一次接触场景削减时会下意识觉得这就是从一堆场景里挑出几个“代表”把相似的删掉。这个理解方向没错但不够准确。站在数学角度看原始场景集定义了一个经验概率分布削减的目的是找到另一个规模更小的分布让二者的“距离”尽量小。这个“距离”在文献里常用Kantorovich距离或者Wasserstein距离来度量——听起来高大上你可以把它理解为两个分布之间“搬运概率质量”的最小代价。所以场景削减的结果不只是一组更少的曲线它同时还必须给每个保留场景分配一个发生概率。这个细节非常重要如果削减之后仍然用等概率来对待每个场景本质上等于刻意扭曲了分布信息。实际操作中很多人拿着聚类算法把场景聚类完、取个簇心就走完全不考虑簇内场景原始概率的累加导致削减后的期望值偏移很大。后面做优化求解的时候目标函数里每个场景的权重一旦错配成本误差就很容易被放大到不可接受的程度。3.2 快速前向削减法原理与手算直觉快速前向削减法Fast Forward SelectionFFS是场景削减领域最经典的方法之一它和另一种叫同步回代削减Simultaneous Backward Reduction的方法是互补的关系。FFS的核心策略是“贪心”式地、从原始场景集中逐个挑出最能代表整体分布的场景直到凑够目标数量。具体流程可以这样描述每一步迭代它从剩余未入选的场景中挑一个出来使得把它加入已选集之后两个场景集之间的Kantorovich距离增量最小。这个做法兼顾了两件事——已选场景彼此之间不能太像不然冗余同时已选场景又得尽量覆盖原始场景集中的“高密度区域”。等迭代到目标数量之后再把原始场景按与哪个已选场景距离最近进行分配并把概率累加给对应的代表场景。这个过程听起来不复杂但在实操中用纯Python循环实现时要小心计算复杂度。原始场景几千个、每个场景几十上百个时段时场景间距离矩阵就是百万级规模每一步迭代还要做贪心搜索不优化一下矩阵运算效率跑起来会非常痛苦。我习惯先把所有场景间的成对距离向量化计算并缓存下来后续的贪心搜索直接对距离矩阵做索引操作速度能提升一个数量级。3.3 聚类方法从工程便利性出发的替代方案如果说FFS是“精雕细琢”K-means聚类就是“大刀阔斧”。工程上我接触到的微网项目里用K-means做场景削减的反而更多原因无他实现快效果也不差。做法很简单把每个场景当成多维空间里的一个点维度数等于时段数然后用K-means算法聚成预先设定好的K类取每个类的中心向量为代表场景类的权重由类内场景数量或者考虑原始概率后的加权和决定。这里有几个工程细节值得注意。一是要归一化。光伏出力的数值范围是0到装机容量负荷可能是几千千瓦风速又是完全不同的量纲如果不做归一化直接扔进聚类算法聚类结果基本由数值大的变量主导。二是距离度量。K-means默认用欧氏距离它在场景削减场景下通常够用但如果场景的形态更重要比如“先涨后跌”和“先跌后涨”虽然均值相同调度意义却不同可以考虑用动态时间规整距离或基于形状的距离不过计算成本会高不少需要权衡。三是K值的选择。这里没有一劳永逸的办法我一般会同时算3~5个K值下削减前后概率分布的Wasserstein距离画一条误差随K值变化的曲线找到“误差开始变平缓”的拐点那个K值就是性价比最高的选择。用K-means做削减时还有一个容易出问题的地方聚类中心是类内场景的均值这种做法天然会把类内的极端波动“平均”掉。如果原始场景集中包含特意构造的极端场景聚类之后它们可能被稀释在一个大簇里等你想在校验恶劣工况时去找对应的极端场景已经找不到了。针对这种情况我通常的补救方案是在K-means削减之后把原始场景集中距离最终代表场景最远的那几个极端场景单独保留下来再按一个小概率附加进削减后的场景集。3.4 削减效果评估三条硬指标场景削减做完到底行不行不能靠感觉得有量化标准。我每次做项目评审时都会给出三组数字比任何解释都管用。第一个是分布层面的指标也就是削减前后两个概率分布的Wasserstein距离。这个值越小说明削减后的场景集在“概率空间”上越接近原始场景集。第二个是统计特征层面的指标比如新能源出力和负荷的期望值、标准差以及各时段分位数。削减后的场景集应该在这些统计量上与原场景集保持接近一般期望值误差能控制在2%以内就算很好了分位数误差尤其要关注尾部——如果削减后的5%分位数偏差过大说明极端场景信息丢失了。第三个是经济层面的指标把两套场景集分别代入同一个动态经济调度模型比较优化出来的期望运行成本、储能充放电次数和弃风弃光率。这个指标最直观也最有说服力。我见过不少场景集在统计指标上完美但代入模型后成本突变好几万块的情况原因就是细节形态比如出力曲线在第13时段附近的尖峰被破坏了。三条指标之间需要平衡不必强求每一项都最优。一个经验性的做法是做削减时以Wasserstein距离为主目标削减完成后用另外两个指标做复核如果统计指标和经济指标偏差过大再回头调整削减数量或换一种削减算法。4. 一套能落地的随机动态经济调度实操流程4.1 数据准备和参数设置光讲原理不过瘾我把一套实际跑通过的流程骨架整理出来给你做个参考。调度周期设为一天分辨率15分钟一共96个时段。微网内主要包含光伏1000kW、储能300kW/600kWh允许从外部电网购电但购电价格分峰谷平时段。负荷数据取某工业园区夏季节典型日光伏出力用Beta分布描述负荷用ARIMA扰动生成。下面是基础参数表参数数值备注调度周期24h / 96时段每时段15分钟光伏容量1000 kW场景生成主要对象储能容量300 kW / 600 kWhSOC范围0.1~0.9储能充/放电效率0.95简化对称效率购电峰值/平时/谷值电价1.2 / 0.75 / 0.4 元/kWh跟当地电价政策有关弃光惩罚0.3 元/kWh仿真中对未消纳光伏的惩罚旋转备用需求负荷的5% 光伏出力的10%应对不确定性的保守策略这套参数不算复杂但足以体现动态经济调度里“动态”二字的含义储能SOC的时序递推、机组爬坡约束、每个时段购电决策对后续时段可用容量的影响这些全都耦合在一起。4.2 从原始数据到调度方案的四步走完整流程可以拆成四步我每个项目都会按这个顺序推进第一步数据预处理。把历史光伏、负荷数据的异常值清掉缺失片段用前后时段插值补齐然后按季节切片。这个步骤看似普通但最影响后面所有环节数据不干净生成场景的分布参数就是错的后面一切努力白费。第二步场景生成。用蒙特卡洛方法生成2000个原始场景每个场景包含96时段的光伏出力和负荷曲线。注意这里要用带时序相关的采样至少加一阶自回归项否则场景曲线看起来“电锯式”抖动。如果项目里同时有风速和光伏就引入Copula把相关性做进去。第三步场景削减。我们在这套流程里用FFS把2000个场景削减到30个。削减完成之后把30个场景的概率归一化确保概率总和为1同时打印削减前后光伏出力的期望值曲线来直观判断质量。原本用一个5000维的场景集做优化现在压缩到30个场景模型规模缩小了两个数量级求解时间能控制在几分钟以内。第四步构建并求解随机动态经济调度模型。目标函数是期望运行成本最小化购电费用 弃光惩罚 储能运维成本。约束条件包括每个时段的功率平衡、储能SOC递推约束、充放电功率上下限、购电功率上限以及一个跨场景耦合的备用约束。求解器我一般用商业求解器搭配YALMIP或直接写Python接口模型规模不大求解很稳。4.3 小型算例的结果长什么样我把这套流程跑过一遍拿到的结果规律性很强削减后的30个场景光伏出力期望值曲线和原始2000个场景的曲线几乎重合波动幅度的分位数带也保持得不错。调度方案的表现是储能基本按照“光伏大发时充电、晚高峰时放电”的模式运行购电尽量集中在谷价时段——这符合直觉也验证了模型逻辑没有跑偏。最让我关注的一个数字是削减前后调度成本的偏差。在这个算例里用30个场景求出的期望运行成本和2000个场景求出的值相差不到1.5%。这说明FFS把关键分布信息保留住了。之前试过用等概率取聚类中心的做法成本偏差直接到6%以上原因就是场景削减后的概率权重没处理好。这个对比充分说明了为什么场景削减不能只砍数量、不管概率。还有一个细节削减后场景里保留了1~2个“光伏出力明显偏低”的尾巴场景。这两个场景概率不高但它们负责撑起备用约束让储能低电量运行时段不会出现备用缺口。这正好呼应前面说的削减场景时不能把极端场景一刀切掉。5. 常见问题与实战排查5.1 削减后概率分布“失真”怎么判断有一次我在项目中削减完场景画出来负荷的期望曲线跟原始曲线偏差很小但带入优化模型后购电成本的P95分位值明显偏低。排查之后发现问题出在负荷尖峰场景原始场景集里有一批负荷尖峰出现在晚高峰的场景在FFS迭代过程中它们没有被单独选中而是被分配给了相近的低负荷代表场景概率被摊薄尖峰信息被抹掉了。解决思路有两个方向。一个是把负荷、光伏分开做削减而不是拼在一起做联合削减因为联合削减时不同变量的削峰会互相掩盖分开削减、再把结果组合起来可以针对性保护关键形态。另一个是在削减目标函数里对极值时段加权也就是给晚高峰时段的负荷偏差更大的权重这样削减算法会优先保住高峰场景。5.2 生成场景波动太“平缓”或太“剧烈”的调参方法场景生成的波动幅度直接取决于采样时扰动项的标准差。如果生成场景的曲线都贴着历史均值走看不到应有的波动那大概率是扰动标准差设小了。反过来如果场景曲线抖得像噪声完全没有时序特征多半是时序相关参数设得太低甚至忘了加自回归项。我常用的校准办法是拿生成场景集算一遍各时段的标准差跟历史数据的时段标准差比较。如果各时段的标准差在历史值的80%~120%范围内我就认为波动幅度是合理的。差得多了就去调节扰动项和自回归系数。这个方法简单有效比跑到优化阶段再回来排查快得多。5.3 调度结果对场景数目“不敏感”的隐情有时候你会发现场景数从500减到20期望运行成本几乎不变看起来很美好。但别高兴太早这往往不是削减算法厉害而是模型本身对不确定性不敏感——比如约束里根本没有备用容量没有储能SOC边界条件或者目标函数里没有弃光惩罚。模型感知不到不确定性的影响自然也不在乎场景数量。这种情况需要回头审视模型设计。一个最直接的验证方法是评估松弛变量检查随机调度结果中有多少时段处于备用约束的临界状态。如果几乎不触碰临界说明不确定性约束太松如果频繁触碰说明模型对场景敏感削减的质量才会真正影响结果。5.4 削减结果不可复现的排查思路很多同行做场景生成时图省事随机种子不固定每次运行生成不同的场景、削出不同的结果优化结论也随之漂移写报告时才发现结果对不上。这个问题解决起来很简单在采样和聚类/削减环节里显式固定随机数生成器的种子最好在代码里把随机种子和关键参数写成一个配置文件每次运行都留档。如果是同一份数据、同一个种子还出现结果不一致那就得检查代码里是否有并行计算的竞态条件或者是求解器线程数设置不一致导致优化结果有细微差异。这种情况在Matlab和Python混合编程的工程里不少见排查起来比较费时间但一旦规范了随机种子、求解器参数的统一入口问题基本能根除。我玩这套流程几年的体会是场景生成和削减看起来是数学问题真正难的是工程细节。分布参数差一点、概率权重错一点、极端场景丢一个最后都会体现在调度方案的经济性和可靠性上。所以每做一个新项目我都会先跑一遍“生成→削减→调度→评估”的全流程闭环确认统计指标和成本指标都能对齐再扩展规模或者改场景模型。别嫌这一步麻烦它帮我省掉的返工时间比写一整段代码多得多。下次你遇到调度结果不合理又查不出模型问题时不妨先回头看看场景集本身是否靠谱多半会有意外发现。
阅读完成 · 觉得有帮助?