尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
基于概率距离快速削减法的风光场景生成与削减MATLAB实现
做新能源并网研究的朋友大概都遇到过这种尴尬手里攒了一整年的风光出力实测数据或者用蒙特卡洛抽了几千个场景结果优化模型一跑就卡死哪怕勉强跑通结果也没有参考价值。商用软件里自带的多场景工具要么是黑盒要么削减效果说不清楚。今天聊的这个MATLAB实现叫“基于概率距离快速削减法的风光场景生成与削减方法”一句话说就是把上千个随机出力场景按概率分布损失最小的原则压缩成几十个甚至几个代表性场景同时保留每个场景的概率权重。它很适合用在随机优化、风险评估、可靠性分析里。不管你是刚开始接触场景法的新人还是已经在调场景规模的老手这篇的内容多少都能给你一些参考。1. 风光场景生成与削减到底在解决什么问题1.1 为什么场景数量会失控风电和光伏出力受天气影响本质上是一个随时间变化的高维随机过程。做随机优化时常规思路是用大量离散场景逼近真实分布比如对风速、光照预测误差采样或者直接历史整年功率序列抽样。单看每一个场景就是一条确定性的时序曲线把几百上千条放在一起就构成一个场景集。麻烦也在这里场景集是蒙特卡洛风格数量一多优化问题里的变量数和约束数直接乘以场景数混合整数规划根本解不动。我之前在一个两阶段随机调度模型里试过1000个场景规模内存占用让人崩溃求解器跑了两小时有余。所以必须做削减用少量场景尽可能还原原始场景集的概率分布特征。这个工作相当于“把实测数据的体积压缩但保留信息密度”概率距离快速削减法干的就是这件事。1.2 场景生成到削减的完整链路在“场景法”建模流程中第一件事是生成初始场景集常见手段包括基于历史数据重采样、用ARMA或者马尔可夫链拟合随机过程、基于Copula描述多变量相关性、或者直接搭一个预测误差模型。第二件事才是削减。削弱的场景集最终作为随机参数输入到优化模型中。概率距离快速削减法属于后处理环节它不关心场景是怎么来的只关心输入场景集S、每个场景的概率p、削减目标数量K输出是保留哪些场景以及保留概率。这个位置很关键因为无论上游生成方法是什么只要你还要用场景做计算就几乎绕不开这一步。它削得好不好直接决定了随机优化结果的可信度。2. 概率距离快速削减法的原理细节2.1 场景之间的距离怎么定义场景削减的前提是“距离”。对两个N维向量的场景来说最常见的距离是欧氏距离。如果把一条时序曲线看作一个点两条曲线之间的“空间距离”可以直接用向量二范数算d(i,j)∥S_i−S_j∥₂在MATLAB里就是vecnorm(S_i - S_j, 2)或者pdist2一把全算出来。欧氏距离实现简单但有时不合适。比如风力发电场景时序存在“时间偏移”同样一股风早一小时和晚一小时通过欧氏距离可能很大而动态时间规整DTW能给出更合理的相似度。不过DTW计算量大在几百上千个场景配对时开销不小所以不是默认选项。如果场景集来自不同量纲的数据混合比如风速、光照、负荷放在一起必须先做标准化否则量级大的变量会把距离计算结果主导导致削减结果几乎只看那个变量。做标准化不是必须的但绝大多数情况下都推荐。单一功率场景时因为量纲一致才可以直接计算。2.2 概率距离与Wasserstein距离这里说的“概率距离”笼统讲是衡量两个概率分布之间差异的度量。离散场景集分布可以写成每个场景点上的概率堆。用最优运输理论的语言削减后的场景集与实际分布之间的Kantorovich距离也叫Wasserstein距离有一个性质在离散情况下它等于按最优方式把概率从原始分布“搬”到削减后分布的最小成本而搬移成本是场景间的距离函数。快速削减法就是在迭代过程中最小化这个搬移损失。道理其实不难理解。生活里你请十几个朋友吃饭不能每个菜都点只能点几个代表菜但必须保证大家能吃饱且口味类型大致覆盖。每代表一个“场景”被点掉你把原先分给这个菜的份额转移给另一个最像它的菜转移成本就是口味差异。场景削减也是一样删掉某些场景后把它们的概率叠加到“最相似”的保留场景上让概率质量不丢失只是转移了一小段距离。2.3 后向削减与前向选择的取舍快速削减法主要有两种实现路线后向削减backward reduction和前向选择forward selection。很多教材里默认的“快速削减法”指前向选择但MATLAB代码里两者都有人写。后向削减的流程是初始化所有场景等概率p_i1/N。计算场景间距离矩阵D。当剩余场景数大于K时循环找到距离最近的一对场景(i,j)删除其中一个比如i把p_i累加到p_j更新距离矩阵只保留未被删除的场景。剩余场景就是削减结果。前向选择则是从空集开始每次从未选中的场景中挑一个加入保留集加入标准是“新增这个场景后保留集到原始场景集的概率距离增量最小”。前向选择计算代价更大但削减精度通常更稳定尤其当K很小的时候。用通俗话讲后向削减是不断“淘汰”人前向选择是不断“面试”人。淘汰简单直接面试更挑剔但选出来的人可能更均衡。实现时先用后向削到给定K如果发现结果明显偏再换前向选择对比一下。2.4 为什么这种方法比聚类削减更常用可能有人会问场景削减直接k-means聚类不就行了吗k-means也能把N个场景聚成K类取聚类中心。问题是聚类中心往往是原始数据坐标空间里的“内插点”它可能不是任何一条真实能看到的时间序列随机优化里你没法直接把它当作一个真实出力场景还需要再做修正。另外k-means对初始中心敏感高维时序场景容易陷入局部最优。概率距离快速削减法保存的是原始场景集合中的“代表性场景”这些场景都是真实采样序列不需要额外重构。概率转移计算也有明确的理论解释在论文里解释起来更能站得住脚。这就是它成为随机优化场景削减标准方法的原因。3. MATLAB代码实现与核心模块拆解3.1 主函数数据结构设计写MATLAB代码第一步是定义清楚输入输出。我习惯把主函数设计成function [redIdx, redProb, loss] scenarioReduction(S, p, K, distType) % S: N-by-T 矩阵每行一个场景共N个场景每个场景T个时间点 % p: N-by-1 概率向量缺省时等概率 ones(N,1)/N % K: 目标保留场景数 % distType: euclidean 或 weighted缺省为 euclidean % 返回 % redIdx: K-by-1 保留场景在原矩阵中的行索引 % redProb: K-by-1 对应的概率和为1 % loss: 削减过程造成的概率距离损失这里有一个关键设计选择场景矩阵S的行索引用原始索引而不是重新编号。好处是后续如果要把削减后的场景和原始数据打通不需要额外记录映射关系。熟手通常会在函数内把工作副本和原始索引分开维护避免删行时索引错乱。3.2 距离矩阵的高效计算场景削减需要反复使用场景间距离。最直接的方式是两层循环D zeros(N, N); for i 1:N for j i1:N D(i,j) norm(S(i,:) - S(j,:)); D(j,i) D(i,j); end end这样写逻辑清晰但N1000时循环约50万次MATLAB跑起来有些慢。我建议用pdist2一步到位D pdist2(S, S, euclidean);对于N1000、T24内存占用约800万浮点数64MB左右完全能接受。但如果N到5000甚至10000D矩阵已经到400MB以上容易卡死。这时就不要全量一次性生成改成按行分块计算或者直接用pdist算出紧凑矩阵再用squareform但pdist同样会先在内存里生成完整矩阵本质没区别。折中办法是分块例如每次只算D(i,:)并只保存对角以下的上三角部分实际上削减过程中每次删掉一个场景后需要更新距离矩阵分块更新比较麻烦。实践上N超过3000时我会先随机抽样或者用启发式方法把规模降下来再用后向削减或者改用“快速前向选择”来降低计算量。3.3 后向削减核心循环的写法给出一个可以跑的骨架代码function [redIdx, redProb, loss] scenarioReduction(S, p, K, distType) if nargin 3, error(至少需要 S, p, K 三个输入); end if nargin 4, distType euclidean; end [N, ~] size(S); if nargin 2 || isempty(p) p ones(N, 1) / N; end % 初始场景索引 idx (1:N); D pdist2(S, S, distType); loss 0; while length(idx) K % 找距离最小的一对场景 dmat D(idx, idx); % 去除对角线 dmat(logical(eye(length(idx)))) inf; [minVal, linIdx] min(dmat(:)); [r, c] ind2sub(size(dmat), linIdx); i idx(r); j idx(c); % 删除i概率加到j p(j) p(j) p(i); loss loss p(i) * minVal; p(i) 0; % 更新有效索引 idx(r) []; % 重新规范化p其实换出来的p(i)已经是0不需要严格归一但保险起见 p p / sum(p); end redIdx idx; redProb p(idx); redProb redProb / sum(redProb); end这段代码有个细节删除索引时如果直接idx(r)[]那么原场景中r位置之后的所有索引在idx里会整体前移所以不要使用原始矩阵S的行号做后续操作。更稳妥的方式是用逻辑掩码或者先找到最要删除的那个场景编号i再从idx中删除idxi的元素。否则容易产生bug。还要注意距离矩阵D永远是原始场景之间的距离不随删除而更新。循环里每次从剩余索引中取出子矩阵找最近对复杂度大约是O((N-K)N²)。K比较小时重复计算子矩阵和min查找并不经济。更高效的实现是在每轮更新距离矩阵自身但当N不大时子矩阵min足够用。3.4 前向选择快速实现思路如果决定用前向选择代码略有不同。常见的快速前向选择算法需要维护原始场景集到保留场景集的“最优传输”关系复杂度高。简化版本是从空集开始循环K次每次遍历所有未选场景计算把该场景加入后削减损失的最小值复杂度O(K N²)。N1000时通常也能接受。写法类似selected []; unselected (1:N); for k 1:K bestLoss inf; for candIdx unselected % 将cand加入selected计算概率距离损失 [~, lossTmp] calcSelectedLoss(S, p, [selected; candIdx]); if lossTmp bestLoss bestLoss lossTmp; bestCand candIdx; end end selected [selected; bestCand]; unselected(unselected bestCand) []; end其中calcSelectedLoss是计算当前保留集与原始集之间的Wasserstein距离这里需要额外实现。为了简化很多代码直接用“最近代表”原则估算损失for i 1:N distToSel min(D(i, selected)); totalLoss totalLoss p(i) * distToSel; end这种做法是后向削减的单步损失在保留集上的推广虽然不是严格的Kantorovich距离但作为快速估算足够用。3.5 可视化模块怎么写削减完不能光给个索引和概率还要能画图。我的习惯是输出三张图第一张原始场景集和削减后场景集叠加。用原始场景的浅色线做背景削减后的代表性场景用粗线突出。第二张削减后场景概率条形图直接用bar(1:K, redProb)。第三张削减前后出力均值、标准差和累积概率分布的对比曲线。可视化模块虽然简单但能帮你直观判断削减是否把边缘分布和时序波动特征保留住。我经常跑完之后先看均值曲线能不能重合再看概率分布尾部是否有明显缺失这两点通过了优化结果才敢拿出去用。4. 参数选择、结果评估与常见问题4.1 目标场景数K怎么选K是最关键的参数。它不是一个需要过拟合的数字而是取决于下游问题的可计算性。两阶段随机优化里场景数每翻一倍对偶变量的规模都会增加所以K要控制在可解范围内。一个比较实用的做法是画“削减损失-场景数”曲线。横轴是K纵轴是削减后的概率距离损失。把K从2一直试到30计算每个K下的loss你会看到曲线先快速下降到某个值后变平缓。选择“肘部”附近的K比如从10到15既保留了主要概率信息又不至于让优化模型爆炸。我之前在某个风电场出力随机调度项目里N500条初始场景看到K8时loss已经降到0.1以内K15后loss基本不下降最后选K12调度模型两分钟能跑完。如果没有这条曲线我可能随手选K5结果就会偏保守。4.2 概率距离度量的选择与影响很多人直接默认用欧氏距离但不同场合有不同考量。使用场景推荐距离原因纯风电/光伏功率时序削减欧氏距离量纲一致计算快效果稳定风速或辐照度场景加权欧氏距离不同时段重要性不同例如峰时段的偏差更值得惩罚多变量联合场景风光负荷先标准化再欧氏距离避免某一维度量纲压制其他维度存在时间偏移的天气过程动态时间规整DTW能表达“相似形态错位”的时间序列但计算量大实践里我遇到过用欧氏距离削完以后保留场景都是“平典型”的出力曲线没有波动剧烈的场景。后来把距离改成“时段加权”白天光伏时段权重高夜晚风电时段权重高削减出来的场景更符合调度关心的关键时段。这个技巧在论文里可以写成“时段自适应距离”。4.3 常见问题与排查速查表我在跑这个代码的过程中踩过几个坑整理成了一张速查表现象可能原因解决方案削减后场景全部集中在均值附近距离度量被极端场景干扰对场景做z-score标准化或改用加权/DTW距离概率分布尾部消失K设置过小后面被削掉了看loss曲线重新选K前向选择替代后向削减运行时间随N增长飞快距离矩阵全量生成每次min全矩阵分块计算距离或用快速前向选择近似算法削减后概率和不等于1删除时概率转移出现遗漏在每轮循环后对p做归一化或在最后强制redProb redProb/sum(redProb)两个保留场景几乎一样初始场景集合本身存在重复先去重再去削或削减时设置最小距离阈值中断/内存不足N×N矩阵溢出减小N到3000以内或用采样预处理另外一个容易被忽视的坑是如果场景是由蒙特卡洛方法生成初始概率不是等概率而是和抽样频率有关。削减时要正确传入p向量不要默认等概率。当时我直接用等概率削结果某个区域概率被整体低估优化结果明显偏离实际情况。4.4 如何验证削减结果是否有效削减完事不能只看损失数值还要看下游应用的稳定性。我一般做两个验证第一是统计验证。把原始场景集和削减后场景集各自算均值、方差、分位数、时序相关系数放在一张表里对比。如果均值误差在1%以内方差误差在5%以内基本合格。第二是优化验证。用一个固定的决策问题分别用原始场景集和削减后场景集求解比较目标函数最优值的偏差。偏差小说明削减没有把决策偏好带偏。做这个验证确实多花时间但能让你在发表结果时有底气。有一次我甚至发现直接用原始1000个场景跑出来的目标函数值和削减后10个场景跑出来的差不到2%但求解时间从一小时降到一分钟。这种对比图放在报告里非常有说服力。5. 双风、风水联合场景削减的实际扩展5.1 联合削减与分别削减的差别实际系统里大概率同时有风电场和光伏电站场景对象就不是单条功率曲线而是两条时序“绑在一起”的联合场景。两种处理办法第一种对风、光分别削减然后做笛卡尔积组合。这种办法麻烦在于如果风电保留8个场景光伏保留8个场景组合起来就是64个场景数量呈平方增长。第二种直接把风、光时序拼接成一个向量每行S_i [风功率序列光伏功率序列]再做一次联合削减。这样保留场景直接的联合相关性不会被破坏而且场景数量可控。我从实际项目里的体会是联合削减更适合风、光互补性强的区域。比如白天光伏有出力、晚上风电大用联合削减可以保证场景集中的“早晚转换”形态仍在而分别削减可能丢掉风、光之间此消彼长的关系。5.2 削减结果怎么与随机优化衔接削减后的场景集和概率可以直接作为随机规划的输入。以两阶段调度模型为例第二阶段变量按场景分别建目标函数写成期望形式sum(redProb(k) * obj_k(redIdx(k)))这里redProb和redIdx正是削减函数返回的结果。注意场景数K要匹配优化模型可解范围。如果追求鲁棒性可以把削减后的场景作为不确定集合的基点再在周围生成一个凸包做鲁棒优化能兼顾概率信息和极端场景。如果还要进一步做CVaR评估削减后的场景集同样适用取每个场景的损失值按概率从大到小排序再计算尾部平均。这里更考验削减算法是否保留尾部场景所以前文提到的“不要把尾部削掉”就格外重要。5.3 一个完整的迷你案例为了让你直观看到代码怎么用我写一个最小可复现案例。假设已有风、光两列数据构建S矩阵后调用削减函数% 假设windData: N-by-T, pvData: N-by-T S [windData, pvData]; % 横向拼接 N size(S, 1); p ones(N, 1) / N; % 等概率 K 10; [redIdx, redProb, ~] scenarioReduction(S, p, K, euclidean); % 可视化 figure; hold on; for k 1:length(redIdx) plot(S(redIdx(k), :), LineWidth, 1.5); end title(削减后的代表场景风电光伏时序拼接);这个例子合并了风、光的时序直接对联合场景削减。实际输出里你可以明显看到保留场景在形态上有差异不会出现冗余。6. 最后说一些实在的体会这套基于概率距离快速削减法的MATLAB代码我在不同项目中反复用了很多次最大的感受是场景削减算法本身不是瓶颈真正影响结果的是“场景怎么生成”和“距离怎么定义”。生成端如果本身质量就差削减算法再精巧也救不回来距离定义如果不贴合业务关注点削减结果就是“距离上最优但业务上不佳”。所以拿到代码不要急着抄完就跑先把自己的数据摸底看看有哪些时段是你真正关心的再决定是否对距离加权以及K取多少。另外如果你以后会在小场景数量下用前向选择也别急着优化速度先保证逻辑对拿一个N5,K2的小例子手算一遍理解“每次选一个场景降低损失”的过程比直接跑大矩阵出结果要可靠得多。代码里多写一点注释把每步的公式和变量含义标清楚后面回来看不会想“这是我写的吗”。把削减函数和可视化、loss曲线放到一个统一入口里遇到新数据直接一键出图能省掉很多重复工作。这也是我推荐任何科研工具代码走的方向先能用再顺手最后通用。
RELATED

