基于IEEE-RTS 24节点系统的电力可靠性评估:从数据解析到LOLE/EENS计算
2026/9/16 15:32:59 网站建设 项目流程

简介:面向电力系统可靠性研究的MATLAB基准模型文件,围绕IEEE RTS-24节点可靠性测试系统构建,适用于高校师生、科研院所及电网工程师进行可靠性评估、故障模拟与运行方式分析。文件包共1个文件,以m源码为主,整体仅2KB,轻量易用;通过case24_ieee_rts.m可在MATLAB中完成24节点系统建模、潮流计算、状态估计及可靠性指标计算等任务,便于二次开发与教学演示。目前已有1537人学习下载,具备较好的参考价值。借助该模型可快速获得RTS-24标准算例数据,支撑FMEA、故障率与修复率分析、可用度与可靠性指数计算等典型场景,也可作为验证新算法或调控策略的公共测试平台,帮助提升电力系统稳定性与鲁棒性研究效率。

1. RTS 24节点数据:为什么IEEE-RTS仍是可靠性研究绕不开的基准

电力系统可靠性研究里有个反直觉的现象:用来验证新算法的最权威模型,不是某省电网的真实接线图,而是一份1979年由IEEE发布的24节点测试系统。这套被称为RTS(Reliability Test System)的数据只有24条母线、32台机组、两个电压等级,却几乎定义了此后所有可靠性算例的跑分方式。case24_ieee_rts正是这套数据在Matpower、Pandapower等工具里的标准命名。本文以RTS 24节点数据为中心,拆开母线、发电机组、线路和8760小时负荷序列这些底层字段,再一步步用Python完成从数据解析、连通性校验到LOLE/EENS指标计算的完整链路,适合做可靠性评估、电力市场或韧性分析的同学快速落地自己的基线算例。

2. 读懂case24_ieee_rts数据:母线、机组、负荷与支路的建模语义

拿到case24_ieee_rts之后,第一件事不是跑潮流,而是弄清这份数据里每个二维表在描述什么。24节点系统虽然规模小,但数据语义和真实调度系统完全同构:母线是网络节点,机组挂在母线上,负荷也挂在母线上,支路则是线路和变压器的统称。这章先把这些对象之间的映射关系理清楚。

2.1 数据从哪来:Pandapower与Matpower两种打开方式

常见做法是从现成工具库导入,而不是从原始PDF表格手工录入。Pandapower中已经内置了这个网络对象,代码只有一行:

from pandapower.networks import case24_ieee_rts net = case24_ieee_rts() print(net.bus[['name', 'vn_kv', 'type']].head()) print(net.gen[['name', 'bus', 'p_mw']].head())

net.bus是母线表,关键列包括name(原始母线编号1到24)、vn_kv(电压等级,RTS有230kV和138kV两层)、type(母线类型,b=PQ母线、pv=PV母线、vd=平衡母线)。net.gen是发电机组表,p_mw是机组额定有功出力,bus列指向机组所在的母线行号。注意这里bus列的值不是原始母线编号1到24,而是Pandapower内部行索引,后面构建图结构时统一用net.bus.index做映射,避免混用。

如果你手里是一份Matpower的case24_ieee_rts.m文件,对应关系也一样:bus表、gen表、branch表。Matpower的branch表里F_BUST_BUS是首末端母线编号,RX是支路阻抗,RATE_A是长期输送容量。Pandapower则把线路和变压器拆成linetrafo两张表,两者的物理意义不同,做N-1扫描时都算可开断支路。

2.2 24条母线的层级关系:138kV与230kV双电压环网

RTS系统的拓扑不是随意画的。上层是230kV环网,负责大电源与大负荷之间的功率交换;下层是138kV网络,主要承担配电侧负荷和部分中小机组;两层之间通过若干联络变压器连接。母线类型分布在可靠性计算里直接影响判断逻辑:带发电机的母线在故障扫描中是"电源点",带负荷的母线是"失负荷点",两者都属于特殊节点集合。

构建连通性检查时,我会把负荷母线和发电机母线分别抽象成两个集合。一个电网状态是否"缺电",最基本的判据是:每个含负荷的连通分量里至少存在一台可用发电机。这个判据不关心线路容量够不够,先把"有没有路"和"有没有源"分开。

表2-1 常用数据表与可靠性分析中的角色

数据表核心字段在可靠性分析中的角色
busname, vn_kv, type网络节点,区分电源节点与负荷节点
genp_mw, min_p_mw, max_p_mw机组容量上限,蒙特卡洛抽样的出力范围
branch/linefrom_bus, to_bus, rate连通性拓扑,容量约束和过载判断
trafohv_bus, lv_bus高低压联络,同样参与N-1开断
loadp_mw, q_mvar基准负荷,8760序列要按此缩放

