ARTICLE DETAIL

资讯详情

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

Matlab实现配电网N-1扩展规划:模型构建与求解实践

Matlab实现配电网N-1扩展规划:模型构建与求解实践 1. N-1扩展规划到底在解决什么问题1.1 从静态规划到N-1校验的演进在配电网规划里早些年大家习惯做静态规划给定未来某一水平年的负荷预测值算一笔账决定哪些线路要新建、哪些线路要扩容目标就是用最小的投资把电送到位。说实话这种做法在负荷增长平缓、结构简单的年代够用了但它有一个致命盲区——它只验证了正常状态下所有约束都满足完全没有回答一个更关键的问题当某条线路或某台变压器发生故障退出运行时系统还扛得住吗我最早接触这个问题的契机是参与一个工业园区的配电网规划项目。当时方案做得很完美投资也压到了最低结果评审会上被一位老工程师一句话问住了如果10kV馈线A跳闸它下面的负荷怎么转供相邻线路的容量够不够我当时愣住了因为静态规划结果里压根没有这个校验逻辑。这个问题背后的本质就是N-1准则在配电网层面的落地。1.2 配电网的N-1准则与主网的不同之处在输电网里N-1准则非常严格任一元件线路、变压器、母线退出运行后系统必须保持稳定运行不损失负荷不发生过载。但配电网的情况要特殊得多——它不是靠复杂网架和多回并列通道来满足N-1而是靠联络关系一条馈线故障后通过联络开关把部分或全部负荷转移到相邻馈线。所以配电网N-1扩展规划的核心逻辑就变成了在扩建方案中把那些可以作为故障后备通道的联络线路一并纳入决策。规划结果要保证的是——任意一条馈线或关键联络支路退出后网络重新配置拓扑仍然能对所有负荷供电且各支路潮流不超过容量。这个思路和输电网最大的差别在于配电网允许停运后甩负荷吗在多数规范里配电网N-1允许切除三级负荷但一、二级负荷必须在故障后通过转供电恢复。所以模型里还要区分负荷等级这给规划问题增加了一个维度。1.3 扩展规划模型的三个核心决策在我用Matlab做配电网N-1扩展规划时会把整个决策拆成三个层次第一层是网架决策哪些现有线路需要升级扩容哪些候选走廊值得新建线路这是一组0-1整数变量直接对应工程上的钱花在哪。第二层是拓扑决策规划的最终网络必然要形成有效的供电结构配电网正常运行要求辐射状闭环设计、开环运行所以新建线路加入后不能形成环网必须保证每个负荷节点有且仅有一条供电路径。第三层是运行决策在N-1场景下某条线路断开后剩余网络里潮流怎么重新分配哪些开关需要闭合这本质上是一组连续变量需要随着每个故障场景动态调整。这三个层次的决策嵌套在一起就构成了一个混合整数规划问题——这也是为什么配电网N-1扩展规划比单纯的潮流计算复杂得多。用Matlab做这个事不是写个solve完事而是要自己搭建优化模型、组织数据、处理N-1场景集最后还要把结果可视化出来。2. N-1约束的数学表述枚举场景背后的计算逻辑2.1 为什么要用枚举——N-1准则的安全域本质要表达N-1约束最直接的方式就是枚举把每条需要校验的支路断开形成一组场景然后在每个场景里重新校验潮流。这个思路说白了就是把任意一条线断了都安全这个命题拆成有限个这条断了系统还安全的子命题。这听起来简单但枚举本身有讲究。全枚举的规模是O(m)m是关键支路数量看起来不大可每个场景里嵌入的潮流方程会把问题撑大m倍。如果规划対象是几十条候选线路、上百个节点模型规模会迅速膨胀。所以我在实操中一般会做两步预处理第一步筛选关键支路。对配电网来说通常只需要枚举主馈线干路和关键联络线而不是把每个分支线都纳入枚举范围。分支线末端故障对系统全局影响小而且分支线的N-1校验可以简化为故障隔离就地切除。第二步场景削减。有些线路断开后的网络状态几乎一样比如同一回路的并联分支可以合并处理减少重复计算。2.2 DistFlow潮流方程与线性化处理配电网潮流计算的经典模型是DistFlow方程它描述的是辐射状网络中节点注入功率与支路潮流、节点电压之间的递推关系。原始的非线性DistFlow形式包含电压平方项和电流平方项直接扔进MIP里很难求解所以实际做扩展规划时会做线性化处理。工程上最常用的线性化DistFlow是这样有功平衡支路流出的有功等于下游所有节点负荷之和忽略网损无功平衡支路流出的无功等于下游所有节点无功负荷之和电压降约束相邻节点电压差近似等于支路有功与电阻的乘积加上无功与电抗的乘积这个线性化在10kV配电网层面精度足够因为配电网线路短、电压等级低网损占比小且电压幅值变化不大。但要注意忽略网损意味着N-1场景下的潮流计算会略微乐观所以我会在求得规划方案后再做一次完整非线性潮流校验确认没有越限——这一步是必须的别偷懒。2.3 N-1场景下的约束生成细节每个N-1场景的本质是在网络拓扑中强制移除一条支路然后在这个新拓扑下重新运行潮流方程。放到优化模型里就是每个场景单独复制一份运行变量和潮流约束但网架决策变量在所有场景中保持一致。这种结构在优化术语里叫在这里制定决策在那里验证后果——规划方案只有同时满足所有场景的约束才算可行也就是所谓鲁棒性。举个实际例子假设有3条候选新建线路x1、x2、x3优化器想选择只建x1和x2因为这些线路便宜但如果某条关键馈线断开后恰好需要x3转供才会不过载那这个方案就会被N-1场景约束直接判为不可行。于是求解器要么换一组合适的线路组合要么额外加固现有线路。我在Matlab里构建这个约束时需要注意支路潮流的方向问题。配电网辐射状运行下支路潮流方向由电源指向负荷本应是单向的但N-1场景中转供后某些支路的潮流方向可能反转。如果模型里给每条支路只定义了一个正方向的有功变量那反转的情况就没法表达。解决办法是给每条支路定义两个方向的潮流变量并加上正负双向约束再用一个0-1变量保证同一时刻只有一个方向有值。这一步在建模时最容易漏漏掉的后果是求解器给出一个实际不可行的伪最优解。3. 混合整数规划建模变量设计与目标函数3.1 决策变量的选取新建设路径与扩容顺序配电网N-1扩展规划里最常见的决策变量有两类新建线路在候选走廊i-j上是否新建一回线路用二进制变量x_ij表示线路扩容对现有线路是否升级导线截面比如从240mm²换成630mm²用二进制变量y_ij表示。有人会问为什么不直接用连续变量表示扩容后的容量非要搞0-1因为工程实际中导线截面是离散规格扩容要么不扩、要么直接升到某一档不存在扩一半的说法。这跟输电网规划里可以用连续变量近似处理的方式不同配电网工程细节更强。除了这两个主变量之外N-1场景下还涉及转供路径选择。有些模型会把它处理成连续潮流变量有些模型则会增加一组整数开关变量来表示故障后哪些联络开关闭合。后者更贴近实际运行但会让模型复杂一个量级。我在自己的实现里采用折中方案正常运行场景下的拓扑由生成树约束保证N-1场景里允许动态调整转供关系用连续潮流变量表达重构后的运行点不做显式开关决策。这样既保证了转供可行性又不至于让整数变量爆炸。3.2 目标函数全生命周期成本怎么算目标函数通常包含两大部分投资成本新建线路和扩容线路的一次性建设费用。这部分要乘上资金回收系数CRF把一次性投资折算到每年的等额成本。CRF的计算与折现率和规划期有关一个典型取值是折现率8%、规划期15年对应CRF约0.117。别小看这个折算它可以完全改变方案排序——如果只看一次性投资短期便宜方案会胜出折算成年值后长期运行损耗高的方案可能被淘汰。运行成本主要是网损费用。N-1场景下的网损也要纳入考量但对规划方案排序影响相对次要。我在实践中会把运行成本乘以一个较小的权重系数如0.3避免目标函数被运行成本主导、把规划方案带偏。这个权重怎么定取决于电网公司的考核口径——如果考核指标里网损率占比高就上调权重如果重点是供电可靠性就弱化网损权重。所以目标函数的标准形式是min ∑新建线路年投资费用×x_ij∑扩容线路年投资费用×y_ij 年网损费用这里的年网损费用需要根据不同场景的持续时间加权——正常运行场景占大多数N-1故障场景只占很少的等效小时数。如果建模时不分场景权重把所有场景等权相加网损费用的计算结果会失真。3.3 拓扑约束辐射状结构的树约束技巧辐射状结构是配电网规划的硬约束我的理解是它相当于一棵树有n个节点必须有n-1条闭合支路且不能成环。放到MIP里这个约束不能直接写支路数等于n-1了事因为那只能保证支路数量对不能保证连通——完全可能出现一个含环的孤立小网络再加一个孤立节点支路数碰巧也等于n-1。工程上推荐的做法是单商品流约束给每个节点分配一个单位的需求量从电源节点出发的流量必须能够到达所有节点。实现方式是引入辅助变量f_ij虚拟流量满足对每个非电源节点流入的虚拟流量减去流出的虚拟流量等于1虚拟流量只有在支路被选中的情况下才允许存在用大M法或直接与0-1变量相乘约束。这个虚拟流技巧在Matlab里实现不复杂但有个性能陷阱辅助变量数量和约束规模会随节点数线性增长对几百个节点的系统问题不大对上万节点的系统就需要用更高效的树约束方法比如生成树割平面。4. Matlab实现架构与关键代码逻辑4.1 数据准备支路参数与负荷预测怎么组织我在Matlab里做N-1扩展规划的第一步从来不是写优化代码而是把数据文件组织清楚。一个好的数据准备可以省掉后面一半的调试时间。通常我会准备以下几个基础矩阵数据类别字段内容典型示例节点数据编号、有功负荷、无功负荷、负荷等级33节点系统节点有功负荷从0到380kW不等现有支路首端节点、末端节点、电阻、电抗、容量上限10kV馈线LGJ-240导线载流量约610A候选支路走廊端点、可建回路数、单位长度投资每条候选线路长度2km造价约80万/km电源参数变电站位置、短路容量、电压基准值根节点电压为1.0pu基准容量10MVA负荷预测我就直接按输入数据给定各节点水平年峰值负荷——规划期只有一年不做时序曲线。如果要做多阶段扩展规划负荷就要按年份做增长率叠加。这里分享一个我踩过的坑节点编号一定要从1开始连续编号而且首端节点编号必须小于末端节点编号。我早期用某份公开数据时支路矩阵里有的支路是末端节点编号更小导致后面写约束时方向判断出错潮流计算结果莫名其妙就反了。后来我写了一个预处理函数把所有支路统一成起点小于终点再构建关联矩阵问题彻底消失。4.2 场景枚举与矩阵构建场景枚举的核心函数逻辑大概是% 定义N-1场景集逐条断开需要校验的关键支路 scenarios struct(); scenario_count 0; for k 1:size(branch, 1) % 只对主馈线段做N-1校验 if is_main_feeder(branch(k, :)) scenario_count scenario_count 1; temp_branch branch; temp_branch(k, 5) 0; % 该支路不可用 scenarios(scenario_count).branch temp_branch; scenarios(scenario_count).outaged_branch k; end end这个矩阵构建阶段的核心在于每个场景下的支路可用性不同但节点和电源数据完全一致。所以我在构建优化模型时会用单元数组存储每个场景的关联矩阵然后在约束中循环引用。性能提示Matlab里循环写约束很慢。我的建议是尽量用向量化方式构建大矩阵把不同场景的约束放在同一个稀疏矩阵里而不是用for循环一行一行addrow。实测下来同样是构建一个含30个N-1场景的模型向量化写法比循环写法快5倍以上——对于动辄几万行约束的MIP这个差距非常可观。4.3 调用求解器用YALMIP还是直接用工具箱这是很多初学者纠结的问题。我的建议是如果你打算用YALMIP就把精力放在建模逻辑上如果你打算直接用intlinprog就要花更多时间在矩阵组装上。用YALMIP适合快速搭建原型、验证模型正确性。写约束像写数学公式可读性好调试方便。缺点是多一层封装求解器报错信息不够直观而且大模型下变量引入会有内存开销。直接用intlinprog适合追求效率、需要精细控制求解过程的场景。但配电网扩展规划的约束数量动辄几千上万行手写矩阵容易出错变量和约束的编号要对齐非常痛苦。我个人实际项目里两种都写过最终倾向于YALMIPCplex/Gurobi的组合。特别是N-1场景约束多、模型大用Gurobi求解MIP的速度比intlinprog快一个量级。YALMIP的安装和配置网络上资源很多这里不赘述只说一个关键点YALMIP的系统推荐搭配一套求解器如Gurobi或Cplex别只依赖内置的intlinprog否则模型稍大你就会等不起。4.4 结果处理与配电网网架图可视化求解完成只是万里长征走了一半后半程是结果处理和可视化。Matlab里的plot函数配上有色节点和线条标签能画出非常直观的规划方案图。我一般会把以下三件事画在一张图上现有运行线路用灰色虚线表示规划新建线路用红色粗实线标出N-1校验中暴露出的薄弱支路接近上限的线路用黄色高亮。写这段可视化代码时有个细节gplot函数搭配自定义坐标比用graph对象更省内存而且对老版本Matlab兼容好。我早期用graph和plot(graph)的方式画33节点系统还行画到100节点时界面卡顿明显换用gplot之后好很多。此外我强烈建议在输出结果里生成一份方案说明表列出每条新建线路的起止节点、长度、投资额以及该方案下各N-1场景的最大负载率。这份表格才是规划结果汇报给决策者时的核心交付物——比几十页报告有用得多。5. 实测中遇到的三类典型问题5.1 N-1场景组合爆炸引起的求解时间失控我第一次跑完整模型时用了一个中等规模系统节点数约120候选线路有60条N-1校验支路有40条。模型建好后YALMIP显示Size: 18420 constraints, 7060 variables里面有近300个二进制变量。当时我用了默认的intlinprog参数结果跑了三个小时没收敛最后只能强制中断。后来摸索出一套组合拳才把求解时间压到可接受范围用Gurobi替代intlinprog求解速度有数量级提升设置MIP Gap容忍度。规划问题不需要证明到小数点后4位MIPGap定在1%以内就足够工程使用。我实测从MIPGap1e-4放松到MIPGap0.01求解时间能缩短60%以上给二进制变量提供初始可行解。先用启发式方法比如按年费用从小到大排序选线路直到N-1约束满足生成一个粗糙方案作为MIP的初始解能极大加速分支定界树的剪枝效率。这三种手段叠加后同样的模型从三小时无解变成二十分钟解到gap1%。这个经验让我意识到配电网扩展规划的瓶颈很多时候不在模型而在求解策略。5.2 线性化松弛导致的潮流精度偏差线性化DistFlow虽然好算但有代价它假设电压在1.0pu附近、支路两端相角差很小。在N-1场景中某些线路断开后转供路径变长电压降可能达到5%~8%——此时线性化结果的误差就会变得明显。我处理这个问题的方法是两阶段校验优化阶段用线性化模型粗筛得到一个候选规划方案然后用Matpower或自写的牛顿法潮流程序对每个N-1场景做精确潮流计算。如果发现某个场景电压越限或线路过载就把对应约束以割平面的方式加回优化模型重新求解。迭代两三轮后最终方案就能同时通过线性化校验和精确校验。这个方法背后的思想其实很简单不要指望一个简化模型在所有工况下都精确而是要让简化模型捕捉到主要矛盾再用精确模型去修正次要偏差。5.3 孤立节点与环形网络的隐性约束遗漏辐射状树约束如果写得不够严谨会出现两类微妙的问题第一类是孤立节点。有一回我检查求解结果发现某个负荷节点竟然没有任何支路连接到电源——但目标函数值还挺好因为该节点的负荷凭空消失了。原因就是我只在约束里限制了虚拟流量的流动上限没有强制每个节点必须有注入流量。加上每个节点虚拟流入量之和等于1的约束后问题才消失。第二类是隐性环网。有时支路数是对的虚拟流也满足但因为虚拟流可以在环内打转求解器会构造出一个带环的网络。处理办法是引入节点父支路概念每个非根节点必须恰好选择一条支路作为其父支路形成有向生成树。这在配电网规划模型里是标准做法但很多教程不会强调——你写约束时务必检查每个节点有且仅有一条入支路这个条件。6. 进一步扩展的方向6.1 多阶段扩展规划以前的模型假设所有线路都在规划期初一次性建成这不符合工程实际——电网建设是分期投入的今年负荷增长慢就没必要提前把线路建好占用资金。多阶段扩展规划把规划期分成若干年段每段有独立的投资决策约束里加跨阶段变量关系某个走廊在第一阶段不建第二阶段才允许建。这相当于把单阶段模型复制成多个时间截面再通过时间耦合约束串联起来。在Matlab里实现多阶段模型时复杂度会呈线性增长而不是指数增长因为各阶段间的变量关系相对简单。但要注意一个实操问题N-1场景的枚举量要乘以阶段数模型规模会成倍上升必须配合前面说的求解策略。6.2 不确定性场景的鲁棒处理未来负荷到底增长多少没人能给出确定数字。传统做法是取保守高值做规划但这样投资浪费严重。现在做得比较多的是用鲁棒优化或随机优化来处理不确定性——把负荷需求描述为一个不确定集区间或盒式约束要求规划方案在最恶劣情况下仍满足N-1。在Matlab里实现鲁棒配电网规划可以用YALMIP的鲁棒优化模块也可以自己手动建模列写对偶约束。手动建模虽然代码量大些但可控性好而且能清晰看出鲁棒约束的物理意义——你的规划方案要能在所有可能的负荷场景和所有可能的N-1故障场景下都站得住脚。6.3 分布式电源接入后的N-1新问题现在配电网规划绕不开分布式光伏和储能。分布式电源接入后N-1校验的性质变了故障后某些孤岛可能依靠光伏继续带负荷运行这既是机遇也是挑战。机遇是DG提供了本地供电支撑提高了故障后的负荷转供能力挑战是DG出力不确定性让故障后能否保电变成了概率问题。在这个方向上我目前在做的是把DG出力场景与N-1故障场景做笛卡尔积枚举然后借用机会约束规划的理念允许部分场景不满足N-1但概率要低于某个阈值比如5%。这个模型在Matlab里实现的核心难点是如何处理联合概率约束目前工程上常用采样法或场景削减法简化处理。最后说点实在的。配电网N-1扩展规划这件事单纯的编程能力远远不够真正难的地方是把电力系统物理规律转化为数学约束的抽象能力。我见过太多的代码结构写得很漂亮但N-1约束本身就写错了也见过模型简化过了头规划出来的网架一做大负荷校验就崩溃。写这篇文章的核心目的是希望后来者少走这些弯路——数学建模时多想一会这个约束的物理含义是什么求解时多试几种参数组合结果出来后务必做一次精确潮流复核。这三点做到了你用Matlab做N-1扩展规划就不会跑偏。
返回列表