ARTICLE DETAIL

资讯详情

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

粒子群算法在配电网分布式电源容量优化中的应用实践

粒子群算法在配电网分布式电源容量优化中的应用实践 前阵子接了一个配电网分布式电源接入规划的小需求一条10kV馈线几十个负荷节点要在其中几个位置接入光伏问每处接多大容量比较合适。我刚开始的想法很朴素——直接手算几个方案试潮流看哪个网损小就用哪个。试到第二个方案就发现问题了各节点的电压相互影响调这一处的容量另一处的电压跟着变试凑法在三维以上基本靠运气。后来我改用粒子群算法PSO做容量寻优以IEEE33节点系统作为标准测试算例把整套程序跑通顺便把选址定容的结果也验证了一遍。这篇文章会把建模思路、算法原理、关键代码和实际调试中踩过的坑完整记录下来给准备做配电网分布式电源规划或正在学粒子群算法应用的同学一个参考。1. 分布式电源容量配置问题的本质是找一组恰到好处的数字1.1 项目背景为什么不能只靠经验拍脑袋在配电网里接入分布式电源DG好处是显而易见的分布式光伏、风电靠近负荷中心能减少上级电网输送压力降低线路损耗也能抬升末端电压。但坏处也很明显——接多了、接错位置可能造成节点电压越上限、线路过载、保护配合失效。我在实际接触的项目里就遇到过这种情况某台区光伏装机规划得比较激进中午光伏大发时10kV母线电压直接顶到1.06-1.07pu虽然还没跳闸但离上限已经不远了。后来重新调整了并网容量和位置问题才缓解。所以分布式电源容量配置本质上要回答两个问题一是在哪些节点接入DG二是每个接入点接多大容量。这个选择直接决定了接入后配电网的网损是否下降、电压分布是否合格。手算试凑在节点数少的时候还能勉强应付但配电网一上规模比如IEEE33节点这种几十个节点的系统可行方案数量是指数级别的必须用优化算法来搜索。1.2 数学化表达目标函数和约束条件把这个问题写成数学优化模型其实并不复杂。假设系统有N个节点选择其中M个作为待接入DG的候选节点决策变量x就是一个M维向量每一维代表对应节点的DG装机容量kW或MW。目标函数我采用最常见的网损最小化min f(x) Ploss(x)Ploss是接入DG后整个配电网的有功网损由潮流计算得到。单看网损不够全面很多文献还会加入电压偏差、DG投资运行费用等目标做成多目标优化。我的做法是先以网损为主目标把电压要求作为硬约束放进罚函数这样程序简单、结果解释也直观。约束条件包括四类潮流平衡约束由潮流计算本身保证不需要显式列方程。节点电压约束0.95 ≤ U ≤ 1.05pu。DG总容量约束总装机不能超过系统总负荷的一定比例我取50%防止渗透率过高带来倒送电问题。单点容量约束每个候选节点的DG容量在[0, DGmax]区间内本文DGmax取0.8MW。加了约束之后问题就从任意寻优变成了在可行域内寻优这也是后面罚函数设计的依据。2. 粒子群算法的核心机制鸟群觅食和电网规划的相似之处2.1 从鸟群到优化器速度-位置更新公式粒子群算法PSO的灵感来自鸟群觅食行为。设想一群鸟在一片区域里找食物每只鸟不知道食物在哪但知道当前自己离食物多远而且能共享信息。最简单有效的策略就是每只鸟既参考自己历史最佳位置又参考整个群体当前的最佳位置综合两者修正飞行方向。在PSO里鸟就是粒子代表一个决策变量取值组合食物就是目标函数最小值飞行方向就是速度向量。具体公式是每个迭代周期内对粒子i的每一维执行v_i(t1) w·v_i(t) c1·r1·(pbest_i - x_i(t)) c2·r2·(gbest - x_i(t)) x_i(t1) x_i(t) v_i(t1)三个项各有分工第一项是惯性项让粒子保持原有飞行趋势w大则全局搜索能力强第二项是认知项拉着粒子回到自己历史最优位置对应个人经验第三项是社会项拉着粒子飞向群体最优位置对应群体协作。c1和c2分别控制个人和群体的拉力强度r1和r2是[0,1]之间的随机数给搜索注入随机性避免所有粒子走同一条路。我最早学PSO的时候觉得公式很抽象后来发现把它理解成调参的过程就好办了w太大粒子的飞行路径太野收敛慢w太小粒子飞两三步就缩在一起容易陷入局部最优。c1和c2的搭配同样关键如果c1明显大于c2粒子容易各自为政群体协作不足反过来则容易一窝蜂冲向当前最优缺少对个体经验的挖掘。配电网容量配置问题维度不算高经典参数w从0.9线性降到0.4、c1c22已经能跑出不错的效果。2.2 为什么选PSO而不是遗传算法很多人在做优化时会纠结选PSO还是遗传算法GA我干脆把两者做了一次对比再做的决定。GA的核心思想是选择、交叉、变异更擅长离散组合优化比如配电网的联络开关组合状态问题而PSO的连续速度-位置机制天然适合连续变量优化。分布式电源容量配置的决策变量本质是连续变量容量数值不是接或不接这种0/1选择所以PSO更顺手。另一个实际原因是PSO参数少、实现简单。GA需要设置种群规模、交叉概率、变异概率、选择策略等一堆参数每个参数怎么配都有说法PSO的核心参数就w、c1、c2三个经验值很成熟调试成本低。我用MATLAB写整个程序从零开始也不过两百多行两天就能跑通。如果以后要扩展多目标优化PSO也有现成的改进方向比如引入Pareto支配关系变成MOPSO迁移成本低。当然这不是说PSO没缺点。它最大的短板是容易早熟收敛迭代后期粒子多样性下降容易停在局部最优。针对这个后面会讲到用线性递减惯性权重、多次运行取最优等手段来缓解。在IEEE33节点这种规模的问题上这些处理已经足够。3. IEEE33节点系统的建模要点与潮流计算方案3.1 先用标准算例搭台IEEE33节点的数据准备IEEE33节点系统是配电网优化研究里最经典的标准算例。它模拟一条辐射状10kV馈线共33个节点、32条支路首端节点1通过变压器接在无穷大电源上总负荷约3715kWj2300kvar基准电压12.66kV。系统完整数据包括每条支路的阻抗、每个节点的有功无功负荷这些数据在配电网相关的教材和论文里都能查到也可以从一些开源电力系统工具箱里直接导入。我实际建数据的时候把它存成了两个矩阵branch矩阵存支路编号、首端节点、末端节点、电阻、电抗load矩阵存节点编号、有功负荷、无功负荷。以节点1到节点2的支路为例阻抗是0.0922j0.0470Ω这个数值很小但压降影响不能忽略。大部分支路数据都有相似规律越接近末端的支路线路越长、阻抗越大所以末端节点电压天然偏低。这也是后面分布式电源应该往末端接的物理依据。原始系统不做任何DG接入时用前推回代潮流算一遍可以得到两个关键值有功网损约202kW节点18末端电压最低约0.913pu。这两个数就是后面优化效果的对照基准。可以说IEEE33节点的优势就在于结构标准、数据公开、结果可比任何算法跑出来的效果都能和文献结果互相验证。3.2 前推回代潮流算法配电网潮流的神器潮流计算是整个优化过程中被调用最频繁的部分PSO迭代一次每个粒子都要算一次潮流所以选择的潮流算法必须又快又稳。配电网是辐射状结构、支路电阻和电抗接近R/X大用传统的牛顿拉夫逊法容易遇到雅可比矩阵病态问题而对配电网来说前推回代法是更合适的选择。它利用辐射状网络功率从首端流向末端、电压从末端反馈回首端的结构特点把计算拆成两个方向交替进行。具体步骤如下初始化所有节点电压为额定值1.0pu。回代计算从最末端节点开始逐支路向首端累加功率损耗得到每条支路的注入功率。前推计算从首端节点开始根据支路功率和阻抗逐支路计算末端节点电压。完成一轮后判断相邻两次迭代的电压差是否小于收敛精度我设为1e-6不满足就重复回代和前推直到收敛。把DG接入潮流计算也很简单在对应的节点上把DG的注入功率叠加到该节点原有负荷上等效为负荷减少或者反向注入来处理。如果DG按恒功率因数1.0运行光伏常见的设置那就只在有功分量上做修正如果功率因数是0.9就同时修正有功和无功分量。前推回代对这种局部修改非常友好不需要重新组装任何矩阵所以整个PSO循环的效率很高。3.3 接入节点与决策变量映射IEEE33节点系统有33个节点理论上每个节点都可以接DG但工程里通常不会这么做——太多接入点意味着施工、通信、运维成本都成问题。实际项目的做法是先从负荷分布和线路情况出发圈定几个候选节点。我的示例程序选择了5个候选节点节点10、17、21、25、32。为什么选这五个节点32在馈线末端附近是电压最低的区域之一DG接入能起到电压支撑作用节点17在某个分支末端节点25在另一条分支上同理节点10、21则靠近中间位置可以分担主干线上的潮流压力。当然候选节点的选择本身也可以做成优化变量那就是选址定容的完整问题本文先固定候选方案、只优化容量是为了把PSO和潮流计算的主逻辑讲清楚。这样一来决策变量就是5维向量每一维代表对应节点接入的DG容量以MW为单位取值0到设定上限。程序里的映射关系是一张固定的节点索引表x(1)→节点10、x(2)→节点17、x(3)→节点21、x(4)→节点25、x(5)→节点32。每次计算适应度时把粒子向量展开成DG注入功率数组再传给潮流函数就完成了从优化空间到配电网物理模型的桥接。4. 程序实现从PSO参数整定到适应度函数设计4.1 参数设置每种参数都有它的道理参数设置看似是一些经验值但背后都有明确考量。我的PSO参数如下参数取值作用备注种群规模nPop30搜索广度5维问题30个粒子足够最大迭代次数MaxIter100迭代深度一般60代就会收敛惯性权重w0.9→0.4线性递减平衡探索与开发前期大步搜索后期精细收敛加速因子c1/c22.0/2.0认知与社会学习强度经典取值多数问题够用速度上限Vmax变量范围的10%防越界避免粒子飞得太远边界处理越界拉回可行域保持比随机重置效果稳定关于惯性权重线性递减我的理解是早期迭代阶段粒子应该尽可能散开去搜索整个解空间此时w取0.9粒子有较强维持自身趋势的能力不容易被某个局部最优牵走后期阶段解的大致区域已经找到需要精细化搜索w降到0.4粒子的步伐变小在最优解附近慢慢打磨。这个策略几乎适用于所有工程优化问题不只在配电网容量配置里有效。4.2 适应度函数与约束罚函数的设计适应度函数是整个程序的灵魂。它的作用和答案对不对直接挂钩设计不好再好的优化器也没用。我的适应度函数结构如下fit Ploss(x) 1000 * max(0, 电压越限总和) 10000 * 容量越界惩罚Ploss是潮流计算得到的有功网损kW这是主目标。电压越限惩罚针对每个节点如果节点电压超出[0.95, 1.05]pu把超出部分平方后累加再乘以惩罚系数1000。这里用平方而不是绝对值是为了对越限程度施加更大的惩罚越得越多罚得越狠。容量越界惩罚则用来保证粒子x的每一维都在[0, DGmax]范围内比如DGmax取0.8MW。核心代码如下function fit CalFitness(x, branch, load, DG_nodes) % x: 决策变量(5维), 单位MW DG_kW x * 1000; % 转为kW % 初始化DG注入向量, 默认所有节点不接DG DG zeros(33, 1); DG(DG_nodes) DG_kW; % 映射到对应节点 % 前推回代潮流 [U, Ploss] BackForwardSweep(branch, load, DG); % 电压越限罚项 V_upper 1.05; V_lower 0.95; vol_penalty sum((max(0, U - V_upper)).^2 max(0, (V_lower - U)).^2); % 容量越界罚项 cap_penalty sum(max(0, x - 0.8) max(0, -x)); % 适应度 网损(kW) 电压惩罚*1000 容量惩罚*10000 fit Ploss 1000 * vol_penalty 10000 * cap_penalty; endBackForwardSweep函数的实现逻辑在上文3.2节已经详细描述过就是标准的前推回代迭代这里不展开全部代码。有一点需要说明罚函数系数1000和10000的量级不是随便定的。系统的网损是200kW量级一个节点电压越限0.01pu平方后是1e-4乘以1000就是0.1看起来不大但如果多个节点严重越限比如越限0.05pu平方后2.5e-3乘以1000是2.5这个量级就能影响最终排序了。实际调参时我会先跑一版看各罚项的数量级再调整系数让约束违反在适应度中占主导地位。4.3 PSO主循环代码骨架PSO主循环的框架很固定初始化粒子位置和速度计算初始适应度然后进入迭代每次迭代更新每个粒子的速度和位置重新计算适应度更新个体最优pbest和全局最优gbest。核心代码如下% PSO主循环 rng(2024); % 固定随机种子, 便于复现 dim 5; nPop 30; MaxIter 100; lb zeros(1, dim); % 下限 0 ub 0.8 * ones(1, dim); % 上限 0.8MW w_max 0.9; w_min 0.4; c1 2.0; c2 2.0; % 初始化 X repmat(lb, nPop, 1) rand(nPop, dim) .* repmat(ub - lb, nPop, 1); V zeros(nPop, dim); fitness zeros(nPop, 1); for i 1:nPop fitness(i) CalFitness(X(i,:), branch, load, DG_nodes); end pbest X; pbest_f fitness; [gbest_f, idx] min(fitness); gbest X(idx, :); % 迭代 for t 1:MaxIter w w_max - (w_max - w_min) * t / MaxIter; % 惯性权重线性递减 for i 1:nPop r1 rand(dim, 1); r2 rand(dim, 1); V(i,:) w * V(i,:) ... c1 * r1 .* (pbest(i,:) - X(i,:)) ... c2 * r2 .* (gbest - X(i,:)); % 速度限制 V(i,:) max(min(V(i,:), 0.08), -0.08); % 位置更新 边界吸收 X(i,:) X(i,:) V(i,:); X(i,:) max(min(X(i,:), ub), lb); % 评估 new_f CalFitness(X(i,:), branch, load, DG_nodes); if new_f pbest_f(i) pbest(i,:) X(i,:); pbest_f(i) new_f; end if new_f gbest_f gbest X(i,:); gbest_f new_f; end end end代码里边界处理用了拉回边界而不是重新初始化。因为我测试过随机重置会把粒子弹到解空间任意位置破坏已经搜索到的信息收敛速度明显变慢拉回边界保留了这个解在边界上的潜力工程上更实用。速度上限Vmax设为变量上限的10%也就是0.08MW/代防止粒子迭代一步飞出太远这也是PSO调试里最容易被忽略的细节之一。5. 一次完整运行的复盘收敛曲线与配置结果解读5.1 原始系统与配置后的对比程序跑完我拿一组典型结果出来做一次复盘。先看原始系统不接任何DG的潮流结果有功网损202kW节点18电压最低只有0.913pu已经低于0.95pu的电压合格线这说明这条馈线末端电压偏低的矛盾是真实存在的。配置DG之后完整运行一次PSO得到的最优解5维向量大致是接入节点DG容量(MW)说明节点100.42主干中段缓解上游供电压力节点170.28分支末端主要用来抬升末端电压节点210.23中段分支兼顾网损和电压节点250.35分支末端电压抬升明显节点320.46最末端电压支撑的关键节点总DG装机约1.74MW占系统总负荷约47%满足预设的50%渗透率上限。配置后的潮流结果显示网损从202kW下降到约121kW降幅约40%最低电压从0.913pu提升到约0.970pu节点18所有节点电压都在0.95-1.05pu区间内。这个改善趋势是符合物理直觉的——DG靠近负荷中心注入有功减少了长线路输送的有功电流网损自然下降末端注入支撑了末端电压把最低电压拉回合格区间。5.2 收敛曲线怎么看运行程序时记录每一代的最优适应度画成收敛曲线能直观看出算法工作是否正常。我这边的曲线大致可以分成两个阶段前20代适应度从初始的400左右快速下降到160左右20代到60代下降速度明显放缓从160缓慢降到121左右60代以后基本贴平收敛于121附近。第一阶段对应惯性权重w较大时的全局搜索粒子快速发现末端接入DG、容量适中的大方向第二阶段w逐渐变小粒子在大方向附近精细调整寻找边界上的最优组合。如果你运行的曲线在后期仍然大幅震荡说明w减得太慢或c1/c2配比让粒子始终在最优解附近跳跃如果前期就早早躺平、曲线变成一条水平线说明w初始值太小或者种群规模不足粒子太早收敛到某个局部最优。这个观察方法不仅对PSO适用。任何元启发式算法跑完以后先看收敛曲线再谈结果是基本的调试习惯。曲线形态不对后面的最优解基本不可信。5.3 配置方案的可解释性优化结果不是黑盒应该能解释得通。我把这组最优方案放回IEEE33节点的物理场景里分析了一下容量较大的两个节点分别是节点320.46MW和节点100.42MW前者在最末端电压支撑收益最大后者在主干中段离首端近、线路损耗小DG注入的收益几乎全部转化为网损下降。容量较小的节点21和17都在分支线路上分支负荷小再接大容量DG容易出现电压越上限所以PSO自动把容量压低了。这就很有意思算法虽然不知道电网的物理结构但通过约束条件和适应度函数的引导找到的方案天然符合末端多接、分支少接、主干中量接入的工程经验。反过来如果某个优化方案输出一个明显违背物理直觉的结果比如给负荷很小的分支接很大的DG那就要怀疑约束条件是否漏写了、罚函数是否没起作用而不是直接采信数值。6. 实测中的坑粒子群算法做电网规划容易忽视的细节6.1 随机性同一段代码每次运行结果不同PSO是随机算法每次运行得到的结果会有波动。我第一次跑完整个程序时连跑三次得到三个略有不同的最优方案当时差点以为程序有bug。后来才反应过来这是随机优化算法的正常特性粒子初始位置、速度更新的随机数都不一样结果自然不完全相同。处理方式有两种。第一是做多次独立运行比如连续跑20次记录每次的最优解和最优适应度最后取适应度最小的一次作为正式结果顺便还能统计出解的分布范围评价算法的稳定性第二是在代码开头固定随机种子比如MATLAB里用rng(2024)这样每次运行结果严格可复现方便调试和发表数据。实际工程验证我建议两个都做调试阶段固定种子最终验收时多次运行取最优。另外提醒一点比较两种算法或两组参数谁更好的时候必须在相同随机种子下做对比否则结果差可能只是随机波动造成的而不是算法本身优劣。6.2 潮流不收敛与假最优PSO在搜索过程中会随意生成各种粒子其中某些极端组合——比如某节点DG容量很大、周围负荷又很小——会导致前推回代潮流迭代不收敛或者收敛到一个电压严重越限的运行点。如果不加处理适应度函数里会出现NaN或Inf整个优化过程就崩了。我的处理办法是在潮流函数里加一个故障保护设定最大迭代次数比如50次如果达到最大次数仍未满足收敛精度直接返回一个极大适应度值比如1e6告诉优化器这个方案不可行。这样粒子会很快远离不可行区域。很多教学代码不会处理这个细节但实测中发现漏掉它会非常痛苦——程序跑着跑着就出现NaN排查半天才发现是某个粒子把DG容量怼到了10MW。6.3 罚函数系数是个玄学罚函数系数的整定确实是这类约束优化问题里最玄学的部分。系数太小约束就形同虚设PSO可能给出电压越限的方案系数太大约束信息淹没主目标算法会优先寻找不越限而非网损小的方案可能错过最优解附近的一些可行解。我的一般做法是先跑几组系数组合观察可行解比例和最优适应度的变化再折中确定。针对本例电压罚系数1000、容量罚系数10000是我两次调整后确定的。判断标准很简单最终得到的gbest方案回代到潮流里必须满足全部约束且约束罚项的数值在适应度中的占比小于10%。如果占比太高说明主目标还没被充分优化太低就检查是否真有越限被漏罚。6.4 如何验证方案靠谱拿到优化结果后我这里说的验证不是看算法跑完了就算完事而是要把方案放回潮流里独立验算一遍。具体要做三件事用最优方案做一次前推回代潮流确认所有节点电压都在0.95-1.05pu内不靠罚函数蒙混过关。把原始系统、配置后系统的潮流结果放在一起对比看网损是否真的下降、下降幅度是否合理。抽一组对照基准随机生成2000组满足约束的容量方案计算各自适应度看PSO找到的解在随机样本中的排名。我在这个项目中用随机对照的方法做了验证2000组随机可行方案里最优适应度的中位数大概在300多而PSO给出的结果适应度是121左右明显优于随机方案的绝大多数。这一步让我彻底放心——说明PSO在这个问题上收敛得不错代码和模型都没有大问题。如果你的结果经不起这种独立验证问题大概率出在建模或罚函数上而不是优化算法本身。整个项目做下来我最大的体会是粒子群算法不是银弹它真正解决的是把工程师从试算循环里解放出来的问题。IEEE33节点只是标准测试算例实际工程里换成一条真实的10kV馈线只需要替换节点数、支路阻抗和负荷数据把候选节点重新指定一遍程序的主逻辑基本不用动。如果之后要接入不同类型DG光伏、储能、小型燃机把DG出力模型从恒功率改成时序曲线再叠加多时段潮流就可以做更精细的规划了。建议刚开始接触这块的读者先关注两件事把前推回代潮流算准确把适应度函数里的约束罚项设计好。这两步做扎实了PSO本身反而不会给你太多麻烦。
返回列表