
1. 配电网里的分布式电源配置到底在优化什么1.1 为什么配电网突然需要“配置优化”我们说分布式电源通常指光伏、风电、小型燃气轮机、储能这类直接挂在配电网用户侧或馈线上的发电设备。前些年还好分布式电源少接一台是一台拣个近的地方并网就行。但现在不行了一个台区动不动报装好几户光伏一到中午发电高峰变压器反向过载电压往上顶原来的保护配合也开始乱套。所以分布式电源优化配置不是写论文才有的玩法它是配电网规划里绕不开的实际需求。配置优化解决的核心问题是在一条馈线或者一个配电网上什么东西装在哪、装多大能让电网运行最划算、最安全、最环保。这里面有两层意思。第一层是“位置”。同样一台光伏接在馈线首端和接在馈线末端对电压和线损的影响完全不同。接入点选不好可能出现馈线末端电压越限或者局部线路过载。第二层是“容量”。装小了收益有限削峰填谷作用不明显装大了超过负荷接纳能力反而造成倒送损耗和保护误动。位置和容量组合起来就是一个高维的搜索空间所以才需要优化算法来跑而不是靠人工经验拍脑袋。1.2 配置优化解决的是电网规划还是运行问题严格说这是一个规划层面的问题。因为DG的选点定容结果出来之后要指导的是“这个区域接下来三年该按什么容量、什么位置去批复分布式电源接入申请”。但规划方案做完又要靠运行数据来验证比如用典型日负荷曲线跑潮流看不同时刻电压和负载率是否会越限。很多初学者会把配置优化跟调度优化混在一起。区别其实很简单调度优化是设备已经装好了我每天怎么调度它配置优化是设备还没装我现在决定装不装、装哪里、装多少。前者是运行问题后者是规划问题。配电网DG配置优化要考虑的典型时间尺度是“年”以年综合费用最小为目标这跟调度里按小时、按分钟去出力的思路有本质区别。而且跟输电网的集中式大机组不同配电网里的分布式电源有一个绕不开的麻烦它发出来的功率是随机的、分布式的且通常不可调度。光伏要看天风电要看风。因此配置优化通常会选择一个典型方式去简化处理比如取典型日平均出力、峰值负荷下的出力或者全年8760小时出力曲线。工程上常用的是把典型日的出力曲线按小时离散然后逐小时跑潮流把全年结果累计起来评估综合费用。这样做精度够了计算量也还能接受。2. 从工程问题到数学模型目标函数与约束怎么定2.1 目标函数经济性、电压质量、网损到底怎么取舍分布式电源配置优化的目标函数业内没有一个唯一标准但大体上可以归成三类第一类经济性目标。设备投资费用、运行维护费用、购电费用、网损费用、政府补贴或绿电收益。做成年度化处理后统一相加就是年综合费用。这个最直观也最好跟电网公司的规划口径对接。第二类技术性目标。节点电压偏差总和、线路有功网损、馈线负载均衡度这些反映电网运行质量。DG接入之后网损通常能降但只要配置不当网损也可能升电压同样可能越限所以不能只算经济账。第三类环境目标。光伏、风电替代火电每年少烧多少标煤、减少多少碳排放。指标偏宏观但规划文本里爱用单独拿出来作为主目标有点勉强更适合罚函数或者约束条件处理。实际工程中我建议采用“经济目标为主技术指标通过约束或加权惩罚来控制”的方式。比如把网损费用直接折算进经济目标因为它已经面面俱到电压偏差则放进罚函数越限就扣适应度。这种做法的好处是最终你得到的是一个单一目标值好比较、好排序不至于在几个目标之间反复权衡导致遗传算法收敛方向摇摆不定。如果一定要做多目标优化可以用加权法把几个目标融合成单目标权重根据电网公司需求来定。举个例子经济目标权重0.6、电压质量权重0.3、环境效益权重0.1归一化之后相加。这个做法简单且稳定不会像NSGA-II那样还要维护Pareto前沿适合工程人员快速落地。需要注意多目标加权之后各目标的量级必须做归一化否则不同量纲的数字放在一起权重就白设了。2.2 约束条件配电网不是你想接就能接优化问题的另一半是约束。DG配置优化的约束条件核心是配电网潮流方程约束即每个节点的有功、无功必须平衡。此外还有几大硬约束节点电压约束电压幅值必须在0.95pu~1.05pu之间国标允许范围光伏大发的中午容易出现末端电压越上限。支路潮流约束流过线路或变压器的电流不能超过载流量。DG总容量约束整个电网的DG安装容量不能超过最大负荷的一定比例比如上限取80%或者100%防止出现严重的反向潮流。DG单点接入容量约束单个节点不能装得过大通常不超过该节点峰值负荷否则局部电压和短路电流都会出问题。每个节点的安装位置约束有些节点在现实中压根不具备接入条件比如纯地下电缆段不易开口、没有合适的并网柜空间这些需要提前设成不可安装。有了这些约束优化问题从数学上就是一个带约束的混合整数非线性规划问题。因为DG位置是离散的整数变量容量通常也按单位容量离散再加上潮流方程非线性问题复杂度陡增。处理约束最稳妥的做法有两种在初始化阶段就把不可行的方案过滤掉把惩罚项加进适应度函数。遗传算法对约束的天然优势就在这里——它不依赖梯度信息只要能评价一个方案好还是不好就能继续迭代。在适应度函数里处理约束我的经验是用线性惩罚对每个越限节点按越限程度乘一个足够大的惩罚系数加到适应度值里。惩罚系数不是越大越好。太大了会让优秀但不完全可行的解直接失去交叉变异时的竞争力种群过早全部变成保守解太小了罚了等于没罚迭代了半天出来的解电压照样越限。一般从1e4~1e6之间取一个量级具体看目标函数本身的数值范围。3. 遗传算法为什么适合这类问题以及怎么把“基因”映射到电网3.1 为什么选遗传算法而不是穷举或梯度法配电网DG配置的搜索空间长什么样举个例子就能说清楚。假设有33个可用节点每个节点最多装5个标准容量单元每个位置还有“不装”这个选项。那么一个解是一串长度为33、每个基因取值范围为0~6的整数序列总搜索空间是7的33次方量级大约是10的28次方。穷举法在这种规模下完全不可行哪怕一秒钟跑一万个方案也得跑到宇宙热寂。梯度类优化算法也不适用因为决策变量离散、目标函数非线性非凸还有大量离散约束数学上几乎处处不可导。这种情况下禁忌搜索、粒子群、模拟退火和遗传算法都是可选项。遗传算法好用在哪里它通过对“种群”并行搜索能在大范围里快速找到优质区域而且不需要你提供初始解随机初始化几代下去好的基因组合就会自然浮现。在实际项目中遗传算法还有一个隐性优势——代码好写、好改。工程上做规划今天可能要换目标函数明天要加约束后天要把单目标扩展成多目标。遗传算法的模块化结构即编码、解码、适应度评价、选择交叉变异各占一块改起来很顺手。粒子群和模拟退火也各有优点但论改造成本遗传算法确实更低。3.2 编码方案怎么把“在哪装、装多少”写进染色体遗传算法操作的是个体个体就是一个候选的DG配置方案。这个方案在算法里表达为“染色体”也就是一串基因。对于DG配置最直接有效的编码方案是整数编码染色体的长度等于候选安装节点数每个基因的值表示该节点的DG安装容量档位。举个例子0表示该节点不装DG1表示装1个标准容量单元2表示装2个单元。标准容量单元可以取50kW或者100kW视项目而定。假设某馈线有10个候选节点一条染色体像这样[0, 2, 1, 0, 0, 3, 0, 1, 2, 0]就表示节点2装2个单元、节点3装1个单元、节点6装3个单元、节点8装1个单元、节点9装2个单元其余节点不装。为什么不用二进制编码早期遗传算法教材里爱用二进制但二进制编码对整数离散变量有两个麻烦一是海明悬崖问题比如70111到81000要变4位影响交叉变异的局部搜索效率二是解码时要把二进制换算成整数多一层不必要的复杂度。整数编码天然匹配问题结构交叉、变异操作也直观现在做配电网DG优化我基本都直接用整数编码。3.3 适应度函数目标函数怎么变成“演化压力”遗传算法里每个个体的“优劣程度”用一个标量来评价这个标量就是适应度。工程实现时通常直接取负的目标函数值目标函数越小越好适应度越大越好。在包含潮流计算之后适应度函数的核心流程是这样的一条染色体解码成DG配置参数把各节点DG有功、无功注入量写入潮流数据然后调用潮流计算程序得到各节点电压和各支路电流根据潮流结果算出网损费用、设备费用、购电费用再加上电压越限惩罚、支路过载惩罚最终得到适应度值。这里面容易忽略的是DG的出力模型。光伏在规划阶段不能简单当成恒定有功源来看通常要分时段处理。比如用典型日光照曲线把每个小时的光伏出力系数0~1乘上安装容量得到该小时的出力负荷也按典型日负荷曲线分时段变化。这样算出来的网损和电压才是贴近实际的否则直接拿峰值负荷配合光伏满发去算容易得到偏保守的结果把一些本来合理的配置方案排除掉。4. 手撕MATLAB实现从0到1写出可运行的优化程序4.1 整体程序框架遗传算法与潮流计算怎么分工MATLAB做这件事的好处是矩阵运算方便而且自带powerflow相关工具包不过我们手写一个前推回代潮流也完全可行。整个程序的框架按照我之前说的模块化来搭数据输入模块线路参数、节点负荷、DG候选节点及容量档位、算法参数。种群初始化模块随机生成N条染色体。解码模块把染色体变成“哪个节点装了几档DG”。潮流计算模块给定DG配置和负荷水平计算节点电压、支路功率、网损。适应度评价模块调用潮流模块计算目标函数和惩罚项输出适应度。选择、交叉、变异模块生成新一代种群。主迭代循环重复上述步骤直到达到最大代数或收敛条件。这个结构的好处是每一个模块都可以单独测试。我习惯先把潮流模块单独跑通再写遗传算法最后联调。如果一上来就全部写完然后调试一旦结果不对你根本分不清是潮流算错了还是遗传算法写错了。4.2 前推回代潮流配电网辐射状结构的天然算法配电网多为辐射状结构用牛拉法或PQ分解法虽然通用但前推回代法实现更简单、计算更快非常适合嵌入遗传算法里反复调用。前推回代的基本思想就两步第一步回代从馈线末端往首端推根据已知的末端功率逐段累加求出各支路的功率和电流。第二步前推从首端往末端推根据已知的首端电压和各支路电流逐段求出各节点电压。反复迭代直到两次迭代的电压差小于收敛阈值。MATLAB实现里最关键的是节点顺序数组。你要把馈线的节点按从首端到末端的顺序排好并记录每条支路的首端节点和末端节点。IU节点编号用IEEE 33节点系统的话节点0是平衡节点其他节点按拓扑排下去。在遗传算法外层代码里DG的容量注入可以叠加到对应节点的注入功率上跟负荷功率相减以后再参与潮流计算。MATLAB核心代码逻辑大概是这样的我简化了数据结构来展示思路function [V, Ploss] powerflow_dist(Bus, Branch, DG_P, DG_Q) % Bus: 节点参数矩阵, 每行: [编号, 有功负荷, 无功负荷] % Branch: 支路参数矩阵, 每行: [首端节点, 末端节点, 电阻, 电抗] % DG_P, DG_Q: 各节点DG注入有功、无功 V ones(size(Bus,1),1); % 电压初始化 S_load Bus(:,2) 1j*Bus(:,3); % 节点复功率 S_dg DG_P 1j*DG_Q; % DG注入复功率 for iter 1:50 V_old V; % 回代从末端求支路电流 I_branch zeros(size(Branch,1),1); for k size(Branch,1):-1:1 % 末端节点注入电流累加到支路 end_node Branch(k,2); I_branch(k) conj((S_load(end_node) - S_dg(end_node)) / V(end_node)); % 叠加下游支路电流此处略需要反推拓扑累积 ... end % 前推从首端更新节点电压 for k 1:size(Branch,1) start_node Branch(k,1); end_node Branch(k,2); I I_branch(k); V(end_node) V(start_node) - (Branch(k,3) 1j*Branch(k,4)) * I; end if max(abs(V - V_old)) 1e-6 break; end end Ploss real(sum(V .* conj(I_branch))); % 简化示意 end实际工程代码肯定比这复杂尤其是支路电流累积那一步需要按树的父子关系做拓扑遍历。如果你不想自己写也可以用MATPOWER的runpf函数替换在适应度函数里把潮流数据改好之后调用两行代码就能拿到结果。缺点是每跑一次潮流都要重建数据总线的结构速度会慢不少。我自己做论文和工程测算时前推回代用得多速度比牛拉法快一个数量级辐射状配电网完全够用。4.3 遗传算子代码逻辑选择、交叉、变异三个关键步骤遗传算法的核心算子有三个。选择算子常用锦标赛选择。每次从种群中随机抽出若干个个体一般取2或3在其中挑适应度最高的那个进入下一代。这样做的好处是防止超强个体统治种群同时给普通个体留一条活路。MATLAB实现也很简单抽下标、比适应度、找最大值。交叉算子是生成新解的主力。我建议用两断点交叉随机在染色体上选两个断点交换两个父代在这段区间的基因。为什么不用单断点因为DG配置问题中各节点之间存在耦合单断点容易把一组协调配置的节点组合比如某个片区内的多个接入点一次性切断破坏优秀的建筑块。两个断点至少能保留更多的成块基因。交叉概率一般取0.7~0.9太低会搜索缓慢太高会破坏已形成的好解。变异算子的作用是维持种群多样性。对整数编码的染色体变异操作就是随机选一个基因位让它在允许的取值范围内重新随机取一个新值。这里有个细节容易被忽略变异量的大小应该跟染色体长度匹配。如果一条染色体有30个基因位变异概率取0.1平均每条染色体要变3个基因这样折腾几代好解很容易被毁掉。通常单条染色体只变异1个基因位让种群整体变异率控制在基因总数的1%~5%。4.4 精英保留别让最优方案在交叉变异中丢了遗传算法的最后一道保险是精英保留策略。具体做法是每代产生新种群之后把上一代适应度最高的那1~2个个体直接复制到新一代里不参与交叉变异。不要觉得这是个可选项在真实工程问题里没有精英保留的遗传算法经常出现这种情况迭代到第30代找到一个不错解结果第33代一交叉这个解被完全破坏了之后又花了20代才重新找到差不多的解。有了精英保留最优解的适应度曲线就是单调不减的至少你不会越优化越差。MATLAB实现时注意一个数据结构问题精英个体需要单独保存不要跟当代种群混在一起否则交叉变异的过程中它也会被改。建议在主循环里单独维护一个best_individual变量每个迭代周期更新一次。5. 典型算例结果与实战避坑几张表说明问题5.1 标准算例IEEE 33节点系统的效果用IEEE 33节点系统做验证是比较标准的做法。这个系统是10kV辐射状网络有33个节点、32条支路总负荷约3715kW 2300kvar。初始状态下系统总网损大约在202kW左右。假如我们规定候选安装节点为10个每个节点DG容量档位0~5档一档100kW种群规模取50最大迭代代数取80交叉概率0.8变异概率0.05运行一次优化最终可能会得到类似下面这种结构具体数字随随机种子浮动这里只展示数量级指标无DG方案GA优化后方案有功网损(kW)202.4108.7电压偏差最大值(pu)0.0710.028DG总装机容量(kW)01400年综合费用(万元)基准下降约18%从结果可以明显看出DG配置优化的价值体现在网损和电压两个维度上。配电网的潮流通常是从变电站单一方向流向负荷DG接入后相当于就地平衡了一部分功率减少了大功率远距离输送的损耗电压支撑作用也直接改善了末端电压偏低的问题。不过我特别想说看算例结果时要警惕“过度乐观”。IEEE 33节点的负荷模型是固定的没有考虑时序变化也没有考虑光伏出力波动。如果你把同样的配置方案搬到一个实际馈线但不去校核全年8760小时的潮流很可能某个中午光伏大发、负荷又轻的时刻电压就冲到1.06pu了。所以标准算例验证的是算法逻辑没问题不代表可以直接照搬现场。5.2 参数整定遗传算法不是调得越猛越好遗传算法参数设置的经验区间业内基本有这么几个参考值种群规模一般取50~100对大多数配电网规划问题够用染色体长就适当增大种群但种群太大迭代慢收益并不线性。交叉概率0.7~0.9低于0.5基本不推荐变异概率0.01~0.1关键看你想让算法更偏向探索还是开发。代数看收敛曲线不用预设太死常见做法是设最大代数为100观察适应度曲线是否在30代之内趋于平稳。调试参数的时候我的习惯是固定其他参数、每次只改一个变量逐次观察收敛曲线。这里面有一个容易被忽略的陷阱种群规模太小时初期可能会因为偶然因素选中一个不真实的最优解导致你误以为算法已经收敛了。判断遗传算法是否真收敛不能只看适应度是否不再变化还要看种群多样性比如统计染色体各基因位的取值是否过于集中。如果所有个体都长得一模一样了那确实是没多样性了大概率陷入了局部最优。有一种实操中非常好用的技巧叫“重启机制”。如果迭代中期发现种群多样性快速下降、适应度又卡在某个值多年不动就保留当前最优个体其余个体随机重新初始化相当于带着一个精英的周口从新起点再跑一轮。这个做法经常能帮算法跳出局部最优而且实现成本几乎为零。5.3 实战最常见的4个问题第一个问题是潮流不收敛。很多新手把DG容量设得很大节点注入功率为负电源往外送加上负荷过低潮流方程发散。排查时先看看DG总容量是否超过负荷再看初始化阶段生成的DG配置是否合理顺手检查潮流迭代上限和收敛阈值是否匹配。第二个问题是适应度函数把量纲搞混。网损费用单位是万元设备投资单位也是万元电压偏差是pu这三者直接相加就毫无意义。必须全部统一成一个量纲比如都折算成年综合费用万元或者都做归一化处理。第三个问题是交叉概率和变异概率选得太激进。有人用默认0.8的交叉概率就再也不动遇到复杂问题迭代五六代就全部收敛到某个局部区域收拾不了。建议运行中统计每代基因多样性如果某个等位基因基本只剩一种取值果断加大变异概率或者重启部分个体。第四个问题是指定位置不可装但算法还在装。处理方式目前提到过最直接的方案就是在初始化阶段强制这些节点基因固定为0解码时不把它们作为决策变量。如果已经写好了通用代码也可以通过一个mask向量来控制哪些基因允许变异哪些必须为0。5.4 工程落地的额外建议配置不是终点最后多说一句DG优化配置做完整套优化之后还有一个经常被忽略的步骤——方案校验。你得到的“最优配置”必须在极限工况下重新校核比如冬季夜间最大负荷但光伏出力为零夏季中午负荷最小但光伏满发这两种情况下电压和潮流是否越限。如果越限就需要适当减小装机容量或增加储能设施把这个约束反馈回优化模型再算一轮。我有一次做实际配电网规划优化的目标函数里只考虑了年综合费用跑出了一个看起来非常漂亮的方案结果一查现场其中两个位置恰好是市区的历史保护街区根本不可能破路施工做接入箱。从那以后我在初始化阶段就先把这类不可行节点剔除掉代码里做法就是给节点加一个禁用标签避免浪费时间。最后分享一点个人经验我记得第一次跑通这套程序的时候看着收敛曲线慢慢下降心里挺激动感觉“优化算法好像也没那么神秘”。但后来在实际项目里被结果的稳定性狠狠教训过几轮才意识到遗传算法本身的代码只是其中三分之一的工作量剩下三分之二花在数据整理、约束建模和结果校核上。一个靠谱的DG配置方案背后是对配电网物理特性的理解算法只是帮你穷举得更聪明一点。如果你现在刚开始接触这个问题建议先不要急着调算法参数先把潮流计算和负荷模型吃透。只有物理模型算得准遗传算法才有个可靠的“裁判”否则再好的搜索方法也只是在错误的游戏规则里白费力气。