干过配电网规划的朋友应该都有体会:光做"负荷预测+网架校验"远远不够,真正让方案落地的挑战在于安全准则的约束,尤其是N-1校验。近两年各省配电网规划逐步从"缺什么补什么"转为"全要素扩展规划",新建线路、扩容变电站、加装联络开关都要在同一个优化框架里决策,而N-1准则是所有方案绕不开的硬底线。这篇文章我围绕"配电网N-1扩展规划"这个课题,完整拆一遍建模思路、约束线性化处理、Matlab实现要点和调试中踩过的坑,文末附可直接复用的代码结构。无论你是在校学生做毕设,还是刚接触网架规划的一线工程师,这套流程都可以直接用起来。
1. 这个课题到底在解决什么问题
1.1 N-1准则为什么是配电网规划绕不开的底线
N-1准则最早源于输电网安全稳定运行的要求,翻译成大白话就是:系统里任意一个元件(线路、主变、母线)退出运行后,电网依然能够保持稳定供电,不甩负荷、不过载、电压不越限。把它下沉到配电网,含义变成"馈线故障或检修停运后,通过联络开关合闸、倒供转带,让非故障区段用户尽快恢复供电"。
规划层面的N-1校验有个微妙之处:输电网N-1故障后主要关注暂态稳定和潮流转移,配电网N-1关注的是拓扑重构后的静态安全。难点在于配电网闭环设计、开环运行,故障后负荷转带路径受联络位置和线路容量双重限制。某条线路N-1停运后,如果相邻馈线没有足够的备用容量,或者联络点位置不合理,照样会切负荷。所以扩展规划必须在优化模型里显式考虑每一类N-1故障场景,而不是规划完再跑一遍校验。
1.2 扩展规划与传统网架规划的本质区别
传统配电网规划通常是"近期校核+中期改造",给定负荷预测结果后,逐条线路校验负载率和电压质量,超限就安排新建或改造项目。这种方式的优点是简单直接,缺点是项目之间相互独立,缺少全局协调。比如钱花在A馈线增容上,结果故障后A馈线的负荷要转带给B馈线,B线却成了新的瓶颈——单看每条线路都没问题,整体方案的N-1通过率仍然上不去。
扩展规划的思路恰恰相反:把现有网架作为基础,把满足目标年负荷需求的"新建线路、新上主变、新增联络"全部作为候选方案,放进同一个混合整数规划模型里统一寻优。决策变量是设备是否投建,目标函数是投资成本加运行成本最小,约束条件包含潮流平衡、电压限值、线路容量和N-1安全约束。结果是一整套"该在哪里建、建几条、什么时候建"的工程包,而不是零散的项目清单。
2. 规划模型的建立:先想清楚目标与约束
2.1 目标函数:投资成本与网损成本怎么权衡
规划模型的优化目标通常写成下面的形式:
$$ \min ; C_{\text{inv}} + C_{\text{loss}} + C_{\text{ope}} $$
其中 $C_{\text{inv}}$ 是新建线路的年均投资成本,线缆选型不同造价也不同,架空线和电缆的造价能差好几倍;$C_{\text{loss}}$ 是年网损费用,网架结构不同,线损率差异很大;$C_{\text{ope}}$ 是运行维护费用,一般按投资成本的一定比例折算。
注意三个细节:
投资成本要按等年值折算,不能只看一次性造价。比如一条电缆线路寿命按30年算,基准折现率取8%,一次性投入200万对应的等年值大约为17.8万。等年值算错,比较方案时会严重失真。
网损成本的计算依赖于典型日负荷曲线,不是只有一个峰值负荷。有些规划方案峰荷时网损不大,但轻载时段由于无功倒送和轻载线路过多造成网损偏高。如果模型只取峰荷场景,会高估重导线的收益。
可靠性指标如果只靠N-1约束作为硬约束,那么目标函数不必再加缺电成本。但若想允许部分N-1场景少量切负荷,则需要把期望缺供电量(EENS)乘以单位停电损失折算进目标函数。初学者不建议一上来就搞多目标,先固定N-1为硬约束,结果更容易解释。
2.2 N-1安全约束的线性化处理
N-1约束放到优化模型里,最大的麻烦在于"故障后潮流要重新分布"。如果对每个N-1场景都重新做一次完整的潮流计算,模型里要嵌入潮流方程,这个规模会让人崩溃。
工程上常用的办法是用直流潮流近似。配电网馈线电抗与电阻比值相对输电网偏低,直流潮流精度稍差,但用于规划阶段的方案比选,精度完全可以接受。更重要的是,直流潮流方程是线性的,N-1场景切换可以用线路状态变量通过大M法处理,模型性质保持为混合整数线性规划(MILP),全局最优解有保障。
这里把最核心的"故障状态线路功率约束"线性化写法列出来。对每条线路 $l$,正常状态下的容量约束是:
$$ -P_{l}^{\max} \cdot z_l \leq P_l \leq P_{l}^{\max} \cdot z_l $$
其中 $z_l$ 是该线路是否投运的0-1决策变量。而某个N-1场景 $s$ 下,如果故障发生在线路 $f$ 上,则 $f$ 的潮流必须为0,同时其余线路的潮流要重新分配。模型可以写为:
$$ P_{l}^{s} - P_{l} = \sum_{g \in G_l} \Delta P_{g}^{s} $$
其中 $\Delta P_{g}^{s}$ 是故障后发电或主变注入功率的调整量。由于配电网中分布式电源和主变注入都有出力上限,调整量本身又受制于机组上下限约束,整个约束链在数学上形成一个封闭的可行域。
为了把"故障线路潮流为零"写进线性模型,引入大M约束:
$$ -M \cdot (1 - u_{f}^{s}) \leq P_{f}^{s} \leq M \cdot (1 - u_{f}^{s}) $$
其中 $u_{f}^{s}$ 表示场景 $s$ 下线路 $f$ 是否正常运行,故障时 $u_{f}^{s}=0$,不等式将 $P_f^s$ 钳制在0附近。$M$ 的取值要大于该线路可能出现的最大潮流的1.2倍,太小会剪掉可行解,太大会造成数值病态,这一点后面第五部分专门展开讲。
2.3 配电网特有的辐射状与孤岛约束
输电网N-1后允许部分区域失去电源,配电网不行。配电网N-1后负荷应当通过联络开关恢复供电,整体网络仍保持辐射状。规划模型中如果不约束网络拓扑的辐射性,优化结果很可能出现"闭环运行"的网架,这在配电网是不允许的。
辐射状约束的经典写法是生成树约束加线路数量约束。对节点数为 $N$ 的网络,投运线路数量必须等于 $N - 1$,同时网络不能出现孤岛和环网。纯数学写法是:
$$ \sum_{l \in L} z_l = |N| - 1 $$
同时利用有向生成树约束割断环路。不过在N-1场景下,网络还要满足"开断任意一条线路后仍保持连通"的约束,实际等价于要求网络是2边连通(或者说每条线路都落在某个联络闭环内)。这个条件用纯线性约束表达比较繁琐,一个工程替代方案是先优化得到基础网架,再在N-1校验模块里检查连通性,不满足就加割集约束重新迭代。
3. Matlab实现:从数学建模到代码落地
3.1 工具链选型:Yalmip与求解器配置
Matlab环境下的建模工具有几个选择:直接用Optimization Toolbox写optimproblem,或使用Yalmip建模语言,配Gurobi或Cplex求解MILP。
我的建议是直接上Yalmip。原因很实际:N-1扩展规划的约束数量动辄上万条,用optimproblem写起来维护成本太高。Yalmip允许直接用矩阵和循环描述约束,语义清晰,调试时能快速定位哪个约束导致不可行。求解器方面,如果只有学生版Matlab,可用内置的intlinprog,但求解规模超过300个二进制变量时会明显变慢。有条件的话接Gurobi免费学术版,MILP求解速度快一到两个数量级。
对于网络参数,推荐全部采用标幺值,基准容量取100MVA,基准电压取10kV。建33节点算例时,把支路参数、节点负荷、网架拓扑整理成结构体数组,按统一格式存储。下面给出参数读入和变量定义的一段核心代码:
% 网络基础数据 bus = load('bus33.m'); % 节点编号, 有功负荷(kW), 无功负荷(kvar) line = load('line33.m'); % 首端, 末端, 电阻(ohm/km), 电抗(ohm/km), 长度(km) % Yalmip建模 X = binvar(n_line, 1); % 每条线路是否新建 P = sdpvar(n_line, 1); % 正常态线路有功潮流 theta = sdpvar(n_bus, 1); % 节点相角 % 目标函数:投资等年值 + 网损成本 + 运维成本 Cost_inv = sum(X .* inv_cost); % inv_cost 已折算为等年值 Cost_loss = base_power * sum(P.^2 .* R_line) * loss_price * 8760; Objective = Cost_inv + Cost_loss + 0.05 * Cost_inv;这里有一个容易忽略的细节:潮流方程里的 $P_l^2$ 项不是线性的。规划模型中正常态的网损可以用两种方式处理:要么忽略网损项,只计算投资成本,编程序最简单;要么把网损分解到每条支路上,用分段线性近似。我建议第二阶段再把网损加入目标函数,先跑通投资成本模型。
3.2 核心代码实现与注释
下面展示N-1扩展规划模型的核心约束代码,整体思路是:定义决策变量、正常态潮流约束、N-1故障场景潮流约束、辐射状约束。
% 正常态潮流平衡约束 for k = 1:n_bus % 注入功率 = 主变注入 + 分布式电源 - 负荷 P_inj(k, 1) = ... P_sub(k, 1) + P_dg(k, 1) - P_load(k, 1); end % 支路潮流与节点相角关系(直流潮流近似) % P = B * theta,其中 B 为节点导纳矩阵的虚部 P_line = B_br * theta; % 每条线路的潮流 = 对应支路导纳 × 相角差 % 容量约束:线路一旦不投运,功率为0 Constraints = [Constraints, -M * (1 - X) <= P_line <= M * (1 - X)]; Constraints = [Constraints, -line_cap <= P_line <= line_cap];上面仅示意了正常态的约束。N-1场景下的写法是把每条线路的故障状态作为索引,逐一生成故障态潮流约束,本质上是同一个约束块在故障前后各写一次,故障场景中该线路潮流强制为0,其余线路参与负荷重新分配。
3.3 故障集合生成与状态变量设计
做N-1扩展规划之前,先想清楚要校验哪些故障。配电网中N-1通常校验三类:
- 线路N-1:任意一回10kV馈线停运;
- 主变N-1:任意一台主变停运,站间联络转供;
- 母线N-1:某一母线失压后负荷全部转移。
在MATLAB中,故障集合以矩阵形式存储,行对应故障场景,列对应线路编号,元素0表示该线路处于故障状态。生成方式非常简单:
% 生成故障场景矩阵 n_scene = n_line; fault_matrix = ones(n_scene, n_line); for k = 1:n_line fault_matrix(k, k) = 0; % 第k条线路故障 end这里注意:故障场景不是在约束里循环添加就可以了,还要注意求解规模。每增加一个故障场景,潮流平衡约束就会新增几十到上百条。如果一个31条馈线的系统做全线路N-1,约束数量会翻几十倍,建模过程要跑很久。建议先做典型故障集(比如按变电站供电分区各选一条关键馈线),方案初筛后再做全N-1校验。
4. 算例结果与方案分析
4.1 规划方案核心指标对比
标准算例用33节点配电系统比较好说明问题,原系统有33个节点、32条支路、5个联络开关。设定目标年负荷在现有基础上增长40%,候选新建线路按走廊条件给出若干条,用上述模型求解得到规划方案。下面是求解后几个关键方案指标对比:
| 方案 | 新建线路数 | 投资等年值(万元) | 年网损成本(万元) | 全N-1通过率 |
|---|---|---|---|---|
| 原网架直接运行 | 0 | 0 | 42.8 | 71% |
| 方案A:人工指定改造 | 3 | 28.5 | 31.2 | 84% |
| 方案B:扩展规划优化结果 | 4 | 35.7 | 22.6 | 100% |
这个结果很有代表性:单纯按负载率超标位置去补强(方案A),和按N-1全场景统一规划(方案B),虽然投资成本相差七八万,但网损一年就能差出近10万,全N-1通过率是硬指标区别。方案B多建的那条线路投资换来的不仅仅是安全性,也为负荷转供提供了通路,这才体现出扩展规划"系统性"的价值。
4.2 为什么要做N-1自动校验
求解完成后的输出不能只停留在"哪些线路该建",必须给出N-1校验报告。扩展规划模型求解得到的优化结果已经硬性满足了故障场景约束,但工程审查阶段仍然需要逐场景展示"故障后负荷如何转带"以及"转带后各线路负载率"。因为评审专家不但要看结论,还要看转供路径合理性。
我习惯把求解结束后自动生成一张N-1校验汇总表,内容包含故障元件、转供路径、恢复后馈线最大负载率、电压最低节点,输出到Excel。发现某个场景最大负载率接近95%,说明方案冗余度不足,需要回头查一下该场景的约束是不是被大M法放宽了。
% 结果展示:提取故障后负载率 for k = 1:n_line load_rate = abs(value(P_line(:, k))) ./ line_cap; fprintf('故障线路 %2d:最大负载率 %.1f%%,最低电压 %.3f p.u.\n', ... k, max(load_rate) * 100, min_voltage(k)); end这里再强调一个工程惯性问题:很多工程师认为"规划模型已经加了N-1约束,最终方案一定满足N-1",这个说法在理论上是真的,但实际求解器可能因为容差问题轻微违反约束,数值上仍然需要二次校验。特别是Big-M取值偏大时,部分场景下的潮流约束可能被"数字性"放宽。所以求解完用潮流计算做一次独立回代,这个习惯能避免大部分返工。
5. 建模与调试中的常见坑
5.1 Big-M参数的"两难"选择
N-1串联约束里,大M取值的平衡是一门实操学问。$M$ 取小了,可能把可行域切掉,导致本来合理的投资方案被错误判为不可行;$M$ 取大了,MILP求解器在分支定界过程中的对偶间隙计算会变差,求解时间爆炸。
我的一般做法是:先不跑优化,只跑原网架和候选网架的最大可能潮流,扫描一遍支路潮流上限,以这个值为基础再乘1.3作为M值。这样既不会因为取值过小而丢解,数值性偏差也可控。另外,Yalmip的implies或者说binary variable约束可以配合use of bound tightening,减少某些场景下的病态。Gurobi内置的Presolve一般能自动收紧大M带来的松弛,但前提是每个M的上下界都要合理。
5.2 求解器数值问题与违约处理
MILP求解的整数容差(MIP Gap)默认是1e-4,但配电网规划模型中目标函数数值差异很大时(比如投资成本几百万元,网损成本只有几万元),稀疏约束下会遇到目标函数差别很小、整数组合却差很多的困境。工程上建议设置MIP Gap为1e-3,既避免没必要的精确搜索,结果也更符合实际。类似这样的配置:
ops = sdpsettings('solver', 'gurobi', 'verbose', 2); ops.gurobi.MIPGap = 1e-3; ops.gurobi.TimeLimit = 600;大量测试表明,这个参数设置下求解时间能缩短约40%,最优性偏差完全在工程可接受范围内。目标函数中投资成本和网损成本的量纲如果相差太多,建议先统一折算成万元,避免量级差造成的数值问题。
5.3 辐射状约束的伪环网陷阱
辐射状约束写成"投运线路数 = 节点数 - 1"后,仍然存在一个隐含陷阱:约束只保证了线路总数,没有排除"断开-环绕"结构。通俗讲,就是可能出现一种情况:整体来看线路数满足要求,但实际是部分节点成环、部分节点孤立,网络并不是一棵树。
举例说明:5个节点配4条线路,其中3个节点两两互成三角形连接(3条线),另外2个节点互相连接(1条线),第5个节点孤立,这时总线路数=4,约束满足,但节点5孤岛、节点1-2-3成环,完全不是辐射状。
解决办法是增加割集约束,对每个候选割集,要求至少有一条线路穿越割集:
$$ \sum_{l \in \delta(S)} z_l \geq 1, \quad \forall S \subset \Omega $$
工程上这个约束可以用分层迭代方式实现:先求解不加连通约束的问题,检查结果是否含有孤岛和环路,若有则加入相应的割约束重新求解,通常迭代2-4次就能收敛。这个"割平面迭代"的思路比一次性写全所有割集效率高得多。
6. 关于扩展方向的几点建议
N-1扩展规划模型跑通之后,可以根据应用场景继续做这几个方向的扩展:
考虑分布式电源:光伏和储能接入后,N-1故障场景下转供策略多了一个"本地供电、减少倒供"的选项。模型里需要增加DG出力切除变量,目标函数中对应增加弃光惩罚费用,优化结果会更贴近实际运行策略。
多阶段扩展规划:把目标年拆成近、中、远三期,设备投建时间作为整数变量。这个方向对模型规模挑战很大,一个实用近似是先把每期方案分别做N-1规划,然后统一回溯拼接,用动态规划或滚动优化思想处理。
考虑负荷不确定性:规划最怕的就是负荷预测不准。可以通过场景法生成多个负荷水平,等值转化为期望成本模型。N-1约束在每一类负荷场景下都要满足,模型规模和求解难度会显著增加,建议至少先把确定性模型消化的很透再上。
我在实际操作中还有一个体会:模型跑出来的投资方案只是参考,落地实施的时候还要结合道路管线条件、停电窗口、施工难度做二次修正。N-1扩展规划的真正价值,是帮你在一堆候选人选中筛掉明显不合理的方案,把有限的资金配置到最该花的地方。规划报告里永远不缺少"拍脑袋"的余地,但有了这个模型,拍脑袋之前至少先看看数学上哪个选择更优。