首页 / 资讯中心 / 文章详情

Python双目标优化:混合配电系统经济性与可靠性规划

Python双目标优化:混合配电系统经济性与可靠性规划 ★ FEATURED ARTICLE
开头在配电网规划这个方向折腾了几年一个特别明显的趋势是现在的“配电系统”早就不是传统意义上那种单电源、辐射状、只负责传电的末端网络了。大量分布式光伏、风电、储能、EV充电桩甚至柴油应急电源接入后系统变成了一种“混合电源多形态负荷”的复杂网络。规划这类系统时如果只盯着经济性很可能算出一个投资最低的方案但一到极端天气或者设备故障场景可靠性惨不忍睹反过来如果只追求高可靠性成本又会成倍往上翻项目根本批不下来。所以这几年圈子里最常用的做法就是做基于经济与可靠性双目标的混合配电系统规划。两个目标一起优化通过Python可以完整落地。Python生态里的pandapower负责潮流计算、numpy/pandas处理数据、pymoo跑多目标进化算法基本能把“规划可靠性评估双目标优化”整条链路打通。这篇文章我会从一个可复现的角度拆开讲混合配电系统规划到底在优化什么、可靠性怎么嵌入规划模型、Python代码结构怎么搭以及我在实际跑数时踩过的坑。适合正在做配电网规划方向的学生、刚接触综合能源系统规划的工程师以及想用Python替代传统商业仿真软件做研究的朋友。1. 问题拆解混合配电系统规划到底在优化什么1.1 什么是混合配电系统先明确边界。混合配电系统的“混合”通常指两个层面一是电源侧的混合。系统里不只有上级变电站提供的传统电力还有分布式光伏、分布式风电、燃气轮机、储能装置等。不同类型电源的出力特性差异很大光伏中午大发、晚上归零风机随风速波动储能既能充电又能放电相当于多了个“时间搬移”的工具。规划时要在什么节点接入什么类型的电源、接入多大容量、储能配在哪这些都是决策变量。二是网络结构层面的混合。传统配电网多为单电源辐射状一根线路从头串到尾某个开关跳闸下游全黑。现在规划常常要引入“多分段多联络”的结构甚至形成弱环网让故障时部分负荷能从其他馈线转供。不同拓扑下同样一套设备的供电可靠性差异非常大。把这两层叠加起来规划问题的复杂程度就上来了既要做电源选址定容又要做网架结构优化还要考虑系统运行方式的约束。这种多变量耦合的问题靠手工试算是完全不现实的必须靠建模加算法求解。1.2 为什么是“双目标”而不是直接加一个权重这是很多初学者最困惑的地方为什么不能把可靠性折算成钱和目标成本合并成一个单目标理论上可以工程上也确实有人这么干——把用户停电损失定义为“缺供电量×单位停电损失费用”然后加到总成本里。但这么做有很实际的问题单位停电损失费用很难定准。居民、商业、工业用户的停电损失差异可能相差一个数量级而且不同地区、不同场景取值争议很大。把目标合并成单目标后其实是在人为指定两个目标之间的“汇率”但规划者往往不确定这个汇率应该定多少。单目标优化只能给一个“最优解”但实际项目评审中决策者更需要的是一组“方案套餐”哪个投资最低但可靠性一般、哪个可靠性高但贵多少、有没有中间选项。双目标优化的输出是一条Pareto前沿。前沿上的每个方案都不被另一个方案完全支配——想要更好的可靠性就必须付出更高的成本想压缩成本就得牺牲一部分可靠性。最终选谁取决于决策者的偏好和项目预算。这个框架比强行合并成单目标要合理得多也是论文和实际工程中都比较认可的思路。1.3 规划中的决策变量与约束条件在模型层面规划问题需要明确决策变量和约束。我整理一个自己常用的模型框架模块决策变量说明网架规划线路新建/升级0-1变量、联络开关状态决定系统拓扑结构分布式电源各节点光伏/风机投建容量连续或离散影响潮流分布与可靠性储能系统储能额定功率与容量、安装节点削峰填谷和应急供电作用明显无功补偿电容器或SVG配置容量约束电压质量影响潮流收敛性对应的约束条件包括潮流方程约束节点功率平衡节点电压上下限比如0.93 p.u.到1.07 p.u.支路容量约束线路不能过载储能充放电功率与SOC约束分布式电源渗透率约束避免反向潮流过大可靠性最低限值如SAIDI不能超过某个阈值这些约束在优化算法里有的可以通过潮流计算直接检验比如电压和过载有的则需要单独建模比如储能SOC的动态变化。Python实现的时候比较简便的做法是把不满足约束的个体直接通过罚函数淘汰或者用修复策略强制拉回可行域。2. 可靠性评估核心指标与嵌入规划的方法2.1 可靠性指标选哪些配电系统可靠性评估的经典指标主要有三个SAIFI系统平均停电频率指标单位用户年停电次数的平均值反映“多久停一次”。SAIDI系统平均停电持续时间指标单位用户年停电小时数的平均值反映“每次停电要停多久”。ENS / EENS失电量 / 期望失电量系统因故障而损失的电量反映停电对供电量的实际影响。在双目标规划里我个人更倾向直接用EENS作为可靠性目标而不是SAIFI或SAIDI。原因很简单EENS和“停电损失”挂钩最紧密而且和成本目标不是同一个量纲做Pareto前沿更直观。SAIFI、SAIDI则可以作为约束或辅助校验指标。比如某个候选方案虽然EENS很低但如果单个停电事件时间过长可能违反用户对最长停电时长的要求这种情况就需要用SAIDI卡一下。2.2 可靠性评估的主流方法配电网可靠性评估的方法可以分三类故障模式与后果分析法FMEA。这是最经典也是工程上最常用的方法。思路是枚举系统中每一个元件线路、变压器、开关的故障分析它对下游负荷点造成的影响然后累加所有故障事件的影响算出系统级指标。优点是原理透明、速度极快适合规划阶段的成百上千次方案评估缺点是需要人工/程序生成故障事件表对含分布式电源和储能的系统还要额外分析孤岛运行状态逻辑会复杂不少。最小割集法。本质上是把FMEA自动化找出系统失效的最小割集组合再通过故障概率计算系统的不可用率。适合拓扑比较复杂的网状网络但建模门槛高代码量也大。序贯蒙特卡洛模拟。按时间序列模拟元件运行和故障状态比如模拟8760小时或10000年的运行过程统计停电事件。好处是能精细刻画储能充放电策略、光伏随机出力、负荷时序变化对可靠性的影响坏处是计算量非常大。内层跑潮流、外层跑模拟容易让整个规划算法慢到无法接受。在双目标规划的大框架里我的建议是外层优化迭代用FMEA或解析法对最终选出的几个Pareto方案再做一次序贯蒙特卡洛精细校验。这种“粗筛精验”的组合速度和精度都能兼顾。2.3 怎样把可靠性评估嵌入规划循环这里有一个新手特别容易忽略的点可靠性评估不能放在规划优化结束后再补一次必须嵌入规划循环内部。因为网架结构、电源位置、储能容量都会直接决定故障后的转供能力和孤岛运行范围如果最后才算可靠性优化过程就完全没有“可靠性视角”算出来的最优方案很可能在可靠性维度上非常差。我实际采用的流程是种群个体对应一组决策变量线路开关状态、DG容量、储能配置。根据个体方案修改电网模型调用潮流计算。如果潮流收敛且电压/容量约束通过再执行可靠性评估。输出成本目标和EENS目标返回给优化算法。这样整个优化过程里每个个体都经过“潮流可靠性”两层校验Pareto前沿上的每个解都是通过潮流可行的。代价是单次评估时间增加所以外层算法要选得对、并行化要做得好。3. Python实现从数学模型到可运行代码3.1 为什么要选Python生态做配电网规划传统工具是商业软件如DIgSILENT、CYME或者自己写MATLAB程序。但Python这几年在科研和工程中的应用越来越广主要原因有三一是pandapower这个库实在太方便了。它建立在pandapower内部的电力系统元件模型之上可以很方便地搭建配电网拓扑、修改元件参数、跑潮流计算不需要自己写导纳矩阵和牛顿-拉夫逊迭代。而且它对IEEE标准算例系统有内置支持比如IEEE 33节点、123节点等省掉了手工输入数据的大麻烦。二是多目标优化算法库成熟。pymoo实现了NSGA-II、NSGA-III等主流多目标进化算法接口规范自定义问题和遗传算子都很灵活。如果自己从头写NSGA-II至少几百行还容易出bug。三是数据处理和可视化的配套太全。pandas整理结果、matplotlib画Pareto前沿、numpy做矩阵运算几乎不需要额外开发工具。环境配置其实非常简单三行命令的事pip install numpy pandas matplotlib pip install pandapower pip install pymoo建议用Python 3.8以上的版本我用的3.9和3.11都能稳定跑通。如果你之前没装过Python记得安装时勾选“Add Python to PATH”不然后面命令行无法直接识别python这是个很低级但频率极高的坑。3.2 双目标优化算法选型在Python里实现双目标规划最常用的算法是NSGA-II。它的核心思路是通过非支配排序把种群分成不同Pareto层级同时用拥挤度距离保持解的多样性再配合选择、交叉、变异生成新一代种群。NSGA-II能够一次运行输出尽可能多的Pareto前沿点很适合分析“成本-可靠性”的权衡关系。还有一个替代方案是epsilon约束法先单独优化经济性目标然后把可靠性作为约束逐步收紧跑多个单目标问题后合成Pareto前沿。这个方法在解空间较小或约束复杂时更稳定但需要反复求解计算量也很大。在pymoo中我一般用NSGA-II配合SBX交叉和多项式变异。种群大小可以设置在50到100进化代数200到300代。下面是一个自定义问题的骨架from pymoo.core.problem import Problem import numpy as np import pandapower as pp import pandapower.networks as pn class DistributionPlanningProblem(Problem): def __init__(self): # 决策变量说明 # x[0]: 联络开关状态0-1整数 # x[1:3]: 光伏接入容量连续 # x[3:5]: 储能功率连续 # 实际项目中按自己的决策变量维度改这里 super().__init__( n_var5, n_obj2, xlnp.array([0, 0, 0, 0, 0]), xunp.array([1, 2, 2, 1, 1]), ) def _evaluate(self, X, out): costs np.zeros(X.shape[0]) eens np.zeros(X.shape[0]) for i, x in enumerate(X): costs[i], eens[i] evaluate_solution(x) out[F] np.column_stack([costs, eens])3.3 目标函数怎么算成本与EENS经济性目标的计算公式通常是C_total C_inv C_om C_loss C_purchase其中C_inv是设备投资年化费用线路建设、DG设备、储能设备等按使用寿命折算到每年C_om是运行维护费用C_loss是网损折价C_purchase是向上级电网购电的费用。这些每一项在代码里都比较直接——单位造价乘以容量再加固废网损由潮流结果乘以电价得出。可靠性目标的计算逻辑是在某个故障场景下识别停电负荷点集合统计停电影响户数和失电量。对于每个故障事件k如果它导致负荷点j停电且停电持续时间为t_k那么EENS的累加式是EENS Σ_k λ_k × P_j × t_k其中λ_k是元件k的故障率次/年P_j是该负荷点的平均负荷功率。这个公式本质上就是FMEA的数学表达代码实现起来很省力。3.4 可靠性评估代码的实用写法我用pandapower实现FMEA可靠性评估核心代码如下def evaluate_reliability(net, fault_rate_dict, load_p_mw_dict): # 遍历所有可选故障元件 total_eens 0.0 total_saidi 0.0 total_users 0.0 for element, rate in fault_rate_dict.items(): # 断开故障元件 pp.run_temporary_disable(net, element) # 潮流计算识别失电节点 try: pp.runpp(net) # 找出电压越限的负荷节点 lost_loads identify_lost_loads(net) except: # 潮流不收敛通常意味着大面积失电 lost_loads all_load_buses(net) # 累加EENS for bus in lost_loads: total_eens rate * load_p_mw_dict[bus] * outage_duration_h # 恢复网络 pp.run_temporary_restore(net) return total_eens, total_saidi有几处细节必须提示pandapower里run_temporary_disable/run_temporary_restore是成套使用的别只disable忘了restore否则网络状态污染后面所有元件评估都会错。潮流不收敛很多时候不是网络真“死”了而是初值不好或并联电容器控制策略导致迭代发散。要区分“潮流计算失败”和“系统失电”两种情况否则EENS会被高估。负荷点的平均功率建议用年负荷曲线折算而不是用峰值负荷。用峰值算出来的EENS会严重偏高这个误差在目标函数里会被放大。4. 算例演示用IEEE 33节点系统跑双目标规划4.1 算例系统构建这里我以IEEE 33节点系统为例它是配电网规划领域最常见的标准算例33个节点、32条支路、1个根节点基准电压12.66 kV总负荷约3.7 MW。pandapower里有现成数据net pn.create_ieee33_bus()在基础网络上我加了几处规划候选位置节点8、节点24、节点30可接入分布式光伏单点容量上限1 MW。节点14和节点29可配置储能单点功率上限0.5 MW、容量上限2 MWh。增加两个联络线候选8-21、9-15用于故障转供。这样就构成了一个带有DG、储能、可调节网架的小型混合配电系统。决策变量一共是2个联络开关0-1变量 3个光伏容量 2个储能功率 7维向量。4.2 优化参数设置与运行结果我用pymoo的NSGA-II做双目标优化种群大小80迭代300代目标函数就是总成本万元/年和EENSMWh/年。跑完后把Pareto前沿画出来from pymoo.algorithms.moo.nsga2 import NSGA2 from pymoo.operators.crossover.sbx import SBX from pymoo.operators.mutation.pm import PM from pymoo.optimize import minimize algorithm NSGA2( pop_size80, crossoverSBX(eta15, prob0.9), mutationPM(eta20), ) res minimize(problem, algorithm, (n_gen, 300), seed1, verboseTrue)结果典型的形态是一条“L型”曲线左边是最小成本方案EENS较高随着成本增加EENS快速下降但在曲线的右下段再增加很多投资可靠性提升已经很小。这就是经济学上说的“边际递减效应”在配电网规划里表现得极其明显。对项目实际决策来说这条曲线最有用的信息是拐点拐点之前的投入能“花小钱办大事”拐点之后继续砸钱换可靠性就不划算了。如果有预算上限也可以直接把预算约束画在图上找交点处的方案。4.3 从Pareto前沿到底选哪个方案很多同学跑完双目标优化拿到一整个前沿就不知道怎么汇报了。这里分享一个很实用的偏好选点法——TOPSIS对Pareto前沿上的所有解按成本和EENS分别做归一化。定义理想点两个目标都最小和负理想点两个目标都最大。计算每个解到理想点和负理想点的欧氏距离取贴近度最大的解作为推荐方案。还有一种更简单的“拐点法”在Pareto前沿上取每个点计算它到两个端点连线的距离距离最大的那个点通常就是性价比最高的折衷解。我自己在论文和项目报告中一般会把“纯经济最优”“纯可靠最优”和“折衷推荐”三个方案并列展示分别列出投资、年运行成本、EENS、SAIDI这几个核心指标。这样评审人一眼就能看懂权衡关系不会觉得你在给他一个“黑箱答案”。5. 常见问题与排查技巧实录5.1 潮流总是不收敛怎么排查这是最大概率会遇到的问题而且原因多种多样。第一步看元件参数。pandapower中等值线路的r_ohm_per_km、x_ohm_per_km、c_nf_per_km这几个参数是否合理。参数填错比如数量级搞混会导致整个网络阻抗异常。第二步看电压初值。含大量DG接入的弱网络用牛顿-拉夫逊很容易因为初值不佳发散。这时候可以先用pp.runpp(net, algorithmiwamoto_nr)试试或者在pandapower里把电压初值设为0.98~1.02 p.u.再算。第三步如果加了储能的充放电控制注意储能元件在潮流模型里是PQ节点还是PV节点。储能按恒功率充电/放电时是PQ节点如果按电压控制模式则要考虑无功支撑能力初值不对也容易发散。一个排查技巧把DG容量逐步从0加到目标值每一步都跑一次潮流。哪个节点加到一定数值发散问题就出在哪。5.2 可靠性评估慢得让人崩溃怎么办如果用的是序贯蒙特卡洛在规划算法里循环几千次时间开销几乎是灾难性的。我的解决思路是分层评估在优化循环内部用FMEA解析法计算速度毫秒级精度对方案筛选足够对最终选出的3到5个Pareto方案再做一次序贯蒙特卡洛精细验证模拟年限取2000到5000年算出更精确的SAIFI、SAIDI和EENS。另一个加速办法是故障事件预生成。对同一个网络结构故障元件集合是固定的只把负荷水平和DG出力作为变量。可以提前枚举好所有故障场景在优化循环内只查表累加不重复跑潮流。我实测下来这个优化能提速20倍以上。5.3 NSGA-II跑出来的Pareto前沿质量差现象一般是两类前沿点太少或者前沿点分布不均匀。前沿点太少大概率是种群数量不够。建议按决策变量维度的5到10倍设置种群大小。7维决策变量pop_size至少70我通常用100。分布不均匀常见原因是交叉变异参数没调好。SBX的eta参数控制子代离父代的远近eta越小子代分布越散越大越聚集。如果发现前沿只集中在一个小块试着把eta从15调小到10如果太散导致收敛差就调大到20。多项式变异的eta也是同理。还有一个容易被忽略的问题如果两个目标函数的数值量纲差距巨大比如成本是百万级别EENS只有几十需要对目标做归一化处理。pymoo里可以通过ref_point或标准化函数处理否则NSGA-II的选择压力会一边倒。5.4 Python环境配置相关的避坑这部分给刚入门的读者。网上热搜里关于Python安装、numpy库安装的提问特别多实际就三件事第一Python环境变量。Windows安装时勾选“Add Python to PATH”否则python命令找不到。如果已经装完发现不能用手动把C:\Users\你的用户名\AppData\Local\Programs\Python\Python39\和同目录的Scripts\加进系统PATH重新打开终端就好。第二包安装失败。pip install pandapower如果速度极慢或报错换成国内镜像源pip install pandapower -i https://pypi.tuna.tsinghua.edu.cn/simple第三numpy版本冲突。pandapower对numpy的版本有一定要求如果pip install把numpy升到过新版本导致pandapower报错可以用pip install numpy2.0回退版本。我自己的环境是numpy 1.26.4非常稳。结尾最后分享一点个人体会。双目标规划这种工作代码本身不是最难的难的是把电网物理逻辑“翻译”成优化模型时别偷懒。比如可靠性评估里每个故障场景是否真的识别对了停电范围储能孤岛运行策略和故障时序是否一致这些细节如果没捋清楚不管算法多高级出来的结果都是错的。我一开始跑这个课题的时候吃过一次大亏FMEA评估里把“故障元件上游”和“下游”的失电范围搞反了导致EENS被严重高估整个Pareto前沿直接往错误方向偏移。后来耐着性子把所有故障场景手算核对了一遍才发现是转供逻辑写反了。所以给想做类似项目的朋友一个建议拿到任何一个新算例系统先用一个小网络比如3节点或5节点手算验证你的代码结果确认无误后再上标准33节点、123节点系统。这个“先小后大”的习惯能帮你省下大量调试时间。多目标规划是个越做越有意思的领域把成本和可靠的权衡讲清楚无论在学术还是工程上都是特别值钱的能力。
阅读完成 · 觉得有帮助?
咨询建站