2.3 32台机组的可靠性参数:FOR先把机组可用率算对

可靠性计算绕不开的一个参数是FOR(Forced Outage Rate,强迫停运率)。FOR的定义是机组处于不可用状态的长期稳态概率,常见计算公式:

FOR = MTTR / (MTBF + MTTR)

其中MTBF是平均无故障时间,MTTR是平均修复时间。比如一台机组平均运行1900小时故障一次,每次修100小时,FOR就是100/(1900+100)=0.05。它和"一年中故障几小时"不是一回事,做非序贯抽样时直接比较随机数和FOR即可,但做序贯蒙特卡洛时要把MTBF和MTTR换算成状态转移率。

RTS系统的机组构成特点是小机组多、大机组少。几十MW的小机组一般FOR偏高,起到调峰和备用作用;几百MW级别的大机组数量少但单台事故影响大。分析时不要只盯着机组台数,要把每台机组的p_mw与FOR乘起来看"期望可用容量"的分布,这才是出力侧的真正风险。

2.4 负荷数据的粒度陷阱:单峰值、多水平与8760小时序列

RTS原始数据完整提供了全年8760小时的负荷系数,但很多简化算例只给出一个峰值负荷2850 MW。做可靠性指标时,这两种数据口径会算出差别很大的结果。单峰值模型假设全年每小时都是最大负荷,相当于把系统置于最严苛工况,得到的LOLE一般显著偏高;8760小时序列则还原了负荷的日周期和季节周期,更接近真实运行。

我一般建议:先拿单峰值模型跑通代码,再去加载8760序列看指标差异。这样做的好处是排查问题时变量少,等逻辑验证完毕再切换到完整负荷模型。后面第4章会展示8760序列如何进入序贯蒙特卡洛循环。

3. 从数据到可计算网络:基于case24_ieee_rts的拓扑构建与N-1扫描

上一章看懂了字段,这一章把它们变成能跑的数据结构。可靠性评估往往要面对成百万个系统状态,Pandapower内部的DataFrame对象适合做单点潮流分析,但不适合反复开断支路、遍历连通分量。常见做法是将Pandapower网络导出成NetworkX图,在图上做结构校验。

3.1 先构建母线映射和可开断支路集合

把Pandapower的母线索引重新编号,然后把线路和变压器统一加入无向图。注意变压器支路也要加入,因为N-1故障分析中变压器和线路一样可能被切除。

import networkx as nx from pandapower.networks import case24_ieee_rts net = case24_ieee_rts() # 用net.bus.index做统一编号,避免原始母线号和DataFrame行号混淆 bus_map = {bus: i for i, bus in enumerate(net.bus.index)} G = nx.Graph() for _, line in net.line.iterrows(): u = bus_map[line.from_bus] v = bus_map[line.to_bus] G.add_edge(u, v, obj=("line", line.name)) for _, trafo in net.trafo.iterrows(): u = bus_map[trafo.hv_bus] v = bus_map[trafo.lv_bus] G.add_edge(u, v, obj=("trafo", trafo.name)) load_buses = set(bus_map[b] for b in net.load.bus) gen_buses = set(bus_map[b] for b in net.gen.bus)

这段代码把所有可开断元件统一为图的边。obj=("line", line.name)是为后续定位具体故障元件服务的,输出N-1结果时可以知道是哪条线路或哪台变压器出了问题。load_busesgen_buses分别聚合了负荷节点和发电节点,这两个集合是后面所有状态判断的基础。

3.2 实现N-1连通性扫描

N-1准则是电力系统规划中最基本的安全校验:任意开断一条支路,系统仍能保持对全部负荷的供电。在图上做这个校验非常直观,逐一删除边,然后检查所有含负荷的连通分量是否都含发电机。

def n1_connectivity_check(G, load_buses, gen_buses): bad_branches = [] for u, v in list(G.edges()): g = G.copy() g.remove_edge(u, v) for comp in nx.connected_components(g): has_load = bool(comp & load_buses) has_gen = bool(comp & gen_buses) if has_load and not has_gen: bad_branches.append((u, v)) break return bad_branches bad = n1_connectivity_check(G, load_buses, gen_buses) print("N-1 failure branches:", bad)

nx.connected_components返回的是无向图的连通分量集合。comp & load_buses是利用Python集合交集判断当前连通分量里是否存在负荷节点;如果某个连通分量有负荷但没有发电机,说明这部分负荷全部失电。break只记录第一条导致失电的支路,避免同一支路被多次计入。

