首页 / 资讯中心 / 文章详情

基于PSO的分布式电源选址定容多目标优化MATLAB实现

基于PSO的分布式电源选址定容多目标优化MATLAB实现 ★ FEATURED ARTICLE
做分布式电源选址定容这个方向一年多前前后后写过好几版程序最常用的还是PSO算法。说句实在话电网里分布式光伏、风电、储能这些电源往哪儿装、装多大直接影响网损、电压质量和新能源消纳率。我基于MATLAB写了一套以网损、电压偏差和光伏消纳为多目标寻优的PSO程序用来做分布式电源的选址定容今天把整体思路、数学模型、代码框架和调试中踩过的坑都整理出来希望能给正在做配电网仿真、光伏规划这类课题的朋友一点参考。这套东西不是什么黑科技但很实用。它解决的典型问题是已知一个配电网的拓扑结构、负荷分布和光伏资源情况怎么确定分布式电源的接入节点和安装容量让系统网损尽量小、节点电压尽量平稳、光伏发出的电尽量不被浪费。适合电力系统专业的研究生、做配网规划的工程师以及打算用智能算法解决工程优化问题的MATLAB用户。1. 选址定容问题为什么网损、电压偏差和光伏消纳是核心目标1.1 分布式电源接入位置容量的连锁效应分布式电源的选址定容本质是两个变量同时决策装在哪里选址装多少定容。很多人一开始会低估这两个决策的耦合程度以为随便选几个节点、给一个合理容量就行但实际跑潮流计算就会发现位置和容量稍微变一点整个系统的功率分布就完全变了。举一个我在IEEE 33节点算例上反复验证过的例子同样是在某条馈线的末端接入一个1.5MW的光伏电源和在前端主干线接入1.5MW光伏系统网损可能相差20%以上。末端接入要是赶上负荷小、光伏出力大的时段还会出现明显的电压抬升甚至倒送功率。反过来如果接入点靠近负荷中心容量又匹配得当不仅能减少线路传输的功率还能降低网损、稳住末端电压。所以选址定容不是一个参数优化问题而是一个结构—运行耦合的规划问题。程序里真正起作用的不只是PSO那一套寻优逻辑更重要的是把配电网的潮流关系、电压约束、光伏出力曲线都准确建模。算法负责搜索潮流计算负责评价两者配合才能出可信结果。1.2 三个目标之间的冲突关系用PSO做多目标寻优首先要面对一个现实网损最小、电压偏差最小、光伏消纳最大这三个目标不是完全一致的甚至在某些场景下互相打架。网损和电压偏差通常方向一致。系统电压越平稳无功分布越合理网损往往也越低。但光伏消纳跟这俩目标存在明显矛盾。如果你一心想消纳更多光伏就得让光伏尽量多发电并上网可在负荷低谷时段光伏出力大反而可能造成局部电压越限同时也可能增加线路损耗。也就是说消纳率做高了网损和电压质量不一定好。因此程序里不能简单地把三个目标塞进一个函数随便加权完事必须处理好目标之间的量纲差异和权重权衡。我采用的是线性加权加罚函数的方式同时额外记录Pareto非支配解集合方便后期对比不同偏好下的配置方案。这个设计在后面会详细展开。2. 多目标优化模型的数学构建与约束处理2.1 目标函数1系统网损最小化配电网的网损计算基础是潮流结果。对于每条支路网损可以表达为Ploss sum( Iij^2 * Rij ) 对所有支路求和实际程序里我用的是基于牛顿—拉夫逊法的三相潮流或者前推回代法。前推回代法在辐射状配电网里收敛快、实现简单我最终采用的是前推回代。每个粒子把候选节点和容量解码出来接上分布式电源后重新跑一次潮流然后从潮流结果里提取各支路的电流和电阻累加得到总网损。目标函数值最终写成F1 Ploss_after_DG / Ploss_base也就是接入分布式电源后的网损除以原始网损归一化处理后便于和其他目标加权比较。2.2 目标函数2电压偏差最小化电压偏差的计算相对直观。程序里对系统的每个节点在典型日每个时段都记录电压幅值然后和基准电压通常取1.0 p.u.做差F2 mean( sum( abs(V_i - V_ref) ) / N )这里V_i是第i个节点的电压幅值V_ref是参考电压N是节点数。如果做动态仿真还需要对多个时段取平均。我程序里用的是典型日24个时段的潮流扫描——每个时段的光伏出力根据光照曲线给定负荷根据日负荷曲线给定然后把24个时段的电压偏差累加起来取平均值。这样做比单时段静态计算更贴近实际因为光伏出力和负荷都在波动。2.3 目标函数3光伏消纳最大化光伏消纳的建模稍微绕一点。分布式光伏接入配电网后如果本地消纳不了就可能出现功率倒送或弃光。我在程序中做了一个简化处理假设光伏逆变器具备一定的无功调节能力同时以实际被系统消纳的光伏电量占理论可发电量的比例来衡量消纳率。数学上这样表达F3 1 - ( E_curtailment / E_available )其中E_available是理论可发电量E_curtailment是根据线路容量约束、电压约束和负荷水平估算出的弃光量。在程序中弃光量通过判断每个时段光伏出力扣除本地负荷后的剩余功率是否超过线路传输极限来估算。如果超过极限超出部分就视为弃光。2.4 等式与不等式约束任何一个优化问题没有约束就是耍流氓。选址定容的约束包括潮流等式约束每个节点的注入功率必须满足功率平衡方程节点电压约束V_min ≤ V_i ≤ V_max一般取0.95~1.05 p.u.支路容量约束I_ij ≤ I_max分布式电源渗透率约束总安装容量不超过系统峰值负荷的一定比例通常取20%~30%单节点安装容量约束每个候选节点的DG容量上限这些约束在PSO里不是全部硬性处理的。电压和支路容量这类非线性约束我用罚函数处理加入总目标值渗透率和单节点容量这类线性约束则直接在粒子编码初始化阶段限制取值范围从源头保证不越界。这里有一个工程上的经验罚函数系数不能设得太离谱。我有一次把电压越限的罚系数调得很大结果算法直接从优化网损变成了无条件保电压最后收敛得到的方案网损比不接入DG还高完全失去意义。正确做法是让罚项只在越限时才起作用并且越限程度越大惩罚越大而不是一越限就一票否决。2.5 多目标处理策略权重系数与Pareto集合多目标寻优的实现方案一般有两种一个是加权求和一个是Pareto支配关系。我程序中两种都做了默认用加权求和快速出结果同时记录非支配解供后续分析。加权求和的关键是权重怎么定。我的做法是先跑一次原系统潮流得到基准网损和基准电压偏差把两个目标归一化后再加权让它们在数值上处于同一量级。这样权重系数就代表真实的偏好程度而不是被数值范围扭曲。比如F w1 * F1 w2 * F2 w3 * (1 - F3) 罚函数项权重w1、w2、w3可以按需求调整。偏重经济性就把w1调大偏重电能质量就调大w2想多消纳光伏就调大w3。我在测试算例中默认取w10.4w20.3w30.3效果比较均衡。3. PSO算法用于选址定容的关键设计3.1 粒子编码位置变量和容量变量怎么塞进一个维数里PSO的常规编码方式是把每个待优化变量当作一维。选址定容涉及两类变量接入节点编号离散和接入容量连续不能直接混在一个维度里做连续寻优。我用的编码方案是连续变量取整映射。假设有N个候选节点每个粒子维度设为2N第1~N维对应每个候选节点是否接入DG的权重值范围[0, 1]第N1~2N维对应每个候选节点的DG安装容量范围[0, 单节点容量上限]在解码时前N维中大于0.5的视为该节点选中并将相应的容量维度的值作为实际安装容量。小于0.5的节点视为不安装其容量维度直接置零。这样PSO的速度—位置更新公式可以正常使用不需要处理离散空间的特殊算子。这种软编码的好处是PSO的连续搜索特性没有被破坏而且因为权重值是连续的粒子可以在0.5附近来回试探相当于隐式地让节点选择过程具备一定的可微性收敛过程不会因为离散切换而剧烈震荡。3.2 惯性权重、学习因子与速度限制PSO在选址定容这种高维、多峰值问题上参数设置比很多教程里写的要敏感得多。我最终采用的是惯性权重线性递减策略w w_max - (w_max - w_min) * (iter / iter_max)w_max取0.9w_min取0.4。前期大惯性权重保证全局搜索能力不容易被局部最优骗住后期小权重增强局部精细搜索提升收敛精度。学习因子c1和c2我取2.0和1.5略不对称。原因是个体认知系数稍大一些能让粒子在前期保持一定的自我探索空间减少群体早熟的概率。速度上限设为变量取值范围的20%左右避免粒子飞出可行域太远导致后续解码出的方案完全畸变。3.3 约束违规与罚函数处理罚函数处理前面已经提过。程序里具体做了三件事每次潮流计算后检查所有节点电压是否在[0.95, 1.05] p.u.范围内超出部分的平方和作为电压罚项检查每条支路功率是否越限越限比例作为支路罚项检查DG总容量是否超过渗透率上限超过比例作为渗透率罚项三个罚项乘以各自罚系数后加进总目标值。罚系数一般在100~1000之间具体数值我通过测试确定——基本原则是让不可行方案的适应度明显劣于可行方案但不至于让算法完全忽略原始目标。需要特别注意的是罚函数的惩罚强度不是越大越好。当罚函数项在目标函数中占绝对主导时PSO根本分不清两个可行解的优劣最终只能保证可行而不能保证最优。这是在多个算例中都验证过的现象。3.4 潮流计算与PSO的耦合方式PSO和潮流计算的耦合是程序性能的瓶颈。一个粒子代表一个DG接入方案要评价这个方案就必须重新跑一次潮流。如果做24时段动态潮流每个粒子就要跑24次潮流。粒子数50、迭代次数100就是5万次潮流计算耗时非常可观。我在程序里做了两个优化。第一潮流计算采用前推回代法并且在Python版本里预计算了网络的稀疏结构MATLAB版则用矢量化的节点矩阵运算代替循环单次潮流速度从毫秒级降到亚毫秒级。第二做24时段评价时如果相邻时段的光伏出力差异不大可以设置一个收敛容忍度把出力变化小于阈值的时段用上一步潮流结果近似代替大幅减少重复计算。这个近似加速在实际工程中很有价值。规划阶段的精度要求并没有高到必须逐时段精确仿真的程度牺牲极小精度换取数量级的计算加速完全可以接受。4. MATLAB程序实现框架与核心代码4.1 主程序流程整套MATLAB程序的结构不算复杂核心是PSO主循环加潮流计算函数。主流程如下加载配电网参数节点数、支路数、阻抗矩阵、负荷分布初始化PSO参数粒子数、迭代次数、速度范围、粒子位置进入迭代循环对每个粒子解码得到DG选址定容方案调用潮流计算函数得到各节点电压、支路电流计算三个目标函数值和罚函数项更新个体最优和全局最优更新所有粒子的速度和位置输出最优方案、收敛曲线和优化前后电压对比用伪代码表达就是%% 初始化 num_particles 50; max_iter 100; dim 2 * num_candidate; pos rand(num_particles, dim); vel zeros(num_particles, dim); pbest pos; pbest_fitness inf(num_particles, 1); gbest pos(1, :); gbest_fitness inf; %% PSO主循环 for iter 1:max_iter for i 1:num_particles % 解码获取选址与定容方案 [placement, capacity] decode_particle(pos(i, :)); % 潮流计算与多目标评价 fitness evaluate_solution(placement, capacity); % 更新个体最优和全局最优 if fitness pbest_fitness(i) pbest(i, :) pos(i, :); pbest_fitness(i) fitness; end if fitness gbest_fitness gbest pos(i, :); gbest_fitness fitness; end end % 更新惯性权重和粒子速度、位置 w w_max - (w_max - w_min) * (iter / max_iter); vel w * vel c1 * rand(size(vel)) .* (pbest - pos) ... c2 * rand(size(vel)) .* (gbest - pos); vel max(min(vel, vel_max), -vel_max); pos pos vel; end4.2 关键代码粒子解码与潮流调用粒子解码函数是整个程序里最容易写错的地方。我的实现思路很直接function [placement, capacity] decode_particle(particle) num_candidate numel(particle) / 2; sel_weight particle(1:num_candidate); cap_value particle(num_candidate1:end); placement zeros(num_candidate, 1); capacity zeros(num_candidate, 1); for i 1:num_candidate if sel_weight(i) 0.5 placement(i) candidate_nodes(i); capacity(i) cap_value(i); % 已限制在 [cap_min, cap_max] end end end这里有个小坑如果某个粒子前N维全部小于0.5解码得到的方案就是一个不接入任何DG的方案此时PSO实际上在退化回原始网损的边界条件。为了避免这种情况我在初始化时保证了每个粒子至少随机选择1~2个候选节点否则该粒子重新初始化。这个细节很重要否则大部分粒子在初期都指向不装DG算法会严重偏向保守方案。潮流调用部分我封装了一个函数function [V, I_branch] powerflow(bus, branch, load, dg_injection) % 前推回代法求解辐射状配电网潮流 % bus: 节点参数矩阵 % branch: 支路参数矩阵 % load: 各节点有功无功负荷 % dg_injection: DG注入功率 % 返回节点电压V和支路电流I_branch end这个函数内部实现了节点编号排序、分层计算和前推回代迭代迭代收敛条件设为相邻两次迭代电压差的无穷范数小于1e-6。因为前推回代法对R/X比较大的配电网依然收敛良好且无需计算雅可比矩阵在PSO反复调用时效率优势非常明显。4.3 光伏出力建模光伏出力不能简单地按额定容量直接当作恒定功率源。我在程序里使用了一个典型日的光照强度曲线通过简化的线性模型计算每个时段的光伏出力P_pv(t) P_rated * (G_t / G_ref) * eta 当 G_t G_cutoff 时G_t是t时刻的光照强度G_ref是参考光照强度1000W/平方米eta是综合考虑温度影响和逆变器效率的系数一般取0.85~0.95。光照曲线我直接在程序里内置24个时段的典型值中午时段最高夜间为0。这样程序才能模拟出白天光伏大发、夜间零出力的真实场景。负荷同样分24时段。我采用的日负荷曲线是配电网典型的双峰形态早晚两个高峰中午较低。这个光伏大发但负荷不高的组合正是研究光伏消纳问题的核心场景。4.4 结果输出与可视化优化完成后程序会输出三样东西最优DG配置方案接入节点编号、对应容量收敛曲线每次迭代的全局最优适应度值优化前后对比电压分布曲线、网损数据和光伏消纳率可视化部分主要用MATLAB的plot。电压分布对比是必画的——横轴节点编号纵轴电压幅值优化前和优化后用两条线叠加能直观看到DG接入对电压的抬升作用。收敛曲线用semilogy画能更清楚地看到适应度在不同阶段的下降趋势。5. 测试算例IEEE 33节点系统实测结果5.1 算例参数我在IEEE 33节点标准配电网测试系统上验证了整套程序。系统参数如下项目数值节点数33含根节点支路数32基准电压12.66 kV总负荷3.72 MW 2.30 Mvar候选安装节点8个根据负荷密度和距变电站距离筛选单节点容量上限0.5 MW渗透率上限25%粒子数50迭代次数100候选节点的选择本身也有讲究。不是所有节点都能装DG一般要考虑场地条件、网架结构和负荷需求。我选了负荷较重、距离电源点较远的节点作为候选这样更贴近实际工程中的光伏优先安装在负荷侧原则。5.2 收敛曲线分析从收敛曲线看前期迭代适应度下降非常快大约20代以内就能搜索到接近最优的区域30代之后曲线逐渐平缓主要是在局部精细调整容量值。我运行多次程序最优方案基本落在同一组节点上说明算法稳定性尚可没有出现严重的早熟现象。惯性权重递减策略在这里起了关键作用。如果固定w0.6不衰减算法基本在40代就停滞最终结果比衰减策略下的最优解要差5%~8%。这正好验证了前期需要大范围探索、后期需要精细收敛的规律。5.3 优化前后对比优化前系统总网损约为202kW部分末端节点电压最低到0.93 p.u.附近已经逼近工程上不可接受的范围。优化后以默认权重w10.4w20.3w30.3为例的效果如下指标优化前优化后变化系统网损202 kW151 kW下降25.2%最低节点电压0.93 p.u.0.97 p.u.明显提升电压偏差指标0.0450.021下降53%光伏消纳率88%97%提升9个百分点网损下降25%这个结果在配电网规划里已经相当可观。更重要的是最低节点电压从0.93提升到0.97意味着系统抵抗负荷增长的能力增强了。从工程角度看这相当于延缓了网架改造的投入价值远大于网损本身的节省。6. 调参踩坑记录从局部最优到稳定收敛6.1 惯性权重衰减方式的影响这部分是我的血泪经验。最早一版程序用的方式很简单把惯性权重固定为0.8结果每次运行结果都不一样有时候收敛到一个明显不是全局最优的解有时候电压约束明明已经被罚得很厉害算法却始终没有改善的迹象。后来逐步测试才发现固定权重下PSO在前期收敛过快粒子群在30代左右就完成了抱团一旦大家都聚集到局部最优点附近c1和c2的随机扰动根本不足以让粒子跳出去。改成线性递减后前期0.9保证搜索范围后期0.4保证收敛精度问题立刻缓解。更进一步我还测试过余弦衰减和非线性递减收敛精度差别不大但线性递减的实现最简单效果最稳定。在没有强理由选更复杂策略的情况下我建议优先用线性递减。6.2 罚函数系数设置罚函数系数是我调试中踩过的第二个坑。最开始我把电压越限罚系数设为5000理由是让不可行解付出惨痛代价结果优化出来的方案全部把DG装在电压最高的节点附近网损几乎等于原系统光伏消纳也差。因为过大的罚项把网损优化这个主要目标彻底盖住了PSO的搜索压力全部集中在别让电压越限上根本没心思优化网损。后来我把罚系数降到200同时把罚函数设计成越限程度平方的形式效果好了很多——算法既没有牺牲太多原始目标又能有效避开电压越限的解。经验是罚函数只负责纠正方向不能让它喧宾夺主。先用无罚函数或小罚函数跑一遍看看自然最优解大概在什么范围再根据这个范围调整罚系数比自己拍脑袋设一个合适的数要靠谱得多。6.3 维数灾难与粒子数选择候选节点一旦变多粒子维度就成倍增加粒子数也要跟着涨。我在33节点系统里候选节点8个粒子维度是16维用50个粒子就够了。但在一个实际馈线模型里候选节点扩大到20个维度变成40维50个粒子已经明显不够收敛曲线出现很长时间的平台期最终结果也不理想。把粒子数加到100才恢复正常。粒子数和维度的关系没有精确公式我的经验是粒子数至少取维数的3倍当维度达到40维以上取4~5倍更稳妥。当然代价是计算时间增加如果做了24时段动态潮流计算量会成倍上升这时就需要用4.5节提到的近似加速或并行计算来兜底。6.4 潮流调用次数与并行计算优化程序运行速度是整个项目最头疼的问题。33节点系统、24时段动态潮流、50个粒子、100次迭代最原始的版本跑一次要将近20分钟。后来做了三件事前推回代法矢量化和预计算分层编号单次潮流从约5ms降到约1ms相邻时段光伏出力变化小于阈值时复用上一次潮流结果粒子评价循环用parfor并行多核并行后整体耗时降到3分钟左右对于规划类课题3分钟跑一次完整优化完全可以接受。如果是更大型的配电网我还会建议把潮流计算改成调Matpower刀闸式函数或商用潮流软件接口不过那就是另一个话题了。写到这里回头再说一点个人体会。这套程序最核心的价值不在PSO本身——PSO算法本身网上到处都是难的是把配电网潮流的物理约束和规划问题的决策变量无缝衔接起来。模型建得好、约束处理得对、参数调得到位结果才可信。我后来在多个算例里反复验证发现优化方案对候选节点集的选择特别敏感所以强烈建议做这类项目时先把配电网拓扑和负荷分布的数据吃透再进算法环节。程序代码可以后补数据和分析思路才是决定成果质量的地基。
阅读完成 · 觉得有帮助?
咨询建站