ARTICLE DETAIL

资讯详情

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

基于Python的混合配电系统多目标规划与NSGA-II求解方法

基于Python的混合配电系统多目标规划与NSGA-II求解方法 1. 项目整体设计与模型构建混合配电系统规划说白了就是在一个既要交流负荷、又要带直流负荷的配电网里回答三个问题在哪里装设备、装多大容量、怎么接线最划算。这三个问题背后其实牵着一个更深的需求——电网公司不能只顾省钱还要保证不停电这两个目标放在一起就变成了非线性的多目标优化问题。这个项目用Python把整套流程跑通从网络结构、设备模型、可靠性指标到优化算法全部编程实现我拿到这个课题第一反应就是真正的难点不在某个单点算法上而是把这几个模块串起来时的接口设计和计算效率。1.1 混合配电系统的“混合”到底指什么传统配电网是纯交流的从10kV母线下来一路变压器到380V所有负荷都挂在交流支路上。但随着光伏直流发电、储能电池、电动车充电桩这些直流设备大规模接入交流—直流—交流来回变换导致效率下降于是出现了交直流混合配电系统——既保留交流馈线又新增直流母线换流器VSC和DC/DC变换器作为接口设备连接两个区域。这个项目里的“混合配电系统规划”规划对象就是这些接口设备的选址和定容以及网架拓扑的调整方案。规划变量包括换流器装在哪条馈线上、容量多大直流母线覆盖哪些负荷储能和光伏的接入位置是否需要新增联络线。约束条件则包含节点电压偏差、线路载流量、变压器容量、可靠性指标上限等。我在实际建模中认为最需要想清楚的是设备替换成本。比如一台VSC换流器它的成本不只是设备购置费还包括安装调试、占地、维护、损耗以及寿命周期内的故障维修费用。不考虑这些规划结果在工程上基本没法落地。1.2 经济性目标函数从账单角度拆解规划成本经济性目标函数通常写成年度综合费用最小化包含四大部分。第一部分是投资等年值。设备投资不是一次性投入当年算完而是要折算到每年。公式是[ C_{inv} \sum_{i \in \Omega_{VSC}} c_{VSC} \cdot S_{VSC,i} \cdot \frac{r(1r)^n}{(1r)^n - 1} ]其中 ( r ) 是折现率一般取0.08( n ) 是设备寿命VSC取20年储能取10年。这个等年值系数就是把一次性投资变成每年的还款额类似房贷等额本息的概念。第二部分是运行维护成本通常按投资额的一定比例估算取2%~3%。第三部分是网损成本这是最考验计算精度的部分需要先做潮流计算求出各支路损耗再乘以电价和年利用小时数。第四部分是购电成本从上级电网买电的费用。很多初学的人会把投资成本和网损成本直接相加忽略了等年值折现这样会导致规划结果偏向选择大容量设备因为大设备能显著降低网损但一次性投资被低估了。这个细节我建议在建模时严查否则结果偏差很大。1.3 可靠性目标用停电损失和缺供电量说话可靠性目标我推荐用缺供电量期望值EENSExpected Energy Not Supplied来量化单位是MWh/年。它衡量的是系统在一年内因为故障、检修、容量不足等原因导致用户少用的电量。EENS越小可靠性越高。计算EENS的工程思路是模拟系统中各个设备的状态正常运行或故障停运对每个状态做潮流计算找出不能正常供电的负荷量乘以其持续时间和概率累加得到期望值。除了EENS还常用的指标包括系统平均停电频率指标SAIFI和系统平均停电持续时间指标SAIDI这两个指标在可靠性评估领域用得非常多但在规划优化里作为约束条件更合适目标函数一般还是用EENS或者停电损失费用。做双目标优化的关键点在于经济性和可靠性是互相冲突的。要提升可靠性就得增加设备冗余、加大导线截面、多装联络开关投资成本上升反过来只省钱可靠性指标就会恶化。于是问题变成了在Pareto前沿上寻找一组非劣解而不是找一个唯一最优解这正是为什么选择多目标进化算法来处理。2. 求解框架为什么用NSGA-II而不是简单加权面对双目标问题新手最容易想到的就是加权求和把两个目标变成单目标。但这个方法有一个致命问题权重系数非常难定而且不同量纲之间需要归一化归一化因子选不好优化方向就会被某个目标主导。实际跑下来你会发现权重法一次只能得到一个解要得到Pareto前沿需要反复调整权重跑几十次效率极低。2.1 三种多目标处理方式的对比权重法、约束法和Pareto支配法是目前最常见的三种思路。权重法实现最简单但结果对权重极其敏感而且无法处理非凸的Pareto前沿。约束法是把一个目标转为约束比如设定EENS不超过某个值然后优化经济性这样也能得到一系列解但需要合理设置约束边界边界的取值会影响解的分布。Pareto支配法则是通过“支配”关系来比较解的好坏一个解A支配解B当且仅当A在所有目标上都不比B差且至少在一个目标上严格优于B。所有不被其他解支配的解构成第一层Pareto前沿。这种方法不需要人为定权重一次运行能生成整个前沿面所以我选了NSGA-II来实现。2.2 NSGA-II的三大核心机制NSGA-II是带精英策略的非支配排序遗传算法它的成功靠三个机制。第一是快速非支配排序。对种群中的每个个体计算它被多少个其他个体支配n_p以及它支配哪些个体S_p然后分层归类。时间复杂度是 ( O(MN^2) )M是目标数量N是种群规模。第二是拥挤度距离。同一Pareto层内的解之间需要保持多样性否则所有解都挤在一个区域。拥挤度距离的计算方法是对每个目标排序计算相邻两个解之间的目标差值归一化后累加。距离越大代表这个解周围越空旷越值得保留。第三是精英保留策略。将父代种群和子代种群合并从中选出前N个最优个体作为下一代。这样可以防止优秀解在交叉变异过程中丢失。我用Python实现时数据结构上用了dataclass来定义个体每个个体包含决策变量数组、两个目标函数值、支配层级和拥挤度距离。代码结构清晰后面扩展第三目标也非常方便。2.3 编码方案与约束处理技巧决策变量怎么编码直接决定算法的搜索效率。我把规划变量分成两类离散型和连续型。换流器安装位置用整数编码索引对应节点编号换流器容量用连续编码范围根据负荷总量设定储能容量也是连续变量。约束处理上我采用了罚函数法加可行性优先策略。具体做法是电压越限和潮流不收敛的解赋予极大的目标值使其在非支配排序中必然处于较差层级。但要注意罚函数值不能设成无穷大否则会影响拥挤度计算时的归一化。一个非常实用的经验是将决策变量的取值范围在种群初始化时对齐物理约束。比如换流器容量范围根据所在馈线的峰值负荷来动态调整而不是整个系统统一范围。这样能大幅减少无效搜索过程收敛速度明显提升。3. 可靠性评估的工程化实现3.1 序贯蒙特卡洛法模拟一整年的系统运行可靠性评估精度直接决定优化结果的可靠性而仿真方法的选取影响计算时间这中间需要平衡。我采用的是序贯蒙特卡洛法Sequential Monte Carlo Simulation它的核心思想是对每个可修复元件建立“正常运行—故障停运—修复—再运行”的两状态模型用随机抽样确定每个状态持续时间然后按时间顺序推进模拟系统一年的运行状态。元件状态持续时间抽样公式是[ T_{up} -\frac{1}{\lambda} \ln U_1, \quad T_{down} -\frac{1}{\mu} \ln U_2 ]其中 ( \lambda ) 是故障率( \mu ) 是修复率( U_1 )、( U_2 ) 是 [0,1] 区间均匀分布的随机数。这套抽样依据的是指数分布的无记忆性。模拟一年的流程是初始化所有元件状态记录每个元件的下一次状态切换时刻找到最早发生切换的元件更新系统状态然后对该状态下的系统进行潮流计算检查是否有负荷失电。如果有累积失电负荷量和持续时间。这个循环反复进行直到模拟时长达到8760小时。3.2 潮流计算前推回代法在交直流混合网里的推广可靠性评估对潮流计算有一个硬性要求快。一次蒙特卡洛模拟一年数据要跑8760个状态每次状态变化都要重算潮流而且这个潮流计算被嵌在进化算法的适应度函数里一跑就是几万次。所以潮流计算速度决定整个项目能不能跑完。我采用的方法是前推回代法它非常适用于辐射状配电网。算法分成两步第一步前推从末端节点向根节点推进根据节点注入功率和电压求支路功率第二步回代从根节点向末端推进更新各节点电压。重复这两步直到收敛。对于交直流混合系统处理思路是把换流器看作一个特殊的功率注入节点。交流侧和直流侧分开计算潮流通过换流器的功率平衡方程进行耦合迭代。直流潮流计算相对简单因为直流网络没有无功和相角只需要求解线性方程组。这里给出一个前推回代法的核心代码骨架方便你直接复现def backward_forward_sweep(nodes, branches, load_power, v01.0, tol1e-4, max_iter50): 前推回代法潮流计算 nodes: 节点列表, branches: 支路列表(包含首端、末端、阻抗) load_power: 各节点负荷复功率, v0: 根节点电压标幺值 v {n: v0 for n in nodes} # 电压初始化 s {n: load_power.get(n, 0j) for n in nodes} # 节点注入功率 for _ in range(max_iter): # 前推从末端累加支路功率 branch_power {} for b in sorted(branches, keylambda x: x[depth], reverseTrue): # 按深度降序 back b[end] s_accum s.get(back, 0j) branch_power[b[id]] s_accum # 回代从根节点更新电压 v_new dict(v) for b in sorted(branches, keylambda x: x[depth]): # 按深度升序 start, end b[start], b[end] z b[impedance] i_br (branch_power[b[id]].conjugate() / (v[start].conjugate() * v0)) if abs(v[start]) 1e-6 else 0j v_new[end] v[start] - z * i_br # 检查收敛 delta max(abs(v_new[n] - v[n]) for n in nodes) v v_new if delta tol: break return v这段代码简化了实际工程中的处理但对理解算法核心非常有效。实际我在项目中加了节点深度排序的预处理大幅降低每次迭代的计算复杂度。3.3 年时序负荷与光伏出力曲线建模可靠性评估不能只用峰值负荷来做因为峰荷只在极少数时段出现用它评估会严重高估缺电风险导致过渡投资。正确做法是构建小时级时序数据。负荷曲线我用了典型日随机波动的方式生成。每组规划方案共用同一个负荷序列确保不同方案之间的比较公平。光伏出力曲线则基于光照强度的Beta分布抽样再换算成功率输出。风速、光照、负荷之间实际上存在一定的相关性但这个项目为了简化假设它们相互独立同时通过划分季节典型场景来兼顾时序耦合关系。在实现中我将时序数据预先计算好存成数组可靠性评估循环里直接索引读取避免每次重复计算。这种预处理看似简单但对性能提升非常明显整个仿真速度能快30%以上。4. 算例分析与避坑指南4.1 IEEE 33节点系统参数与场景设置测试算例我选用经典的IEEE 33节点配电系统基准电压12.66kV基准功率10MVA系统总峰值负荷3715kW2300kvar。在原始拓扑基础上预设三个待选节点作为光伏接入候选点两个待选节点作为储能接入候选点三个待选位置作为VSC换流器接入点连接构建直流网络。种群规模设为50进化代数为100交叉概率0.9变异概率0.1模拟年数为2000年序贯蒙特卡洛的抽样年数。这些参数我在多次试验后发现比较平衡既不会让计算时间爆炸也能保证EENS的方差收敛。4.2 关键代码目标函数内部的可靠性评估调用目标函数必须把“一个规划方案”映射为“两个目标值”。核心代码逻辑如下def evaluate(individual): # 解码规划变量生成网络拓扑和设备参数 vsc_pos int(individual[0]) vsc_cap individual[1] ess_cap individual[2] pv_cap individual[3] # 更新网络参数 network build_network(vsc_pos, vsc_cap, ess_cap, pv_cap) # 经济性目标计算综合费用投资等年值 运维 购电 网损 cost_inv calc_invest_annuity(vsc_cap, ess_cap, pv_cap) cost_om 0.03 * cost_inv cost_loss, cost_purchase calc_operation_cost(network) f1 cost_inv cost_om cost_loss cost_purchase # 可靠性目标序贯蒙特卡洛模拟计算EENS eens sequential_mc(network, n_samples2000) f2 eens return f1, f2运行时你会发现这个函数非常耗时所以后面的性能优化显得尤为重要。4.3 常见问题与调试技巧实录问题一目标函数出现None或NaN。原因通常是潮流计算不收敛时没有处理返回结果。解决方案是在目标函数开头就做潮流预检如果潮流不收敛直接返回一个大罚函数值而不是让异常传递到上层。问题二Pareto前沿分布不均匀解全部集中在经济性好的区域。这通常是拥挤度距离计算时的归一化出了问题。当两个目标量纲差异极大时比如一个成本是10^6量级EENS是10^2量级必须对目标值做归一化后再计算拥挤度否则EENS维度几乎不起作用。问题三仿真时间爆炸。2000年序贯仿真加上100代进化每代50个个体总共要评估10000个方案每个方案2000次年仿真计算量巨大。我的解决方案分三层第一层把潮流计算从Python循环改成NumPy向量化操作第二层采用时间并行——把2000年拆成多个片段并行计算第三层在进化早期使用低精度评估比如500年后期才使用完整2000年评估。三层优化合起来整个项目的运行时间从原来的三小时压缩到了约二十分钟工程意义非常明显。4.4 快速验收的实用指标跑完之后怎么判断结果靠不靠谱我一般看三个信号。一看Pareto前沿形状。正常结果应该是一条从左上到右下平滑下降的曲线。如果出现阶梯形或Z字形多半是离散变量编码粒度太粗或者约束罚函数设置不当。二看经济极端解的设备配置。最便宜方案大概率是所有设备容量都取下界如果出现容量反而很大的现象说明目标函数里有漏算的成本项。三看可靠性极端解的电源配置。最高可靠性方案的储能和换流器容量应该接近上界且分布式电源会分散接入多个节点而不是集中在一处。如果集中在一处说明可靠性评估代码可能存在孤岛效应误判。这三招可以帮助你快速定位代码缺陷而不是对着完全不合理的曲线发呆。我个人做下来的体会是这个项目最有价值的不是某个算法本身而是把一个真实的工程规划问题完整拆成了可运行的代码逻辑。对新手而言能坚持把经济性模型、可靠性仿真和进化算法这三块拼接整合比单点调参的收获大得多。最后再分享一个小技巧所有随机数生成器无论是蒙特卡洛仿真还是遗传算法的种群初始化和交叉变异都固定随机种子。这样每次运行的对比才有意义调试定位问题也会轻松很多。我因为在调试时忽略了这件事曾花了整整一个晚上排查一个根本不存在的“随机Bug”。
返回列表