☰
电力系统可靠性评估的MATLAB实现:核心指标与蒙特卡洛仿真
2026/10/14 1:36:21 网站建设 项目流程

简介:针对电力系统可靠性评估问题,这份 MATLAB 实现案例面向电力专业学生、研究人员及从业者,覆盖从元件故障建模到系统指标计算的分析链路,可用来分析系统在各类运行条件下的稳定性与可用性。压缩包内共二十个文件,以十七个 m 格式的 MATLAB 源代码文件为主体,另含两个 asv 自动保存版本与一份 readme.txt 说明文档,整体仅 19KB,便于快速下载阅读。代码实现包括可靠性模型、故障概率计算、负荷分配、状态估计以及 SAIFI、SAIDI 等可靠性指标计算,并融入矩阵运算、优化算法与仿真分析思路;readme 中还给出了执行步骤与可能遇到的问题说明。已有三千五百五十二人学习,适合作为电力系统方向课程设计、毕业设计或工程应用的参考,帮助读者将理论方法落实到具体 MATLAB 工程实现中。

1. 电力系统可靠性评估的MATLAB实现:先想清楚指标,再写第一行代码

拿到一个命名为“电力系统可靠性评估(matlab实现)”的压缩包,大多数人第一反应是解压、找主程序、点运行。但真正决定这次评估靠不靠谱的,不是那几行蒙特卡洛循环,而是你打算用什么指标回答“系统可不可靠”——同一个电网,换一种指标口径,结论可以完全反过来:一种口径说缺电概率1.2%,另一种口径说一年缺电8.7小时,规划评审里被追问的往往是后者。可靠性评估在电力系统里的位置,是用量化手段回答三个问题:发电侧一年有多少概率带不动负荷、平均缺多少电;配网侧一年每户停多少次电、每次停多久。这篇文章按发电系统和配电系统两条线,把序贯蒙特卡洛与解析枚举两类MATLAB实现路径拆开讲,从指标定义、数据表、仿真循环到收敛判据和常见坑,照着写就能跑出可复现的结果,也能帮你判断哪种技术路线值得投入。

2. 可靠性评估的核心指标与算法选型:为什么序贯蒙特卡洛成了默认选择

做评估前先选指标,指标选错,后面代码写得再漂亮也是白搭。发电系统常用的可靠性指标和配网系统差别很大,很多人把LOLP和SAIFI混在一起算,结果出来的数字自己都解释不了。先花一页篇幅把指标口径理清楚,再决定用什么算法去算它们。

2.1 四个必懂指标:LOLP、LOLE、EENS 与 SAIFI/SAIDI 的区别与用法

发电系统可靠性指标回答的是“充裕度”问题:给定发电容量和负荷曲线,系统一年里有多少概率兜不住负荷。LOLP(失负荷概率)是一个无量纲概率,表示任意时刻系统可用容量低于负荷的概率;LOLE(失负荷期望)是把LOLP折算成时间,单位是小时/年,直接回答“一年里平均缺电多少小时”;EENS(期望缺供电量)单位是MWh/年,回答“一年里平均缺多少电量”,电网经济性分析、定电价、算损失都靠它。这三个指标是发电可靠性评估的标准输出,缺一不可。

配网系统则用另一套面向用户的指标。SAIFI(系统平均停电频率)单位是次/(户·年),表示每户每年平均停电几次;SAIDI(系统平均停电持续时间)单位是小时/(户·年),表示每户每年平均停电多少小时;由SAIDI除以SAIFI得到CAIDI,即平均每次停电持续多久。这些指标的计算分母是“总用户数”,分子是把每段馈线故障造成的用户停电次数或时间累加起来,所以配网评估的核心工作是建模“故障发生在哪、哪些用户受影响”。

指标全称单位回答的问题
LOLPLoss of Load Probability无单位(概率)系统某时刻带不动负荷的概率
LOLELoss of Load Expectationh/年一年平均缺电多少小时
EENSExpected Energy Not SuppliedMWh/年一年平均缺多少电量
SAIFISystem Average Interruption Frequency Index次/(户·年)每户每年平均停几次电
SAIDISystem Average Interruption Duration Indexh/(户·年)每户每年平均停多少小时
CAIDICustomer Average Interruption Duration Indexh/次平均每次停电持续多久

