ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

基于MOPSO的主动配电网实时无功优化仿真平台搭建与实现

基于MOPSO的主动配电网实时无功优化仿真平台搭建与实现 做配电网无功优化这个方向的同行应该都有体会项目最麻烦的往往不是算法本身而是怎么把“风电和光伏接入”“实时”“多目标”这几个词同时落到实处。我最近用Matlab搭了一套主动配电网实时无功优化仿真平台核心是采用多目标粒子群算法MOPSO处理网损最小和电压偏差最小两个目标风电和光伏按不同渗透率接入IEEE 33节点算例跑通了全天24个时段的滚动优化。这篇就把整个实现过程的思路、模型、代码细节和踩坑记录整理出来给正在做类似课题的研究生或工程技术人员一个可以直接参考的完整方案。先说结论这套平台从建模到跑完24小时场景仿真核心耗时全在算法迭代和潮流计算之间反复调用实时性的瓶颈也在这。要是你正准备做主动配电网优化方向或者已经被导师安排到“含分布式电源的无功优化”这个课题上这篇内容应该能帮你少走几个月的弯路。1. 先看清问题主动配电网里的无功优化到底在调什么1.1 为什么分布式电源接入后无功问题变复杂了传统配电网的无功优化是个相对成熟的领域目标就是通过调节有载调压变压器分接头、并联电容器组投切这些设备让网络在满足电压约束的前提下网损最小。但风电和光伏大规模接入后情况完全变了个样。首先是随机性。光伏出力跟着光照走风电出力跟着风速走这两个都是典型的强波动电源。早晨光伏爬坡时段馈线电压可能被推高傍晚光伏骤降电压又可能跌落风电就更不可控了一阵强风过来局部节点电压可能直接越上限。传统配电网那种“固定时段调一次”的静态无功优化已经没法应对这种分钟级的波动。其次是潮流方向的改变。传统配电网是单电源辐射状供电潮流从变电站母线单向流向负荷。但分布式电源就地注入功率后馈线某些区段可能出现潮流反转这时候原本按单向潮流设计的无功补偿策略就会失效甚至可能加剧电压问题。这也是“主动配电网”这个概念的核心——从被动接受到主动管理配电系统需要实时感知分布式电源出力变化并快速调整控制手段。1.2 “网损最小电压偏差最小”两个目标的现实含义标题里的“以网损和...”后面省略的第二个目标在绝大多数工程实践和文献里都是电压偏差Voltage Deviation或电压越限程度。我在这套实现里用的就是网损最小和电压偏差最小两个目标函数二者在物理意义上是存在冲突的。网损最小化偏向于让无功就地平衡减少长距离无功传输电压偏差最小化则偏向于把各节点电压尽量维持在额定值附近。但配电网的电压是由有功和无功共同决定的风电光伏注入点的电压抬高问题有时候要通过调节无功补偿设备和变压器分接头来解决可这又会增大某些支路的无功流动导致网损上升。两者需要Pareto折中——这就是为什么不能用单目标优化一把梭的原因。从数字上看一下两个目标的表达式。第一个目标是系统网损最小[ \min f_1 \sum_{k \in E} G_k \left( V_i^2 V_j^2 - 2V_i V_j \cos\theta_{ij} \right) ]第二个目标是节点电压偏差最小[ \min f_2 \sum_{i1}^{N} \left| V_i - V_{ref} \right| ]其中 ( V_{ref} ) 通常取1.0 p.u. ( N ) 为系统节点数。我实际测试的时候发现如果不加权重直接做单目标把网损做到最小末端节点电压往往会压到0.95 p.u. 附近反过来如果只做电压偏差最小网损可能比最优值高出30%以上。两个目标的冲突性就是这么直观。1.3 为什么选多目标粒子群而不是其他算法现在做多目标优化的算法很多NSGA-II是学术界的常客单目标PSO加权重法在工程上也常见那我为什么最终选择了MOPSO第一是因为PSO收敛速度快。实时优化对计算时间有硬约束NSGA-II里非支配排序和拥挤度计算在每代都要重做种群规模一大就拖慢迭代。PSO本身没有选择、交叉、变异那套遗传操作粒子直接通过速度-位置更新公式飞行对大种群的计算负担更轻。在配电网潮流计算本身就是主要耗时的那道坎上算法自身开销能省一点是一点。第二是因为MOPSO处理连续变量很自然。配电网里电容器组的容量分组虽然是离散的但逆变器无功出力、SVC补偿容量、分布式电源的无功功率这些控制变量本质是连续的PSO的连续变量编码天生匹配这类问题。第三是因为MOPSO做多目标的框架清晰。基于Pareto支配关系维护一个外部档案集用网格法保持解的多样性整体结构比在单目标框架里反复加权求解要直接得多。实际跑下来在IEEE 33节点算例上MOPSO找到的Pareto前沿质量、分布均匀性是完全够用的。2. 从模型到代码搭建仿真平台的关键决策2.1 算例选择与数据准备算例选了IEEE 33节点配电网系统这是一套标准的辐射状配电测试系统基准电压12.66 kV基准功率10 MVA含32条支路总负荷约3715 kW 2300 kvar。这个算例在各类含分布式电源接入的研究里用得最多好处是数据公开、结果可对比你随便搜都能找到它的线路参数表。分布式电源接入位置和容量我是这样设置的风机在节点18一条长馈线的末端电压本身就容易偏低风机出力可以抬升电压光伏在节点22和节点33各接一组容量分别按照渗透率来定。渗透率我设置为20%~40%之间几个场景渗透率的定义是分布式电源总出力占系统总负荷的比例。由于“实时”优化要跑全天24个时段需要准备两类时序数据负荷曲线和分布式电源出力曲线。负荷曲线我用的是典型的配电网日负荷标幺值曲线峰值出现在18:00~21:00低谷在03:00左右。光伏出力曲线按正态分布的高斯曲线模拟中午12点左右达到峰值风机出力用实测风速数据拟合的功率曲线来生成波动性比光伏更大。这些数据在Matlab里用函数生成然后保存为.mat文件在仿真主程序中直接加载。以33号节点为例分布式电源接入数据设置如下节点电源类型额定容量接入方式18风电400 kW恒功率因数0.9522光伏300 kW逆变器无功可调-200~200 kvar33光伏300 kW逆变器无功可调-200~200 kvar这里有一个关键选择风机按恒功率因数处理光伏逆变器按无功可调处理。原因是风机部分我假设是异步机直接并网无功调节能力有限光伏逆变器则具备PQ解耦控制能力可以在一定范围内提供无功支撑。这两类控制方式对应了实际工程中不同类型分布式电源的接入方式也让优化问题里包含不同类型的控制变量。2.2 潮流求解方案Matpower还是自编牛顿-拉夫逊无功优化的每一次粒子评价都需要做一次潮流计算潮流求解器是整个平台的计算核心。我最初尝试自编牛顿-拉夫逊法但很快放弃了——配电网的线路R/X比高潮流收敛性比输电网差自己调试收敛判据和松弛因子的工作量非常大。最终选择了Matpower工具包它是Matlab环境里最成熟的开源潮流计算工具。% 调用Matpower进行潮流计算 mpc loadcase(case33); mpc.bus(:, 3) P_load; % 更新有功负荷kW - MW mpc.bus(:, 4) Q_load; % 更新无功负荷 mpc.bus(:, 9) Xd; % 分布式电源有功出力 mpc.bus(:, 10) Qd; % 分布式电源无功出力补偿容量 % 设置发电机节点 gen_idx find(Xd 0); mpc.gen zeros(length(gen_idx), 21); mpc.gen(:, 1) gen_idx; mpc.gen(:, 2) Xd(gen_idx); mpc.gen(:, 3) Qd(gen_idx); mpc.gen(:, 4) Qmax_val; mpc.gen(:, 5) Qmin_val; mpc.gen(:, 6) 1; % 参与调度 mpc.gen(:, 7) 1; % 电压幅值初值 opt mpoption(OUT_ALL, 0, VERBOSE, 0); results runpf(mpc, opt);要注意Matpower的单位换算。Matpower内部基准功率是MW/Mvar而配电网负荷通常用kW/kvar表示写代码时一定要统一量纲不然潮流解出来电压和功率完全对不上。使用Matpower还有一个额外的好处runpf会返回每个节点的电压幅值、相角、支路潮流和系统总网损这些数据正是目标函数计算需要的不用自己再从雅可比矩阵里额外提取省了很多后处理的工作。2.3 控制变量的编码方式MOPSO中的每个粒子代表一组无功控制方案粒子位置向量的维度就是控制变量的个数。我的控制变量按下表设计变量编号控制变量类型范围1~5节点18~22处的补偿电容器组投切容量连续归一化0~1映射到0~300 kvar6~7光伏逆变器无功出力连续-200~200 kvar8变电站有载调压变压器分接头挡位离散归一化0~1映射到0.95~1.05 p.u.这里有个细节需要注意变压器分接头和电容器组本质是离散变量但标准MOPSO是连续优化算法。我采用了“连续编码就近取整”的方式即粒子在连续空间飞行计算适应度时把对应维度做个取整映射。这样做的好处是保持了粒子群在连续空间中的收敛特性缺点是取整会引入量化误差所以我加了变异操作来弥补离散化带来的多样性损失。看一下粒子编码的核心代码function [X_quant, X_round] decode_particle(x, dims) % x: 粒子位置向量范围[0,1] % X_quant: 量化后的实际控制量 % 电容器组映射到0~300 kvar cap_idx 1:5; X_quant(cap_idx) round(x(cap_idx) * 3) * 100; % 0, 100, 200, 300 kvar % 逆变器无功映射到[-200, 200] kvar inv_idx 6:7; X_quant(inv_idx) x(inv_idx) * 400 - 200; % 变压器分接头映射到[0.95, 1.05]步长0.0125 tap_idx 8; tap_pos round(x(tap_idx) * 8) / 8; % 9挡 X_quant(tap_idx) 0.95 tap_pos * 0.1; end这里的映射关系是核心务必根据实际设备参数来定义取值范围不能照搬。尤其逆变器无功范围要参考所选的逆变器型号我用的±200 kvar是针对300 kW光伏组串配置的常见参数实际项目要看设备手册。2.4 约束处理与罚函数设计无功优化问题有等式约束潮流方程和不等式约束控制变量上下限、节点电压上下限。等式约束由Matpower的runpf在潮流求解时自动满足关键是处理不等式约束。控制变量本身的上下限我在粒子初始化时就直接限定在[0,1]范围内飞行更新后做越界钳制clipping这很简单。真正的难点在节点电压约束。配电网的电压允许偏差一般是额定值的±7%也就是0.93~1.07 p.u.。如果直接将越限粒子判为不可行会导致可行性压力过大粒子群在搜索早期容易全部聚集到可行域内丢失边界区域的Pareto解。我采用的是罚函数法。具体做法是在电压偏差目标函数中叠加一个较大的惩罚项当节点电压越限时惩罚会急剧放大目标值从而引导粒子向可行域飞行。惩罚系数不能太小太小则越限解可能成为伪Pareto最优也不能太大太大会让目标函数地形过于崎岖降低收敛速度。我经过调参后最终取惩罚系数为1000效果比较理想。function fitness evaluate_particle(x, mpc_base, load_data, dg_data) % 解码控制变量 controls decode_particle(x); % 更新潮流数据 mpc update_mpc(mpc_base, load_data, dg_data, controls); % 潮流计算 opt mpoption(OUT_ALL, 0, VERBOSE, 0); results runpf(mpc, opt); if results.success ~ 1 % 潮流不收敛赋予极大惩罚值 fitness [1e6, 1e6]; return; end % 目标1网损 loss results.branch(:, 14) results.branch(:, 15); f1 sum(loss) * 1000; % 转换为kW % 目标2电压偏差之和 V results.bus(:, 8); V_dev sum(abs(V - 1.0)); % 电压越限惩罚 V_low 0.93; V_high 1.07; pen sum((V - V_high) .* ((V - V_high) 0)) ... sum((V_low - V) .* ((V_low - V) 0)); pen pen * 1000; f2 V_dev pen; fitness [f1, f2]; end罚函数值是经验性参数在目标函数值本身量级很小时适当调大罚函数值有助于粒子迅速回到可行域。我测试的时候发现罚函数值从100调到1000前50代收敛速度明显加快再往上调就开始影响解的多样性了。3. 多目标粒子群核心细节从基础原理到改进实现3.1 Pareto支配关系与外部档案集MOPSO里的核心数据组织方式是“外部档案集”External Archive用来存放当前找到的非支配解集。判断一个解是否应被放入档案靠的是Pareto支配关系——在多目标优化里一个解A支配解B意味着A在所有目标上都不差于B且至少在一个目标上严格优于B。所有不被任何其他解支配的解构成非支配解集。对应到这里就是方案A比方案B网损更小、电压偏差也更小那B就没有存在价值如果A网损小但电压偏差大B网损大但电压偏差小两者互不支配都是Pareto解都要保留在档案中。这个关系可以用下面这段代码实现function dominate_flag dominates(ind1, fit1, ind2, fit2) % 判断ind1是否支配ind2两个目标都是越小越好 better false; for k 1:2 if fit1(k) fit2(k) dominate_flag false; return; end if fit1(k) fit2(k) better true; end end dominate_flag better; end档案集的维护逻辑是每个粒子更新后如果新解被档案中某个解支配则拒绝加入如果新解支配了档案中的某些解则删除被支配的解并把新解放入档案如果新解与档案中所有解互不支配则加入档案。但当档案容量满了之后就需要用多样性保持机制决定删除哪些解。3.2 网格法保持解的均匀分布档案集容量我设置为100。但实际操作中迭代几代后档案很容易满且解分布会逐渐向某个区域聚拢——如果只保留非支配解不管分布十几个解就挤在Pareto前沿的一小块区域另一端完全没有解那这个多目标结果参考价值就很低了。解决分布性问题用的是网格法。具体做法是把目标空间划分为一个个等宽网格每个解根据其目标函数值落入某个网格然后通过统计各网格内解的数量来调节分布。当档案满时优先删除网格内解数量最多的那个解选择全局最优gbest时则从解数量最少的网格中随机选一个解。function [grid_idx, grid_prop] grid_division(fitness, grid_num, min_f, max_f) % 将目标空间划分为grid_num x grid_num的网格 % 输出粒子所属网格编号和网格属性 d (max_f - min_f) / grid_num; g1 min(grid_num, max(1, floor((fitness(1) - min_f(1)) / d(1)) 1)); g2 min(grid_num, max(1, floor((fitness(2) - min_f(2)) / d(2)) 1)); grid_idx sub2ind([grid_num, grid_num], g1, g2); end一开始我担心网格法要维护网格坐标比较麻烦实际实现下来发现也就几十行代码的事而且效果立竿见影——最终Pareto前沿的均匀性明显好于不用网格法的版本。如果你的问题目标数超过3个网格法的效率会下降那时候可以考虑改用拥挤度距离或者参考向量法。3.3 粒子速度-位置更新与边界处理MOPSO的粒子更新沿用了经典PSO的速度-位置更新公式[ v_i(t1) w v_i(t) c_1 r_1 (pbest_i - x_i(t)) c_2 r_2 (gbest_i - x_i(t)) ][ x_i(t1) x_i(t) v_i(t1) ]其中 ( w ) 是惯性权重 ( c_1 )、 ( c_2 ) 是学习因子 ( r_1 )、 ( r_2 ) 是[0,1]均匀随机数。 ( pbest_i ) 是粒子个体历史最优 ( gbest_i ) 是全局最优从外部档案集中通过网格法选择。参数设置上我试了两组配置参数第1组第2组最终采用惯性权重 w0.4固定0.9递减到0.4学习因子 c1/c21.5/1.52.0/2.0种群规模50100最大迭代次数100200变异概率00.1线性递减惯性权重的效果很明显。前期w大粒子探索能力强能够覆盖宽敞的搜索空间后期w小收敛能力强避免在最优解附近振荡。实际上对于8维控制变量的中等问题固定w0.4也能收敛但Pareto前沿的覆盖面差一些。把w从0.9线性减到0.4是在求解质量和收敛速度之间一个比较稳妥的选择。边界处理采用简单地钳制粒子位置更新后如果某维越界就把该维拉到边界上并把该维的速度归零。避免粒子反复在边界上弹跳导致后续迭代搜索效率下降。3.4 实时性的落地24时段滚动优化说回“实时”这两个字。实时无功优化并不是说要把仿真时间压缩到秒级以下那是硬件和RTDS干的事而是在满足控制需求的前提下把决策周期缩短到分钟级并用滚动优化的思路来跟踪系统变化。我的做法是将24小时划分为96个时段每15分钟一个时段在每个时段开始时根据负荷预测和新能源出力预测数据启动一次MOPSO优化得到该时段的最优无功控制方案执行到下一个时段之前。也就是说每个时段都要跑一遍完整的MOPSO迭代流程期间潮流计算次数等于 种群规模 × 最大迭代次数 100 × 200 20000次。Matpower单次潮流约5~10毫秒一个时段就要100~200秒96个时段累积约3~5小时。对离线仿真研究来说可以接受但对真正的在线应用肯定不够。所以在仿真平台里我做了三项优化第一预测数据和实时数据分离。仿真时认为光伏和风电出力“已知”每个时段直接采用该时段出力数据作为优化输入省去在线预测模块——这是离线仿真的简化假设做在线实时系统时需要增加预测环节。第二上一时段的解冷启动当前时段。由于相邻时段负荷和出力变化是连续的上一时段的最优解在当前时段依然是个不错的初始解。把上时段的档案集和部分粒子用来初始化当前时段的种群可以显著减少达到收敛所需的迭代次数。实测下来用冷启动策略后单时段收敛所需的迭代次数可以从200下降至70~100左右。第三潮流计算加速。Matpower的runpf每次都要重新组装导纳矩阵如果能提前把电网拓扑结构和导纳矩阵缓存复用相同拓扑下的潮流求解也可以节省大量时间。这个优化我在最终版本做了但效果有限——因为配电网的节点注入功率每时段都在变导纳矩阵的解析本身不是主要耗时点。真正的耗时点在牛顿法的迭代过程这部分受问题规模约束不好再加速。4. 仿真结果怎么看、怎么用4.1 Pareto前沿与决策分析先看24个时段中的典型时段——中午12:00光伏出力峰值时段。这个时段光伏出力达到接近额定值配电网电压容易被抬高网损和电压偏差的冲突最为明显。MOPSO运行结束后输出Pareto前沿横轴为网损kW纵轴为电压偏差p.u.。从结果可以看出Pareto前沿呈典型的L形分布网损最小的一端电压偏差达到0.15 p.u.左右电压偏差最小的一端网损接近160 kW。前沿在两个端点之间连续分布提供了多个可选方案。实际操作中决策者可以根据调度偏好从中选点——比如采用最小距离法选择Pareto前沿上距离理想点网损0、电压偏差0最近的解作为最终方案简单实用。我用最小距离法筛选出的妥协解网损约为97 kW电压偏差约为0.08 p.u.相比优化前的基础潮流结果网损约131 kW电压偏差约0.21 p.u.网损下降了26%电压偏差下降了62%。这个结果验证了MOPSO方案在折中意义上的有效性。4.2 电压剖面改善效果再看全天电压剖面。以节点18为例风电接入末端节点未优化时该节点全天电压波动范围是0.92~1.08 p.u.已经出现了越限风险。采用MOPSO滚动优化后节点电压被控制在0.95~1.04 p.u.之间全天都没有越限。这组数据说明一个关键点实时优化的价值不只是降低网损更核心的是保证电压质量。在分布式电源渗透率较高的时段午后光伏出力高峰如果不做无功优化末端节点电压很可能被抬到1.07 p.u.以上。风电和光伏在时间上互补的特性也让优化存在时间维度上的协调空间——午后光伏出力大、负荷相对低电压偏高问题突出晚间负荷高峰时光伏出力归零电压又可能偏低。MOPSO在每个时段重新优化天然适配这种时变特性。时段类型优化前电压/p.u.优化后电压/p.u.08:00光伏起步负荷爬升0.9890.99512:00光伏峰值负荷持平1.0621.01616:00光伏回落负荷上升1.0311.00420:00光伏归零负荷高峰0.9460.9834.3 不同渗透率场景的对比分析为了验证方案的适应性我另外做了30%和40%渗透率两个场景。对比结果很有意思渗透率从20%提高到30%时网损和电压偏差的最优Pareto前沿整体下移说明分布式电源接入改善了局部无功电压支撑条件。但渗透率到40%时前沿反而上移了尤其是电压偏差目标明显恶化——这是因为光伏渗透率过高后馈线上的倒送功率显著增加末端电压被抬得过高现有的电容器组和逆变器无功容量已经不足以完全平抑电压波动。这个发现对我们实际做项目有个重要提示分布式电源接入容量不是越多越好无功优化设备的容量配置需要与分布式电源渗透率匹配。算出来临界点在35%左右超出这个水平后需要考虑额外配置动态无功补偿装置或者储能系统参与电压调节。5. 常见问题与排查实录5.1 典型问题排查速查表现象可能原因解决方法潮流计算不收敛分布式电源出力 负荷需求系统失稳检查注入功率量级增加平衡节点容量或改用分布式潮流算法Pareto前沿只有几个点网格数太大/档案集太小多样性丢失增加档案集容量减小网格划分数增加变异概率优化结果反复震荡惯性权重过大或学习因子不匹配使用递减惯性权重减小c2电压约束频繁越限罚函数系数偏小将罚函数系数调至目标值量级的100~1000倍粒子全部聚集到边界边界钳制导致速度丢失越界后随机重置该维而非简单归零5.2 潮流不收敛的深层排查Matpower的runpf返回success0时最初我以为是分布式电源出力设置有问题反复检查了一整天。后来才发现真正原因是过大的光伏出力导致局部节点电压超过1.1 p.u.牛顿法在迭代中发散。这个问题表面上看起来是数学问题实际上反映了物理本质——配电网承载分布式电源的容量确实有限电压越限会导致潮流无解。排查办法分三步走第一步检查Matpower弹出的警告信息看是发散还是在迭代边界徘徊第二步把分布式电源出力逐步调小找到能收敛的临界值判断系统承载极限第三步把变压器分接头和电容器补偿放到较大值后重新计算确认无功支撑可以有效改善电压收敛性。这个排查过程本身就是对配电网承载能力的认知过程做多了就大概能估算出不同线路能带多少装机了。5.3 粒子分布不均的调试记录有几次运行完我画Pareto前沿图发现30个非支配解全挤在目标空间的左上角右下角大片空白。第一反应是算法本身收敛过快多样性不足。尝试把变异概率从0.05提高到0.1效果有一点但不明显。后来分析目标函数分布才发现电压偏差目标函数本身数值范围就是0.05~0.3而网损是50~150两个目标量纲差异很大导致网格划分时每个网格在电压偏差维度的宽度只有0.005左右而在网损维度却有5 kW出头——网格形状极度狭长解在网格计数上表现为稀疏多样性判断失真。解决方法是先对两个目标做归一化让它们都映射到[0,1]区间然后再划分网格。归一化后网格形状变成了正方形解的分布均匀性立刻提升。这个坑在文献里很少被提到但对实际调试的影响非常大强烈建议每个做MOPSO的同行都注意。6. 一点后续扩展的想法项目目前算是跑通了离线仿真验证但我个人觉得还有几个方向可以继续深挖。第一是加入储能系统的联合优化。储能在时序上具有跨时段调节能力如果能把储能的充放电功率和SOC状态纳入MOPSO控制变量优化问题就从单时段变成了带时间耦合的多时段优化模型更贴近“源网荷储”协同的实际场景但求解复杂度也会明显上升。第二是用深度强化学习替代滚动MOPSO。虽然我实测下来的滚动优化耗时已经降到了可接受范围但1秒保证不了硬实时如果未来要部署到实测定制平台训练一个DRL智能体的吸引力会越来越大。第三是考虑配电网三相不平衡问题。现在用的是正序模型实际配电网往往三相不平衡特别是单相光伏大量接入后这个问题会愈发明显把MOPSO从单相模型扩展到三相模型也是一个值得做的方向。写到最后说一句无功优化这个课题看着很传统但把分布式电源不确定性和多目标框架加进来之后需要考虑的细节远比想象中多。我这几千字只能算是个引路真正深入的时候还会遇到很多意想不到的坑希望这篇内容能帮你绕开一些我走过的弯路。
返回列表