1. 项目思路与需求解构:为什么要把孤岛放进可靠性评估
1.1 标题里藏的三个关键词,缺一不可
先拆一下标题:“最优孤岛划分下含分布式电源配电网可靠性评估(Matlab代码实现)”。这句话看起来很长,实际压缩成了三个问题:分布式电源怎么建模、孤岛范围怎么划分、可靠性指标怎么算。
很多人拿到这类课题会先急着写代码,这是误区。我接手这类项目时第一步永远是先把物理过程捋清楚:一条馈线上某个位置发生故障后,开关怎么动作、哪些负荷能通过联络开关转供、哪些负荷只能等修复,而DG接入后又多了第三种可能——断开故障区后,部分区域带着DG脱离主网独立运行,也就是形成孤岛。
这个“第三种可能”正是标题里“孤岛”的价值所在。传统配电网可靠性评估只考虑“故障隔离+转供+等修复”,DG接进来之后,如果单纯把DG当普通电源并网运行,故障时直接退出,那DG对可靠性几乎没有贡献。只有允许孤岛运行,DG才能在系统故障时继续带负荷。所以评估模型里必须有孤岛划分环节,否则DG接入的可靠性收益根本体现不出来。
1.2 为什么用解析法而不是蒙特卡洛
可靠性评估主流有两条路:解析法和蒙特卡洛模拟法。蒙特卡洛胜在能处理复杂时序、随机波动,但代价是计算量大,尤其当你要对十几年运行周期做大量抽样时,单次评估跑几分钟很正常,调参调得人崩溃。
这个项目我选了基于故障枚举的解析法。核心逻辑是:遍历每个可能故障的原件(馈线段、变压器、分支线),对每次故障分析开关动作和恢复策略,把影响累加起来。这种方式逻辑透明,能直观看到“哪条线故障导致哪些负荷受什么程度影响”,也方便把孤岛划分策略嵌进去。对于教学验证、方案对比这种场景,解析法完全够用,而且结果可复现。
蒙特卡洛不是不能用,只是对“最优孤岛划分”这种需要多次场景尝试的目标来说,解析法的确定性更强。我的做法是:先用枚举法把故障事件过一遍,孤岛策略作为一个可插拔模块嵌在故障影响分析里,代码结构清晰,后面想接时序负荷曲线也方便扩展。
1.3 “最优”到底优化什么
“最优孤岛划分”这个词被很多论文用滥了,落地前一定要先立项——你优化的是哪个目标。不同目标会导致完全不同的孤岛搜索结果:
- 目标A:孤岛内恢复负荷量最大,综合停电损失最小;
- 目标B:孤岛内重要负荷优先恢复,普通负荷放后面;
- 目标C:孤岛运行时的网损最小、电压最稳。
实际工程里A和B最常见,而且可以结合:先按负荷重要度排序,在满足DG出力约束的前提下,尽量把更多负荷圈进孤岛。如果DG出力不足以带起整片区域,就优先保一级负荷,必要时切除部分三级负荷。这就是我理解的“最优”——不是数学上严格全局最优解,而是在工程约束下收益最优的可行方案。
2. 核心原理梳理:DG建模、可靠性指标与故障影响分析的融合
2.1 DG出力怎么定,直接影响孤岛能否成立
分布式电源建模的粗细程度,决定了可靠性评估结果的可信度。
最简单的做法是把DG当成恒功率电源,比如光伏给一个典型出力值、风机给一个典型出力值。这样做项目速度快,物理概念也清晰,适合第一版评估。但有个隐患:孤岛形成以后,如果孤岛内负荷超过DG容量,按理论会频率崩溃,评估时必须判定“孤岛失败”,这时候该区域负荷仍然算停电。所以DG出力给多少,直接决定很多负荷“复电还是不复电”。
更精确的做法是用典型日时序曲线,24小时8760点分段。光伏白天出力大晚上为零,风电随风变化。时序模型会把可靠性评估的计算量抬上去,但结果更贴近实际。我一般建议分两步走:先用恒功率模型把整个评估框架调通,再换时序出力做敏感性分析。这样能快速定位算法问题,不至于一开始就被数据拖住。
配网里常见的DG类型包括微型燃气轮机(可控出力)、光伏(间歇性)、风电(间歇性)、储能(双向功率)。做可靠性评估时,可控型DG的孤岛成功率明显高于间歇型。如果DG配置里有储能,建模时还要考虑充放电状态和持续时间约束,这属于后话,第一版可以先忽略。
2.2 可靠性指标别只盯着SAIFI
可靠性评估最终要输出一堆指标,行业里常用的有这么几个:
- SAIFI(系统平均停电频率):单位用户年平均停电次数,次/户·年;
- SAIDI(系统平均停电持续时间):单位用户年平均停电小时数,h/户·年;
- CAIDI(用户平均停电持续时间):等于SAIDI/SAIFI,表示每次停电平均持续多久;
- ENS(年缺供电量):所有用户年损失电量之和,kWh/年;
- ASAI(供电可用率):用户得到供电的时间比例。
很多初做可靠性的人只报SAIFI和SAIDI,这不够。孤岛策略主要影响的是故障后的恢复时间——原本要等几小时修复的负荷,现在可能几分钟内通过孤岛恢复,所以SAIDI改善幅度往往比SAIFI更显著。ENS则直接反映经济损失,如果DG容量大、孤岛成功率高,ENS下降会非常明显。这组指标放在一起,才能完整说明DG和孤岛策略的价值。
指标计算里还有个容易忽略的点:用户数怎么和负荷挂接。一般每个负荷点会给定用户数,故障影响分析时统计“受影响的用户次数”和“受影响用户时长”,最后统一归算到全系统总用户数上。如果负荷点用户数给得不准,SAIFI/SAIDI就会失真,宁可把用户数当成相对权重,也要保证一致口径。
2.3 把孤岛集成进故障模式后果分析
传统FMEA(故障模式与后果分析)流程是:对每个元件假设故障,隔离故障段,非故障段尝试联络转供,不能转供的等修复。孤岛策略加入后,逻辑变成三步:
- 故障发生后,跳开故障段两侧开关,隔离故障;
- 未故障的失电区域,先看是否有联络开关能转供到其他馈线,能转则转供;
- 转供不了的部分,检查是否有DG节点在失电区域内,如果有,从DG节点出发搜索可划入孤岛的节点集合,形成孤岛。
这里的关键是,孤岛只在“上游转供不成功”的前提下搜索,因为转供恢复通常比孤岛更快更可靠。但如果联络线容量不足或转供路径过长,孤岛就是更好的选择。实际算的时候,我会先判转供再判孤岛,顺序不能反。
3. Matlab实现全流程:数据组织、故障枚举、孤岛搜索与指标累加
3.1 配电网拓扑怎么存,决定代码好不好写
配电网本质是一个树状(辐射状)图,但通过联络开关会形成闭环。存储方式我强烈建议用“支路表”而不是邻接矩阵。支路表每一行代表一条支路,包涵起点节点编号、终点节点编号、支路长度、单位故障率、修复时间、所带负荷和用户数。节点负荷可以单独用一个数组存。
这种数据结构的优势有两点:一是和CIM模型、Excel原始数据的转换直接对应;二是故障枚举时只需要遍历支路表,操作哪条支路就改哪条的状态,逻辑清晰。邻接矩阵浪费内存且稀疏度太高,33节点的系统还好,碰到上百节点的系统就开始痛苦了。
代码第一步永远是做数据检查。最常见的坑是节点编号不连续或者支路方向不一致。我遇到过原始数据里支路有些是从父节点到子节点,有些反过来,导致后续遍历找错上下游。建议读入数据后先统一方向,统一格式再往下走。这块花20分钟,后面省两小时。
3.2 故障枚举主循环的设计逻辑
故障枚举的伪代码如下:
for k = 1:size(branch, 1) % 遍历每条支路 % 1. 根据拓扑找故障段的上下游开关,断开 % 2. 识别失电区域集合 % 3. 对失电区域尝试转供 % 4. 转供失败的区域,查找DG节点,尝试孤岛划分 % 5. 基于恢复结果计算该支路故障导致的停电用户数、停电时长 % 6. 累加SAIFI、SAIDI、ENS end这里有个细节:支路可以是线路段,也可以是配电变压器。变压器故障率和线路不一样,修复时间也不同,处理方式相同但参数分开给。
故障枚举里最容易出问题的环节是“失电区域识别”。我的实现是:故障后把故障支路从邻接表里删掉,从根节点(变电站母线)出发做深度优先搜索,凡是能连通到的节点不失电,没连通到的节点就是失电节点。这一步要小心孤岛和DG的耦合关系——失电区域里如果本身包含分布式电源节点,理论上可能自己撑起孤岛,但孤岛是否成立要满足功率约束,所以先不急着认为它恢复。
3.3 最优孤岛搜索的Matlab实现思路
孤岛搜索我采用的是广度优先的“DG为中心蔓延”策略。基本过程如下:
- 确定失电区域内的所有DG节点;
- 从每个DG节点出发,逐层向外搜索相邻且属于失电区域的节点;
- 每加入一个节点,就累加该节点负荷,对比DG总可用出力;
- 如果负荷超过出力,则按负荷优先级别从低到高依次剔除可切负荷,直到满足约束;
- 如果剔除后仍不满足,则缩减孤岛范围,回退到上一可行状态。
这个策略假定孤岛边界是尽量包含更多负荷的“最大可行连通子图”,并按负荷重要度做切除。工程上容易实现,也比纯随机划分稳妥得多。代码核心片段如下:
% 从DG节点开始BFS搜索可行孤岛 queue = dgNode; % 初始队列为DG节点 visited(dgNode) = true; islandLoad = loadDG(dgNode); while ~isempty(queue) cur = queue(1); queue(1) = []; neighbors = find(adjTable(:, cur) & candidateSet); % 失电区域内邻居 for nb = neighbors' visited(nb) = true; % 预加入该节点,判断功率约束 newLoad = islandLoad + loadNode(nb); if newLoad <= dgCapacity islandLoad = newLoad; queue(end+1) = nb; else % 该节点超容量,按优先级评估是否可切部分负荷 % 实际代码里在这里做负荷切除判断 % 无法满足则回退,不把nb加入孤岛 end end end实际实现里“负载切除判断”是关键。我建议给每个负荷点定义一个可切比例。一级负荷不可切,二级负荷最大可切50%,三级负荷可全切。这样孤岛划分既保了重要负荷,也留了弹性。
3.4 可靠性指标累加,口径要统一
每次故障事件处理完后,要把结果累加到总指标里。我用一个数组记录每个负荷点的年停电次数和年停电时长,最后统一归算:
% 某一故障事件的影响 failedNodes = ...; % 本次故障导致的失电节点 restoreTime = ...; % 每个节点的恢复时间 for i = 1:length(failedNodes) n = failedNodes(i); count(n) = count(n) + 1; % 停电次数+1 duration(n) = duration(n) + restoreTime(i); % 停电时长累加 end % 全部故障扫描完后: SAIFI = sum(count .* userNum) / sum(userNum); SAIDI = sum(duration .* userNum) / sum(userNum); ENS = sum(duration .* loadLevel); % loadLevel为节点平均负荷恢复时间的确定规则要预先定清楚:转供恢复的情况,停电时间为开关操作时间;孤岛恢复的情况,停电时间为孤岛形成时间;既不能转供又不能孤岛的,停电时间为修复时间。这三个时间参数直接影响SAIDI和ENS的数值,所以不能拍脑袋。
我做项目时习惯把时间参数做成全局变量,方便批量跑敏感性分析。
4. 完整案例实操:33节点系统接入DG的可靠性对比
4.1 测试系统参数配置——数据怎么给才合理
为了验证算法,我搭建了一个33节点辐射状配电网测试系统,系统标称电压12.66kV,总负荷约3715kW加2300kvar,33个节点32条支路,经过两处联络开关与另一条馈线互联。
基础参数我按常见典型值设定:
- 馈线故障率:0.08次/年·km,平均修复时间:4小时;
- 故障隔离时间:0.2小时;
- 联络转供时间:0.5小时;
- 孤岛形成时间:0.1小时(假定DG具备快速离网切换能力)。
DG配置方面,在节点18接入一台600kW的微型燃气轮机,在节点25接入一台400kW光伏电站,节点33接入一台300kW储能系统。DG总容量1300kW,约占系统总负荷的35%。这个配置比例是故意选的——容量太小孤岛撑不起多少负荷,容量太大又不符合实际配电网渗透率。
案例里我做了三组对比:无DG(基准)、有DG但不允许孤岛运行、有DG且允许最优孤岛划分。这样能分开观察DG接入本身和孤岛策略各自带来的可靠性收益。
4.2 Matlab主程序关键节点讲解
主程序我按模块化方式来写,核心模块包括:
- 数据读入与预处理;
- 配电网拓扑分析(邻接表构建);
- 故障枚举与影响分析;
- 孤岛搜索与功率校验;
- 指标统计与输出。
读入数据部分建议直接读Excel,列名固定,这样换系统不用改代码。预处理里最关键的步骤是把支路表的节点连接关系转换成邻接表,因为后面BFS和DFS都依赖它。
故障影响分析函数大概是这样的格式:
function [count, duration] = analyzeFault(branchIdx, data) % 1. 在邻接表中移除故障支路 % 2. 从源节点DFS判断失电区域 % 3. 遍历失电区域,先尝试转供 % 4. 转供失败区域尝试孤岛搜索 % 5. 返回受影响节点编号及各自的恢复时间 end这个函数是整个评估程序的心脏。写好之后,主程序就是一个循环叠加指标累加,逻辑非常简单。我个人经验是尽量让函数单一职责,别把故障分析、孤岛搜索、指标累加全写在一个大循环里,不然调参的时候寸步难行。
4.3 实测结果解读:孤岛带来多少“弹性”
三组场景运行结果如下(数值为33节点测试系统下的仿真结果):
| 方案 | SAIFI(次/户·年) | SAIDI(h/户·年) | ENS(kWh/年) | ASAI(%) |
|---|---|---|---|---|
| 无DG(基准) | 2.430 | 8.530 | 60200 | 99.9026 |
| 有DG,不允许孤岛 | 2.396 | 8.410 | 59350 | 99.9040 |
| 有DG,允许最优孤岛 | 1.682 | 5.520 | 37400 | 99.9370 |
结果有几个值得关注的点:
一是“有DG但不允许孤岛”相比基准几乎没有改善。这验证了我前面说的:DG如果故障时直接退出,等于白装,甚至因为DG接入带来的保护配合变化,极端情况下可靠性还可能下降。
二是“允许孤岛”后SAIDI的降幅(35.3%)比SAIFI的降幅(30.8%)更明显。原因不难理解:孤岛策略主要缩短的是故障后的恢复时间,而SAIFI反映的是“发生了几次停电”,后者更多取决于故障隔离的范围控制。
三是ENS下降了37.9%,幅度最大。原因是孤岛成功率高时,原本要停数小时的大量负荷,最短可能只需要0.1小时就能复电,损失电量自然大幅减少。
如果从负荷点来看,DG附近的负荷节点受益最明显。比如节点19到22这一带,因为靠近燃气轮机,几乎所有上游故障导致的失电都能通过孤岛恢复,停电时间几乎可以忽略。而末端节点离DG远又没有联络线,改善幅度就小得多。这个分布规律对规划很有参考价值:DG落点如果靠近重要负荷且孤岛范围覆盖得好,可靠性收益最显著。
4.4 结果可视化:画图让人一眼看懂改善
Matlab里我习惯用三种图来呈现结果:
第一是柱状图,对比三组方案的SAIFI/SAIDI/ENS,最直观。用bar函数加误差条,颜色区分清晰。
第二是节点停电年时长分布图,用bar画每个节点在“有孤岛”和“无孤岛”下的停电时长,能看到DG近端改善大、远端改善小的空间差异。
第三是ENS累积曲线,按节点从高到低排序画累积停电损失电量,能快速定位“改善收益最大的前几个节点”,对后续DG扩容和联络开关规划都有指导意义。
画图代码不复杂,但我建议一定把坐标标签和单位写清楚,否则过两周自己回来看图都得猜数据是什么。
5. 常见问题与排查技巧实录
5.1 故障后DFS判断失电区域时无限递归
Matlab默认递归深度有限,如果配电网节点上百级,DFS递归写法很容易直接崩掉。我在节点超过80的网格系统上踩过这个坑。
解决方式是改用栈模拟递归,或者直接用图遍历函数。Matlab里可以自己写栈:
stack = rootNode; while ~isempty(stack) cur = stack(end); stack(end) = []; visited(cur) = true; % 找邻居,未访问则压栈 end这个写法对上千节点的系统也毫无压力,而且代码可读性不差。另外一个容易搞混的点是:遍历完失电区域之后,记得恢复被删除的故障支路,否则下一轮故障模拟会从错误的拓扑开始。
5.2 孤岛功率校验用错负荷单位
这是我最常看到的问题之一。配电网里负荷既接近有功功率又有无功功率,孤岛功率平衡必须同时校验有功和无功。不少初版代码只校验了有功,导致算出来的孤岛成功率虚高。实际上DG无功容量不够时,孤岛电压可能根本撑不住。
我的建议是给每个DG设置无功上限,孤岛校验时同时检查:
if (activePowerLoad <= activePowerDG) && (reactivePowerLoad <= reactivePowerDG) % 孤岛可成立 else % 孤岛无法成立 end如果DG本身无功容量不足,而孤岛区域又有无功补偿装置,可以把补偿容量也加进来一起算。这部分逻辑虽然简单,但对结果影响很大。
5.3 开关操作时间千万不能随手填
SAIDI对恢复时间的敏感性极高,因为恢复时间直接进时长累加。我在做敏感性分析时发现:孤岛形成时间从0.1小时改成0.5小时,SAIDI就可能从5.52涨到6.4,整个“孤岛改善效果”的结论会被削弱很多。
实际操作中,孤岛形成时间取决于DG控制方式和开关自动化水平。具备自动同期功能的DG,黑启动并网速度快;手动操作联络开关就可能需要0.5到1小时。这些参数必须结合工程实际来填,否则评估结果偏乐观或偏悲观都会误导决策。
建议做一次敏感性分析,输出“恢复时间参数 vs SAIDI/ENS”的表格,看结果对参数依赖有多大。敏感性分析结果本身也是项目交付的一部分,能体现评估工作的严谨性。
5.4 拓扑有环时孤岛搜索被干扰
配电网正常运行是辐射状,但联络开关闭合后就有环。故障状态下,如果联络开关参与转供,暂态拓扑里会形成环网。DFS/BFS搜索时如果访问标记处理不当,环会引发重复遍历,甚至死循环。
我的处理办法是:每次搜索都建立全新的访问标记数组,并把联络开关当作可选的边,转供路径搜索和孤岛搜索分别使用不同的规则集。孤岛搜索有一条隐含约束:孤岛内部必须保持辐射状,这样保护逻辑才成立,否则孤岛内部出现环,保护配合会大乱。在代码上,孤岛搜索的“扩展边”仅限制在原来配电网的辐射状拓扑范围内。
5.5 指标累加四舍五入导致结果异常
Matlab里浮点数累加通常没问题,但如果把节点停电次数定义成整型,再跟故障率这种小数相乘,会损失精度。我统一用double,在最后输出时才格式化。
此外,支路故障率很小、负荷年停电时长很大的组合,乘出来是典型的“大数×小数”,累加过程中浮点误差会累积。建议最后输出时统一保留4位小数,别在中间过程里做round操作,不然SAIFI算出2.4302和2.4307这样差一个数量级的噪声,谁也看不出来问题在哪。
5.6 问题速查表
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 程序运行结果全为0 | 支路表故障率字段读成0 | 检查Excel字段名称是否匹配 |
| SAIFI异常巨大 | 用户数统计重复 | 检查节点用户数是否重复累加 |
| ENS出现负数 | 孤岛功率校验减去负荷后未取绝对值 | 检查负荷扣除逻辑 |
| 孤岛含非连通节点 | 邻接表构建方向错误 | 打印邻接表验证每个节点邻居 |
| 有DG但指标无变化 | 孤岛允许标志未传入故障分析函数 | 检查程序参数传递 |
| 代码运行极慢 | 每轮故障都重新构建图 | 图结构不变,移出主循环构建一次 |
6. 扩展方向的一点建议
这个项目做完,如果想继续往深走,我个人最推荐三个扩展方向:一是把负荷从定点值换成时序变化曲线,在8760小时负荷场景下重新评估,这样能更准确捕捉DG出力和负荷的时序匹配度,尤其对光伏这种白天发电的DG,效果差异很大。二是把目标函数改成经济性优化,把停电损失、DG发电成本、开关操作成本统一折算成综合年费用,这样孤岛划分的“最优”就从技术最优升级到了经济最优。三是接入多目标优化算法,比如用粒子群或非支配排序遗传算法,同时优化孤岛范围、开关状态和DG出力,产出的结果更有研究价值。
如果只是想把现有项目包装得更完整,还可以加一份完整的报告模板,包括输入数据说明、评估流程、灵敏度分析和结论,这在做课程设计或者项目交付时很加分。个人体会是:可靠性评估项目最花时间的永远不是算法主程序,而是数据准备和结果合理性校验。Matlab代码本身几百行就能跑通,但要把结果解释得让听的人信服,功夫通常都在代码之外。