相关推荐

大模型应用入门:向量数据库、嵌入与GPT核心概念全解析

大模型应用入门:向量数据库、嵌入与GPT核心概念全解析

这几年大模型的热度一直在涨,身边越来越多做后端、做客户端、甚至是产品经理的朋友都开始问同一个问题:想系统学AI大模型,到底该从哪里下手?说实话,市面上的资料不算少,但大多数不是太偏理论就是太偏Demo&a…

📅 2026/10/20 16:13:32
LLM推理服务如何利用Prefill与Decode功耗不对称性降低电费成本

LLM推理服务如何利用Prefill与Decode功耗不对称性降低电费成本

1. 从"电费账单"说起:为什么LLM推理服务需要看电网脸色 第一次看到这个标题的时候,我脑子里冒出来的第一个疑问是:一个做LLM推理服务优化的论文,为什么标题里会出现"Demand Response"这种电力系统里的术语&am…

📅 2026/10/20 16:08:31
零幻觉AI客服技术解析:RAG检索增强与置信度阈值实践

零幻觉AI客服技术解析:RAG检索增强与置信度阈值实践

1. 从“零幻觉”说起:AI客服到底在解决什么真问题做客服系统的人都有一个共识:用户找客服,十次里有八次是带着情绪来的。订单没到、退款没到账、功能不会用、账单对不上——这些问题背后往往藏着焦虑甚至愤怒。传统客服体系里,解决…