还有一个容易被忽略的ASAI(供电可用率),它是8760减去SAIDI再除以8760,反映全年供电时间占比。做配网改造时,供电可靠性考核常用ASAI,但评估报告里更常直接给SAIDI和SAIFI原始值。我的习惯是把这组指标表格放在代码文件头的注释里,每算一个新系统先明确要输出哪几个数字,避免后面拿着EENS去解释配网停电频次,那就对不上口径了。

2.2 解析法、状态枚举与序贯蒙特卡洛:三种路线的选型边界

选算法不是越复杂越好,而是看系统规模和你需要什么指标。解析法基于解析公式和卷积,对小型发电系统可以精确求LOLP,但一旦负荷时序复杂、机组台数多,公式推导就变得不可维护;状态枚举法把系统所有可能的故障组合列出来,逐状态计算概率和后果,适合元件数量少、故障组合清晰的配电网,但当馈线段超过几十条时,组合数会爆炸;序贯蒙特卡洛则是按时间轴逐小时抽样元件状态,天然支持时序负荷、储能策略、检修计划这些复杂逻辑,代价是计算量大,通常要数千个仿真年才能收敛。

我的选型取舍是这样:发电系统统一走序贯蒙特卡洛,因为它能直接输出LOLE和EENS,还能同时跑出来时序峰荷影响;配网小系统(馈线段少于30条)用解析枚举或影响矩阵法,几秒钟出结果,且结果稳定可复现;配网大系统或带分布式电源、储能策略时,再切到序贯蒙特卡洛。很多压缩包里默认写序贯蒙特卡洛,但如果你只是算一个10段馈线的SAIDI,用解析法会更快,而且不用纠结随机数这种玄学问题。

维度解析法状态枚举序贯蒙特卡洛
适用系统小型发电系统中小型配网发电/配网/微电网
时序负荷难处理可近似完全支持
计算量小随元件数指数增长大,需数千仿真年
输出稳定性确定结果确定结果含随机波动
典型用途手算验证配网SAIFI/SAIDILOLE/EENS、复杂策略

算法选型定下来,后面每一步都围绕它展开。接下来先啃发电系统这块硬骨头。

3. 发电系统可靠性评估:序贯蒙特卡洛的最小MATLAB实现

发电系统可靠性评估的核心逻辑可以压缩成一句话:让每台机组按故障与修复的随机规律运行,在每个小时比较可用容量与负荷,缺了就累计。下面按数据准备、仿真循环、收敛判据三步把最小可实现版本写出来,所有代码复制到MATLAB里就能跑。

3.1 把系统拆成数据表:发电机、负荷与时序负荷曲线怎么进代码

第一件事是建数据表。发电机组需要三个基础参数:额定容量、年故障率λ(次/年)、平均修复时间MTTR(小时)。年故障率来自设备长期统计的强迫停运率,是评估的输入前提;MTTR是从故障发生到修复完成的平均时长。负荷侧则需要一整年的逐小时功率序列,8760个点,来源可以是电网调度系统的历史负荷,也可以是按季节典型日扩展生成的数据。

% 发电机组参数: [额定容量MW, 故障率λ(次/年), 平均修复时间MTTR(h)] gen = [ 400, 2.0, 12; 200, 3.5, 10; 150, 4.2, 8; ]; % 8760小时负荷曲线(MW), 替换为实际系统的历史负荷或规划负荷 % 这里用基础负荷+日周期+年周期生成一个演示曲线 t = (0:8759)'; loadProfile = 480 + 120 * sin(2*pi*t/24 - pi/2) ... + 30 * sin(2*pi*t/(24*365));

代码的逻辑是把系统参数和负荷数据全部集中在文件头部,后面任何脚本改动都只改这里,评估逻辑本身不用动。参数说明里有三个容易出错的地方:λ的单位是次/年,不是次/小时,后面转概率时要除以8760;MTTR单位是小时,转修复率时要取倒数;负荷曲线必须是8760个点,少一个点或多一个点都会导致后续指标算错。演示曲线中的日波动用sin函数生成,峰值在傍晚,年周期叠加了一个小幅度季节分量,替换实测数据时只需把loadProfile整体换成你的列向量。

