ARTICLE DETAIL

资讯详情

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

混合配电系统双目标规划与可靠性评估:Python实现全解析

混合配电系统双目标规划与可靠性评估:Python实现全解析 混合配电系统规划这个方向我前前后后做了快两年从最开始只会调包跑通到后来能自己搭模型、改算法、啃可靠性评估踩过的坑足够写出一本小册子。今天这篇就把“基于经济与可靠性双目标的混合配电系统规划及可靠性评估”这个课题从头到尾拆开揉碎讲一遍重点放在Python代码怎么落地以及背后那些参数、公式、算法为什么要这么选。这个课题解决的核心问题很朴素配电网里要装分布式电源了装在哪、装多大、什么样的网架结构才能既省钱又不停电传统规划只看经济性结果往往是系统在故障时大面积失负荷只追求可靠性投资成本又会飙到无法接受。所以需要把经济性和可靠性放在同一个优化框架里算最后输出一组权衡方案。适合谁来参考正在做配电网规划方向毕业设计的研究生、电网公司做规划设计的工程师以及想了解电力系统优化从建模到代码实现全流程的算法工程师。1. 课题背景与核心问题拆解1.1 混合配电系统到底“混合”在哪里先说清楚什么叫混合配电系统。它不是单纯在传统辐射状配电网的基础上多装几个光伏板而是一个多元素混杂的复杂系统电压等级上可能包含中压和低压拓扑上可能有交流线路和直流线路电源侧涵盖了分布式光伏、风电、储能、柴油发电机负荷侧还有电动汽车充电桩这类随机性极强的负载。我做这个课题时最直观的感受是传统配电网规划的那套“负荷预测-变电站定容-线路选型”流程面对混合系统几乎失效。原因很简单分布式电源改变了潮流方向配电网从“被动接受”变成了“主动管理”电压越限、反向过载、保护误动这些问题一个接一个冒出来。比如中午光伏大发、负荷却很低的时候馈线末端电压可能直接顶到1.07倍额定电压这在传统配电网里根本不会出现。所以在建模阶段就必须把这些“混合”特征纳入规划变量。具体来说规划变量通常有三个维度分布式电源的选址与定容在哪些节点接入、单点容量多少、总渗透率控制在什么水平储能系统的配置装在哪、功率和容量大小网架改造决策哪些线路需要扩容、哪些位置要增加联络开关实现故障转供。1.2 为什么必须做“经济可靠”双目标如果只考虑经济性目标函数就是投资成本、运行维护成本、购电成本之和最小。优化算法会倾向于把分布式电源集中在少数几个节点、容量尽量大因为单位造价随容量增大而摊薄。但这种方案在可靠性上极其脆弱集中接入意味着一旦该节点故障或上游线路跳闸一大批电源同时脱网负荷恢复能力反而变差。如果只考虑可靠性把目标定成“系统年平均停电时间最短”或者“失负荷量最小”那算法会到处装电源、处处加强网架甚至每个节点都配上储能。投资成本必然爆炸工程上根本不具备可实施性。这两个目标本质上是一对矛盾不以谁的权重更高来定胜负而是需要算出一组帕累托前沿解让决策者根据实际资金预算和供电可靠性要求来挑选最终方案。这才是双目标规划的正确打开方式。1.3 课题成果的最终形态这个课题做完后最终交付物应该是这样一套内容一个完整的混合配电系统数学模型包括目标函数、约束条件、决策变量定义一套基于Python的优化代码框架能够读入配电网参数、运行潮流计算、调用优化算法迭代求解一组非劣解集帕累托前沿每个解都对应一个具体的电源配置方案和该方案的经济性与可靠性指标可靠性评估部分的独立模块可以单独输入某个规划方案输出SAIFI、SAIDI、EENS等指标。我当年做的时候代码骨架不到两千行但调参和排查问题花的时间远远超过写代码本身。下面按我实际做项目的顺序把每个环节的关键点讲清楚。2. 整体方案设计与模型构建2.1 经济性目标函数怎么定经济性目标不能只算初始投资还要把全寿命周期内的费用折算到同一个时间尺度上。我采用的是“年费用最小化”思路把所有成本都折算成年值这样和可靠性指标里的“年停电损失”可以直接比大小、做加权。年费用总成本C_total由四部分构成投资等年值C_inv设备初始投资乘以资金回收系数CRF将一次性投资分摊到规划年限内运行维护成本C_om光伏、储能、柴发每年的运维费用通常按装机容量乘以单位运维成本计算购电费用C_pur从上级电网网购电的年费用用年购电量乘以购电电价停电损失C_outage由可靠性评估算出的年缺供电量EENS乘以单位停电损失费用如单位电量停电损失评估值。这里有一个非常容易踩的坑投资成本是“一次性巨款”停电损失是“逐年小钱”如果直接相加优化算法会倾向于完全不投资因为停电损失再大也比一次性的巨额投资小。解决办法就是引入资金回收系数做等年值折算CRF r×(1r)^n / ((1r)^n - 1)其中r是折现率n是规划年限。比如折现率取8%规划期20年CRF大约0.10185。一台1000万元的光储系统折算成年值就是101.85万元/年。这样它才能跟每年几十万到几百万的停电损失坐到同一张谈判桌上。2.2 可靠性指标怎么选、怎么算可靠性指标有几十种做规划课题不必全部算重点抓三类指标全称单位怎么理解规划用途SAIFI系统平均停电频率次/户·年每户每年平均停几次电反映停电频次SAIDI系统平均停电持续时间小时/户·年每户每年平均停多久反映停电时长EENS期望缺供电量kWh/年全系统每年少送多少电与经济性直接挂钩ENS缺供电量kWh/次单次故障损失电量故障场景分析我在代码里重点用的是EENS因为它能量化成功率缺额直接乘单位停电损失费用就能换算成停电损失方便和经济性目标合并。SAIFI和SAIDI通常作为辅助输出用来绘制最终方案的可靠性报告。计算EENS有两种主流思路解析法和模拟法。解析法基于故障枚举把每个元件的故障率、修复时间代入算出各故障场景的发生概率和失负荷量模拟法蒙特卡洛则通过大量随机抽样模拟元件故障和修复过程统计累积失负荷。对于混合配电系统我强烈建议用蒙特卡洛时序模拟因为分布式电源出力的时序波动性、储能充放电策略、以及故障后的孤岛运行状态解析法很难精确建模。2.3 双层优化框架为什么是标配混合配电系统规划的难点在于外层决策“装什么、装在哪、装多少”内层评估“这个方案在故障情况下顶不顶得住”。这两个问题耦合同步求解直接扔给一个优化器会非常难收敛。行业里普遍采用双层优化框架上层优化算法生成候选规划方案也就是一组决策变量电源位置、容量、储能配置等下层对每个候选方案做潮流分析和可靠性评估返回EENS、电压越限程度等指标上层拿到这些指标后计算目标函数再生成下一代方案。这种结构的优势在于把一个复杂问题解耦上下层各管各的。我在代码里把下层封装成一个函数输入一个规划方案输出经济性和可靠性指标。上层优化器只跟这个函数打交道完全不关心潮流怎么算、故障怎么模拟。2.4 为什么选用NSGA-II而不是普通遗传算法单目标优化其实也可以用但前面说过经济性和可靠性本质矛盾我们需要整个帕累托前沿来辅助决策所以选择多目标进化算法。我对比过几种常见算法NSGA-II基于非支配排序和拥挤度距离能同时保留解的多样性和收敛性Python里pymoo库有成熟实现最适合做这个课题粒子群PSO收敛快但多目标版本容易早熟解分布不均匀模拟退火思想简单但针对离散的选址定容问题效率偏低。NSGA-II代码看起来不复杂核心就是非支配排序、拥挤度计算、锦标赛选择、交叉变异四步。但自己手写容易在拥挤度距离上出错如果只是想快速验证模型直接用pymoo即可。如果想发高水平论文建议至少手写一遍加深理解。3. Python代码实现从建模到求解3.1 环境与依赖库准备先解决环境问题。用Anaconda创建虚拟环境Python版本用3.8到3.10都行再安装以下几个库pip install numpy pandas scipy matplotlib networkx pymoo pandapowernumpy/scipy矩阵运算、优化基础networkx配电网拓扑图处理做孤岛划分和转供分析特别方便pandapower潮流计算引擎IEEE 33节点算例直接支持省去自己写牛拉法pymoo多目标优化算法库NSGA-II直接调用。很多新手在这第一步就卡住比如numpy装不上或者版本冲突。建议先创建干净虚拟环境不要用系统全局Python避免乱七八糟的依赖污染。3.2 配电网数据建模IEEE 33节点怎么读进来做规划课题最常用的测试系统是IEEE 33节点配电网有33个节点、32条支路额定电压12.66kV总负荷3715kW2300kvar。pandapower自带这个算例也可以用networkx自己建图。我习惯先把网络结构抽象成两个数据结构节点表节点编号、有功负荷、无功负荷、电压基准值、节点类型PQ/PV/平衡支路表首端节点、末端节点、电阻、电抗、线路容量、是否带开关。有两种方式导入一是pandapower.create_ieee33()直接创建二是从标准的数据文件比如matpower格式读取解析成pandapower的bus和line表。建议新手从pandapower内置算例开始跑通了再换成自己手里的实际网架。3.3 潮流计算和约束校验怎么写方案生成后第一步要做潮流计算校验这个方案是否满足运行约束。约束条件包括节点电压幅值在0.95~1.05pu之间支路电流或视在功率不超过线路容量分布式电源出力不超过其额定容量平衡节点上级电网注入功率在允许范围内。用pandapower做潮流计算非常省事import pandapower as pp import pandapower.networks as nw net nw.create_ieee33() pp.runpp(net) violations [] for idx, row in net.res_bus.iterrows(): if not 0.95 row[vm_pu] 1.05: violations.append(f节点{idx}电压越限: {row[vm_pu]:.3f}pu)如果出现电压越限这个规划方案直接标记为不可行返回一个很大的惩罚值优化器下一代会自动避开。3.4 双层优化代码框架我把优化主循环写成下面这个逻辑这是整个代码的核心骨架from pymoo.algorithms.moo.nsga2 import NSGA2 from pymoo.core.problem import Problem from pymoo.optimize import minimize import numpy as np class DGPlanningProblem(Problem): def __init__(self): # 决策变量每个候选节点的DG容量单位kW假设有5个候选节点 n_var 5 super().__init__(n_varn_var, n_obj2, xl0, xu500, vtypefloat) def _evaluate(self, X, out, *args, **kwargs): cost_year [] eens [] for x in X: c, e evaluate_plan(x) # 内核评估函数 cost_year.append(c) eens.append(e) out[F] np.column_stack([cost_year, eens]) # 核心评估函数输入DG容量方案输出年费用和EENS def evaluate_plan(x): net build_network_with_dg(x) pp.runpp(net) if has_violation(net): return 1e10, 1e10 # 惩罚 cost calc_annual_cost(net, x) reliability monte_carlo_reliability(net, x, sim_years5) return cost, reliability algorithm NSGA2(pop_size50) res minimize(DGPlanningProblem(), algorithm, (n_gen, 100), seed42)这里面最关键的就是evaluate_plan函数它把上层优化器和下层可靠性评估连接起来。一次评估的时间直接决定整个优化能不能跑完所以内层可靠性评估的效率至关重要。3.5 帕累托前沿的提取与可视化NSGA-II跑完之后res.F是每一代所有个体的目标函数值res.X是对应的决策变量。提取最终前沿的代码如下import matplotlib.pyplot as plt from pymoo.util.nds.non_dominated_sorting import NonDominatedSorting F res.F pf_mask NonDominatedSorting().do(F, only_non_dominated_frontTrue) pf_F F[pf_mask[0]] pf_X res.X[pf_mask[0]] plt.scatter(F[:, 0], F[:, 1], clightgray, s20, label所有解) plt.scatter(pf_F[:, 0], pf_F[:, 1], ccrimson, s30, label帕累托前沿) plt.xlabel(年综合费用万元) plt.ylabel(EENSMWh/年) plt.legend() plt.grid(alpha0.3) plt.show()注意pymoo的NonDominatedSorting输出的索引是二维的取[0]就是第一前沿。画出图后你会看到典型的L形曲线拐点附近的方案性价比最高具体怎么选我后面专门讲。4. 可靠性评估深度实操4.1 蒙特卡洛时序模拟的原理和步骤蒙特卡洛时序模拟的基本思想是把配电网一年8760小时的运行状态当成一条时序轨迹每个元件的故障和修复过程用随机抽样来模拟跑很多年之后统计平均失负荷。具体步骤我拆成五步第一步初始化系统状态。设定仿真年数比如5年甚至10年设置随机数种子保证结果可复现。第二步生成元件状态时序。每个元件线路、变压器、开关都有年故障率λ次/年和平均修复时间MTTR小时。用“序贯抽样”法先抽样该元件下一次故障的时间再抽样故障持续时长修复时间交替推进形成完整的故障-修复时间轴。第三步生成负荷和DG出力时序。负荷用年8760小时曲线光伏出力用典型日曲线乘以随机波动系数风速用Weibull分布抽样再换算成风电出力。第四步故障事件处理。当某个元件故障判断系统是否失去部分负荷。这时要看配电网络有没有联络开关、能不能转供、DG能不能划分成孤岛继续供电。用networkx把断开支路移除后检查连通性再对孤岛做潮流计算。第五步统计累积失负荷计算各项可靠性指标。把每次故障事件中损失的负荷量和停电时长累加起来除以仿真年数得到年均结果。4.2 孤岛供电判定与大停电恢复逻辑这部分是可靠性评估里最容易出错的地方。故障后配电网可能被撕裂成几个子网络其中包含分布式电源的子网络如果在满足功率平衡的情况下可以脱离主网形成孤岛继续供电。孤岛判定的核心逻辑是上游开关断开后用graph搜索找出所有连通分量对每个含DG的连通分量计算总DG出力和总负荷如果DG出力大于等于负荷则无需甩负荷孤岛成立如果DG出力小于负荷则按负荷优先级切除部分负荷切除量计入ENS。实际做的时候我建议用networkx的connected_components函数速度非常快。另外要特别注意孤岛运行必须具备“独立供电能力”DG的容量太小或者没有储能参与调频孤岛并不稳定。我的简化处理是设置一个负荷/DG容量比阈值超过就认为孤岛不可行。4.3 收敛判据为什么不能拍脑袋定仿真年数蒙特卡洛模拟的核心收敛判据是方差系数β定义为指标估计值的标准差除以均值。通常β小于5%就认为结果稳定可以停止仿真。我在代码里用EENS做收敛监控def monte_carlo_convergence(eens_list, threshold0.05): e np.array(eens_list) mean_e e.mean() std_e e.std() / np.sqrt(len(e)) beta std_e / mean_e if mean_e 1e-6 else 0 return beta, beta threshold有人为了省时间不管收敛没收敛直接固定跑2年就出结果这种做法是不可取的。EENS波动非常大特别是故障率低的元件如果抽样不到结果会严重偏小。稳妥的做法是设定最大仿真年限比如20年当方差系数达标就提前终止。4.4 解析法故障枚举作为验证手段蒙特卡洛结果虽然直观但总让人担心是不是抽样偏差。我每次跑完模拟会用状态枚举法独立验算一遍关键指标。对配电系统故障枚举法就是遍历所有元件的故障场景通常只考虑N-1也就是单个元件故障对每个场景计算失负荷量和概率最后累加EENS Σ_i p_i × ENS_i其中p_i是第i个故障场景的年发生概率ENS_i是该场景下的失负荷电量。对于带DG的配电系统每个故障场景还要重新做潮流和孤岛判定。这个方法对系统规模较小、元件数不多的场景非常精确而且速度比蒙特卡洛快。两套结果对得上我的模拟代码才敢说写对了。5. 常见问题与避坑实战5.1 目标函数量纲不一致这是我第一次跑代码时最崩溃的问题。经济性成本动辄上百万EENS正常在几百MWh以下两个目标放在NSGA-II里拥挤度距离计算会完全被大数值的那个目标主导帕累托前沿直接退化成一个点。解决办法有两个一是把EENS乘以单位停电损失费用转成停电损失金额这样两个目标都是“钱”二是做归一化处理。我实际操作中采用的是第一种把可靠性目标定成“年停电损失费用”这样最终画图时两个维度单位一致决策者也更容易理解。5.2 潮流计算不收敛pandapower偶尔会报潮流不收敛通常原因有三个DG节点给定有功出力过大系统无功不足导致电压崩溃。解决方法是给DG添加无功出力范围或设置PV节点让潮流计算自动调节初始电压猜测太差。pandapower默认平启动对弱网络可能失败可以设置initdc先用直流潮流得到初值阻抗数据和负荷数据不匹配。IEEE 33节点例模型标幺值很容易配错建议逐个核对base_kv和sn_mva。我还会加一层防呆潮流不收敛时直接返回惩罚值优化器会把这个方案过滤掉而不会让程序崩溃中断。5.3 可靠性评估结果忽高忽低同一个方案重复跑两次蒙特卡洛EENS差30%以上这种问题几乎都是仿真年限不够导致的。我建议直接在代码里加收敛判定不要手工试。另外就是随机数种子问题。我在代码开头的第一步就固定np.random.seed(42)这样所有结果可以复现。同一台电脑、同一个种子每次跑出来的结果完全一致这对写论文特别重要。还有一个隐蔽问题负荷时序和DG出力时序不对齐。有人把光伏出力峰值放在夏季负荷峰值却放在冬季这种风马牛不相及的组合会让评估结果完全失真。做时序模拟之前一定要画出8760小时负荷曲线和光伏出力曲线人工确认峰值时段基本重合。5.4 常见问题速查表问题现象可能原因解决方法优化结果全部是零投资停电损失费用远小于投资等年值调整单位停电损失费用或折现率帕累托前沿只有一两个点目标量纲差距过大导致支配关系失衡统一两个目标的量纲潮流计算报错DG出力超出系统承载力限制决策变量上限或增加储能协调可靠性评估耗时过长每个方案都跑20年蒙特卡洛加收敛判定或者用故障枚举近似DG容量明明很大但EENS居高不下孤岛判定逻辑过于保守检查算法把孤岛给“一刀切”掉了没有多组重复实验Pareto前沿差异大随机种子未固定跑之前设置np.random.seed5.5 性能优化别让可靠性评估变成性能瓶颈整个项目最耗时的地方就是蒙特卡洛可靠性评估。一个IEEE 33节点系统单个方案跑5年时序模拟如果不优化大概需要十几秒。NSGA-II跑100代、50个种群就是100×50个方案一个方案十几秒算下来要好几天这肯定不等。我的优化策略从低级到高级逐个套用第一向量化计算。所有负荷、故障时间轴都用numpy矩阵运算避免for循环。第二故障场景筛选。不是所有元件故障都会导致失负荷。先做一个预筛选只对断开后拓扑会分裂或潮流会越限的线路做详细评估。第三并行化。pymoo支持并行评估设置worker4将四个子进程同时跑直接提速四倍。第四代理模型。如果还是太慢可以先用少量仿真年数粗评估然后用Kriging或RBF代理模型拟合目标函数最后选出的最优解再用全精度验证。这个方案精度会损失一些但速度能再快一个数量级。6. 从课题到工程应用的几点认知6.1 靠不靠谱先拿着样本方案检验一遍代码跑完之后不要急着写论文。我习惯的做法是从帕累托前沿里挑三个典型方案分别是“最低投资方案”“拐点方案”“最高可靠性方案”然后对这三个方案分别做一次更长时间的蒙特卡洛模拟用10000次仿真看可靠性指标。如果第二次验证结果和优化器里返回的指标偏差超过10%那说明内层评估精度不足需要回炉。读取测试系统数据时也要留意实际系统的接线和运行方式。IEEE 33节点模型是辐射状网络线路参数简单真实配电网往往是多联络、含电缆和架空线混合、还有各种不可控开关。这些差异会直接影响差距评估的准确性一般我会在论文里注明“该方法在简化算例上验证应用于实际系统时需补充精细化数据”。6.2 代码还能往哪些方向扩展这个课题的代码框架具有很强的扩展性我后来在它基础上做了三个方向的改动考虑风光荷不确定性的鲁棒规划把确定性模型换成机会约束规划用场景法处理不确定因素储能容量协同优化将储能SOC状态变量引入可靠性评估让孤岛恢复阶段更有韧性极端天气下的韧性评估把故障概率从固定值改成随台风强度变化的时间分布评估系统在极端事件下的恢复能力。这些扩展基本都是把“评估模块”换掉或者加约束优化主框架完全不动。所以最开始写代码的时候把接口设计清晰很重要模块之间耦合越少后面扩展越舒服。6.3 我在实际项目里的几点体会最后说点实在的。第一做这类课题设计良好的数据接口比算法本身更重要。我一开始花了很多时间手写潮流后来换了pandapower反而把精力放在了可靠性模块上进度快得多。第二蒙特卡洛模拟一定要做收敛性判断和结果验证不然写论文时审稿人一句“仿真年数为什么是5年”就足够让你无地自容。第三多目标规划做完不是终点把帕累托前沿变成通俗易懂的方案对比表才是交付的最后一公里。如果项目是配合工程落地的我更愿意用“不同方案下投资回收期、停电时间、年损失”这种几句话说清楚而不是扔一张帕累托图就完事。
返回列表