ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

最优孤岛划分下含分布式电源配电网可靠性评估Matlab实现

最优孤岛划分下含分布式电源配电网可靠性评估Matlab实现

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(故障模式与后果分析)流程是:对每个元件假设故障,隔离故障段,非故障段尝试联络转供,不能转供的等修复。孤岛策略加入后,逻辑变成三步:

  1. 故障发生后,跳开故障段两侧开关,隔离故障;
  2. 未故障的失电区域,先看是否有联络开关能转供到其他馈线,能转则转供;
  3. 转供不了的部分,检查是否有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为中心蔓延”策略。基本过程如下:

  1. 确定失电区域内的所有DG节点;
  2. 从每个DG节点出发,逐层向外搜索相邻且属于失电区域的节点;
  3. 每加入一个节点,就累加该节点负荷,对比DG总可用出力;
  4. 如果负荷超过出力,则按负荷优先级别从低到高依次剔除可切负荷,直到满足约束;
  5. 如果剔除后仍不满足,则缩减孤岛范围,回退到上一可行状态。

这个策略假定孤岛边界是尽量包含更多负荷的“最大可行连通子图”,并按负荷重要度做切除。工程上容易实现,也比纯随机划分稳妥得多。代码核心片段如下:

% 从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.4308.5306020099.9026
有DG,不允许孤岛2.3968.4105935099.9040
有DG,允许最优孤岛1.6825.5203740099.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代码本身几百行就能跑通,但要把结果解释得让听的人信服,功夫通常都在代码之外。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进