3.2 核心仿真循环:状态抽样、缺电判断与指标累计

仿真循环的每一步都要回答一个问题:这一小时,每台机组是运行还是故障?比较朴素的做法是逐小时扫描,对运行中的机组按小时故障概率判断是否跳闸,对故障中的机组按小时修复概率判断是否复电。小时故障概率用λ/8760近似,当λ远小于8760时这个近似很准,机组的年强迫停运小时数本就只有几十到几百小时,逐小时扫描的误差可以忽略。

% 仿真参数 nGen = size(gen, 1); nYears = 2000; % 仿真年数, 收敛性决定 rng(2024); % 固定随机数种子, 保证可复现 % 累计量 outageHours = 0; % 缺电小时数累计 energyShort = 0; % 缺供电量累计(MWh) yearOutage = zeros(nYears, 1); % 记录每个仿真年的缺电小时数 % 主循环: 逐年逐小时扫描 for y = 1:nYears % 每台机组初始状态置为运行(1), 故障为(0) avail = ones(nGen, 1); for h = 1:8760 % 状态转移判断 for g = 1:nGen if avail(g) == 1 % 运行中跳闸: 概率 = λ/8760 if rand() < gen(g, 2) / 8760 avail(g) = 0; end else % 故障中修复: 概率 = 1/MTTR(小时) if rand() < 1 / gen(g, 3) avail(g) = 1; end end end % 计算当前可用容量 capAvail = sum(gen(:, 1) .* avail); % 缺电判断与累计 if capAvail < loadProfile(h) outageHours = outageHours + 1; energyShort = energyShort + (loadProfile(h) - capAvail); yearOutage(y) = yearOutage(y) + 1; end end end % 指标输出 LOLP = outageHours / (nYears * 8760); LOLE = outageHours / nYears; EENS = energyShort / nYears; fprintf('LOLP=%.4f%%, LOLE=%.2f h/year, EENS=%.2f MWh/year\n', ... LOLP*100, LOLE, EENS);

逻辑说明:这里把每小时的转移概率当成独立事件处理,相当于用小时步长离散化连续时间马尔可夫过程。运行中机组的跳闸判断用rand() < λ/8760,当λ=2次/年时,小时跳闸概率约2.28e-4,一个仿真年里400MW机组平均跳闸约2次,符合设定。修复判断用rand() < 1/MTTR,MTTR=12小时对应小时修复概率约8.3%,平均修复时长约12小时,符合设定。缺电判断发生在系统可用总容量小于该小时负荷时,缺电量按负荷与当时可用容量的差值累计。

参数说明:nYears=2000是保守设置,为了让方差系数足够小;rng(2024)固定随机数种子,让每次运行结果一致,否则同一套参数每次跑出来LOLE都不一样,调试时根本分不清是代码问题还是随机波动。如果你要跑严格的序贯蒙特卡洛事件驱动版本,把逐小时扫描换成状态持续时间抽样即可:每台机组进入运行状态时用ttf = -log(rand()) * 8760 / λ抽下一次故障时刻,进入故障状态时用ttr = -log(rand()) * MTTR抽下一次修复时刻,然后按最小事件时刻推进。事件驱动版本避免了小时步长近似,但对每个仿真年需要维护一个事件队列,代码量会大一些。

3.3 收敛性判别与仿真年数设置:什么时候可以停机

蒙特卡洛仿真的结果本身是一个随机变量,仿真年数不够时,均值尚未收敛,你输出一个看起来精确到小数点后两位的LOLE,实际可能是噪声。收敛判断的标准做法是计算方差系数β,也就是均值的相对标准差。β越小,结果越可信。工程上β小于0.05可以接受,追求论文级精度时要压到0.02以下。

