做配电网规划的人一提到N-1脑子里最先浮现的往往是输电网那套成熟校核规则任一元件退出后系统不掉负荷、不越限。真正到了配电网层面N-1就变成了一个让人又爱又恨的问题。爱的是它确实能逼着规划方案把供电可靠性落到实处恨的是配电网闭环设计、开环运行馈线联络关系复杂故障后的转供路径还得靠分段开关和联络开关一点点拼出来。我最近刚好把一个配电网N-1扩展规划项目完整跑通了一遍整套思路和Matlab代码也整理好了。这篇就把从模型搭建、N-1校核逻辑到Matlab实现的关键细节一次说清楚适合正在做配电网规划课程设计、研究生课题或者刚接触可靠性校核的同行参考。这个项目解决的核心问题其实很直接在现有配电网基础上面对未来负荷增长应该新建哪些馈线、加哪几条联络才能让电网在任意一条线路或主变故障退出后仍能通过转供把负荷带起来同时投资和损耗都可控。扩展规划的关键词不只是“规划”而是“N-1校核下的增量改造”。下面我按自己的实现流程拆开讲模型怎么做、代码怎么搭、哪些坑最容易踩一并交代。1. 配电网N-1扩展规划先搞清楚它到底在优化什么1.1 N-1准则到底是什么——从输电网到配电网N-1准则最早是输电网的可靠性原则含义很简单系统中任意一个独立元件线路、变压器、发电机因故障退出运行后系统仍然能保持稳定供电不出现非计划停电且各项运行指标不越限。输电网的网络结构强、环网运行某个元件退出后潮流会自动转移校核起来相对干净。但配电网不一样。大多数配电网是“闭环设计、开环运行”正常方式下馈线在某个分段开关处解列每条馈线是辐射状网。某条馈线故障跳闸后电流不会像输电网那样自动寻找别的路径必须依靠合上联络开关把失电负荷转带到相邻馈线。这个“靠开关倒负荷”的过程就是配电网N-1校核的核心。所以配电网N-1校核真正做的事情是枚举任意一条馈线或主变故障退出检查其余馈线能否通过联络开关承接它的全部或部分负荷并保证承接后所有馈线不过载、节点电压不越限。扩展规划则要把这个校核从“校核”升级成“优化”用数学方法找出一组合适的新建馈线和联络线方案让N-1校核通过率达到目标。1.2 配电网N-1校核的特殊难点相比输电网配电网N-1校核有三个明显的难点。第一是转供路径不唯一且依赖开关状态。一条馈线故障后失电区域可能同时与多个相邻馈线存在联络关系需要判断哪些联络开关可以合上、合上后功率怎么分配。如果网架结构复杂转供路径的搜索会非常繁琐。第二是辐射状拓扑约束。正常运行时配电网必须是辐射状合上联络开关转供时也要保证不出现环网或孤岛。在建模里这个约束对应的是网络拓扑的连通性和树状结构限制处理起来比输电网的潮流约束麻烦得多。第三是分布式电源改变了故障特性。如果故障馈线下游有分布式光伏或小水电故障后这些DG可能继续供电形成孤岛也可能因保护动作而脱网。规划阶段做N-1校核时DG的处理方式会直接影响转供判断结果。正因为这些难点配电网N-1扩展规划不能简单套用输电网的模型需要单独设计目标函数、约束条件和求解策略。1.3 扩展规划与常规规划的区别扩展规划Expansion Planning和从零开始的新建规划在思路上有本质区别。新建规划假设没有存量网架可以天马行空设计扩展规划面对的是一张已经存在且正在运行的网规划任务是“增量改造”。具体到配电网N-1扩展规划有几个典型特征输入是现状网架负荷预测候选工程列表不是空白画布决策变量是0-1变量代表“新建某条馈线”“新建某条联络线”“更换某段导线截面”等选项是否被选中约束条件包含正常方式下的潮流约束、电压约束以及N-1方式下的转供约束目标通常是年费用最小包括投资折算费用、网损费用和缺电损失。我在做这个项目时最直观的感受是常规规划只要把“最重负荷方式”下跑通潮流就算完成N-1扩展规划却要把几十个甚至上百个故障场景逐一放进优化模型里。场景一多变量规模和求解难度就上来了怎么平衡精度和计算速度是整个项目的核心矛盾。2. 数学模型怎么搭目标函数、约束和转供校核2.1 目标函数怎么定目标函数我采用的是“年费用最小”口径把一次性投资和长期运行费用放到同一个时间尺度上比较。具体包含三块成本项建模方法说明投资成本新建馈线、联络线的造价乘以等年值系数把一次性投资折算为每年分摊费用公式为 ( CRF \frac{r(1r)^n}{(1r)^n-1} )其中 ( r ) 是贴现率( n ) 是设备使用年限网损费用典型日或最大负荷方式下网络损耗的电能费用配电网线损是规划中不可忽视的成本项通常用年损耗电量乘以电价缺电成本负荷点停电损失电量乘以单位缺电成本用EENSExpected Energy Not Supplied期望缺供电量来量化能反映N-1校核通过率的价值工程上通常写为[ \min \quad C_{invest} C_{loss} C_{ens} ]其中 ( C_{invest} ) 是选中候选工程的年投资费用( C_{loss} ) 是网损费用( C_{ens} ) 是故障场景下的缺电成本。很多人在建模时只盯投资费用忽略了缺电成本结果优化出来的方案投资最低但N-1通过率很难看。把缺电成本放进目标函数本质是给“可靠性”标了价让优化器自己权衡多投资一条联络线划算还是容忍一定的停电损失划算。2.2 网络模型与潮流约束配电网潮流计算我推荐用DistFlow支路潮流模型而不是常规的牛拉法。原因在于DistFlow天然适配辐射状配电网方程是支路功率和电压降落的递推关系形式简洁方便后续做凸松弛和混合整数规划。对每条支路 ( (i, j) )DistFlow写为[ P_{ij} - \sum_{k \in child(j)} P_{jk} P_{load,j} ][ Q_{ij} - \sum_{k \in child(j)} Q_{jk} Q_{load,j} ][ V_j^2 V_i^2 - 2(r_{ij}P_{ij} x_{ij}Q_{ij}) ]其中 ( P_{ij} )、( Q_{ij} ) 是支路首端有功和无功功率( r_{ij} )、( x_{ij} ) 是支路电阻和电抗( V_i ) 是节点电压。实际求解时通常用二阶锥松弛将非线性方程转成凸约束这样配电网扩展规划就可以建模成混合整数二阶锥规划交给Gurobi或CPLEX求解。节点电压要满足[ V_{min}^2 \leq V_i^2 \leq V_{max}^2 ]馈线容量约束为[ P_{ij}^2 Q_{ij}^2 \leq S_{ij,max}^2 ]2.3 N-1校核的关键约束转供路径与越限判断这是整个模型最花心思的地方。N-1校核不能只在校核阶段做验证因为优化过程中产生的每个候选方案都必须满足N-1约束否则淘汰。我采用的方式是把故障场景直接耦合进优化模型。具体思路是对每一个需要校核的故障场景 ( s )第 ( s ) 条线路或主变退出在约束条件里增加该场景对应的潮流方程、电压约束和馈线容量约束。正常方式下闭合的联络开关在故障场景下可以被优化器决策为闭合从而实现转供。这里有三个细节值得特别注意变量维数会膨胀。如果有 ( N ) 条馈线要做N-1校核每个场景都要一套潮流变量变量数量近似乘以 ( N )。实际算例中若有30条馈线那就相当于同时求解30个扩展后的潮流问题。这就是为什么N-1扩展规划的计算量远大于普通规划的原因。转供容量不是全部承接下来。实际倒负荷时故障馈线的部分负荷可能被切除尤其非重要负荷模型中用一个“可转供比例”或“允许切除负荷比例”来控制。更严谨的做法是设置每个负荷点的优先级N-1校核通过的定义由项目要求决定。负载率上限一般留裕量。N-1转供后承接馈线的负载率一般不允许跑到100%我习惯限制在60%~80%之间具体取值看当地配电网规划导则。留裕量是为了给后续负荷增长留空间也是为了应对实际运行中比规划模型更复杂的工况。辐射状约束在这个模型里要单独处理。正常方式下网络必须是辐射状故障转供后也必须保持辐射状。经典做法是引入生成树约束或者对每个场景校验“节点数支路数1且网络连通”在优化模型里用环路消除约束近似实现。2.4 为什么要用混合整数二阶锥模型配电网N-1扩展规划的本质是个大规模组合优化问题。候选工程是0-1决策潮流约束是非线性的两者组合起来如果用普通非线性规划求解全局最优性没有保证如果暴力枚举所有候选组合组合数爆炸。混合整数二阶锥规划MISOCP是目前工程上比较成熟的选择DistFlow经过二阶锥松弛后是凸约束0-1变量负责决策“建哪条线”“合哪个开关”商用求解器能在可接受时间内给出全局最优解或带最优性间隙的解。我在Matlab里就是用YALMIP搭模型、Gurobi做求解后面代码部分会细说。当然如果网络规模特别大比如上百条馈线的城市配电网MISOCP也可能求解时间过长。这种情况下我一般退一步用遗传算法或粒子群算法先搜索候选方案再用N-1校核逐方案验证。启发式算法不保证最优但胜在能处理更大规模适合工程上“找一套很好的可行方案”的需求。3. Matlab代码实现从数据到N-1校核的完整链路3.1 整体程序框架与数据结构设计Matlab实现这套扩展规划我建议按模块化思路组织。整个项目拆成六个核心文件main_expansion_planning.m % 主程序数据、建模、求解、结果输出 load_case_data.m % 读取算例数据节点、支路、负荷、候选工程 build_network_model.m % 构建正常方式下的DistFlow约束 build_n1_constraints.m % 构建N-1故障场景约束 solve_planning_model.m % YALMIP建模Gurobi求解 run_n1_verification.m % 对优化结果做独立N-1校核验证数据结构方面我用结构体struct存三类核心数据bus节点编号、节点类型、有功负荷、无功负荷、电压上下限branch支路编号、首末端节点、电阻、电抗、容量上限、是否为现有线路candidate候选工程列表包括新建馈线/联络线的首末端、造价、容量。这里有个经验分享候选工程列表的数据一定要单独存放不要和现有线路混在一起。因为现有线路是必须投运的候选线路是优化器选不选的混在一个矩阵里会给约束索引带来很大麻烦。我在第一次实现时就是吃了这个亏后面重构才理顺。3.2 潮流计算模块DistFlow与求解器选型潮流计算模块我用DistFlow而不是Matpower。原因有两方面一是Matpower的潮流模型面向通用电力系统接入混合整数优化模型时不方便特别是要添加大量0-1变量时二是DistFlow形式简洁直接写成一阶约束非常方便。核心代码框架长这样% DistFlow约束构建正常方式 % x_new 表示候选馈线是否投运的0-1变量 % P、Q、I 分别表示支路功率和电流平方 Constraints []; for k 1:size(branch_opt, 1) i branch_opt(k, 1); % 首端节点 j branch_opt(k, 2); % 末端节点 if is_switchable(k) % 候选线路 Constraints [Constraints, ... P(k) -M * x_new(k), ... P(k) M * x_new(k)]; end % 支路容量约束 Constraints [Constraints, ... P(k)^2 Q(k)^2 S_max(k)^2]; end % 节点功率平衡 for n 1:num_bus Constraints [Constraints, ... sum(P_in(n)) - sum(P_out(n)) P_load(n)]; end这里的 ( M ) 是大M法的辅助参数作用是当候选线路没被选中时( x_{new}0 )该支路功率被强制为0选中时( x_{new}1 )功率上限由容量约束控制。大M的取值要稍微大于所有支路可能的最大功率值太小会错误限制支路功率太大则可能导致数值病态。3.3 N-1校核模块的实现细节N-1校核模块是这个项目里代码量最大、最容易出错的部分。我把它拆成两层优化模型内部的内嵌N-1约束和求解完成后的独立校核验证。内嵌N-1约束的构建方式举例% 对故障场景s线路s退出运行 % 在模型中添加一组额外的DistFlow变量 % P_s、Q_s、V_s场景s下的支路功率和节点电压 for s 1:num_branch_check % 场景s下线路s退出 Constraints [Constraints, ... P_s(ks) 0, ... % 故障线路功率为0 Q_s(ks) 0]; % 联络开关在场景s下可闭合 % tie_close_s是0-1变量1表示闭合联络线 Constraints [Constraints, ... P_tie_s - M * tie_close_s 0, ... -M * tie_close_s - P_tie_s 0]; end求解完成后的独立校核验证我写了一个更直观的遍历函数好多排查问题都靠它function pass_flag n1_check(net, tie_lines, load_limit) % net: 网络结构 % tie_lines: 联络线集合 % load_limit: 馈线负载率上限 pass_flag true; for k 1:size(net.branch, 1) if ~is_branch_checkable(net, k) continue; % 有些联络线本身不需要做N-1 end % 断开第k条馈线找出失电区域 island find_island(net, k); % 搜索可用转供路径闭合哪些联络线 [transfer_path, transfer_ok] find_transfer_path(net, k, tie_lines); if ~transfer_ok pass_flag false; fprintf(馈线%d故障后无可用转供路径\n, k); continue; end % 重新计算转供后潮流 result distflow_solve(net, transfer_path); % 判断负载率和电压 if max(result.branch_load) load_limit || ... min(result.voltage) 0.93 || ... max(result.voltage) 1.07 pass_flag false; fprintf(馈线%d故障后转供越限\n, k); end end end这段独立验证函数特别重要。优化模型的N-1约束因为做了二阶锥松弛理论上可能存在微小的松弛误差独立验证函数用原始DistFlow再跑一遍精确解能确认最终方案确实满足N-1而不是只在模型里“看起来满足”。3.4 环境搭建Matlab版本、YALMIP与求解器配置指南Matlab代码要跑起来环境配置是个隐藏坑。我用的组合是Matlab YALMIP Gurobi。YALMIP是Matlab下的建模工具箱负责把优化模型翻译成求解器能识别的标准格式Gurobi是底层的数学优化求解器负责真正求解MISOCP。安装配置时要注意几点Matlab版本和求解器版本要匹配。有些新版Matlab对旧版Gurobi的mex接口不兼容装完以后YALMIP报错找不到求解器。建议先装好Matlab再去Gurobi官网下载对应版本。很多新手卡在“明明装了GurobiYALMIP却报solver not found”多半是mex接口版本不匹配或环境变量没配好。YALMIP的安装很简单把解压后的文件夹加入Matlab路径即可。Gurobi则要安装后用gurobi_setup添加路径并且在系统环境变量里配置GUROBI_HOME指向安装目录。license激活常见问题Gurobi需要许可证文件学术版用学校邮箱申请免费licenselicense文件路径可以通过环境变量GRB_LICENSE_FILE指定不然Matlab里调用会一直报license error。求解器验证配置完成后在Matlab里执行yalmiptest看Gurobi是否被识别。我在实际配置中碰到过YALMIP识别了Gurobi但实际求解时调用了默认的sedumi的情况因为sdpsettings(solver,gurobi)没显式指定。这个一定要显式指定否则模型规模一大sedumi根本算不动。另外如果只是做课程设计或者教学演示不装Gurobi也可以用Matlab自带的intlinprog求解部分线性化模型但性能差距很大——我试过同样的算例Gurobi几十秒解完intlinprog跑了五六分钟还停在很差的可行解上。场景多的时候商用求解器基本是必需品。4. 算例跑通结果长什么样IEEE 33节点案例复盘4.1 算例设置与初始网络状态我用的算例是经典的IEEE 33节点配电网系统改造版。基准电压12.66kV功率基准10MVA共33个节点、32条分段支路初始总负荷约3700kW加上2300kvar无功。经典算例自带5条联络线但我这个项目模拟的是一个前期建设不太完善、联络率偏低的规划场景初始只有2条联络线且部分关键区段导线截面偏小负荷增长后多条馈线在N-1校核下明显不过关。初始网络的问题非常典型主干馈线负载率最高达到87%一旦故障相邻馈线接过去立刻过载末端节点电压最低到0.925 p.u.低于0.93的限值N-1后电压进一步恶化只有2条联络线部分馈线故障后失电负荷根本没有转供路径只能等人去现场拉临时线路。候选工程列表我设了6个4条新建联络线连接不同馈线的末端节点2段导线增容工程。每个候选工程给定投资造价和容量参数。这样就构成了一个典型的N-1扩展规划问题选哪些联络线和增容工程使得所有馈线故障后都能可靠转供同时年费用最小。4.2 扩展方案与N-1校核结果对比经过求解优化器给出的推荐方案是新建3条联络线其中2条导线增容工程选中1段。投资年费用约28万元按20年使用年限、8%贴现率折算加上网损费用和期望缺电成本综合年费用约41.6万元。扩展方案的核心思路很清晰新增的3条联络线正好补齐了“单联络孤立馈线”的短板让原本只能靠一条馈线供电的区域有了第二个电源方向导线增容则针对潮流瓶颈区段让转供时不至于因截面不够而卡脖子。扩展前后的N-1校核结果对比如下指标扩展前扩展后N-1校核通过馈线数18/3232/32最大馈线负载率N-1方式112%76%最低节点电压N-1方式0.918 p.u.0.952 p.u.年网损电量86.5万kWh71.2万kWh综合年费用约53.8万元约41.6万元这里有个反直觉的点扩展前的综合年费用反而比扩展后高。原因在于缺电成本和网损成本占了很大比例。扩展前N-1校核不过意味着每年都有一定概率发生长时间停电缺电成本折算下来相当高网损也高导线细、负载重损耗自然大。加了联络线和增容后虽然多了投资费用但缺电成本和网损费用降得更明显总账反而划算。4.3 投资-可靠性权衡的量化分析做优化规划最忌讳只看最终推荐方案不看方案的敏感性。我特意跑了三组对比只加联络线不增容、只增容不加联络线、联合方案结果差异很大。只加联络线时大部分馈线故障后能找到转供路径但承接馈线很快过载N-1通过率只到78%左右只增容时馈线容量上来了但部分区域根本没有第二条电源路径故障后照样失电通过率更低。联合方案才能真正解决N-1问题。这个结论在电网规划里很普遍联络线解决“有没有路”的问题导线增容解决“路够不够宽”的问题两者缺一不可。你在做类似项目时如果N-1校核不过先判断是“转供路径缺失”还是“转供后容量/电压越限”对症下药不要无脑加线。5. 调试阶段最常踩的坑与排查思路5.1 潮流不收敛与变量尺度问题第一次跑DistFlowMISOCP时最容易遇到的坑是求解器报“numerical trouble”或“infeasible”。排查下来一半以上都是变量尺度问题功率基准和电压基准没选好导致二阶锥约束里的数值跨度横跨10的6次方以上Gurobi内部处理起来精度崩掉。我习惯把所有量都归到标幺值体系功率基准取10MVA或100MVA电压基准取12.66kV或10kV线电压阻抗用标幺值。这样所有约束的数值都在0.01到10这个量级求解器数值稳定性好得多。另外大M的取值尽量紧凑不要一股脑给1e6。5.2 整数变量过多导致求解时间爆炸N-1扩展规划的整数变量规模很容易失控。每个候选工程一个0-1变量还好说但每个故障场景下的联络开关闭合状态如果也建模成0-1变量变量数量就按故障场景数倍增。我碰到过一个小规模算例因为场景内变量建得太细Gurobi跑了一个小时还没收敛到1%间隙以内。排查思路是看变量明细YALMIP里用yalmiptable打印变量列表检查每个变量是否必要。我们项目的实践中“联络开关在场景下的闭合状态”其实可以少数场景预判或通过灵敏度分析固定一部分把整数变量规模砍掉一半以上。另外Gurobi的参数也要调MIPGap设到1%或2%就好设成0.01%纯属和自己过不去MIPFocus设为1有时能明显加速可行解的搜索。5.3 N-1校核误判与转供路径遗漏这是最隐蔽也最严重的坑。优化模型内嵌N-1约束通过但独立验证却失败追查后发现是转供路径搜索函数漏了一条联络线。我最初的find_transfer_path只考虑直接相邻的联络关系没有考虑“多级转供”——失电区域先转给相邻馈线AA再通过联络线转一部分给馈线B。实际配电网里这种两级转供很常见。后来我把转供路径搜索改成递归或BFS广度优先搜索方式从失电孤岛出发逐级扩展可达的电源路径并把每级路径的负载率累积计算才算把这条坑填平。做独立校核验证时建议不只是看最终负载率还要输出“故障馈线编号-转供路径-各段承接负荷比例”的明细人工抽查几条避免搜索函数逻辑错误带偏整个判断。5.4 常见错误与排查速查表现象可能原因排查方法YALMIP报“No solver found”Gurobi没正确加载或版本不兼容运行yalmiptest确认求解器被识别检查GUROBI_HOME环境变量Gurobi报license errorlicense文件未配置或已过期设置GRB_LICENSE_FILE指向有效license文件学术license每年要续模型求解时间为无穷大变量尺度严重不等全部转标幺值检查大M取值是否过大或过小返回infeasible但人工校验没毛病约束矛盾常见于节点功率平衡或辐射状约束写错用solvertime和check(Constraints)定位是哪条约束出问题挨个打印残差N-1验证结果比模型结果差很多转供路径搜索遗漏、二阶锥松弛误差先用原始DistFlow重跑每个场景再检查转供路径搜索是否支持多级转供候选线路被选中但负载率为0变量M取值导致约束失效检查该支路功率与X_new的耦合约束是否写对了方向6. 项目延伸与个人实操心得6.1 从N-1到N-1-1与极端场景N-1校核是最基本的可靠性要求实际工程中还有N-1-1校核检修方式下再发生N-1故障、N-2校核同塔双回同时跳闸和台风、冰灾等极端灾害场景。扩展规划模型要往这些方向延伸核心改动并不复杂把故障场景从“单条馈线退出”扩展成“线路检修方式”组合或“同塔双回同时退出”约束结构不变变量规模会进一步膨胀。做研究的话这是个很好的扩展方向特别是N-1-1场景下转供策略更复杂也更贴近实际运行。6.2 分布式电源接入对N-1校核的影响这个项目没有详细建模DG但我实际做过的相关项目里DG对N-1校核的影响非常复杂。乐观的一面是DG在故障孤岛内可能继续供电提高N-1通过率悲观的一面是DG出力波动和不确定性导致转供后潮流方向改变原有保护配置和电压调节可能失效。规划阶段建议至少做两个场景对比DG按0出力保守和DG按额定出力乐观看N-1校核结果是否稳健。如果想把DG纳入扩展规划目标函数里还要加上DG的投资或运行成本约束里加出力上下限和爬坡约束模型就从纯电网扩展规划变成了“源网协同规划”计算复杂度再上一个台阶。6.3 最后说点个人体会我在实际做这套N-1扩展规划时最大的体会是模型不是越复杂越好关键是N-1校核逻辑要经得起独立验证。很多人花了很多精力把优化模型建得很漂亮但独立校核环节写得很随意结果方案看起来最优实际根本过不了N-1所有优化都白做了。我强烈建议你在自己的项目里无论如何都要保留一个独立的N-1校核脚本对优化输出的方案逐条馈线再校核一遍。另外Matlab跑这套规划代码调试时不要一上来就跑全量算例。先用一个10节点左右的小网络把模型和校核逻辑跑通确认无误后再换IEEE 33节点或更大的算例。这个习惯帮我节约了大量排查时间也更容易定位是模型问题还是代码问题。最后分享一个小技巧N-1校核模块里转供路径搜索函数可以在调试阶段打开“输出模式”把每条故障馈线的转供路径和负荷分配打印到命令行或Excel。一旦结果异常逐条比对路径问题基本一眼就能看出来。这个功能平时不显眼但排查时比断点调试好用得多。