资讯详情

配电网韧性提升:基于场景随机规划的MPS预配置建模与求解

📅 2026/10/14 5:55:46 | 华诺云谱 👁 阅读
配电网韧性提升:基于场景随机规划的MPS预配置建模与求解
1. 为什么MPS预配置能决定灾后恢复的上限1.1 配电网韧性评价与MPS的定位先讲一个我在某高校课题组做韧性仿真时印象很深的现象同样是5台应急移动电源灾害前布置在关键节点和灾害后临时调配恢复效果能差出两倍以上。配电网韧性Resilience核心衡量的是电网对极端事件的抗扰动与恢复能力。业内常用“韧性曲线”来描述整个过程灾前正常运行灾害发生瞬间系统性能骤降然后经过一段“性能低谷期”之后随着抢修完成逐段恢复。曲线横轴是时间纵轴是系统供电比例或者幸存负荷比例。曲线越低、低谷持续越久韧性就越差。在低谷期里配电网处于最脆弱的阶段线路断了变电站出线跳闸分布式光伏可能因孤岛保护全站退出而抢修队伍哪怕全天候作业也要先确认故障、签工作票、准备材料整个过程需要小时甚至天级的时间。这个阶段里能够立刻接通负荷的不是抢修队而是应急移动电源Mobile Power SourceMPS。MPS可以理解成大号充电宝加移动底盘灾害前部署到安全位置灾害后开到故障区域附近通过临时线路给关键负荷供电。但MPS有几个天然限制数量有限、单台容量有限、移动需要时间、道路在灾害中可能受阻。这几个限制决定了MPS不可能出现在所有需要它的地方。那么问题就变成了在灾害到来之前有限的MPS到底应该放在哪几个节点才能让灾后尽可能多恢复关键负荷。这就是预配置Pre-allocation要回答的问题。1.2 “预配置”和“动态调度”的决策时间轴很多刚接触这个方向的同学会把“预配置”和“动态调度”混在一起。实际上两个决策位于灾害时间轴的不同位置求解逻辑也完全不同。灾害前约48~72小时气象部门给出预警调度中心启动应急响应。此时变电站、线路都还完好道路也还能通行决策者要确定MPS的初始停靠点以及每台MPS预留的容量等级。这是预配置。灾害发生后第2~6小时故障信息逐步到位哪些线路断了基本清楚。此时调度MPS从初始停靠点驶向目标接入点这是第一轮动态调度。灾害后6~48小时抢修持续推进故障线路陆续修复。前一个接入点恢复供电后MPS可以拔掉线路开到下一个待恢复节点。这个过程是滚动动态调度。可以看到动态调度的效果上限由预配置决定。如果MPS一开始全部放在电网边缘灾后主网架还没修复前它们可能根本到不了负荷中心如果全部堆在同一个负荷节点其他重要负荷又只能干等。预配置相当于在下棋时先把棋子摆到最有价值的位置后面怎么走棋是动态调度的事。这篇聚焦的是第一阶段也就是MPS预配置。理解了时间轴再看下面建模就顺了。1.3 这类SCI论文通常偏好用什么方法我复现过几篇韧性方向的工作一个明显规律是标题里带“Resilience”且发表在电力系统主流期刊上的文章MPS预配置部分几乎都是“场景驱动的随机规划”或者“鲁棒优化”很少有人用纯启发式算法去解第一阶段问题。原因是灾害的不确定性太强。线路断在哪里、断多少条、修复要多久都是事先无法精确预知的。如果只用单一确定性场景做配置灾害场景一偏移预配置结果可能完全失效。场景法把历史台风、冰灾数据转成一组带概率的离散场景让预配置在“所有可能场景的平均表现”上最优这是目前最主流的方式。鲁棒优化则更进一步不假设概率分布直接让预配置在最恶劣场景下也不至于太差。代价是模型更保守、求解难度更大。对大多数复现者来说从基于场景的两阶段随机规划入手是最容易跑通、也最能和论文结果对得上的路径。2. 预配置问题的数学模型场景、目标与约束怎么落到纸面2.1 场景与不确定性建模把灾害不确定性转成数学可处理的形式我用的方法是这样的第一步根据历史记录确定每条线路的断线概率。同一个台风过程里离风圈近、树线矛盾严重的线路断线概率高反之则低。这个概率是场景生成的基础。第二步蒙特卡洛抽样生成大量原始场景。每个场景里包含“哪些线路断开”以及“线路修复需要多长时间”。比如一个200个场景的样本集每个场景标记一组断线集合。第三步场景削减。直接拿200个场景去建模型第二阶段变量会展开200份模型规模爆炸普通电脑根本跑不动。业内常用快速前向选择法把场景缩减到10~20个代表性场景保证缩减前后概率分布差异尽量小。缩减后的每个场景带一个概率权重π_s所有场景权重和为1。第四步对每个场景定义故障恢复时序。比如场景1里线路5在第2小时断开、第14小时修复那么MPS在场景1里的供电窗口就受这些时间点约束。这里有个容易被忽略的细节MPS到达时间也是场景的一部分。灾害后部分道路可能无法通行MPS从初始位置到接入节点的时间要乘以一个道路受阻系数。这个系数如果你不加论文里的对比结果很可能就对不上。2.2 目标函数加权失负荷是最常见的指标预配置问题的目标函数我见过两种主流写法。第一种是期望加权失负荷最小化。写法类似min Σ_{s∈S} π_s Σ_{t∈T} Σ_{i∈N} w_i · (1 - sup_{i,s,t})其中sup是一个连续的供电比例变量——节点i在场景s、时刻t下的供电量占其需求量的比例。w_i是节点i的负荷权重用来区分关键负荷和普通负荷。医院、通信基站、供水泵站权重高普通居民负荷权重低。第二种是最大化恢复加权负荷量本质是上式的等价变换只是换了角度。有的论文还加一个恢复速度项希望负荷在更短时间内恢复也就是在目标里对恢复时刻加指数衰减权重。操作上我建议先实现第一种理由很实际加权失负荷是负值最小化数值稳定便于和论文表格里的指标直接对比。指标定义务必和原文一致否则后面所有验证都是白做。确定负荷权重时要注意w_i到底是绝对权重还是比例权重。有的论文用绝对权重比如一级负荷1.0、二级0.5有的用归一化权重按总负荷比例归一。这一个细节不对你的最优配置点可能和原文完全不同。2.3 关键约束从DistFlow到MPS接入约束配电网潮流约束是模型的核心也是新手最容易写错的部分。配电网是辐射状网络常用DistFlow潮流模型描述。它的物理含义可以类比小区供水管网水流从主干管进来沿管线逐级分流每段管子的压降和流量、管阻有关。DistFlow的原始形式包含线路电流平方项是非凸约束。SCI论文常用的处理方式有两种一是线性化DistFlow忽略网损高阶项把电压差近似成P、Q的线性组合二是二阶锥松弛把约束转成二阶锥形式再在后处理中检查松弛间隙。我的建议是复现阶段直接用线性化DistFlow理由稍后讲。线性化之后的节点功率平衡约束长这样P_j Σ_{(i,j)} (P_ij - r_ij·l_ij) P_jD Σ_{(j,k)} P_jk其中l_ij是电流平方项如果忽略网损可以约掉。电压约束近似成V_j ≈ V_i - (r_ij·P_ij x_ij·Q_ij)然后加上节点电压上下限约束V_min ≤ V_j ≤ V_max以及支路容量约束。MPS相关的约束要特别注意我列几个最容易出问题的预配置变量x_pre,i是二进制变量表示是否在节点i预置MPS每台MPS在同一时刻只能接入一个节点但一个节点可以接多台MPSMPS输出功率不能超过其额定容量如果没接入输出功率必须强制为0这个用大M法写p_mps ≤ M · x_connectMPS从预配置点到接入点的行驶时间必须在故障时段内可行预算约束所有预配置点的建设与运输成本之和不超过总预算。2.4 为什么预配置本身是一个两阶段问题把上面的变量分类你会发现预配置变量x_pre不依赖场景而供电比例sup、接入连接变量x_connect都带场景索引。这正是两阶段随机规划的标准结构第一阶段“现在”决定MPS预配置位置此时灾害场景未知第二阶段“灾害后”观察断线场景再决定MPS怎么接、给谁供电。第一阶段的目标函数必须建立在“所有场景期望值”之上因为决策者无法预知哪个场景会发生。从算法角度看这种结构天然适合Benders分解或基于场景的MILP直接求解。规模不大时直接建单层MILP交给求解器速度反而更快。3. 求解框架与工具链选型MILP方案为什么最省心3.1 线性化与凸松弛先说为什么我建议线性化DistFlow而不是直接上二阶锥松弛。二阶锥松弛在数学上更精确但需要求解器支持锥约束而且松弛后要额外验证间隙。如果间隙大还要迭代收紧代码量明显增加。对于预配置这种“第一阶段决定位置”的问题潮流模型带来的误差相对有限线性化足以给出和原文趋势一致的配置结果。等做动态调度、需要精细计算电压分布时再升级成SOCP也不迟。线性化过程中大M取值是个技术活。比如功率是否接入的约束写成p_mps ≤ M · x_connectM应该取该节点最大可接入功率上界而不是随手写个1e4。太大会导致数值病态太小会把可行域截掉。我习惯先算一遍各节点理论最大供应能力再取1.2倍作为M实测效果稳定得多。3.2 场景削减场景削减工具有些论文用自带的启发式脚本MYLS一步步初始100个场景用快速前向选择保留15个。判断标准是削减前后所有场景的总失负荷期望偏差不超过3%这样既保精度又保速度。削减还有一个隐藏好处场景越少模型越容易调试。你先用5个场景跑通全流程再逐步加到15个、20个。直接上50个场景求解器卡住的时候你分不清是模型错还是规模太大。3.3 求解器选型与YALMIP搭建这套模型我推荐用Matlab YALMIP Gurobi的组合。YALMIP是一个建模层语言优势是语法简洁、建模速度快、换求解器方便。你只需要用binvar定义二进制变量、sdpvar定义连续变量然后写约束和目标最后调用optimize即可。如果实验室只有Cplex授权YALMIP也可以无缝切换约束和变量声明都不用改。我实测两种求解器对这个规模问题的求解速度差异不算大但Gurobi在MILP上的默认启发式更强首解出现更快。3.4 计算规模控制的几个技巧33节点算例、15个场景、24个时段规模大概是预配置二进制变量候选节点数比如10个连接二进制变量候选节点数量 × 场景数 × 时段数大约10×15×243600个连续变量节点数 × 场景数 × 时段数 × 若干几万个这个规模在Gurobi默认参数下通常几十秒到几分钟能解完。如果算例换成123节点、场景翻倍建议先做以下几个控制只对候选节点引入预配置变量别把全部节点都列为候选项时间维度用关键时段比如24小时切成8个代表时段而不是逐小时相同容量的MPS不做编号区分避免排列对称导致分支数爆炸求解器MIPGap设置为1%甚至3%省掉的求解时间很可观用一个“先给一个可行解”的启发式热启动Gurobi的Start参数配合我下面提的贪婪初始化思路很好用。4. Matlab代码复现的完整骨架从算例数据到结果图4.1 算例与参数准备我先用IEEE 33节点标准算例做验证这是一个公开的配电网测试系统基准电压12.66kV有32条支路结构是典型辐射状非常适合练手。参数我用两个表格规划建模时照着填就行。参数取值说明基准电压12.66 kV系统基准基准功率10 MVA标幺制换算节点数33含根节点MPS单台容量300 kW / 200 kWh输出功率 / 能量上限MPS台数3~5对比用候选预配置节点子集比如节点8、18、22、25、33地理上可停放且道路可达一级负荷权重1.0医疗、通信等三级负荷权重0.1普通居民场景参数取值线路断线概率区间0.05~0.4修复时间区间4~16 h初始场景数200削减后场景数15道路受阻系数1.5~2.04.2 代码结构设计我建议主程序不要写成一个大脚本按下面的结构拆main_mps_preallocation.m主入口设定参数调用各模块data_network33.m返回节点坐标、支路参数、负荷分布gen_scenarios.m蒙特卡洛抽样 场景削减输出场景集和概率build_model.m用YALMIP构建MILP模型run_solver.m设置求解器参数并求解plot_resilience.m绘制韧性曲线和配置结果图。这样的好处是后续做动态调度时你可以把build_model拆成“预配置模块”和“调度模块”复用数据接口不用推倒重来。4.3 核心代码片段下面这段是YALMIP风格的MILP骨架说明建模思路可以直接改参数套用。% 加载网络与场景数据 [bus, branch] data_network33(); [scen, prob] gen_scenarios(); % 决策变量 x_pre binvar(n_candidate, 1); % 预配置位置 x_conn binvar(n_candidate, n_scen, n_t); % 场景s、时刻t是否接入 p_mps sdpvar(n_candidate, n_scen, n_t); % MPS输出功率 gamma sdpvar(n_bus, n_scen, n_t); % 各节点供电比例 % 目标期望加权失负荷最小 obj 0; for s 1:n_scen for t 1:n_t obj obj prob(s) * w * (1 - gamma(:, s, t)); end end % 约束 Constraints []; % 预配置数量约束 Constraints [Constraints, sum(x_pre) n_mps]; % MPS输出功率上限与接入逻辑大M Mbig 1.2 * max_load_serve; for s 1:n_scen for t 1:n_t Constraints [Constraints, p_mps(:, s, t) Mbig * x_conn(:, s, t)]; Constraints [Constraints, p_mps(:, s, t) 0]; % MPS接入点与预配置点一致 Constraints [Constraints, x_conn(:, s, t) x_pre]; end end % 节点功率平衡线性DistFlow % ... 这里4.3节后面详述 % 求解 ops sdpsettings(solver, gurobi, verbose, 1, mipgaptol, 0.01); sol optimize(Constraints, obj, ops);节点功率平衡那段比较长单独提取出来。线性DistFlow的核心是把每条支路的潮流和节点电压松弛成线性方程不需要二阶锥变量建起来很快。for s 1:n_scen for t 1:n_t % 根节点电压固定 Constraints [Constraints, V(1, s, t) 1.0]; for k 1:n_branch i branch(k, 1); j branch(k, 2); r branch(k, 4); x branch(k, 5); Constraints [Constraints, ... P(k, s, t) sum_P_down - P_D(j, t) p_mps_at_j]; Constraints [Constraints, ... V(j, s, t) V(i, s, t) - (r*P(k, s, t) x*Q(k, s, t))]; end % 电压安全约束 Constraints [Constraints, 0.95 V(:, s, t) 1.05]; end end这里的sum_P_down表示下游支路潮流之和具体下标需要按你的支路编号表展开。代码只是演示核心逻辑不是可直接跑的全量脚本但框架是完整的。4.4 输出与可视化求解完成后第一时间输出三样东西预配置位置、目标函数值、韧性曲线数据。韧性曲线很关键画图用的代码反而简单figure; plot(time_hours, resilience_no_mps, --, LineWidth, 1.5); hold on; plot(time_hours, resilience_with_mps, -, LineWidth, 1.5); xlabel(时间 (h)); ylabel(系统供电比例); legend(无MPS, 含MPS预配置); grid on;我这里用了一个从故障发生到抢修完成的24小时时间窗系统供电比例在故障瞬间从1跌到某个值再逐步回升。有没有MPS配置曲线形状差很多特别是“低谷期的深度和长度”。5. 结果验证与指标对比韧性提升到底该看哪几个数5.1 韧性曲线与量化指标跑通模型后第一步不是调参而是看曲线形态是否符合物理直觉。对33节点算例我得到的结果大致是这样的规律故障发生后无MPS场景的系统供电比例直接掉到0.3左右然后随抢修逐步恢复到1而加了MPS预配置后低谷期供电比例可以维持在0.65以上恢复时间也提前了几个小时。光看曲线还不够要量化对比。我常用的指标有四个指标含义低谷期平均供电比例故障后前12小时的平均加权失负荷期望目标函数本身恢复时间延长量达到90%供电的时间差韧性面积提升曲线下面积差反映总能量损失减少我用一套测试算例对比了不同MPS数量的效果MPS台数加权失负荷相对值低谷期供电比例恢复至90%耗时01.000.2818 h20.680.4515 h30.510.5813 h50.370.6611 h注意这些是相对值只是为了说明趋势。真正复现论文时你必须用原文的负荷数据和故障场景才能得到一致绝对数值。5.2 对不上论文数值时的排查清单复现时最痛苦的是结果和论文数字差一截。我在这个方向上吃过亏总结出五个排查点第一个是基准值。原文用的是标幺值还是有名值基准容量是不是10MVA一个基准功率对不上电压和潮流全部偏。第二个是负荷权重定义。原文的w_i如果是按节点负荷占系统总负荷比例归一而你用绝对值那配置优先级会乱。第三个是时段划分。有些论文用16个时段有些用24个还有用故障前后两阶段的。时段数不同MPS的移动窗口就不同配置结果会变。第四个是场景削减的随机种子。场景削减不是决定性算法随机种子的选择会影响削减后的场景集合进而影响配置结果。复现时最好固定种子并在论文里记录种子值。第五个是无功负荷。配电网R/X很大无功压降不能忽略。如果模型里只建有功功率平衡电压偏低会导致部分接入点不可行最优配置点可能偏移。6. 复现中的硬核避坑记录数值、场景与求解器的日常6.1 大M取值引发的数值坑我第一版模型里大M取的是1e4结果求解器给出的最优解里MPS输出功率出现了0.5到几kW的“泄漏”误差。更麻烦的是Gurobi的原始单纯形法在数值病态下会报约束冲突。排查后发现问题就出在M上。后来我把M改成“该节点最大可恢复负荷的1.2倍”对33节点算例大概是几百的量级所有数值异常消失。这是复现这类问题最常见的低级坑写代码时务必先算M的紧上界。6.2 时间步长与恢复时长的匹配有一次我把预配置时间步长设成1小时动态调度里却用了15分钟的分辨率结果两组曲线衔接处出现台阶跳变。问题是两类决策对时间精度的需求不同但共用同一时间轴。解决办法是预配置阶段就统一到与调度一致的离散时间点按15分钟切96个点或者至少切48个半小时点而不是图省事只切24个小时点。6.3 场景数量与求解时间的权衡实测200个场景直接求解模型光构建约束就要两三分钟求解器内存经常超过8G。削减到15个场景后求解时间降到半分钟以内而配置结果和200场景全解的目标值偏差大约在2%左右完全在可接受范围。另外提一句即使削减了场景我也建议先用3~5个场景调试模型逻辑等数值稳定了再上15个场景。模型有bug时场景一多只会让bug更难定位。6.4 给“下篇”动态调度的扩展建议预配置解出来后直接作为动态调度的初始条件。动态调度问题比预配置更细决策变量变成MPS的时空调度路径哪里断电就开到哪里修好了就拔线去下一处。它本质上是一个时变的混合整数规划而且每个时段都要更新故障信息属于滚动时域控制的经典场景。如果你要连做上下两篇建议把预配置的约束模块和参数结构体都封装成函数动态调度直接调用这套接口别把代码写死在一个脚本里。这样下篇动刀动枪的时候能少改很多重复劳动。6.5 关于求解结果“可复现”的最后一个习惯最后分享一个让我少走了很多弯路的习惯每次跑完一组实验把求解器版本、YALMIP版本、随机种子、MIPGap、场景削减参数全部写进结果文件的注释头里。这不是论文要求但等你在几周后回头对比不同配置结果时你会发现没有这组记录你根本不知道当前这套结果是怎么来的。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