% 基于逐年的缺电小时数判断收敛 meanVal = mean(yearOutage); stdVal = std(yearOutage); beta = stdVal / (meanVal * sqrt(nYears)); if beta < 0.05 fprintf('已收敛: 年均缺电小时 = %.2f h/year, β = %.4f\n', ... meanVal, beta); else fprintf('未收敛: 当前β = %.4f, 请增加仿真年数\n', beta); end

这个收敛判据只对LOLE有效,因为yearOutage的平均值直接对应LOLE。EENS的方差往往比缺电小时数更大,因为一次严重缺电事件可能贡献大量缺电量,所以EENS的收敛速度更慢。实际运行中,我一般会同时打印两个β值,一个针对LOLE,一个针对EENS,当两者都满足阈值时才认为仿真可以停。还有一种常见做法是固定仿真年数,比如1000年、5000年,跑完再输出β值供报告引用,这样即使收敛性不够,结果也是可追溯的。

4. 配电系统可靠性评估:从馈线分区到可靠性指标的两种建模路径

配网可靠性的计算逻辑和发电系统完全不同。发电系统关心“容量够不够”,配网关心“故障导致哪些用户停电、停多久”。所以配网评估的第一步不是建机组表,而是把馈线按开关位置分成若干区段,每个区段有自己的故障率、修复时间和影响的用户集合。

4.1 配电网可靠性指标的计算逻辑:故障率、修复时间与开关动作

一条中压馈线上有断路器、分段开关、联络开关。当某个区段发生永久性故障时,故障点上游的区段可以由断路器跳闸后重合恢复,故障点所在的区段必须等修复完成才能送电,故障点下游如果存在联络开关,可以通过转供恢复。因此一次故障事件,对不同位置的用户影响完全不同,要分别计算三类停电时间:瞬间停电(开关自动重合闸,时间几秒)、短时停电(操作隔离后恢复,时间十几分钟到几小时)、持续停电(等待修复完成)。

计算SAIFI和SAIDI时,把每条馈线段当成一个“故障源”,列出它发生一次故障时影响到的用户集合,以及这些用户分别停多久,然后按故障率加权累加。这个“故障影响矩阵”是配网可靠性的核心数据,实际项目中通常由拓扑分析自动生成,而不是手写。矩阵的行是馈线段,列是负荷节点,元素为1表示该段故障会导致该节点停电。

4.2 解析法用影响矩阵做状态枚举的MATLAB实现

对于馈线段数据齐全的小型配网,解析枚举法能直接给出确定性的SAIFI和SAIDI,不需要蒙特卡洛,也不需要讨论收敛性。下面这个代码用影响矩阵把每条馈线段故障的用户后果全部累加,最后归一化到总用户数。

% 馈线段参数: 故障率(次/年) 与 平均停电持续时间(h) % 停电持续时间已按开关动作折算: 修复时间+操作时间加权 segRate = [0.15; 0.10; 0.12]; % 各段年故障次数 repTime = [3.0; 2.5; 4.0]; % 各段造成用户停电的平均小时数 % 影响矩阵 impact(i,j)=1 表示第i段故障会导致第j个负荷节点停电 impact = [ 1, 1, 0, 0, 0; 0, 1, 1, 1, 0; 0, 1, 1, 1, 1; ]; % 各负荷节点用户数 loadUsers = [100; 150; 120; 200; 180]; nSeg = size(impact, 1); nNode = size(impact, 2); % 累计量 totalStopTimes = 0; % Σ(用户数 × 停电次数) totalStopHours = 0; % Σ(用户数 × 停电小时数) for i = 1:nSeg affected = find(impact(i, :) == 1); usersAff = sum(loadUsers(affected)); totalStopTimes = totalStopTimes + usersAff * segRate(i); totalStopHours = totalStopHours + usersAff * segRate(i) * repTime(i); end totalUsers = sum(loadUsers); SAIFI = totalStopTimes / totalUsers; SAIDI = totalStopHours / totalUsers; CAIDI = SAIDI / SAIFI; fprintf('SAIFI=%.3f 次/(户·年), SAIDI=%.2f h/(户·年), CAIDI=%.2f h/次\n', ... SAIFI, SAIDI, CAIDI);

