微网动态经济调度中的场景生成与削减:从蒙特卡洛到SBR

发布时间:2026/10/7 22:32:40
微网动态经济调度中的场景生成与削减:从蒙特卡洛到SBR 最近刷到一个视频上传一段视频就能生成对应的三维场景评论区都在感慨“场景生成”这件事越来越魔幻了。但对做微网动态经济调度的人来说“场景生成”这四个字完全是另一层含义——它不是为了重建三维空间而是为未来24小时的光伏出力、风电功率和负荷需求编排出若干条“可能的命运线”。这篇文章我就结合自己做微网动态经济调度的实际经验把场景生成和场景削减这两件事从头到尾说透为什么要做、怎么做、做完之后怎么用以及那些论文里不会写的坑。如果你是刚接触微网优化调度的研究生或者在做微电网能量管理系统的工程师又或者只是好奇随机优化里那一堆“场景”到底怎么来的这篇文章都值得你花二十分钟慢慢看。我会尽量不堆公式但该说清楚的原理和参数一个都不会少。1. 动态经济调度为什么绕不开“场景”这道坎1.1 微网的不确定性光伏、风电、负荷三座大山微网里最让人头疼的不是设备模型有多复杂而是输入数据本身就带着一大堆不确定性。屋顶光伏出力取决于云层遮挡的随机过程风电输出跟随风速的脉动负荷则受住户作息、气温、节假日甚至大型赛事直播的影响。这三类不确定性的统计特征还完全不一样光伏有明显的昼夜和季节规律风电有更长的持续性和空间相关性负荷则带有强烈的日内周期。我在一个校园微网项目里做过统计晴天和阴天之间光伏出力的日发电量可以差到七八成风速稍微变一下风机的出力就可能从额定功率掉到三分之一以下。所谓“预测曲线”本质上只是一个条件期望真实值会在它周围大幅波动。更麻烦的是这些波动不是孤立的——光伏弱的时候往往天气差负荷反而因为取暖或照明需求在涨这就在某些时段制造出非常极端的净负荷缺口。1.2 确定性调度的问题一条曲线扛不住一万种现实很多刚入行的同学会觉得只要把预测模型调准然后把预测曲线塞进经济调度模型里求最优不就完事了吗我一开始也是这么干的直到有一次调度方案在第二天吃了大亏预测出傍晚光伏还有15kW出力储能按照这个预测在午后多充了一些电结果现场一块大云层压过来光伏出力掉到只有2kW储能又已经快放空柴油机爬坡来不及最后只能甩掉一部分次要负荷。这事让我彻底明白了一个道理确定性调度把所有赌注押在一条曲线上而真实世界是无数条曲线的叠加。预测再准也只是把期望提高了极端情况依然存在而且恰恰是这些极端情况决定了调度方案安不安全。微网不同于大电网可调容量小、备用少、惯性弱一个偏差就可能触发越限、切负荷甚至设备保护动作。1.3 场景法解决的其实是“鲁棒性”问题场景法scenario-based stochastic optimization的思路很朴素与其只拿一条期望曲线做决策不如一次性把上百条可能的光伏出力、风电功率和负荷曲线摆到优化模型面前让调度方案在“所有可能发生的情况”下都能过关目标函数里再按各条曲线的概率做加权最终求的是期望成本最小、同时保证每种场景下的约束都成立。这就是“场景生成”和“场景削减”要做的事。前者把不确定性从统计分布变成一串具体的、可计算的时序曲线后者在这个基础上做减法把一千条曲线削减到几十条让优化模型在计算量可以接受的前提下依然能保留原始不确定性的关键特征。一句话总结场景生成管“怎么把不确定性说清楚”场景削减管“怎么把冗余信息删掉”。两者配合得好调度模型才能既算得动、又靠得住。2. 场景生成的主流打法从蒙特卡洛到生成式模型2.1 蒙特卡洛与拉丁超立方基础但别瞧不起最朴素的场景生成方式就是蒙特卡洛抽样。先根据历史数据拟合出光伏、风电、负荷的概率分布或者直接用经验分布然后独立随机抽样得到一组未来时段的功率序列。这个方法胜在简单写几十行代码就能跑缺点也明显纯随机抽样容易扎堆明明光伏出力低概率很小抽出来的场景里可能反而少见严重偏离的尾巴导致后面做经济调度时对极端情况估计不足。改进版的拉丁超立方抽样LHS值得一提。它相当于先把概率空间沿各维度等分成若干层再从每一层里强制抽取一个样本保证采样点在全空间均匀分布。用生活化的类比蒙特卡洛是在一块地里随机撒种子可能一边密一边疏LHS则是先把地划成网格每个格子里至少播一粒。同样的抽样数量下LHS得到的场景集合方差更小统计特性更稳所花代价几乎为零。我做实验对比过同样生成500个场景纯蒙特卡洛的期望出力曲线抖得厉害LHS则明显平稳尾部分位数也更接近历史实测分布。所以哪怕后面要上更高级的生成方法我也建议至少把LHS当“地板”来用。2.2 用时间序列模型和Copula把相关性“钉死”蒙特卡洛和LHS解决的是“单个时段怎么抽”的问题但它们有一个隐蔽的软肋——如果逐时段独立抽样生成的功率序列会是锯齿状的上一小时光伏还接近满发下一小时突然归零再下一小时又恢复。这种场景在物理上根本不可能出现而且一旦喂给调度模型爬坡约束会被严重夸张优化结果失去意义。所以工程上更靠谱的做法是用时间序列模型一次生成整条曲线把自相关结构带进来。对负荷ARIMA这类模型已经很成熟用历史负荷差分序列估计参数然后蒙特卡洛模拟残差的未来路径即可对风速可以先模拟风速序列再通过风机功率曲线换算成电功率对光伏则经常对晴空指数建模——先算理论晴空辐射再模拟云层引起的随机遮挡系数这样生成的曲线天然满足“有平滑波动、也有突降”的物理特征。多变量之间的相关性处理则要请出Copula。我举个具体例子校园微网夏季傍晚空调负荷和光伏出力往往负相关——太阳落山时光伏下降负荷却还在高峰。如果抽样时完全独立地抽负荷和光伏就会生成大量“傍晚光伏满发负荷低迷”的假场景反而把真正危险的“傍晚光伏低负荷高”组合稀释掉了。Copula的思路是把每个变量的边缘分布和它们之间的连接结构分开建模先各抽各的再用一个相关结构把它们“绑”起来这样生成的联合场景才能保住“光伏弱的时候负荷往往更高”这种真实相依性。在代码里这通常表现为先抽一组满足相关关系的均匀分布再分别做逆变换映射回各变量的实际功率值。2.3 生成式模型GAN和扩散模型的尝试与顾虑这两年深度学习也卷进了场景生成。GAN的用法是把历史光伏/风速/负荷曲线当作训练样本让生成器学习真实曲线的分布再批量输出看起来“很真”的场景。扩散模型的路子更是从低噪声逐步去噪生成样本图像生成那边效果一流做时序场景的潜力也被一堆论文看好。我个人的态度是可以试但要留着心眼。这类模型确实能生成风格非常逼真的曲线不像蒙特卡洛那样需要人工选分布。但它们在电力场景上有几个实际问题一是训练需要大量高质量历史数据微网现场往往只有一两年、还带缺测的记录二是GAN容易模式坍塌生成出来的场景种类变少极端天气可能在训练中被平均掉三是生成式模型的可解释性差你没法直观说出“这个场景对应什么天气”而这对调度员来说是重要的心理安全感。所以我现在的主流工作流里深度学习模型更多是作为交叉验证手段看看统计方法和真实历史分布有没有系统性偏差真正进调度模型做约束校验的场景集还是以“历史日筛选统计扰动”为主。3. 场景削减怎么从一千个场景里挑出最有用的一百个3.1 削减的必要性计算量的账要算清楚假设一个24小时动态经济调度模型机组加储能一共35个0/1状态变量连续变量几百个负荷和光伏同时引入500个场景那整数变量的总规模就变成35×500×2442万个现代求解器面对这种规模的MILP求解时间会从分钟级飙到小时级甚至直接内存爆炸。但反过来场景太少也不行少了信息损失大调度结果在真实世界的期望性能会明显变差。我自己的项目经验是对中等规模微网十来台设备、24小时调度生成1000个原始场景削减到50~100个是当前主流求解器能在合理时间内出解的区间。削减就是在N大步N小的天平上找那个甜点。3.2 同步回代消除法与快速前向选择经典削减算法的原理场景削减领域最经典的算法是同步回代消除法SBR和快速前向选择FFS。它们都基于同一个思想用削减后的场景集去逼近原始场景集的概率分布两个分布的差异用Kantorovich距离来衡量——直观理解就是“把一堆沙子从A地形搬到B地形所需的最小工作量”搬得越少两个分布越像。SBR的做法是迭代地删场景。每一步都找出“删掉会对分布影响最小”的那个场景把它删掉再把它的概率匀给最近的邻居。伪代码大致是输入原始场景集 Ω {ξ1, ..., ξN}保留数量 K 初始化每个场景概率 p_i 1/N while |Ω| K: for i in Ω: 找 j* argmin_{j≠i} d(ξi, ξj) // 最近邻 删除代价 p_i * d(ξi, ξj*) // 概率乘距离 选 k argmin 删除代价 把 p_k 加到 p_{j*} 上 从 Ω 中删除 ξk这里的距离函数 d(ξi, ξj) 通常取欧氏距离的某种加权形式。SBR的优势是高效每步只需维护最近邻信息工程实现容易缺点是一旦某个场景被删了它的信息就彻底没了只能靠“概率转移”来补救。FFS的思路恰好反过来它是逐步“选”场景而不是“删”场景。从空集出发每轮从剩余候选中挑一个能使已选集合与原始分布之间距离增量最小的场景加入保留集直到凑满K个。这种方式在保留分布形状上往往比SBR更精细代价是计算开销更大。实际对比测试中当需要从1000个场景削到50个时FFS在尾部近似上通常更好一点但SBR基本够用速度还快一个数量级。工程上我建议先用SBR跑一轮基准结果不满意再上FFS。3.3 K-means聚类削减工程上最简单也最容易用错比SBR更简单粗暴的方法是K-means聚类。把每个场景看作一个24维向量直接聚类成K个簇每个簇的质心代表该簇场景每个簇内原始场景的个数占总数的比例就是新场景的概率。优点太明显了代码现成、跑得快、处理1万个场景也不慌。但我踩过几个坑必须提醒你。第一个坑是“质心平滑化”。K-means求出来的是簇内平均曲线平均会抹平波动导致特征场景比真实场景平滑很多。拿这种平滑曲线去做经济调度储能会被安排得更乐观实际运行时波动一来就触界。我的对策是聚类后不用质心而是在每个簇里挑那个离质心最近的真实历史场景作为代表这样既保留波动特征又不牺牲聚类效率。第二个坑是“距离度量选欧氏距离时本质是把所有时段一视同仁”。但微网调度对高峰时段的偏差远比对凌晨时段的偏差敏感。想解决这个可以在距离计算里给峰值时段更高的权重或者干脆换成动态时间规整DTW来处理相位偏移。当然DTW计算量不小在数千个场景两两算距离会很肉疼这个权衡要自己把握。4. 削减后的场景如何接进动态经济调度模型4.1 场景概率更新删完别忘了重新归一化很多新手在削减完场景后直接拿一个新场景集去跑模型结果约束全被低估——问题出在概率更新。以SBR为例删除场景后其概率要累加到最近的保留场景上所以削减后的场景概率不再是均匀的有的场景被合并得多概率可能高达百分之十几有的场景孤零零的概率还不到百分之一。在建立优化模型的目标函数时必须用这个更新后的概率做加权否则大概率场景和边缘场景对期望成本的贡献就失真了。我习惯在削减结束后立刻打印一份概率分布检查看最大概率和最小概率的比值是否在合理范围一般不超过10倍。如果某个场景概率被累加到0.2以上说明它周围有大量相似场景本质上是同一类天气这时不妨考虑把削减目标数调高一些给这一类天气多留几个代表否则在求解时这个“超级场景”会对调度方案产生过大的引导作用。4.2 随机调度模型的变量分层与约束设置场景削减完下一步就是把场景接入动态经济调度模型。这里必须想清楚一个关键问题哪些决策是“场景无关”的哪些是“场景相关”的。用大白话说调度员每天早晨做启停计划的时候并不知道明天下午光伏到底出多少电所以机组的启停状态、储能是否需要预留容量这类“先定下来”的决策在所有场景里必须保持一致——这就是非预期性约束non-anticipativity constraints也是随机规划区别于确定性模型的核心点。而机组出力、储能实际充放电功率这些“事后调整”的决策则可以随场景变化而变化。我搭的模型大概长这样目标函数是最小化所有场景下运行成本的期望成本包含柴油机燃料成本、启停成本、储能循环损耗折算以及弃负荷、弃光弃风的惩罚项。约束分三类——第一类对所有场景公共包括机组启停逻辑、储能初始SOC一致性第二类在每个场景内部成立包括功率平衡、机组容量与爬坡、储能充放电功率与SOC递推第三类就是那条非预期性约束把第一阶段的启停变量跟场景解耦。求解器方面Gurobi或者Cplex处理这种中规模MILP完全没问题建模语言用YALMIP或者Pyomo都顺手我更多用Pyomo做后处理和可视化。4.3 正式求解前的“预调度”验证每次削完场景我不会直接拿去跑正式模型而是先跑一遍“预调度”验证花十分钟能避开后面大半天返工。验证分三步。第一步把削减后的场景集和原始场景集的期望曲线画在一起要求形状吻合误差控制在几个百分点以内。第二步看边界分位数比如10%和90%分位数曲线如果削减后分位数被明显压缩说明场景多样性丢了得回调目标场景数。第三步用一个简化版调度模型分别跑原始场景集不削减用小场景数做粗略对比和削减后的场景集对比总期望成本和最差场景成本。如果成本差异在可接受范围内我一般设5%以内就可以放心进入正式求解了。这个过程听起来繁琐但对动态经济调度这种每天要跑的模型来说一次可靠的削减比追求“最新算法”重要得多。5. 实战中的经验总结与避坑清单5.1 场景数量不是越多越好用“稳定度”说话总有人问“到底该生成多少个场景、削减到多少个”我的回答永远是别拍脑袋用稳定度来定。把削减目标K从20一路扫到300每个K下跑一遍均值成本你会看到一条随K增大而逐渐收敛的曲线。当K超过某个值后成本几乎不再变化那个拐点就是模型能接受的下限。我在几个项目里得到的经验值普遍在50到150之间——小于50时成本波动能到8%以上调度方案在真实运行时经常触界大于150后收益极低但求解时间成倍上涨。5.2 时序自相关丢失锯齿场景毁掉爬坡约束有一类隐蔽错误特别容易发生生成场景时逐时段独立抽样得到一模“锯齿”曲线。这类场景虽然统计上每时段边缘分布都对但爬坡速率根本不现实喂给模型后优化器会认为需要预留大量爬坡能力储能被调度得异常保守经济性大打折扣。判断方法很简单把场景画出来如果相邻时段出力突变频繁且幅度大那一定是自相关被丢了。解决方法要么用ARIMA这类时序模型要么对完整历史日曲线做扰动——我后面的项目基本都改成“历史日曲线多元扰动”的方式了生成质量立刻上了一个台阶。5.3 尾部极端场景被削没了CVaR校验与强制保留削场景最大的隐性风险是把那些“概率小、影响大”的极端场景削掉。比如冷锋过境导致的光伏骤降、连续阴天叠加晚高峰高负荷这类场景在聚类时很容易被归并到附近的普通场景里分布看起来没问题但调度方案面对真实极端天气时会措手不及。我建议对风险敏感的应用做两个补救。第一削减后单独计算CVaR条件风险价值也就是最差那5%场景的平均成本如果比原始场景集明显偏低说明尾巴被削没了。第二把极端场景人工挑出来强制保留在削减后的集合里哪怕它的概率很“碍眼”。这相当于给随机优化加了一个鲁棒性的保险代价很小收益很大。5.4 距离度量选不对削减等于白做最后说一个很小的细节但影响超大距离度量。SBR、FFS和K-means全都依赖场景之间的距离定义。欧氏距离最常用但它在24维空间里会把“整体偏移”和“局部尖峰”混为一谈——两个场景如果整体水平差不多只是峰值差一度欧氏距离可能很小但对调度而言峰值那一个点的功率差恰恰决定了储能够不够用。我目前的做法是给距离加权重把净负荷高峰时段的权重设成凌晨时段的2到3倍这样削减算法会更珍惜“峰值形状和高度”的相似性。如果相位错位问题严重比如同样一个负荷高峰一个出现在19点一个出现在20点还可以考虑DTW但要接受它的计算开销。没有哪个距离度量是万能的工程上永远是“先看调度关注什么再决定削什么是相似”。最后再分享一点个人体会。早期做这类项目时我总把精力花在追新算法上——试过GAN生成、试过各种变分推断结果在工程现场真正救命的反而是把LHS抽样的均匀性、SBR的概率合并逻辑、CVaR的尾部校验这些“基本功”抠到位。场景生成与削减看起来是调度模型的预处理步骤其实它决定了下游优化结果能不能在真实世界站稳。你在自己项目里跑通一次完整的“生成—削减—建模—求解—实测对比”闭环之后就会明白这整套流程里最值钱的经验往往都藏在那些看似不起眼的选择里。