需要说明的是,这里只考虑了拓扑连通性,没有校验线路潮流是否越限。工程上更完整的N-1校验流程是:先断开支路,再做直流潮流,最后看剩余支路有没有过载、母线电压有没有越限。连通性扫描的价值在于快速筛选出"结构性失电"场景,这类场景无论线路容量多大都救不回来。

表3-1 N-1校验的三种常见判据

判据实现方式反映的问题
拓扑连通性连通分量内是否含电源是否存在孤岛失电
直流潮流越限求解B' theta后检查线路功率输送容量是否够用
最小切负荷求解直流OPF,统计切负荷量系统能否通过调度恢复供电

3.3 连通性通过后,用潮流验证完整工况

连通性扫描只能证明"有路可走",不能证明"走得过去"。对于单个正常工况,直接用Pandapower跑牛顿-拉夫逊潮流,检查支路负载率:

import pandapower as pp pp.runpp(net, algorithm="nr", max_iteration=30, tolerance_mva=1e-8) overload = net.res_line.loading_percent[net.res_line.loading_percent > 100] print(overload) if not overload.empty: print("overload lines:", net.line.loc[overload.index, ["from_bus", "to_bus"]])

algorithm="nr"指定牛顿-拉夫逊法,适合这种中小规模网络;max_iteration=30是迭代上限,正常网络几次迭代就收敛;tolerance_mva=1e-8是功率误差门槛,数值越小结果越精确但迭代可能更慢。loading_percent是支路负载率的百分比,超过100意味着过载。这一步不作为蒙特卡洛主循环的一部分,只在调试时用于确认数据没有明显错误。

4. 可靠性指标实操:基于RTS-24数据计算LOLE、EENS与可用率

连通性只是"结构安全"层面的检查,可靠性指标回答的是更实际的问题:一年里到底有多少小时可能缺电?每年缺多少电量?这章给出从RTS数据直接算LOLE和EENS的完整路径。

4.1 三个容易混淆的指标先摆清楚

表4-1 可靠性核心指标对比

指标全称单位含义
LOLELoss of Load Expectation小时/年每年缺电小时数的期望
EENSExpected Energy Not SuppliedMWh/年每年缺供电量的期望
LOLFLoss of Load Frequency次/年每年发生缺电事件的次数

LOLE只看"有没有缺电",不关心缺多少;EENS把缺电深度也计入;LOLF则反映缺电事故的频率。规划工作中常用LOLE做标准,例如很多系统的目标水平是小于24小时/年或0.1天/年;运行评估和电量损失分析更看重EENS。三者在蒙特卡洛模拟里可以一次算出来。

4.2 序贯蒙特卡洛:8760小时负荷曲线下的最小模拟循环

这里给出一个可运行的容量充裕性评估函数。它的假设是:发电机组每个小时独立抽样运行/停运状态,负荷曲线按小时给定,不考虑线路过载和电压问题,只比较"可用发电容量"和"当前负荷"。

import numpy as np def simulate_one_year(rng, cap_mw, for_, load_curve): # cap_mw: 每台机组的容量数组,shape (n_gen,) # for_: 每台机组的强迫停运率,shape (n_gen,) # load_curve: 8760小时负荷序列 n_gen = cap_mw.size n_hours = load_curve.size # 生成全年机组状态矩阵,True表示运行 up = rng.random((n_gen, n_hours)) >= for_[:, None] # 矩阵乘法求出每小时可用容量 available = up.T @ cap_mw deficit = load_curve - available lole_hours = int(np.sum(deficit > 0)) eens_mwh = float(np.sum(np.maximum(deficit, 0))) return lole_hours, eens_mwh rng = np.random.default_rng(20240101) years = 20000 total_lole = 0.0 total_eens = 0.0 for _ in range(years): lole, eens = simulate_one_year(rng, cap_mw, for_, load_curve) total_lole += lole total_eens += eens print("LOLE = {:.4f} h/yr".format(total_lole / years)) print("EENS = {:.2f} MWh/yr".format(total_eens / years))

关键在up = rng.random((n_gen, n_hours)) >= for_[:, None]这一行。for_[:, None]把一维FOR数组变成列向量,与n_hours维随机矩阵逐列比较,生成一个n_gen x 8760的布尔矩阵。矩阵乘法up.T @ cap_mw等价于每小时把所有运行机组的容量加起来,得到该小时的可用发电容量。deficit > 0统计缺电小时,np.maximum(deficit, 0)累加缺电量。

这段代码把可靠性抽样简化成了线性代数运算,比一层层for循环快得多。缺点是up矩阵在模拟多年时不能一次性全建,否则内存会不够,所以外层循环按年切分。

