含分布式电源的配电网可靠性评估与最优孤岛划分Matlab实现 1. 项目概述“含分布式电源的配电网可靠性评估”是近年来配电系统规划和运行绕不开的一个课题而我在拿到这个项目标题的时候第一反应就是它把两个很硬的点焊在了一起——一是配电网的可靠性指标怎么算得准二是分布式电源接入之后孤岛怎么划才最划算。很多资料里要么只谈分布式电源的随机性建模要么只讲配电网的传统可靠性评估真正把“孤岛划分”作为变量、并且以“最优”为目标来做可靠性评估的完整实现其实并不多。这个项目能解决的实际问题很明确当配电网上游发生故障、主网电源断开时分布式电源能不能通过预先或者动态划分出的孤岛继续给一部分负荷供电能供多久能供多少去掉了多少电量不足把这些量化成可靠性指标就是可靠性评估而“怎么划分能最大程度减少停电损失”就是最优孤岛划分。整套流程用Matlab实现适合电力系统方向的研究生、从事配电网规划的工程师以及刚入行想做分布式电源接入影响分析的人参考。这篇文章我会把整个思路拆开从模型建立、可靠性指标计算、孤岛划分优化到Matlab代码的架构和踩坑记录全部讲清楚。2. 可靠性评估的核心思路与模型拆解2.1 为什么孤岛划分会直接影响可靠性指标先理清一个基础概念。配电网可靠性评估里面最常用的两个指标一个是系统平均停电频率指标SAIFI另一个是系统平均停电持续时间指标SAIDI还有比如电量不足期望值EENS这类反映缺电量的指标。传统配电网一般是单电源辐射状上游变电站是唯一供电点一旦10kV馈线某处故障后面挂着的负荷全部停电直到故障隔离和修复。这时候供电恢复的手段基本只有“拉开上游开关、合上联络开关从相邻馈线转供”这一条路。加了分布式电源Distributed Generator以下简称DG之后情况就变了。DG可以脱离主网独立给周围的负荷供电这种“自成一派”的运行状态就是孤岛。孤岛分成两类计划性孤岛和非计划性孤岛。可靠性评估里面讨论的大多数是计划性孤岛或可控孤岛——也就是在故障发生之后通过保护配合和开关操作有意识地把一部分负荷和DG划在一起继续运行。这时候问题就来了DG的容量有限不是所有负荷都能带得动配电网里开关众多从哪个位置断开、把哪些负荷划进孤岛直接决定了哪些用户能继续用电、哪些只能停电。所以孤岛划分方案本质上是一个“在故障状态下通过控制开关状态来改变供电拓扑从而影响可靠性指标”的决策变量。同一个配电网同样的DG接入位置和容量有的划分方案能保住八成的负荷有的可能只能保住三成。这就是“最优孤岛划分”存在的意义。2.2 可靠性评估的解析法思路配电网可靠性评估常用方法有解析法和模拟法蒙特卡洛。本项目用解析法相对合适因为我们要研究不同孤岛划分方案下的可靠性变化解析法能稳定复现、不引入随机波动适合方案对比。解析法的基本流程是枚举馈线上所有可能发生故障的元件线路段、变压器、开关等。对每个故障确定其影响的负荷范围也就是哪些负荷点会停电。结合故障隔离、联络转供、孤岛运行等恢复策略计算每个负荷点的停电次数和停电时间。汇总得到系统级可靠性指标。在传统配电网中故障影响范围可以通过“搜索故障点上游至电源之间的开关”来确定故障点上游负荷不受影响因为电源侧仍能供电故障点下游负荷在隔离故障前全部停电隔离后如果能通过联络开关转供则停电时间为开关操作时间否则停电时间为故障修复时间。引入DG和孤岛之后故障影响范围判定新增了一项故障点下游的一部分负荷如果被划进孤岛且孤岛内有足够的DG出力支撑那么这部分负荷在故障隔离后的停电时间就降为零或者只计算短时的切换时间。这就改变了每个负荷点的停运持续时间进而改变了SAIDI和EENS。这里有个关键的说法要澄清不是“DG能让整个下游都不断电”而是“能带多少负荷取决于孤岛容量”。所以计算机必须把“最优孤岛划分”作为一个约束条件或优化子问题嵌入可靠性评估循环。2.3 最优孤岛划分问题建模最优孤岛划分可以抽象成一个带约束的组合优化问题。给定一个辐射状配电网节点母线集合为N支路集合为B若干节点上接了DG各DG的出力上限为P_DG,i各节点的负荷为P_L,j。当某条支路发生故障导致上游电源不可达时我们希望选出一个节点子集S和一个支路子集B_island使得由B_island和S构成的子图是连通的S中至少包含一个DG节点孤岛内所有DG的出力上限之和大于等于孤岛内所有负荷之和功率平衡约束在这个前提下孤岛内负荷总容量最大化或者说孤岛外被切除的负荷价值最小化。表达出来就是目标函数max Σ_{j∈S} w_j * P_L,j约束条件连通性约束S在支路B_island下连通功率平衡约束Σ_{i∈S∩DG} P_DG,i ≥ Σ_{j∈S} P_L,j拓扑约束孤岛与主网的连接支路处于断开状态故障隔离和孤岛边界开关动作节点电压和支路潮流约束可选重负荷情况下要考虑但作为简化可以用容量约束代替。需要注意的是目标函数里有个权重w_j代表负荷的重要程度。如果不加权重可以认为所有负荷同权那目标就是孤岛内总额定负荷最大加了权重可以体现一级负荷优先。最实用的是把权重设为负荷等级系数这对工程决策更有意义。这个模型求解上有个麻烦点连通性约束是非凸的直接做整数规划也要小心规模爆炸。好在配电网一般是几十个节点的小规模系统完全可以用启发式搜索、遗传算法、或者图论里的连通子图枚举来搞定。Matlab里最舒服的做法是利用图对象graph和深度优先搜索把连通性判断封装成一个函数再配合遍历或智能优化算法去搜索孤岛方案。我在实现时采用的是“基于搜索树的连通子集生成 功率平衡校验 目标函数评价”的框架对于常见IEEE RBTS Bus 2/FEEDER这类几十节点的系统搜索效率足够。2.4 DG出力模型处理孤岛运行期间DG出力怎么定这个直接决定可靠性指标算出来偏乐观还是偏悲观。我这里采用一个折中且工程上可接受的模型光伏、风机这类间歇性DG在孤岛运行时其出力不一定等于额定容量。可靠性评估通常取一个“可支撑出力”系数比如取额定容量的某个百分数或者按时序数据取统计值。储能型DG带储能的DG可以按额定放电功率和放电持续时间来支撑孤岛这更适合作为孤岛的主电源。柴油发电机、微型燃机这类可控DG孤岛运行时可以认为出力在额定范围内连续可调按负荷需求分配。在实际代码里我建立了一个“孤岛支撑能力”向量P_support每个DG节点给一个支撑容量。为了做保守估计通常会把间歇性DG的支撑容量乘以一个小于1的置信系数比如光伏取0.3~0.5风机取0.4~0.6可控DG取1.0。如果做的是更精细的时序可靠性评估可以把8760小时的出力曲线和负荷曲线都带进去每次故障发生在不同时刻对应的支撑容量不同但这会让计算量猛增一般用于规划层面的专项分析。本项目主体版本采用固定支撑容量的简化模型同时在扩展版本里预留了时序接口。3. 可靠性指标计算与孤岛优化实现3.1 可靠性指标定义与计算公式在做Matlab实现前先把要算的指标公式写清楚不然代码写到后面容易乱了。假设系统一共有N个负荷点每个负荷点j的平均负荷为L_j单位kW年故障次数由该负荷点所处的馈线位置决定记每次故障事件k对负荷点j造成的停电时间为r_jk单位小时/次则该负荷点的年平均停电时间U_j为U_j Σ_k r_jk负荷点j的年平均停电次数λ_j为λ_j Σ_k 1{负荷点j在第k次故障事件中停电}系统级指标SAIFI系统平均停电频率次/户·年 SAIFI Σ_j λ_j * N_j / Σ_j N_j其中N_j为负荷点j的用户数或按容量折算。SAIDI系统平均停电持续时间小时/户·年 SAIDI Σ_j U_j * N_j / Σ_j N_jEENS电量不足期望值MWh/年 EENS Σ_j U_j * L_j如果要考虑分布式电源支撑带来的减少停电核心就是U_j的变化。比如某个故障事件发生原本负荷点j要停r_repair小时故障修复时间现在因为孤岛划分成功只停了r_switch小时开关切换时间通常就几分钟那U_j就减少了一大截。如果孤岛能做到无缝切换或者黑启动时间极短甚至可以认为r_jk0。指标对孤岛策略的敏感性主要就体现在这个收益上。3.2 孤岛划分求解的原理解析最优孤岛划分本质上是在一个辐射状树上找一个“含DG的连通子树”并且子树总负荷尽量大。这一步我一开始想直接用现成的整数规划工具箱后来发现对于连通性约束处理起来特别绕而且依赖工具箱会降低代码通用性。所以我换了个思路直接用图的搜索。核心步骤概括为使用Matlab的graph对象建立配电网拓扑。枚举故障支路断开该支路后把下游节点子图提取出来。在故障场景下以下游某一DG节点为根向上游或向两侧做连通搜索生成候选孤岛包含根节点和周围可达节点。对每个候选孤岛做功率平衡校验并计算负荷价值。在所有候选孤岛中选择目标函数最大的方案作为该故障场景下的最优孤岛划分。返回该划分下的负荷停电时间修正结果更新可靠性指标。实际代码中我并不是枚举所有连通子集节点50个时子集数量爆炸而是用了一个非常有效的策略“从DG节点出发逐步扩张”。这个策略背后的直觉是孤岛一定要包含至少一个DG而且从该DG能找到一条连通的路径扩展出去囊尽量多的负荷。那么一个自然的方法是固定一个DG根节点沿所有连通方向搜索每次尝试加入一个相邻节点判断功率约束是否可行可行则保留不可行则回溯。这是一种回溯剪枝的搜索方式。配合负荷价值排序策略可以快速逼近最优解。为了不让搜索规模失去控制我做了一个近似处理当候选节点数超过一个阈值时采用贪心策略每次优先加入单位功率价值最高的相邻负荷节点这样能保证算得很快且结果工程上可用。3.3 Matlab代码架构与关键函数整体代码我按功能拆成五个模块这样后期改指标、换DG位置、调算法都很方便。项目目录/ ├── data/ % 配电网数据节点、支路、DG、负荷 ├── core/ │ ├── main_reliability.m % 主程序遍历故障汇总指标 │ ├── load_data.m % 读取网架数据 │ ├── build_graph.m % 构建graph对象 │ ├── failure_simulation.m % 单次故障分析 │ ├── island_search.m % 最优孤岛搜索算法 │ ├── calc_reliability.m % 可靠性指标汇总 │ └── utils/ │ ├── check_connectivity.m │ ├── check_power_balance.m │ └── find_downstream_nodes.m下面挑几个核心函数讲。3.3.1build_graph.m把网架数据转成图对象接线数据通常是这样的表格形式支路编号 | 首端节点 | 末端节点 | 是否含开关 | 故障率(次/km·年) | 长度(km)用Matlab的graph函数可以直接建G graph(from_nodes, to_nodes);然后我把支路数据存在一个结构体数组里每条支路带上故障率和长度。用G.Edges设置权重方便后面做最短路径或连通性判断。这个阶段没啥坑唯一要注意的是节点编号必须从1开始连续如果原始数据是字符串节点名先做映射。3.3.2find_downstream_nodes.m确定故障影响范围对于故障发生在支路k上首端节点为f末端节点为t如果主电源在f侧那么以f为起点在断开支路k之后t侧节点全部属于“下游区域”。用graph做这件事非常方便G_temp rmedge(G, f, t); % 暂时去掉故障支路 downstream reachable_nodes(G_temp, t); % 从t出发能到达的所有节点reachable_nodes可以用bfsearch实现nodes bfsearch(G_temp, t);bfsearch是广度优先搜索返回从t出发按顺序访问的所有节点正好符合“下游可达”的定义。这个方法比扫邻接矩阵高效而且不用关心系统到底多大是Matlab图工具箱带来的一个福利。3.3.3island_search.m核心搜索算法island_search接收的参数是故障后下游子图、DG节点列表、DG支撑容量、负荷数据。返回值是一个结构体包含孤岛包含的节点集合、连接关系、总负荷、总DG容量。function island island_search(G_sub, dg_nodes, dg_cap, load_data) best_island []; best_value 0; % 对于每个DG节点作为根节点 for root dg_nodes % 使用DFS回溯搜索包含root的连通子集 candidate dfs_expand(G_sub, root, dg_nodes, dg_cap, load_data); if candidate.total_value best_value best_island candidate; best_value candidate.total_value; end end island best_island; enddfs_expand里面需要维护“已加入节点集合”和“当前总负荷”。每次尝试加入一个与当前集合相邻且在子图中的节点判断加入后总负荷是否小于等于总DG支撑容量。如果满足就递归继续扩展如果不满足就不加尝试下一个相邻节点。这个过程中需要记录能够达到的最大总负荷也就是最优目标函数值。这里有个非常重要的细节孤岛搜索的时候必须保证功率平衡是“实时约束”因为后续可能继续加入节点现在满足不代表加入更多节点后还满足。所以递归逻辑是在“当前可能是最优解”这一层就更新答案然后把满足容量约束的新节点加进去继续搜。路径剪枝的顺序能显著影响性能我推荐按相邻节点的负荷从大到小排序进行尝试这样很容易先找到大负荷方案尽早更新上界配合剪枝能省不少时间。3.3.4failure_simulation.m单次故障集成的评估函数这个函数做的是对某个故障事件k的完整处理流程读取故障支路信息。判断上游、下游节点范围。对下游每个负荷点先视作“停电”停运时间为故障修复时间r_repair。检查下游是否存在DG。若无DG保持原停电时间。若存在DG调用island_search求出最优孤岛。对孤岛内的负荷点停电时间改为开关切换时间r_switch一般取0.05~0.5小时取决于自动化水平孤岛外的负荷点依然停电。同时上游节点的负荷不受影响电源连续。保存该故障事件中各负荷点的停电时间贡献。需要特别提醒的是对于计划性孤岛切换时间怎么取如果配电网有馈线自动化能在几百毫秒内完成故障隔离和孤岛解列那r_switch可以取0.1小时甚至更低如果是人工操作联络开关可能要0.5~1小时。这个参数的取值直接影响SAIDI和EENS结果做分析时建议做敏感性分析不要拍脑袋定一个就完事。3.3.5calc_reliability.m指标统计把所有故障事件的停电时间贡献汇总到每个负荷点然后套用前面给的公式算SAIFI、SAIDI、EENS。这一步在实现上就是累加器和权重的活但注意平均负荷L_j要用年最大负荷还是年平均负荷要前后一致。通常可靠性评估用的是峰值负荷或平均负荷看设定但要写清楚。3.4 算例数据准备我拿一个扩展的IEEE RBTS Bus 2馈线模型作为示例这是很多论文里常用的标准测试系统。为了说明问题把系统简化成32个节点一条主馈线带若干分支节点10和节点25分别接了一台DG。负荷数据用一个矩阵三列节点号、年平均负荷(kW)、用户数。做孤岛搜索之前需要把DG支撑容量写进一个数组比如dg_nodes [10, 25]; dg_capacity [800, 1000]; % 单位kW这是孤岛可支撑容量假设节点10的DG是可控型燃气机组支撑容量800kW节点25的DG是带储能的光伏系统按置信折算后支撑容量1000kW。两个DG的支撑容量合计1800kW。下游子图如果包含了节点25附近的馈线段那么孤岛搜索就会尝试把节点25、节点30、节点32等负荷拉进来直到总负荷接近1000kW。如果节点10的DG也在同一孤岛内那总支撑容量就是1800能带动的负荷更多。这里就存在“多个DG是否联合成一个孤岛”的决策如果两个DG之间的路径是连通的且容量允许往往联合成一个大孤岛更好因为能带的负荷更多但有时候双DG分别带各自区域负荷可能更优取决于负荷分布。搜索算法对这些情况都能自动处理因为它枚举了以每个DG为根的候选孤岛并比较目标函数。3.5 场景对比有孤岛和无孤岛的可靠性差异我跑了一个小型算例来演示效果。设故障修复时间平均为4小时开关切换时间为0.2小时DG支撑容量分别为800kW和1000kW负荷均为居民负荷。无孤岛划分的情况下某个中段支路故障会导致6个负荷点停电EENS增量约3400 kWh/年接入DG并做最优孤岛划分后其中4个负荷点被孤岛覆盖停电时间从4小时降到0.2小时EENS增量降到约680 kWh/年。SAIDI从原来的约2.1小时/户·年下降到1.4小时/户·年这个数字和具体系统的联络转供能力有关系。可见DG孤岛对指标改善非常明显。但也必须看到反向情况如果负荷太重DG带不动孤岛划分失败那这些负荷仍然要停4小时。所以“最优”不代表“全能”还得在规划阶段合理配置DG容量和位置最好和负荷中心靠得近一点。这个案例告诉我们可靠性评估的价值不仅在于“算个数字”更在于帮你发现DG接入点和容量配置上的短板。4. 实操过程中的常见问题与排查技巧4.1 搜索效率低节点多时跑不动刚开始我用的是纯枚举所有连通子图节点一旦超过30个就非常吃力。后来优化成“从DG根节点DFS扩展剪枝”速度提升明显。如果你的网络节点数到了100以上建议再叠加贪心策略每次优先尝试加入负荷最大的相邻节点这样不一定保证全局最优但结果通常接近最优而耗时从分钟级降到秒级。4.2 孤岛划分结果里出现不连通的孤立节点这是个很容易犯的错。如果DFS时只判断节点集合而不检查连通性就会把一些和孤岛主体不相连的节点也包含进来实际物理上不可能。解决办法是在加入新节点前先确认该节点与当前集合中的某个节点之间存在边且这条边在故障后仍可用。用graph做这个检查很方便if any(hasedge(G_sub, new_node, current_nodes)) % 可以加入 end但注意hasedge一次只能查一个节点对如果当前集合有几十个节点需要循环性能一般。更好的办法是提前用neighbors(G_sub, new_node)获取邻接节点再与当前集合求交集非空则加入。4.3 电源容量和负荷功率单位不一致导致的假平衡很常见的坑DG容量标的是kVA负荷用的是kW不乘以功率因数就去做平衡校验结果明明实际带不动却判断成“可行”。孤岛内功率平衡不仅要看有功还要看无功或视在功率。简单做法是把所有容量和负荷都归算到相同的基准下比如统一用kVA负荷kVAkW/功率因数。如果不考虑无功至少要在文档里说明假设功率因数为1。我的实践是默认负荷功率因数0.9DG容量按kVA有功出力按容量乘0.9无功容量如果不做潮流校验就先忽略。4.4 故障隔离和孤岛边界开关动作顺序搞反孤岛划分必须在故障隔离后进行。如果故障支路尚未被隔离直接搜索孤岛可能会把故障点包含进来导致孤岛内带上故障造成保护误动那就变成非计划孤岛了。我写代码时专门把“隔离故障支路”和“扩展孤岛边界”分成两步先移除故障支路再在剩余子图上搜索从逻辑上杜绝了这种可能。这一点也是工程上审查可靠性计算结果时最容易被质疑的地方务必保证代码注释里写清楚。4.5 只有一台DG当孤岛电源时保护配合怎么做虽然本项目主要做可靠性评估不需要建立继电保护模型但作为电力系统背景的博主还是想提醒孤岛划分方案必须与保护定值、重合闸策略相匹配。如果孤岛内有逆变型DG故障穿越、防孤岛保护、低频减载这些都会影响孤岛能否成功建立。可靠性评估里如果假设“孤岛百分百成功”结果是偏乐观的。实际工程评估可以考虑一个孤岛成功率系数比如0.95把这个不确定性纳入停电时间计算会让结果更可信。4.6 多DG孤岛的功率分配处理当孤岛内有两个及以上DG时功率平衡约束需要满足的是ΣP_DG ≥ ΣP_load但具体每个DG出力多少会受DG类型和控制方式影响。代码里我简单采用等比例分担方式按各DG可用容量比例分配负荷。这样做不算精确但作为可靠性评估层次的稳态分析够用了。如果要考虑更精细的电压/潮流那得引入潮流计算本文档就不展开了但代码结构上已经预留了接口你可以在check_power_balance.m里自行扩展为潮流校验。4.7 数据格式不规范导致图构建失败最常遇到的是节点编号不连续、存在孤立的负荷节点、支路表里有重复边。我在load_data.m里加了检查函数提取所有节点编号排序检查最大编号是否等于节点数如果有间隙就重编号。重复边用unique处理。这些数据清洗的功夫虽然不起眼但能省掉后面一大段debug时间。我的建议是所有数据在进入模型前先做一次完整性校验包括支路两端节点都存在、负荷节点序号合法、DG节点序号合法等。4.8 关于指标计算口径的补充SAIFI和SAIDI计算时用户数N_j到底是户口数、人数还是变压器容量不同资料口径不同但只要保持一致就不会有问题。我在代码里直接用用户数并在结果表里注明。EENS的单位常用MWh/年如果负荷单位是kW、停电时间是小时则EENS天然为kWh/年要除以1000转成MWh/年。这个细节非常容易忽略建议输出前统一换算。5. 扩展方向从静态评估到时序可靠性目前这个版本是“故障场景静态评估”也就是说每个故障事件下DG出力取固定支撑容量、负荷取平均负荷。这个方法简单高效适合规划方案初步比较。但如果想更贴近实际建议扩展为时序仿真将8760小时的负荷曲线和DG出力曲线导入每个故障事件发生时刻都不同对应的孤岛支撑容量也不同。考虑储能DG的SOC状态孤岛运行时间受储能容量限制支撑能力不再是一个恒定值而是一个时间函数。考虑故障修复过程中如果孤岛内DG出力不足可能需要切负荷这样停电时间就不是0.2小时或4小时这种二值关系而是部分时间停电、部分时间供电的混合状态。这种时序版本虽然计算量大但能给出EENS的更准确估计也能分析DG接入容量与负荷曲线匹配度的问题。我在项目代码里把时序接口已经预留了只要把dg_capacity从常量改成时间序列把load_data改成时序矩阵然后在failure_simulation里根据故障时刻取数据其余逻辑基本不用改。6. 使用Matlab代码时的环境建议Matlab的graph对象需要R2015b之后的版本推荐R2019b以上因为bfsearch、hasedge这些函数的性能在小规模网络上都很快。代码本身不依赖任何额外工具箱只有核心Matlab环境所以复制到哪个机器都能跑。运行时间方面32节点系统遍历所有支路故障、每个故障调用一次孤岛搜索总共几十次搜索在普通笔记本上秒级完成。如果网络扩展到几百节点建议把孤岛搜索部分的DFS改为并行遍历用parfor或者用更高效的启发式算法替代精确回溯。我个人在实际操作中的体会是别迷信“最优”这两个字工程上更看重的是“可行、快速、可解释”。我的实现里搜索策略偏向于近似最优在一定规模的配电网下已经能给出和精确算法几乎一致的可靠性评估结果但计算时间节省了一个数量级。如果你追求理论上严格的最优解可以在小规模系统里用我代码里的精确DFS跑通再根据你的网络规模决定是否切换到启发式模式。最后分享一个实际调试的小技巧在island_search.m里加一行打印输出每次找到的孤岛节点编号和总负荷这样可以直接验证搜索逻辑是否符合预期。我在调通整个项目前就是靠这行打印发现了一个“孤岛包含了故障支路”的严重bug。修复后再看可靠性指标结果立刻合理了很多。这行打印在实际算例分析时注释掉就好不必删以后调试其他参数还能用得上。