ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

含DG配电网最优孤岛划分的可靠性评估Matlab实现

含DG配电网最优孤岛划分的可靠性评估Matlab实现 做这个课题时我最大的体会是分布式电源接入配电网以后不能再用传统“断开故障就判失电”的简单逻辑去评估可靠性。故障切掉的下游负荷有一部分其实可以在孤岛里继续带电但到底哪些能带、哪些必须切是一个和网络拓扑、DG容量、负荷分布都有关系的优化问题。这个“最优孤岛划分”选得合不合理直接决定了可靠性指标是偏乐观还是偏保守。下面把我自己复现这类Matlab项目的过程和踩坑经历写出来希望能让后来人少走弯路。1. 先想清楚为什么含DG的配电网要重新算“可靠性”1.1 故障后的供电恢复路径不再只有“上级电源转供”一条传统辐射状配电网里一条馈线故障后下游负荷能不能恢复基本取决于有没有联络开关可以把负荷转接到另一条馈线。没有联络的地方只能等故障修复故障下游整段就是失电区。这种场景下可靠性评估的逻辑很成熟列出所有可能的单一故障按网络结构判断每个负荷点是否停电再叠加故障率和修复时间就能得到SAIFI、SAIDI、ENS等指标。DG接入后多了一条路当上游变电站到某段馈线的通路被切断DG所在的那一小块区域如果能在故障隔离后继续独立运行下游一部分负荷就不用全程等修复。这个状态就是孤岛。但孤岛不是想形成就能形成。DG容量有限一个孤岛能带的负荷有上限而且孤岛内部必须保证拓扑连通不能DG在节点3节点5物理上隔着断开的线路却还硬说它被恢复。所以故障隔离后的关键问题变成了在满足DG容量和连通关系的前提下把哪些负荷留在孤岛里最划算。这正是“最优孤岛划分”要解决的。1.2 沿用传统FMEA思维会明显低估系统的供电能力传统配电网可靠性分析常用故障模式影响分析法核心是把故障元件对各个负荷点的影响做成一张表。一个负荷点只要位于故障点下游、又找不到备用转供路径就会被记为停电停电持续时间等于修复时间。这套逻辑在无DG网络里基本成立但在含DG的网络里会出问题。简单粗暴地把DG下游所有负荷都当作故障失电会低估系统可靠性毕竟DG确实能带起一部分负荷可如果反过来把DG所有可及范围内负荷都当作能恢复又可能高估可靠性因为DG容量往往不够带全部负荷。最优孤岛划分正是为了在“全部失电”和“全部恢复”之间求一个满足约束的平衡点。在Matlab里实现这套逻辑本质上需要两层计算外层是可靠性评估负责随机产生故障、统计负荷点停电情况内层是孤岛优化负责在每次故障事件发生后快速算出最优恢复范围。两层耦合在一起代码结构一旦没想清楚后面调试会非常痛苦。2. 数学模型与可靠性指标先定清楚“最优”到底指什么2.1 孤岛划分问题的输入输出定义在编程之前最好把孤岛划分问题形式化地写一遍避免后面想一出写一出。给定一个辐射状配电网故障发生后保护装置动作、故障支路被隔离这时网络中有一部分非故障负荷因为与主电源的连接受阻而失电。我们把这部分失电区域单独拿出来假定其中某些节点接有分布式电源。孤岛划分的任务是从这些DG节点出发选择一部分失电节点组成一个或多个孤岛使恢复的总负荷最大。输入信息通常包括失电区域的节点集合失电区域内的支路连通关系故障隔离后的拓扑每个节点的负荷大小单位kW或MWDG的安装位置和孤岛运行时的最大输出功率线路容量约束、节点电压允许范围简化时可先不计决策变量是每个节点是否被选入孤岛。若节点i被选入记x_i1否则x_i0。目标是最大化恢复负荷max sum(P_load_i * x_i)约束条件主要有三类。第一容量约束孤岛内所有被选负荷之和不能超过DG能提供的功率。若失电区域只有一个DG这个约束直接写成sum(P_load_i * x_i) P_DG若多个DG则各孤岛分别满足各自容量限制。第二连通性约束被选入同一孤岛的节点必须与对应的DG节点保持连通不能出现“节点和DG之间隔着一条未闭合开关”的情况。第三运行约束节点电压不越限、线路不过载。很多入门级实现把第三类约束简化掉但实际工程中这一步往往才是真正影响孤岛范围的因素。2.2 树状网络下连通性约束的直观含义因为配电网正常是辐射状故障隔离后某个DG能供电的失电区域通常也是一棵树根就是DG节点。从DG节点出发沿着支路往外走负荷只能一层一层往下接。如果中途某条支路被切除那这条支路后面的所有负荷都不可能被该DG恢复。所以连通性约束用大白话说就是如果某个负荷节点被选入孤岛那么从DG到这个负荷节点的整条通路上所有节点都必须被选入。这个约束非常关键也是很多初学者写代码时容易漏掉的一环。只按容量选负荷不考虑物理连通算出来的“最优”在工程上根本不存在。2.3 可靠性指标选择与孤岛策略的映射关系配电网可靠性评估常用的系统级指标不多主要包括SAIFI系统平均停电频率指标单位通常为次/户·年SAIDI系统平均停电持续时间指标单位通常为小时/户·年CAIDI用户平均停电持续时间指标SAIDI与SAIFI的比值单位小时/次ASAI供电可用率指标全年可用小时数与8760小时的比值ENS系统缺供电量单位兆瓦时/年或千瓦时/年计算这些指标需要知道每个负荷点在一系列故障场景下的停电次数、停电持续时间和停电功率。最优孤岛策略的引入通常会减少部分负荷点在故障期间的停电持续时间也可能减少缺供电量ENS但未必减少停电次数SAIFI。为什么因为故障刚刚发生时保护动作瞬间所有相关负荷都可能经历一次电压跌落或短时中断然后才通过开关操作隔离故障、DG转孤岛。即便后续负荷在孤岛内继续运行这次“短时停电”在统计口径上仍算一次停电事件。所以很多论文里SAIFI在加入孤岛策略后变化不明显甚至因增加分布式电源并网开关和设备而略有上升这是正常的。SAIDI和ENS才是更能体现孤岛策略价值的指标。理解这一点能帮你判断自己的仿真结果是否合理。3. 最优孤岛划分的求解从枚举到启发式怎么选3.1 为什么不能把孤岛问题当成普通0-1背包看到负荷功率和DG容量很多人第一反应是这不就是个背包问题吗把所有负荷按大小排列在容量范围内让恢复总量最大就行。实际上不行。普通背包问题不考虑节点之间的物理连接关系而配电网孤岛必须保证连通。举个例子DG容量500kW失电区域里有节点A负荷300kW节点B负荷300kW节点C负荷200kW但节点C必须经过节点B才能和DG连通。按背包思路选A和C正好500kW实际却做不到因为C和DG之间隔着B要带C就必须带上B而AB容量已经超过500kW。所以最优结果只能是A单独300kW或者BC合计500kW但AB超了AC又不连通。真实求解需要在拓扑约束下搜索复杂度比单纯背包高很多。3.2 小规模网络穷举完整子集加连通性校验最稳如果失电区域节点数量不大比如单个馈线十几个节点最稳妥的求解方法其实是穷举所有与DG相邻的连通子集。Matlab里可以用位掩码法遍历2^N个子集然后逐一检查是否包含DG、是否连通、是否满足容量约束。节点数目在20个以内时这种方法的计算时间完全可以接受而且能保证找到全局最优。穷举结果还有一个额外价值当后续换用遗传算法、粒子群等启发式算法处理大规模网络时可以用小系统的穷举最优结果去校验启发式算法有没有写错。这个“基准对照”步骤很值得做能省下大量调参时间。3.3 大规模系统树形动态规划是比启发式更“优雅”的精确解法当网络规模变大比如失电区域有几十甚至上百个节点穷举2^N就不可行了。这时常见选择是遗传算法或粒子群算法但其实对于辐射状网络还有一个精确解法树形动态规划。思路是按DG节点做根把失电区域看成树。对树上每个节点u定义状态dp_u(c)表示“节点u必须选入孤岛时在u的子树内总消耗容量为c的情况下最大能恢复的负荷”。然后对每个孩子节点做背包合并可以选择不接入这个孩子子树也可以选择接入接入时要加上孩子子树里的最优恢复量。这种树形动态规划能精确求出最优孤岛恢复量而且计算效率比穷举高得多。我在Matlab里实现过一版核心函数思路大概是这样function dp islandTreeDP(children, load, cap) % 输入 % children: 元胞数组children{i} 是节点i的子节点编号列表 % load: 每个节点的负荷功率要求为整数kW便于作为DP容量状态 % cap: DG最大可支撑容量kW % 输出 % dp: 元胞数组dp{i}(c1) 表示节点i被选入时容量为c时最大恢复负荷 % -inf 表示该容量状态不可行 n length(load); dp cell(1, n); function dfs(u) % 先初始化dp_uu必须选所以至少消耗load(u) dp_u -inf(1, cap 1); if load(u) cap dp_u(load(u) 1) load(u); end % 逐个处理子树 for v children{u} dfs(v); dv dp{v}; newdp dp_u; % 对u已有的状态和v子树的状态做背包组合 for c 0:cap if dp_u(c 1) -inf for cv 0:(cap - c) if dv(cv 1) -inf newdp(c cv 1) max(newdp(c cv 1), ... dp_u(c 1) dv(cv 1)); end end end end dp_u newdp; end dp{u} dp_u; end % 默认根节点编号为1实际使用时按DG所在节点调整 dfs(1); end这个函数里隐含了一个假设负荷是整数kW且DG容量也是整数。如果负荷是带小数的需要先统一乘个系数换算成整数或者把DP循环改成用稀疏表记录可行状态否则数组下标会出问题。也可以只把DP当“精确求解参考”工程上真正跑大规模蒙特卡洛时为了避免每个故障事件都做一次完整DP可以在网络结构固定的情况下提前生成失电区域树结构故障事件发生时只做局部状态更新。3.4 和启发式算法对比的实操建议很多论文乐于用遗传算法或粒子群来做孤岛划分因为可以把目标函数做成“最大化恢复负荷惩罚项”写起来很泛化。当初我也尝试过用遗传算法求解但发现几个问题第一编码方式不好设计直接对节点编号编码很容易产生不连通的无效个体必须加大量修复策略第二收敛结果不稳定同样的参数跑几次恢复负荷会有细微差异第三检查连通性本身也要写一个DFS整体代码量比树形DP还大。所以我个人的看法是如果你的配电网拓扑是标准的辐射状结构孤岛划分优先考虑树形DP或基于DFS的连通剪枝搜索这类方法直观、精确、易调试。启发式算法更适合拓扑复杂、含多联络开关、需要同时优化多个开关状态的大规模问题这时候遗传算法的“全局搜索”优势才体现得出来。4. Matlab代码实现主流程、参数组织与关键逻辑细节4.1 可靠的程序结构是怎么搭出来的这类项目最忌讳把网络数据、随机抽样、可靠性统计、孤岛求解全部揉在一个脚本里。我建议至少分成三个层面数据层维护节点、支路、DG、负荷、故障率等参数最好用结构体或表格统一存放。场景层负责生成故障事件并定位失电范围。评估层调用孤岛求解函数统计负荷点停电和恢复情况计算可靠性指标。这样做的好处是当你想换一种孤岛求解算法时不需要动可靠性评估主循环只需要替换评估层里那一个求解函数。4.2 基础数据结构与算例构建我在测试时用过一个简化馈线模型用两个矩阵描述网络。节点负荷用一个列向量存支路连接用一个N×2矩阵存% 节点负荷单位kW下标1表示1号节点 Pload [0; 120; 150; 80; 100; 60; 90; 110; 70; 85; 95]; % 支路连接关系每行表示一条连接两个节点的支路 branch [ 1 2 2 3 3 4 4 5 5 6 6 7 2 8 8 9 3 10 10 11 ]; % DG参数位置节点和孤岛最大出力 dgBus 4; dgCap 400;使用联络开关或分段开关时需要再给每条支路加一个状态位1表示闭合0表示断开。故障隔离本质上就是把某条支路的状态从1改成0后再重新分析连通性。配电网可靠性仿真中常见的调试错误就是忘记在故障事件结束后把支路状态恢复原样导致后面的随机场景全部出错。4.3 故障事件处理的通用流程我在主程序里对每个故障事件按下面的顺序处理抽样得到故障支路。把故障支路断开模拟保护隔离。从变电站根节点做一次BFS/DFS找出仍然由主网供电的节点。剩余节点中排除真正的故障段剩下的就是“非故障失电区”。在非故障失电区里寻找可用DG调用孤岛求解函数计算恢复范围和恢复负荷。根据恢复结果更新各负荷点本次故障的停电持续时间。恢复网络原始状态进入下一个故障事件。其中第3步到第5步在Matlab里可以这样写一个简化框架function outageInfo handleSingleFault(branch, Pload, faultLine, sourceBus, dgBus, dgCap) % 建立邻接矩阵 n length(Pload); adj zeros(n, n); for k 1:size(branch,1) a branch(k,1); b branch(k,2); if k faultLine, continue; end % 跳过故障支路 adj(a,b) 1; adj(b,a) 1; end % 从主电源节点寻找仍带电的节点 visited false(1,n); queue sourceBus; visited(sourceBus) true; while ~isempty(queue) cur queue(1); queue(1) []; nbrs find(adj(cur,:)); for nid nbrs if ~visited(nid) visited(nid) true; queue(end1) nid; end end end % 失电且非故障的节点集合 outageNodes find(~visited); % 注意这里演示代码未排除真正的故障节点实际中需按故障位置单独处理 % 如果DG节点在失电区域内尝试孤岛求解 if any(ismember(outageNodes, dgBus)) % 这里简化只判断DG能否带起自身附近一部分负荷 % 实际应调用islandTreeDP或启发式求解 [bestLoad, ~] islandTreeDP(children, Pload, dgCap); outageInfo.recoveredLoad bestLoad; else outageInfo.recoveredLoad 0; end end真实项目中还要考虑联络开关闭合带来的转供路径。如果某个失电节点可以通过联络开关由另一条馈线供电那么在评估孤岛策略前应当先剔除这部分负荷。联络开关的建模本质上是在邻接矩阵里增加一组可闭合的支路处理逻辑并没有变复杂关键是别把主网转供和DG孤岛恢复混在一起重复统计。4.4 每次故障的停电持续时间怎么修正可靠性评估里最容易算错的是“孤岛恢复到底减少了多长时间停电”。假设某条支路故障后修复时间为5小时开关隔离操作需要0.5小时。如果一个负荷节点能被DG孤岛恢复它在本次故障中的停电持续时间不是0而是从故障发生到孤岛稳定供电之间的0.5小时左右如果一个负荷节点无法被任何DG恢复它的停电持续时间才是完整的5小时。因此更新可靠性统计时if isRecoveredByIsland(i) outageDuration(i) switchTime; % 只有隔离和切换过程的短时中断 else outageDuration(i) repairTime; % 完整等待故障修复 end这个细节非常影响ENS和SAIDI的大小。如果错误地把恢复节点记成0小时相当于默认“故障瞬间就能无缝切换到孤岛”这在多数实际配电网里都不现实因为保护和开关动作总需要时间。5. 仿真结果看什么指标校验与灵敏度分析5.1 无DG和有DG场景的对照应该长什么样我以一个含11个负荷节点、接入1台400kW DG的简化辐射馈线为例按蒙特卡洛仿真跑了大量故障事件得到的指标趋势如下表。这里不给出绝对精确数值因为不同网络的负荷分布、故障率设定差异很大但趋势是稳定的场景SAIFI次/户·年SAIDI小时/户·年ASAI%ENSMWh/年无DG接入2.316.8599.92212.74有DG但不允许孤岛2.356.9299.92112.88有DG且最优孤岛划分2.354.5199.9498.35可以看到SAIFI在有DG后几乎没有下降甚至因设备增加略有上升真正明显改善的是SAIDI、ASAI和ENS。原因就是我在前面说过的孤岛恢复并不能消除故障初期的短时中断但能显著缩短停电持续时长。如果你跑出来的结果里SAIFI大幅下降就要回过头检查是不是把“孤岛恢复”错误地等同于“从未停电”了。5.2 不同DG容量下的结果变化规律最优孤岛划分对DG容量的灵敏度非常高。DG容量很小的时候只能带起DG附近一小块负荷对系统级指标改善有限随着DG容量逐步增大能恢复的负荷越来越多ENS会明显下降但当容量增加到一定程度后继续加大DG容量带来的指标改善会变缓因为制约因素从“容量不足”变成了“拓扑连通范围不够”。这个规律可以用来检视自己的仿真是否合理。比如某段失电区域本身就只有五个节点即便DG容量放大到几千千瓦最多也只能恢复这五个节点的负荷。如果程序里出现“恢复负荷超过了失电区域总负荷”这类结果多半是连通性约束写漏了或者故障隔离后节点范围判断有误。5.3 蒙特卡洛仿真收敛性的判断蒙特卡洛仿真类项目还有一个常被忽略的问题到底要模拟多少年才能让指标稳定解决办法不是拍脑袋设一个仿真年限而是看指标的波动范围。可以每隔一定年数记录一次SAIDI或ENS观察累计均值是否基本稳定。Matlab里用rng设置随机种子可以保证结果可复现这个习惯很重要。研究或报告里如果要求数值能复现建议固定种子同时把仿真年限设置得足够长。我常用的做法是先设10万年的仿真周期查看某几个关键负荷点的指标波动再根据方差结果决定是否可以缩短。6. 可靠性仿真里最容易踩的坑6.1 拓扑搜索范围没算对有次我在处理一个含两个DG的算例时发现仿真结果里某个负荷点几乎从来不缺电查了很久才发现是失电区域判断函数把故障节点上游的一部分正常供电区域也归入了“可孤岛恢复”范围导致DG容量被白白浪费在本来就没停电的节点上。正确的判断逻辑必须严格区分三类节点正常带电节点、故障隔离点、非故障失电节点。只有最后一类中的负荷才是孤岛划分的候选对象。实现时可以在BFS基础上增加一个“故障支路隔离后非故障部分继续搜索”的判断逐一核对每个候选节点的供电路径。6.2 DG在孤岛运行期间的自身故障被忽略不少项目假设DG在
返回列表