4.3 仿真年数、收敛判据与随机种子

20年、2000年、20000年抽样出来的LOLE稳定性完全不同。RTS系统的缺电概率本身很低,LOLE通常在个位数到十几小时/年,对应缺电概率约千分之一量级。抽样长度不够时,LOLE估计值的抖动非常大。

表4-2 蒙特卡洛抽样参数建议

参数建议值说明
单次模拟年数5000-20000先跑5000年看指标波动
方差系数COV<3%-5%COV太高就加长模拟
随机种子固定并记录保证结果可复现
并行方式按年切分joblib或multiprocessing均可

收敛判断一般看统计量的方差系数,计算公式是std / (sqrt(N) * mean)。如果跑5000年得到的LOLE是9.2,再跑5000年变成8.5,说明样本长度不足,需要加到20000年以上。实际工程中,我会把每一年模拟结果存成数组,而不是只存总和,这样能直接算置信区间和方差系数。

4.4 从容量充裕性升级到N-k潮流评估

上面这套容量模拟没有考虑输电约束。RTS系统的潮流限制在某些场景下会显著增加EENS,因为即使全网发电容量充足,特定线路检修时也可能出现局部送电瓶颈。更精细的做法是:对每个小时的故障状态样本,先做连通性判断,再调用直流最优潮流(DCOPF)计算最小切负荷量。Pandapower中对应的求解器是pp.runopp,目标函数设为最小化切负荷时,需要在net.load上增加可切负荷的controllable属性。

这一步的代价是每个小时都要解一个线性规划,20000年乘8760小时对普通笔记本不现实。常见做法是先做容量充裕性粗筛,只对"可用容量接近负荷"的高风险小时子集做潮流校核,把计算量降低两到三个数量级。

5. 结果验证与避坑:让case24_ieee_rts的可靠性计算结果真正可复现

可靠性计算最大的问题不是代码跑不通,而是跑通了但没人敢信结果。这里给出一套上线前的验证手段。

5.1 先做两个极端工况回归测试

把全部机组FOR设为0时,系统永远不缺电,LOLE和EENS都必须是0;把全部机组FOR设为1时,系统全年无可用发电,LOLE必须等于8760小时/年。这两个用例能同时校验机组状态抽样逻辑、负荷序列长度和指标汇总代码:

for_zeros = np.zeros_like(for_) for_ones = np.ones_like(for_) lole_0, eens_0 = simulate_one_year(rng, cap_mw, for_zeros, load_curve) lole_1, eens_1 = simulate_one_year(rng, cap_mw, for_ones, load_curve) assert lole_0 == 0, "FOR=0 时不应缺电" assert lole_1 == 8760, "FOR=1 时应全年缺电"

如果这两条断言过不了,问题几乎一定出在rng.random比较方向或者deficit > 0的边界处理上,先修这个再谈指标精度。

5.2 与IEEE-RTS基准量级对齐,但不要死磕具体数字

IEEE原始报告和后续文献在标准负荷模型下给出的LOLE常见量级在9小时/年左右。因为不同复现版本对负荷曲线处理、机组状态转移模型、是否考虑线路约束的做法不同,算出来落在7到12小时/年都属于正常范围。对齐时固定三件事:负荷曲线版本、FOR数据来源、是否包含线路N-1约束。三者确定后,偏大偏小才有可比性。

5.3 三个最隐蔽的坑

第一个坑是把FOR直接当故障概率,省略了时间相关性。非序贯抽样可以这么用,但序贯模拟中同一台机组应该通过转移率在运行和停运之间切换,而不是每小时独立掷骰子。用独立抽样算出的LOLE通常偏低,因为它忽略了故障持续小时数的影响。

第二个坑是重复计入同一事故。做N-1扫描时断开支路,同时模拟发电机组停运,如果不区分故障来源,一个由线路开断导致的孤岛会被再次归因于机组停运,造成LOLE虚高。状态枚举时要把"支路开断"和"机组停运"拆成两个独立维度分别记录。

第三个坑是负荷模型单位不统一。单峰值模型算出来的是"峰值负荷下的小时数",8760模型算出来的是"全年小时数",两者直接比较会把LOLE放大几十倍。切换模型时要同步检查负荷数组长度和单位定义。

最后说一个实用习惯:把随机种子、抽样年数、FOR文件和负荷文件路径一起写进实验记录,每轮结果存成带版本号的CSV。这样后续无论换Pandapower版本还是换数据源,都能快速定位是模型改了还是数据换了。對比结果时用同一套种子跑新旧两份数据,比重新跑一整轮蒙特卡洛省事得多。

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

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

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

立即咨询