
做配电网研究的人都知道极端天气才是检验规划方案的试金石。一次台风过境往往造成十几条馈线同时失电变电站出口跳闸后下游只能靠分布式电源和储能设备撑起孤岛。但固定储能装在哪里灾后就只能在哪里发挥作用而移动储能车却能跟着故障走——这也是这几年“移动储能应急调度”热度居高不下的原因。这篇文章基于经典的IEEE 33节点配电系统完整复现了一套“灾前预布局灾后动态调度”两阶段优化策略用Matlab代码实现模型覆盖配电网潮流、储能运移、孤岛划分等关键环节适合做配电网韧性提升、应急供电、移动储能调度方向研究的人直接作为基线参考。我最早接触到这个题目是在帮某课题组补一项韧性评估的对比实验。当时他们在跑一个固定储能规划模型结论很明确储能安装位置离故障区域远一点恢复效果就大打折扣。但现实中的问题恰恰是故障位置不确定于是大家都把目光投向了移动储能。真正动手复现之后我才发现模型本身不算复杂但里面的坑不少从潮流方程怎么写、储能车移动时间怎么折算到求解器选什么每一步都直接影响结果是否合理。下面我把完整思路和实操细节拆开来讲。1. 为什么移动储能适合做配电网韧性提升从一次典型故障场景说起1.1 韧性评估与可靠性评估到底差在哪很多刚接触这个方向的同学会把韧性和可靠性混在一起但两者的时间尺度和研究对象完全不同。可靠性评估关心的是多年平均意义上的供电可用率比如ASAI、SAIDI这些指标它描述的是“常态”下系统维持供电的能力韧性则关心极端事件冲击下系统从“大面积失电”到“逐步恢复供电”这个过程到底有多快、损失有多小。研究配电网韧性通常要看三个维度扰动前的预防能力、扰动中的生存能力、扰动后的恢复能力。移动储能预布局恰好同时踩中了“预防”和“恢复”两个维度。灾前把储能车停在风险较高的分区附近相当于预防灾后利用它移动补电、支撑关键负荷相当于恢复。整个策略关注的核心指标可以统一成“失电负荷加权削减量”“关键负荷恢复率”“恢复时间”这几项。而这些指标都跟储能在哪、何时接入、充放电功率怎么定直接相关所以建模时不能把它们拆开必须放在一个统一优化框架里求解。1.2 为什么移动储能的价值在灾害场景里才真正放大固定式储能的接入位置在规划阶段就固定了容量和功率等级也绑定在节点上投资成本高利用系数却很低。平时它顶多参与削峰填谷真正遇到极端故障时只能帮到它所在馈线附近的负荷一旦故障点在上游储能装在下游也照样送不出电。移动储能则完全不同一台储能车可以按小时级的精度在配电网中迁移哪条馈线故障严重就提前开到哪里。灾害场景的不确定性意味着你无法提前预知哪个分区会被切除此时移动储能实际上是把“储能资源”从固定位置约束里解放出来变成一个可在交通网络约束下重新分配的资源。这也是很多省级公司开始配置移动储能车的现实原因——应急保障功能要远大于峰谷套利功能。对比维度固定储能移动储能空间灵活性无位置固定强可在节点间迁移故障适应能力只能就地支撑可绕开故障区域补电投资/维护成本土建成本较高车辆电池成本较高应急响应速度即时接入需考虑道路通行时间典型应用场景削峰填谷、备用灾后孤岛供电、保电任务1.3 预布局和动态调度两个阶段是如何咬合的预布局阶段发生在灾害预警发布之后、故障实际发生之前。这一阶段决策的是每台移动储能车的初始停靠节点和初始SOC荷电状态。动态调度阶段发生在故障发生后的完整应急时间窗内决策的是每个时段储能车移动到哪里、接入哪个节点、以多大功率放电或充电、哪些负荷被削减。这两个阶段不是独立求解的而是通过目标函数共享和约束条件耦合预布局选点要尽量贴近不确定故障的最坏情况动态调度则是在给定预布局方案下做运行优化。复现时如果只做第二阶段忽略第一阶段的不确定性建模整个策略就会退化成“灾后应急优化”丢失预布局本身的预防价值。两阶段模型的价值正在于它让储能车在故障尚未发生时就已经提前部署到位而不是等故障发生后再临时从远处调车。2. 两阶段优化模型全拆解目标函数与约束条件逐层解读2.1 目标函数里到底优化了什么整个模型的目标一般是最小化灾害时间窗内的综合损失常见表达为min F 预布局固定成本 负荷削减惩罚成本 储能运行成本 移动成本每一项其实都是可以独立调节的杠杆。预布局固定成本可以看成常数对优化结果影响不大真正起决定作用的是负荷削减惩罚项因为它的权重大小直接决定了系统愿意“牺牲”哪些负荷去保哪些负荷。我把核心负荷比如医院、通信基站的权重系数设成普通负荷的5倍这样优化器会自动优先给这些关键节点供电。储能运行成本包含充放电损耗通常按充电成本和放电收益的差值计算移动成本按移动次数或移动距离折算。目标函数里有两个必须注意的细节。第一负荷削减成本的时间粒度要和调度时段完全一致否则累计的经济损失会算错第二移动成本按“行动”计不能按“时段”计——一辆车在一个时段里只移动一次如果你把移动成本写成所有时段都付费结果会让优化器倾向“不移动”反而削弱移动储能的灵活性。2.2 预布局阶段的决策变量和候选站点约束预布局阶段的核心决策是每辆储能车的初始位置通常用一个二进制变量表示x(i,n) 1表示第i台移动储能车预布局在节点n。候选站点的选取一般来自两类约束接入可行性必须选在配电网可接入节点不是任意节点都能停靠道路交通可达性储能车必须在预警期内到达候选节点这与道路网络和通行速度有关。建模时几乎都会加∑x(i,n)1这样的约束保证每台车只能停一个地方。如果车辆数量有限比如系统只有4到6台移动储能车还要额外加总数量约束保证不会出现“所有节点都停了一台车”的松弛解。这里我想提醒一个经常被忽略的细节预布局阶段的SOC不一定是满的。车辆可能从不同充电站出发行驶到预布局点本身也会消耗电量。初始SOC设得不对后面动态调度的可放电量就会被高估最终结果会偏乐观。我复现时把初始SOC设为0.8并假设车辆到达预布局点后还有机会进行最后一次补电这样才比较接近工程实际。2.3 动态调度阶段潮流、储能动态和孤岛划分约束动态调度阶段比第一阶段复杂得多必须同时处理配电网潮流约束、储能SOC约束、移动时序约束和孤岛运行约束。潮流约束建议采用DistFlow模型它把每条支路上的有功、无功、电压和电流关联起来非常适合辐射状配电网。核心关系包括三块节点功率平衡方程、支路压降方程、支路电流与功率的关系。节点功率平衡讲的是“流入节点的功率加上储能放电功率等于负荷功率加流出功率”压降方程描述的是电流流过线路阻抗后电压的下降电流功率关系则把这三个物理量统一起来。储能动态约束是典型的时序耦合约束表示SOC的递推关系下一时段SOC等于上一时段SOC减去放电量除以放电效率再加上充电量乘以充电效率。这里必须小心两个点充电效率和放电效率不是同一个数有些复现代码为了省事把两个效率设成一样的值会导致整个能量平衡计算偏乐观在某个具体时刻充电功率和放电功率不能同时为正必须用二进制变量或一组互斥约束强行限制。孤岛划分约束通常用连通性约束来保证所有带电区域满足辐射状拓扑。如果在动态调度里同时开放拓扑重构会引入大量二进制变量模型变成混合整数二阶锥规划MISOCP。求解器面对这种模型会比较吃力尤其当系统规模变大时。我的处理思路是先固定初始拓扑只允许储能车接入某些预设节点用数学规划求出参考解再在参考解基础上开放拓扑重构做精细调优。3. IEEE33节点系统的建模细节与参数处理3.1 为什么选这个标准算例做韧性研究IEEE 33节点系统是配电网研究里使用频率最高的标准算例之一包含33个节点、32条支路额定电压12.66 kV系统总负荷约3.7 MW。它的拓扑属于典型的放射状结构适合做潮流计算、网络重构、分布式电源规划和各种运行优化。韧性研究选它还有一个额外好处规模不大不小。太小的系统比如5节点看不出算法效果和计算瓶颈太大的系统比如上千节点又会把大量精力耗在数据准备上。33节点刚好能让研究者把注意力集中在“策略设计”和“模型构建”上而且几乎所有公开文献里的潮流计算结果都能对得上非常适合用来验证自己代码有没有写错。3.2 网络数据与负荷数据准备复现之前建议先把IEEE 33节点数据整理成三个表节点参数表节点编号、有功负荷、无功负荷、支路参数表首末节点、电阻、电抗、额定容量、系统参数表基准电压、基准功率。代码里通常把基准容量设为10 MVA基准电压设为12.66 kV这样支路阻抗使用标幺值计算潮流约束的数值稳定性会好很多。负荷数据除了基准负荷外建议按典型日负荷曲线再缩放一遍给动态调度增加时间维度上的变化。这一步别偷懒我见过不少复现代码里负荷数据错位或者支路数据漏了一条导致结果里出现大规模的功率不守恒却没人回头检查数据最后把精力全部耗在调试求解器上。3.3 移动储能参数与故障场景怎么设定移动储能参数可以参照真实储能车的典型规格来设定容量约200~1200 kWhPCS功率约100~500 kW移动速度按道路限速折算成“节点间移动时间”。调度时段通常取1小时或30分钟。我复现时采用6台移动储能车单台容量600 kWh额定功率150 kW初始SOC设为0.8移动时间按车辆在道路网络上的最短通行时间计算。故障场景通过蒙特卡洛抽样生成随机选择2到5条支路同时故障故障发生时间固定在某个时段持续若干时段后部分线路恢复供电。场景样本量太大时求解时间会失控我的建议是先用50个场景做参数敏感性测试再决定要不要引入场景削减算法。如果你用的故障场景太单一结果只能反映某一种故障形态写在论文里会显得说服力不足。4. Matlab代码实现的关键链路从数据准备到求解器调用4.1 代码架构和文件组织代码目录可以这样组织main.m主程序入口负责加载数据、构建模型、调用求解器、绘图展示data33.mIEEE 33节点系统数据和移动储能参数定义build_model.m用YALMIP构建优化变量和约束scenario_gen.m随机生成故障场景并做场景削减run_case.m对给定场景求解两阶段优化模型plot_result.m绘制配电网拓扑和负荷恢复曲线。不建议把全部代码堆在一个脚本里。我最早复现时就是把所有约束写在一个接近2000行的文件里结果任何一个约束报错都要全局翻变量调试效率极低。拆分成独立函数之后每个函数只负责一小块逻辑检查起来方便后面做参数化扩展也更容易。对于刚接触这个方向的读者我强烈建议保持这个文件拆分习惯不要嫌麻烦。4.2 用YALMIP构建优化模型的核心写法YALMIP是Matlab环境下非常友好的优化建模工具可以避免手工梳理大规模矩阵。下面是核心建模结构的简化框架% 定义变量 % x(i,n) 表示第i台储能车预布局在节点n x binvar(nMES, nNode, full); z binvar(nMES, nT, full); % t时段是否移动 P_ch sdpvar(nMES, nT, full); % 充电功率 P_dis sdpvar(nMES, nT, full); % 放电功率 SOC sdpvar(nMES, nT1, full); % 荷电状态 % 约束组装 C []; C [C, sum(x, 2) ones(nMES, 1)]; % 每台车只能选一个预布局点 C [C, P_ch 0, P_dis 0]; C [C, P_ch Pmax, P_dis Pmax]; C [C, SOC(:,1) SOC0]; % 初始SOC for t 1:nT C [C, SOC(:, t1) SOC(:, t) - P_dis(:,t) / eta_dis eta_ch * P_ch(:,t)]; C [C, SOCmin SOC(:, t1) SOCmax]; end % 目标函数 Objective sum(sum(w .* P_loss)) sum(sum(alpha .* P_dis)) sum(sum(beta_move .* z)); % 求解 ops sdpsettings(solver, gurobi, verbose, 2, debug, 1); optimize(C, Objective, ops);我故意把潮流约束等省略了因为完整代码很长放在博客里反而淹没重点。关键想说明的是YALMIP的建模逻辑非常直观——sdpvar和binvar定义连续变量和二进制变量然后直接写约束表达式最后调用optimize函数。对于33节点这样的小系统完全不用手动构造稀疏矩阵YALMIP会自动处理维度匹配问题。4.3 求解器选择与求解时间实测模型最终是混合整数二阶锥规划SDPT3这类免费求解器只能解连续问题二进制变量一多就很难收敛。我实测下来最卡的情况是场景数达到200个以后模型规模激增单次优化耗时会从几十秒暴涨到几个小时。工业级求解器比如Gurobi或CPLEX对MISOCP支持较好加上二阶锥松弛后收敛速度明显提升。实测在33节点6台储能24个调度时段50个典型场景的配置下单次完整优化大约需要1到3分钟。如果去掉移动约束求解时间还能再快一些。如果手边暂时没有商业求解器建议至少也要用Mosek不要指望SDPT3扛住带二进制变量的混合整数二阶锥问题。5. 复现过程踩坑与解决办法5.1 潮流方程不收敛用二阶锥松弛绕开非凸原始的DistFlow方程中存在电压平方与电流平方的乘积项加上支路功率的乘积关系整个模型是非凸的直接丢给非线性规划求解器基本是死路。解决办法是把DistFlow中的非线性项做二阶锥松弛把原本严格相等的关系放宽成锥不等式使问题变为混合整数二阶锥规划。这是目前配电网优化领域最主流的做法可复现性也最强。但这里必须提醒松弛后求得的解不一定严格满足原潮流方程。要检查对偶间隙或者功率残差如果松弛不紧凑得到的“最优解”在物理上可能无法运行。我当时在代码里加了一步校验把优化出的各节点电压和节点注入功率取出来再用Matpower重新做一次潮流计算对比两组结果的偏差。偏差在容差范围内才认为这次求解有效。5.2 时间粒度与道路移动时间对不上移动储能调度里的“移动”是跨时段动作。一辆车从A点到B点可能需要40分钟而调度时段设置成30分钟就会出现非整数对齐问题。常见做法有三种一是把道路交通时间取整到调度时段的整数倍二是对移动时间向上取整保守估计三是引入更细的时间分段来近似。另一个容易被忽视的细节是储能车在移动途中不能放电所以移动状态和放电状态必须互斥。这个约束在代码里要用类似 z_move y_access 1 的表达式绑定否则模型可能出现“一边开车一边放电”的不物理解。类似的互斥约束还包括充电和放电不能同时进行我在初版代码里漏了这个约束结果目标值异常偏小排查了很久才发现是这块逻辑缺失。5.3 场景数量与求解时长的魔咒韧性优化的核心难点是不确定性。故障场景少了结果过于乐观场景多了模型规模爆炸。实战做法是先按蒙特卡洛抽样生成大量候选场景然后用聚类方法比如K-means或后向削减把场景压缩到可接受的规模。我复现时先随机生成1000个故障场景再用快速前向选择法削减到30到50个在IEEE33节点系统上效果非常明显计算时间降了一个数量级而目标函数变化很小。如果你看到某篇论文里声称“考虑10000个场景”大概率是用了某种高效场景削减或者并行计算否则纯靠优化求解器硬解不现实。自己做实验时也要遵循“先小规模验证、再大规模跑数”的节奏。6. 从复现到举一反三后续扩展方向6.1 把移动储能与移动发电机、抢修队联合调度移动储能不是唯一可移动的应急资源。把应急发电机、抢修队伍、备用变压器都纳入同一个预布局模型可以更贴近真实应急抢修过程。发电机提供持续功率但有噪声和燃料限制抢修队修复线路后能让系统更快恢复它们与移动储能的协同优化在数学上只是目标函数和约束里多了几组变量但实际收益非常明显。做扩展时建议先保持现有代码骨架不变只增加“资源种类”这一维不要重写整个模型。6.2 从确定性模型走向分布鲁棒和机会约束如果希望论文更有深度可以把故障场景下的不确定性描述从“有限场景集合”升级为“分布鲁棒”用模糊集合包围真实分布。这种做法的好处是不再依赖对故障概率的精确估计结果更保守也更符合工程实际。不过这个扩展需要处理模糊集和对偶变换数学门槛会高一个层次。复现基础版本时我的建议是先把确定性模型玩透再考虑场景法最后才碰分布鲁棒。6.3 把策略迁移到更大规模算例和动态重构场景33节点模型验证方法没问题后可以平移到IEEE 123节点等更接近实际规模的系统。平移时要注意节点数和支路数增加后二进制变量会显著膨胀MISOCP求解时间会快速上升这时可以考虑引入Benders分解把两阶段模型拆开求解。另一个很自然的扩展是让配电网拓扑在应急过程中可以动态重构把故障隔离和恢复路径联合优化这正是当前配电网恢复控制研究里的热门组合。我在实际复现中最深的体会是先把一个场景跑通再扩到几十个场景先把拓扑固定再开放重构先看目标值对不对再调权重系数。很多人一上来就追求“完美复现”和复杂模型结果卡在求解器上也卡在物理合理性上。复现的价值不只是得到一张漂亮的恢复曲线而是通过亲手搭建模型真正理解移动储能在韧性提升里的边界条件——哪些假设是合理的哪些场景下策略会失效这些问题只有动手做过才能有体感。希望这份拆解能帮你少走一些弯路把精力放到真正值得研究的问题上。