逻辑说明:这个实现把每条馈线段当成独立的故障事件,假设同一时间只发生一处故障,这对配网是合理近似。影响矩阵的行对应故障源,列对应负荷节点,find(impact(i,:)==1)取出第i段故障时所有受影响的节点,累加这些节点的总用户数。停电次数用用户数乘以故障率,停电时间用用户数乘故障率再乘平均停电小时数。归一化到总用户数后就得到SAIFI和SAIDI。

参数说明:repTime是“折算后的平均停电持续时间”,它不是单纯的修复时间,而是把开关操作、转供、修复综合后的期望值。比如某段故障时,上游用户停0.5小时就恢复,下游用户停4小时才修复,则repTime要按用户加权折成一个等效值。这个折算最容易出错,建议在程序注释里写明每个值的计算依据。影响矩阵在代码里是手写的,这只是演示,实际工程中应该从配网拓扑连接关系和开关位置自动生成,否则几十条馈线手写会写到怀疑人生。

4.3 顺序仿真接入时序负荷后的参数设置

解析法算SAIFI和SAIDI很快,但它算不了EENS,因为EENS需要逐小时的负荷数据。想知道“一年里配网用户总共损失多少电量”,就要用序贯仿真:对每条馈线段模拟故障-修复事件序列,在故障持续期间叠加8760小时负荷曲线,逐小时计算损失电量。这个模型的参数设置比发电系统多两个关键点:一是故障修复时间要按分布抽样,而不是直接用均值;二是负荷曲线要用节点级时序数据,如果只有馈线首端总负荷,需要按用户容量分摊到各节点。

顺序仿真还有一个优势是能建模“故障与时序负荷的耦合”:同样的两小时停电,发生在夏季晚高峰和发生在凌晨,EENS差别是数倍的。这种耦合效应是解析法做不到的,也是配网可靠性评估从“算指标”走向“算电量损失”的关键一步。参数设置上,仿真年数依然用β收敛判据控制,通常配网故障率较低,年缺电小时数方差更大,仿真年数一般要3000年以上才稳。

5. 可靠性评估的常见坑与排查:从随机数到收敛性的五个现场

做可靠性评估踩过的坑,比算法本身的坑多得多。这一章列五个高频问题,每条按“现象、原因、解决”展开,都是能在代码里直接定位的实战问题。

5.1 随机数种子没固定,结果一跑一个样

现象:同一套参数,今天跑和明天跑,LOLE差10%甚至更多;换个机器跑,EENS对不上报告里的数字。

原因:代码里没写rng固定语句,MATLAB每次启动随机数流都不同;或者虽然固定了种子,但循环里提前调用了rand改变了随机数流的位置。更隐蔽的版本是仿真年数只有50到100年,样本量太小,均值本身还在大幅波动。

解决:在所有rand调用之前加上rng(2024),并把它放在主脚本最前面,不要放在循环内部。然后检查仿真年数,用第3章的β判据检验,如果β大于0.1,先加年数再谈其他优化。固定种子还有一个额外好处:代码出问题时,可以用相同随机序列逐步调试状态转移,定位哪一年哪一小时开始偏离预期。

5.2 负荷时序与故障时序错位:把8760小时截成24小时的误区

现象:EENS明显偏小,和手算的粗略估计差好几倍;LOLE看起来正常,但缺电年份集中在某几个极端日。

原因:为了“简化计算”只用一天24点负荷曲线循环一年,或者用日峰值负荷代替全年时序。这样会抹掉季节波动和连续高温日等场景,而恰恰是这些极端场景贡献了大部分缺电风险。峰值负荷如果取高了,EENS会被夸大;取平均值,EENS又会被严重低估。

解决:坚持使用完整8760小时负荷序列。历史负荷不完整时,至少按四个季节分别做典型日曲线,再拼接成8760点,同时把历史峰值日单独叠加进去作为校验场景。配网场景里如果负荷数据是月峰或日峰,不能直接用于EENS计算,需要先还原成小时级曲线。

5.3 修复时间只用均值:指数分布假设的边界

现象:两台机组MTTR相同,评估结果EENS相差5%到8%,同一份报告里没法解释差异。

