做配电网规划或运行研究的人应该都遇到过同一个问题分布式电源和无功补偿装置到底装在哪、装多大效果才最好这个问题看着简单真上手做就发现牵一发动全身——装错了位置电压不但没改善反而可能越界容量选得太大线损不降反升无功补偿补得猛了末端过电压又冒出来。这就是配电网优化配置要解决的典型问题。我最早接触“基于遗传算法的配电网优化配置”这个题目是帮学生做毕设时被拉着一起调参。当时手头有一个IEEE 33节点配电网系统要在里面接入分布式电源DG和无功补偿装置目标是让网损最小、电压质量最优。刚开始想用穷举法一个节点一个节点试结果节点一多、容量组合一多枚举空间直接爆炸。后来换了遗传算法把“装在哪、装多大”编码成染色体让候选方案自己进化十几分钟就能出一版可用的结果。这篇内容就是给打算用Matlab做配电网选址定容、无功补偿配置的同学和工程师看的。我会把问题建模、遗传算法设计、Matlab实现步骤、常见坑位排查一条龙讲清楚代码逻辑可以直接沿用换一个配电网算例也能复用不需要从头再设计一套。1. 配电网优化配置问题到底在优化什么优化配置的第一件事不是写代码而是把问题用数学语言讲清楚。很多初学者上来就调遗传算法工具箱跑出来的结果根本没法解释就是因为模型没建对。1.1 决策变量与编码思路配电网优化配置的决策变量分两类位置变量和容量变量。位置变量指的是DG、无功补偿装置通常是无功补偿电容器或者SVC等接在配电网的哪个节点。配电网一般是辐射状拓扑节点数从几十到几百不等每个节点都有成为安装位置的潜力。位置变量的本质是一个离散整数选择问题。容量变量指的是每个安装点的DG装机容量或者无功补偿容量。DG容量一般按照额定值的倍数离散化比如每档50 kW从0到额定上限无功补偿容量则是按电容器组数离散例如每组25 kvar。实际操作时我习惯把容量值直接映射到一组档位编号这样遗传算法编码、变异、交叉时非常好处理不会出现非法解。把这两类变量串起来就是一条染色体。举个例子如果系统有33个节点我允许DG接入节点最多3个那么染色体可以用“位置基因 容量基因”两段拼接。位置基因用节点编号表示容量基因用档位编号表示。这里有一个很多新手会踩的坑位置基因如果用二进制编码把节点编号转成0/1序列交叉变异后很容易出现超出节点范围的非法值后期还得修复。所以我更推荐采用实数编码或者整数编码位置基因和容量基因都直接用数值本身处理简单又直观。1.2 目标函数的取舍配电网优化配置的目标函数常见的就三类有功网损最小、电压偏差最小、投资运行经济性最优。先说有功网损。配电网有功网损可以表示为支路电流平方乘以支路电阻之和简化公式可以写成Ploss sum(I_j^2 * R_j)其中I_j是第j条支路的电流R_j是支路电阻。加装DG和无功补偿之后线路潮流分布会改变网损自然跟着变。目标就是找到一种配置方案让这个值最小。再说电压偏差。节点电压越接近额定值电能质量越好。电压偏差通常取所有节点电压与额定电压差值的平方和或者用最大偏差。表达式可以写成V_dev sum((V_i - V_ref)^2)实际仿真中我一般把网损和电压偏差做加权组合F w1 * Ploss_normalized w2 * V_dev_normalized归一化处理很关键因为网损的数值可能是几百千瓦电压偏差可能是零点几权重如果设置不当小数值项会被直接淹没。我习惯先把两种指标分别除以初始运行状态下的值再乘权重这样两个目标量级一致权重调节才有意义。投资经济性更复杂一点需要把DG的设备成本、运行维护成本、无功补偿装置成本折算成等年值然后和目标网损费用叠加。如果做单目标优化可以写成年综合费用最小如果做多目标建议直接上NSGA-II用Pareto前沿展示成本和网损之间的权衡关系。不过对大部分毕设或者课题研究来说网损加电压偏差的加权单目标已经够用。1.3 约束条件怎么处理优化配置模型的约束条件配电网勘察类跑不了这么几个潮流平衡约束各节点注入功率之和加上网损等于电源输出功率节点电压上下限约束V_min V_i V_max通常取0.95到1.05倍额定电压支路电流热极限约束I_j I_j,maxDG总装机容量上限总容量不超过系统最大负荷的一定比例比如30%无功补偿容量约束每个节点的补偿容量不超过该节点无功负荷的某个比例或者不超过补偿点最大容量同一节点不允许重复配置DG和补偿装置约束条件的处理办法我推荐“可行性优先 罚函数”。可行性优先是指如果两个方案都能满足约束谁的目标函数值小谁就赢。罚函数是指如果某个方案违反约束就在目标函数上加上一个很大的惩罚项比如违反电压约束就加10^6倍的偏差量。这样遗传算法在进化过程中会自动淘汰掉违反约束的个体。如果完全不处理约束直接用遗传算法搜索大概率会算出“所有节点装最大容量”这种荒谬结果。因为从网损角度看DG多装了确实会降网损但不满足安全性约束。这一点务必在写代码前想清楚。2. 遗传算法在这个场景里为什么好用配电网优化配置是一个典型的混合整数非线性优化问题变量有离散的、有连续的潮流约束是非线性的。传统梯度类算法在这个问题里很难下嘴因为目标函数不可导、不光滑穷举法倒是可靠但节点数量一多组合数是指数爆炸的。遗传算法的优势正好体现在这里它不要求目标函数连续可导只需要能对每个候选方案算出适应度值剩下的交给“优胜劣汰”机制去搜索。2.1 遗传算法审美是怎么回事遗传算法的核心思想说白了就是模拟生物进化中的自然选择。一个种群就是一组候选方案每个方案的好坏用适应度值衡量好方案被选中参与繁殖的概率高交叉和变异产生新方案下一代继续竞争经过若干代进化之后种群整体会往目标函数更优的方向收敛。这里给一个生活化类比想象你开一个运输车队要给20个配送点排路线。你手里有100条不同的路线每条路线对应一个总里程。遗传算法做的事情就是把这100条路线当成100个个体拿出里程短的路线让它们“配种”、偶尔“变异”一下产生新的路线如此反复迭代几百轮最终的路线一定比最初的随机方案优秀得多。配电网优化配置和这个逻辑一模一样只是优化变量从路线变成了“DG装在哪、装多大、无功补偿装在哪、装多大”适应度函数从总里程变成了“网损电压偏差”或“年综合费用”。2.2 关键操作选择、交叉、变异的设计选择操作推荐“锦标赛选择 精英保留”。锦标赛选择就是从种群中随机抽几个个体取适应度最好的一个进入下一代反复操作直到填满新种群。精英保留就是把当前最优个体原封不动复制到下一代防止最优方案在交叉变异中被破坏。我实测下来精英保留几乎是必须的没有它收敛曲线会上下震荡最后结果不稳定。交叉操作位置基因用分段交叉容量基因用算术交叉或者均匀交叉。举个例子如果种群里有A、B两个个体交叉点选在第3位基因之后A的前段B的后段生成新个体B的前段A的后段生成另一个新个体。对容量基因更精细的做法是算术交叉新容量 alpha * A容量 (1 - alpha) * B容量alpha取0到1之间的随机数然后就近取整到档位。变异操作要结合修复机制。遗传算法的变异率通常取0.05到0.1过高会导致算法退化成随机搜索过低会过早收敛。位置基因变异就是把某个安装节点替换成另一个随机节点容量基因变异就是随机跳到相邻档位。变异之后要做合法性检查比如节点重复就要修复让后一个变异的位置转移到未被占用的节点上。2.3 遗传算法与潮流计算的耦合遗传算法的个体评估必须调用潮流计算程序。这一步是整个仿真的性能瓶颈也是正确性最容易出问题的地方。一次潮流计算就是在给定DG有功出力和无功补偿容量后算出各节点电压、各支路电流再据此计算目标函数和约束违反量。配电网潮流计算一般有两种方案一是用Matpower工具箱二是自己写前推回代法。如果你只是想快速验证算法用Matpower的runpf函数最省事但如果你希望代码自我包含、不依赖外部工具箱我建议自己写前推回代法代码量不大而且对辐射状配电网收敛性非常好。前推回代法的基本原理是先假设所有节点电压都是1.0 p.u.从末端节点往前推逐段累加支路功率得到各支路的功率分布然后从电源节点往后回代逐段更新节点电压反复迭代直到两次迭代的电压差小于收敛阈値比如10^-6。这个算法只适用于辐射状网络但配电网正好满足这个条件。潮流计算每评估一个个体就要跑一次如果种群大小是50、迭代100代那就是5000次潮流计算。所以潮流计算函数的效率非常重要建议去掉所有不必要的数据打印用矩阵运算代替for循环把迭代限幅设置合理。后面的常见问题里我会详细讲怎么排查潮流不收敛的情况。3. Matlab实操从数据准备到结果分析这一部分是我实际动手的全流程记录。我以IEEE 33节点配电网为标准测试系统给出可复现的操作和核心代码逻辑不用外部工具箱也能跑完整个优化。3.1 测试系统与数据准备IEEE 33节点配电网是一个经典的辐射状系统基准电压12.66 kV基准功率10 MVA总负荷大约3.7 MW加2.3 Mvar。这个系统自带一份标准线路参数数据网上很容易找到格式是“起始节点、终止节点、支路电阻、支路电抗、支路长度”之类的。拿到数据后第一步不是写遗传算法而是先把潮流程序跑通。我习惯先写一个脚本只做一件事输入网络参数输出基准潮流结果包含所有节点电压和支路电流。只有确认了基准潮流正常才能开始叠加优化代码否则后续所有结果都建立在流沙上。数据准备阶段还需要明确DG的接入上限和无功补偿容量范围。我通常在IEEE 33节点系统里设置DG总容量上限为系统总负荷的30%约1.1 MWDG单点容量上限0.5 MW无功补偿每组容量30 kvar每个节点最多补偿5组。这些参数不是固定的你可以根据自己研究场景调整但一定要在代码开头统一写成常量方便后面改。3.2 程序框架和核心代码整个Matlab程序我分成四个文件main.m主控、powerflow.m潮流计算、fitness.m适应度计算、ga_main.m遗传算法主循环。main.m负责读网络参数、设置算法参数、调用ga_main.m、画收敛曲线和电压分布图。powerflow.m是前推回代法输入网络参数、DG出力、无功补偿容量输出节点电压和网损。核心循环大致是这样的function [V, Ploss, Pij] powerflow(branch, bus, P_DG, Q_DG, Q_comp) % branch: [fbus, tbus, R, X] % bus: [busnum, P_load, Q_load] % P_DG: 节点注入有功向量 % Q_DG: 节点注入无功向量 % Q_comp: 无功补偿容量向量 max_iter 50; V ones(size(bus,1),1); for iter 1:max_iter V_old V; % 前推计算支路功率 % 回代计算节点电压 % 根据迭代差值判断是否收敛 if max(abs(V - V_old)) 1e-6 break; end end Ploss sum(Pij.^2 .* branch(:,3)) / 1000; % 网损单位kW end真正写的时候前推回代需要按照网络拓扑从末梢向根遍历这里建议先把支路排成层级顺序方便用矩阵计算。很多开源代码里直接用树的遍历实现我更喜欢把节点按层数排序然后用for循环按层更新逻辑更清晰。fitness.m是最关键的功能函数。输入一条染色体解析出DG接入节点、DG容量、无功补偿节点、补偿容量然后调用powerflow.m返回网损、电压偏差、约束违反量再合成最终的适应度值。注意适应度值越小代表方案越好而遗传算法的选择操作通常倾向“适应度越大越好”所以我在代码里取目标函数的倒数或者用一个大数减目标函数值来转换。ga_main.m是遗传算法主循环初始化种群、评估适应度、选择、交叉、变异、精英保留、记录历代最优值。核心主循环骨架类似这样pop init_population(Npop, bus, num_DG, max_capacity); best_history zeros(MaxGen, 1); for gen 1:MaxGen fitness_all evaluate_population(pop, ...); [best_val, best_idx] min(fitness_all); best_history(gen) best_val; % 精英保留 elite_pop(1) pop(best_idx, :); % 选择 selected tournament_select(pop, fitness_all, 3); % 交叉 offspring crossover(selected, pc, ...); % 变异 offspring mutate(offspring, pm, ...); % 合并精英与新种群 pop [elite_pop; offspring(1:end-1, :)]; end3.3 遗传算法参数设置我用这套参数稳定复现遗传算法的参数没有“标准答案”但有一组比较稳的起点我实测可以这样设置种群规模50最大迭代代数100交叉概率0.85变异概率0.08锦标赛选择规模3精英保留数量1罚函数系数电压越限惩罚1e6支路电流越限惩罚1e6这几个参数不算最优但对IEEE 33节点这种规模够用收敛曲线在40代左右就趋于平稳。如果你发现收敛速度太慢或者结果偏劣优先调变异概率其次是种群规模最后再动交叉概率。交叉概率太高会破坏优质基因组合变异概率太低又容易陷入局部最优这个度需要根据问题规模感觉一下。另外罚函数系数也不是越大越好。系数太大种群中一旦出现违反约束的个体适应度直接被压到谷底多样性快速丧失系数太小非法个体和合法个体区分度不够算法会大量保留违规方案。我的经验是把约束违反量先归一化再乘以1e6这样惩罚力度对问题规模是自适应的。3.4 结果分析收敛曲线、网损对比和电压分布优化完成后至少要输出三类结果迭代收敛曲线、优化前后网损对比表、优化前后节点电压分布图。收敛曲线用于确认算法没有跑飞、没有出现适应度震荡。正常情况下曲线是一条阶梯下降的曲线前期快速下降中后期平缓逼近最优值。如果曲线出现断层式跳升说明精英保留没做好要么是目标函数计算有 bug要么是约束处理方式有问题。网损对比IEEE 33节点系统在没有任何DG和无功补偿时有功网损大约200 kW左右。接入优化后的DG和补偿装置之后网损可以降到原来的一半甚至更低具体数值取决于负荷水平跟DG渗透率。我记得一次仿真里优化后网损从210 kW降到96 kW电压最低点从0.94 p.u.升到0.97 p.u.效果还是很明显的。电压分布图是把优化前后所有节点电压画在同一个图里对比如果优化后的曲线整体上移、波动变平说明方案确实有效。画图用Matlab自带的 plot 就行把节点编号作为横轴电压标幺值作为纵轴两条曲线分别标注“优化前”和“优化后”。建议输出一个表格记录最优染色体哪个节点装了多大DG、哪个节点补了多大无功方便写论文和做后续验证。4. 常见问题与排查技巧实录这套程序在跑的过程中我踩过很多坑也帮助不少同学排查过类似问题。下面这些问题基本都是高频出现的我按“症状、原因、解决办法”的方式整理成速查表供你对照排查。4.1 典型问题速查表问题现象可能原因解决办法潮流计算不收敛迭代次数到上限DG容量过大导致末端电压越界把DG容量上限调低或者把潮流迭代次数提高到100收敛曲线后期震荡不平稳精英保留实现错误最优个体被变异破坏检查精英保留逻辑让最优个体不参与交叉变异结果总是落在同一个配置点上变异率太低种群多样性不足把变异率从0.05调到0.1甚至引入动态变异罚函数权重太大合法解被淘汰优化问题规模小但罚因子过猛约束违反量先归一化再乘以1e6不要直接乘原值电压越限但结果仍然显示正常潮流计算未更新DG注入功率检查fitness函数是否把QG、QC正确传给powerflow程序运行极慢跑一轮要几小时潮流计算用for循环逐支路计算没有矩阵化把前推回代算法向量化减少不必要的节点打印位置基因重复出现多个DG在同一个节点交叉变异后没有做修复增加修复函数越界或重复时重新随机分配优化结果比初始方案还差目标函数符号搞反了算法在找极大值检查适应度转换确认越小代表越优4.2 独家避坑经验第一惩罚函数的系数一定要“分阶段递增”。我的做法是前20代用比较小的罚系数让种群自由探索20代以后逐步增大罚系数把搜索重心拉到可行域内部。这样的好处是前期不容易过早收敛到局部最优后期又能保证解满足约束。动态罚因子在Matlab里实现很简单每代乘以一个1.02的系数到100代时自然增长到一个大数。第二DG节点建议固定接在少数几个位置而不是所有节点均可选。把可接入节点集合预先缩小到“电气上比较敏感”的节点比如线路中段、负荷集中的节点、电压偏低的末端节点。这样既符合实际工程约束又能大幅缩小搜索空间遗传算法收敛质量明显提升。我常用做法是先用潮流计算跑一遍基准结果把电压最低的10个节点作为候选安装点再让遗传算法在这个候选集合里面选址。第三验证算法正确性是必做的一步。跑完遗传算法把最优染色体放到潮流程序里重新计算一遍确认所有约束都满足。然后做一个“小规模暴力穷举验证”比如只在5个候选节点中选1个安装点、容量只有3档先用穷举法得全局最优解再用遗传算法跑同一场景看两个结果是否一致。这个方法虽然费一点算力但能快速排查编码、适应度函数、目标函数的大 bug强烈建议第一次使用时做一次。第四容量的离散化档位不宜太密。我在第一次实现时把DG容量从0到500 kW按每10 kW一档划分结果搜索空间膨胀收敛速度被拖慢。后来改成每50 kW一档50个个体、100代就能稳定收敛。实际工程中设备容量本来就不是连续任意取的档位不要设太密50到100 kW一档完全够用。无功补偿电容器更是按组数取整天然离散不存在这个问题。4.3 一点个人体会做了几轮配电网优化配置之后我对这类问题的最大体会是遗传算法本身并不难难的是把配电网的物理约束转写清楚。很多跑崩的结果并不是遗传算法的锅而是潮流计算给了错误输入或者罚函数把可行解误杀了。所以我对每个仿真结果的建议都一样先小规模试错、一步步验证不要一上来就全系统上大种群跑迭代。如果你手头也有一个类似的课题建议按照“模型清晰 → 潮流可靠 → 算法简化 → 逐步加条件”的顺序来推进。先用最简模型跑出稳定结果再往目标函数里加电压偏差、经济性等项这样每一步出了问题都能定位到具体环节。别急着一步到位把这套框架跑通之后无论是换DG类型、加储能还是改拓扑结构都能顺手改出来。最后分享一个小技巧用遗传算法做完优化之后不要只留一个最优解把种群中排名前10的方案都导出来。这些方案之间的差异往往能告诉你哪些节点对目标函数特别敏感、哪些容量参数在一定范围内变化不大。在毕业设计或者工程项目答辩中这些分析比一张收敛曲线图要有说服力得多。