📅 2026/10/20 16:08:31
MORE NEWS

更多资讯

📰

软考高项案例分析:成本管理与挣值计算公式详解

1. 核心定位:成本管理为什么是“万金油”1.1 案例考试的考情现状软考高级信息系统项目管理师的案例分析科目,一直是很多考生的拦路虎。上午的选择题靠刷题能过,论文靠背范文能过,唯独下午案例,给的场景又长又碎&#x…

📰

AI编程助手Context Mode详解:上下文视野如何决定代码质量

1. 什么是Context Mode:AI助手的一张“视野地图” 1.1 一个下拉框引发的“答非所问” 先说个我自己的经历。前阵子接手一个维护了快五年的老订单系统,代码风格比较混乱,关键业务逻辑散落在好几个模块里。我刚开始用AI辅助编程工具时&#xf…

📰

从「一人公司」到「AI 员工取代同事」:Paperclip 正在改写中国创客叙事

从「一人公司」到「AI 员工取代同事」:Paperclip 正在改写中国创客叙事 【免费下载链接】paperclip The open-source app everyone uses to manage agents at work 项目地址: https://gitcode.com/GitHub_Trending/papercl/paperclip 最近科技圈里最热的一个…

📰

Manus手势SDK如何被AI大厂重构为手部语义管道

1. “Manus被AI大厂重新定价”——这句热搜背后的真实产业信号 “Manus被AI大厂重新定价”不是一句营销口号,也不是某次发布会的临时话术,而是过去18个月内我跟踪观察多个工业级人机交互项目时反复验证的一个结构性变化: 一家原本专注高精度…

📰

MiniCPM-V 4.7-35B-A3B-FP8的10个实战场景:OCR识别、PDF解析与视觉定位完全指南

大模型多模态模型量化本地部署openBMB 【免费下载链接】MiniCPM-V-4.7-35B-A3B-FP8 项目地址: https://ai.gitcode.com/OpenBMB/MiniCPM-V-4.7-35B-A3B-FP8 点击查看 免费下载 MiniCPM-V 4.7-35B-A3B-FP8 是 OpenBMB 出品的开源多模态大模型的 FP8 量化版本&#x…

📰

学生党省钱用AI全攻略:从免费工具到本地部署的按需付费方案

2026年聊学生党省钱降AI,已经不是“要不要用AI”的问题,而是“怎么用最少的钱把AI用爽”的问题。你随便打开一个AI助手,免费版有,会员也有,看似选择自由,其实处处是账单:月付、年付、按次、按量…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