原因:修理时间实际分布往往比重指数分布更“重尾”——少数设备故障需要几天甚至几周的更换周期,这些长修复事件对EENS的贡献远大于平均时长。只用均值时,这些长尾事件完全体现不出来。

解决:对修复时间改用对数正态分布抽样。先设定均值和标准差,用lognrnd生成抽样值时通过对数变换保持均值匹配。发电机的强迫停运率和修复时间应该由设备台账统计拟合,不要拍脑袋填数。如果你的数据只有MTTR没有方差,可以先用MTTR×0.5作为标准差做一个保守估计,并在报告里注明。

5.4 收敛判据只看均值,不看波动

现象:LOLE稳定到小数点后两位,但EENS的逐年波动仍然很大;β计算出来0.02,为什么EENS还在跳?

原因:LOLE由缺电小时数决定,这是一个相对稳定的计数;EENS由缺电量决定,单次极端缺电事件就能贡献全年一半的缺电量,方差远大于LOLE。只看一个指标的β,其他指标可能根本没收敛。

解决:对每个输出指标单独计算β。EENS的采样方差大,可以在统计EENS时记录每小时的缺电量序列,而不是只记录年总量,然后用电量序列计算方差系数。如果EENS的β压不下来,考虑增加仿真年数,或者用后面的拉丁超立方抽样做方差缩减。

5.5 解析法状态枚举爆炸:馈线段一多就卡死

现象:馈线段超过30条时,影响矩阵枚举法开始变慢;超过40条,内存直接耗尽或计算时间无法接受。

原因:穷举所有故障组合的复杂度是2的n次方,即使限制“最多同时两段故障”,组合数也随n快速膨胀。很多人把配网评估当成全状态枚举,规模一大就翻车。

解决:把故障后果相同或相似的馈线段合并成群组,每组只枚举一次;或者放弃解析枚举,切换到序贯蒙特卡洛。配网模型超过30条馈线段时,序贯仿真无论是代码简洁度还是计算效率,通常都优于解析枚举。还有一招是用稀疏影响矩阵加向量化累加,避免在循环里逐段find。

6. 验证你的评估结果:标准系统对拍与两种MATLAB加速技巧

代码写完了,输出了一堆指标,但怎么确认这些数字可信?我的做法是准备三套验证手段:手算小系统做基准、公开测试系统做均值对拍、敏感性分析看趋势。手算系统用两三台机组,直接枚举所有运行状态,把LOLP用解析公式手算出来,再和仿真结果对比;公开测试系统不指名的话,重点是复现文献里的均值,偏差在1%以内说明模型主逻辑正确。这套验证流程做一次,之后改代码改参数就有底气了。

验证之外还有个效率问题:序贯蒙特卡洛最怕计算量大。两种加速手段值得掌握。第一种是拉丁超立方抽样,它把每个维度的随机数空间均匀分层,比纯随机抽样更均匀地覆盖极端场景,在同样仿真年数下能把方差压低一个量级。MATLAB自带的lhsdesign可以直接用,替换掉rand生成指数分布的样本即可:

% 用拉丁超立方抽样生成指数分布故障间隔 % nSamples 为抽样数, lambdaRate 为年故障率 nSamples = 5000; u = lhsdesign(nSamples, 1); % 生成[0,1]均匀分层样本 ttf = -log(1 - u) * 8760 / lambdaRate; % 逆变换得到指数分布

第二种是公共随机数法:在不同方案对比时,让每台机组使用完全相同的随机数序列,这样方案间的差异只来自参数本身的改变,而不是随机波动的干扰。做法是在每个方案循环前重置rng到同一个种子,跑A方案和B方案都用rng(42)开始。这两个技巧配合使用,能把蒙特卡洛的“玄学”成分大幅压掉,输出的指标曲线也更稳定。

我现在的习惯是每次跑可靠性仿真,第一件事固定随机数种子,第二件事在代码注释里写下手算基准值,第三件事跑完先看β再看均值。这三个动作救过我很多次,至少能让你在汇报数据时,不用为一次仿真结果反复解释“为什么跑两次不一样”。希望帮到你。

本文还有配套的精品资源,点击获取

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

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

立即咨询