
简介面向电力系统可靠性研究的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节点测试系统。这套被称为RTSReliability 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母线类型bPQ母线、pvPV母线、vd平衡母线。net.gen是发电机组表p_mw是机组额定有功出力bus列指向机组所在的母线行号。注意这里bus列的值不是原始母线编号1到24而是Pandapower内部行索引后面构建图结构时统一用net.bus.index做映射避免混用。如果你手里是一份Matpower的case24_ieee_rts.m文件对应关系也一样bus表、gen表、branch表。Matpower的branch表里F_BUS和T_BUS是首末端母线编号R、X是支路阻抗RATE_A是长期输送容量。Pandapower则把线路和变压器拆成line和trafo两张表两者的物理意义不同做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先把机组可用率算对可靠性计算绕不开的一个参数是FORForced Outage Rate强迫停运率。FOR的定义是机组处于不可用状态的长期稳态概率常见计算公式FOR MTTR / (MTBF MTTR)其中MTBF是平均无故障时间MTTR是平均修复时间。比如一台机组平均运行1900小时故障一次每次修100小时FOR就是100/(1900100)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_buses和gen_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, algorithmnr, max_iteration30, tolerance_mva1e-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]])algorithmnr指定牛顿-拉夫逊法适合这种中小规模网络max_iteration30是迭代上限正常网络几次迭代就收敛tolerance_mva1e-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年看指标波动方差系数COV3%-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, FOR0 时不应缺电 assert lole_1 8760, FOR1 时应全年缺电如果这两条断言过不了问题几乎一定出在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版本还是换数据源都能快速定位是模型改了还是数据换了。對比结果时用同一套种子跑新旧两份数据比重新跑一整轮蒙特卡洛省事得多。本文还有配套的精品资源点击获取