如果要用一句话概括这个方向,我会说:把一天分成若干个时段,在每个时段里找一组无功调节手段,让全天网损尽量小、电压尽量稳,但一天下来开关设备不能来回折腾太多次。这个"不能折腾太多次",正是动态无功优化和静态无功优化之间最本质的分界线。
最近不少做配电网方向的朋友都在碰这道题——含分布式电源(DG)的配电网无功优化,算法指定用粒子群(PSO),算例指定用IEEE33节点系统。我也从"只会算静态单时段"的阶段走过来,中间踩过维度爆炸、离散变量编码、参数调不动等不少坑。这篇就以IEEE33节点系统为对象,把从问题建模、算法设计、程序实现到结果解读的完整链路说透,给准备复现或正在写论文的同学一份可以直接落地参考的思路。
1. 分布式电源接入后,无功优化为什么不能继续"照老方子抓药"
传统配电网的无功优化,本质上是一个"单向潮流下的局部问题":负荷从变电站逐级往末端流,电压沿着馈线越走越低,末端电压偏低是主要矛盾。优化手段也很固定——调节有载调压变压器(OLTC)的分接头,投切并联电容器组,少数场合配合静止无功补偿装置。因为运行方式变化不大,取一个典型负荷断面做单时段优化,结果基本够用。
分布式电源接入改变了两件根本性的事:一是潮流方向不再单向。光伏、风电大发时段,DG出力超过本地负荷,功率会倒送上游,原先"电压只降不升"的经验失效,DG接入点附近反而可能出现电压越上限。二是出力随时间剧烈波动。光伏午间出力大、夜间为零,风电随风速起伏,这导致无功优化不能再只盯一个断面,必须把一条24小时甚至96个15分钟时段的运行曲线摆在一起看。
我把两种场景的差异整理成一张表,方便快速对比:
| 对比维度 | 传统配电网 | 含DG配电网 |
|---|---|---|
| 潮流方向 | 单向,从变电站到负荷 | 双向,可能出现倒送 |
| 主要电压问题 | 末端电压偏低 | 局部电压抬升、时段性波动 |
| 无功调节资源 | OLTC分接头、电容器组 | 上述设备 + 逆变器无功能力 |
| 优化时间尺度 | 单时段为主 | 多时段耦合,设备动作受限 |
第三点值得展开说。传统观念里"无功补偿就是投电容器",但逆变器型DG在变流器容量有裕度时,可以像STATCOM一样连续输出或吸收无功,响应速度远快于机械开关。这等于给优化问题增加了连续型控制变量,调起来更灵活,但也让约束体系变得更复杂——因为你不能为了降网损把逆变器无功用到极限而不管有功输出是否被压缩。
还有一个容易忽略的现实因素:负荷曲线和DG出力曲线在时间上常常错峰。光伏出力高峰在中午,而配网负荷高峰通常在晚间,DG接入后可能让系统出现"午间过压、晚间欠压"的交替状态。如果按静态方式逐时段独立优化,结果可能给出"每个小时都要投切一次电容器"的方案,这在纸上很好看,实际却没法执行——机械开关的动作次数是有寿命限制的,频繁操作也带来安全隐患。这正是动态优化存在的理由:用一个跨越全天的统一决策模型,把设备动作次数压到合理范围。
2. 把"动态"落到数学上:目标函数、决策变量与约束体系
动态无功优化的数学模型,比单时段版本多了一层时间耦合。我在建模时把一天划分为T个时段(我常用T=24,也有文献用96),每个时段对应一组负荷水平和DG出力。下面逐个拆开说。
2.1 目标函数:全天网损最小是主目标
最常见的优化目标是日网损电量最小:
min F = Σ_{t=1}^{T} P_loss,t · Δt
其中每个时段的网损按支路求和:
P_loss,t = Σ_{ij∈Ω} R_ij × (P_ij,t² + Q_ij,t²) / V_i,t²
这里的Ω是支路集合,P_ij和Q_ij是流过支路ij的有功和无功功率,V_i是支路首端电压。可以看到,网损和"无功就地平衡"程度强相关——无功功率在线路上长距离流动,本身就制造额外损耗。把无功补偿靠近负荷和DG接入点,网损自然下降,这就是无功优化的物理本质。
有些研究会把电压偏差也并进目标函数,做成多目标加权。我在实际程序里采用的做法是:主目标仍然是网损,电压越限通过惩罚项并入适应度,不单独作为优化目标。这样既简化了编程,结果也便于和同类文献对比。
2.2 决策变量:三种设备三种数学形态
这个问题的决策变量分三类:
| 变量类型 | 设备 | 取值范围 | 数学性质 |
|---|---|---|---|
| 离散整数 | 有载调压变压器分接头挡位 | 比如1~9挡 | 整数变量 |
| 离散整数 | 并联电容器组投切组数 | 比如0~5组 | 整数变量 |
| 连续实数 | DG逆变器无功输出 | Q_min ~ Q_max | 连续变量 |
加上时间维度后,每个粒子实际上要表示的是一整天的控制策略。假设有1台OLTC、3组电容器、2个DG,T=24时段,那么单个粒子的维度就是(1+3+2)×24=144维。这就是动态优化和静态优化在编程上最直观的区别:粒子维度一下子上去了。
2.3 等式与不等式约束
约束体系包括:
- 潮流方程约束:每个节点每个时段的注入功率必须满足潮流平衡,这是等式约束,通过调用潮流计算隐式满足。
- 节点电压约束:V_min ≤ V_i,t ≤ V_max,通常取0.95~1.05 p.u.,DG渗透率高时可适当收窄上限。
- 支路电流/容量约束:线路不能过载。
- 控制变量自身边界:分接头挡位、电容器组数、DG无功出力均须在允许范围内。
2.4 时间耦合约束是动态优化的灵魂
动态和静态最大的差别,是这条约束:
Σ_{t=2}^{T} |u_t − u_{t-1}| ≤ N_max
其中u_t代表某一设备在t时段的挡位或组数,N_max是全天允许动作次数上限。OLTC分接头和电容器组分开计,比如分接头一天动作不超过5次,电容器组不超过6次。
这条约束的现实含义,打个比方:开长途车不能为了保持瞬时最省油而每分钟都猛打一次方向盘,设备动作频率太高,机械寿命和操作风险都扛不住。动态无功优化就是给"设备动作频率"上一个总量限制,迫使其在"全天最优"和"可执行性"之间找平衡。编程实现时,我把它作为罚函数加到适应度里:动作次数超出上限越多,罚得越重。也可以采用可行化修复策略,但罚函数法在PSO框架下实现成本最低,效果也够稳定。
3. 粒子群算法为什么适合这类混合整数非线性问题
确定模型之后就是选算法。为什么这个方向几乎人手一个PSO?因为它和这个问题的数学结构确实匹配。
3.1 从速度-位置更新说起
PSO的核心逻辑非常简单:一群粒子在解空间里飞,每个粒子记住自己找到过的最好位置(pbest),整个群体共享当前全局最好位置(gbest),然后每个粒子朝这两个方向靠拢。
速度更新公式:
v_i(k+1) = w·v_i(k) + c1·r1·(pbest_i − x_i(k)) + c2·r2·(gbest − x_i(k))
位置更新公式:
x_i(k+1) = x_i(k) + v_i(k+1)
其中w是惯性权重,c1和c2是学习因子,r1和r2是[0,1]之间的随机数。w大时粒子探索能力强,w小时局部开发能力强。我做动态无功优化时习惯让w从0.9线性衰减到0.4,前期快速锁定有希望的区域,后期细调。
3.2 和其他算法比,PSO胜在简单且稳
我把PSO和另外两类常见方案做了对比:
| 方案 | 优点 | 缺点 | 适用性 |
|---|---|---|---|
| 内点法/序列二次规划 | 收敛快,有严格最优性理论 | 难以直接处理离散变量和非凸约束 | 不适合含OLTC/电容器的混合整数问题 |
| 遗传算法(GA) | 全局搜索能力强,天然处理离散编码 | 编码/交叉/变异算子设计繁琐,调参维度多 | 可用,但实现成本高于PSO |
| 粒子群(PSO) | 代码简洁,参数少,对非凸问题鲁棒 | 可能早熟收敛,离散变量需映射处理 | 非常适合作为本课题的基线算法 |
从复现角度看,PSO几十行代码就能跑通一个静态版本,再扩展动态版本也不会让代码结构崩溃。而GA的交叉算子在这种"多时段串联编码"的个体上设计起来很别扭——一个时段的最优片段可能在另一个粒子身上,但交叉之后动作次数约束经常被破坏,修复逻辑相当烦琐。
3.3 编码设计与约束处理
在实际编码时,我把粒子位置向量按"设备-时段"二维展开:
x = [k_1,...,k_24, c_1,...,c_24, Qdg1_1,...,Qdg1_24, Qdg2_1,...,Qdg2_24]
- 分接头挡位k和电容器组数c是整数变量,但粒子位置是连续值。处理方式是:在评估适应度前对连续值做就近取整(round),取整后再代入潮流计算。这是混合整数PSO最简单实用的做法。
- DG无功Qdg是连续变量,但要检查是否在逆变器无功能力范围内,越界就拉到边界值。
- 动作次数约束用罚函数处理:统计相邻时段取整后变量的变化次数,超出上限就按超出次数乘以罚系数累加到适应度。
核心伪代码如下:
初始化粒子群(位置、速度) for iter = 1 to maxIter: for each particle: 1. 对位置x取整/限幅 → 得到控制变量策略u[设备][时段] 2. 计算动作次数 penalty = max(0, actionCount - Nmax) 3. for t = 1 to T: 调用前推回代潮流计算 计算该时段网损、节点电压 4. 适应度 = 日网损 + w1*电压越限罚 + w2*动作次数罚 5. 更新pbest, gbest 更新惯性权重w,更新粒子速度与位置 输出gbest对应的控制策略这套流程我在多个算例上跑过,稳定性和结果都靠谱。要注意的是:取整操作会引入"连续位置相同但取整后不同"的跳变,导致适应度函数不光滑,这一点后面专门讲坑。
4. IEEE33节点算例的程序实现细节
IEEE33节点系统是配电网研究里最常用的标准测试算例之一,公开资料多,结果便于和文献互验。我用的基础参数如下:
4.1 算例规模与基础数据
- 基准电压12.66 kV,基准容量10 MVA
- 33个节点、32条支路,辐射状拓扑
- 总负荷约3715 kW + 2300 kvar,属于中等规模馈线
- 首端节点接变电站,OLTC设在首端;电容器组和DG接入点按文献常见方案布置
DG我选了典型方案:在18号节点接入一个光伏电站(装机容量约800 kW),在22号节点接入一个风电场(约600 kW),在33号末端节点再接一组光伏(约500 kW)。为什么这样放?因为18号和33号分别是两条长馈线的末端,电压最薄弱;22号在中段,用来观察DG接入对中段电压的抬升作用。这个组合能比较全面地暴露含DG配网的电压问题。
4.2 负荷曲线和DG出力曲线的时序处理
动态优化必须有时间曲线。负荷方面,我采用典型日负荷曲线,把基准负荷按比例缩放:凌晨低谷约0.5倍,午间约0.75倍,晚高峰约1.2倍。光伏出力曲线按"无出力—爬升—峰值—下降—归零"的钟形曲线建模,中午12点到14点出力最大,取额定容量的0.9左右;风电出力按日波动曲线,取0.2~0.8倍随机波动但不越界。
这里有个关键选择:时段数T取多少。T=24(每小时一个断面)比较常见,计算量适中;T=96(每15分钟一个断面)能更精细反映波动,但粒子维度变成原来的4倍,PSO收敛难度明显上升。我的做法是先用T=24验证算法正确性,再视论文需要扩展。
4.3 潮流计算选择:前推回代法
含DG配网潮流计算,我没有用牛拉法,而是用了前推回代法。这是辐射状配电网最经典的潮流算法,原理是:先假定各节点电压为额定值,从末端往首端"回代"计算各支路潮流;再根据支路潮流从首端往末端"前推"更新节点电压;反复迭代直到前后两次电压差小于收敛精度。
为什么不用牛拉法?辐射状网络的前推回代法无需形成完整的雅可比矩阵,迭代一次速度极快,编程也简单。优化算法要反复调用潮流计算(PSO 40个粒子×200代×24时段,意味着几十万次潮流计算),潮流计算快一点,整个程序就能早一点跑完。我实测下来前推回代法收敛稳定,对IEEE33这种网络几轮迭代就能达到10^-6精度。
4.4 PSO参数整定与主循环
我最终采用的PSO参数如下:
| 参数 | 取值 | 说明 |
|---|---|---|
| 种群规模 | 40 | 维度144时40个粒子够用,再大会拖慢速度 |
| 最大迭代次数 | 200 | 观察收敛曲线在150代左右趋于平稳 |
| 惯性权重w | 0.9 → 0.4 线性衰减 | 前期探索、后期开发 |
| 学习因子c1/c2 | 2.0 / 2.0 | 经典取值,个体经验和群体经验均衡 |
| 速度上限vmax | 位置范围的20% | 防止粒子飞过头 |
| 电压越限罚系数 | 100 | 保证电压越限方案被大幅淘汰 |
| 动作次数罚系数 | 50 | 每超一次动作罚50 |
主循环顺序:初始化粒子位置(在变量可行域内随机均匀分布)和速度(可取零或小随机值)→ 评估适应度 → 更新pbest/gbest → 更新速度和位置 → 判断是否达到最大迭代。每100代打印一次gbest,方便观察收敛过程。
5. 仿真结果怎么读:收敛曲线、电压剖面和动作次数
程序跑出来之后,很多人只会看"最终网损降了多少",其实动态无功优化的结果有四个维度值得逐一解读。
5.1 收敛曲线:不要只看"降下来了"
收敛曲线反映的是gbest随迭代次数下降的过程。正常的收敛曲线应该是:前50代快速下降,100代后放缓,150代后基本平直。如果你看到100代后曲线还在明显阶梯式下跳,说明种群还没有稳定,要么迭代次数不够,要么粒子维度下多样性不足,需要增大种群或调整惯性权重。
如果曲线过早平直且最终结果明显差于文献值,基本可以判断是早熟收敛——所有粒子都聚到了某个局部最优附近。此时优先检查是不是取整操作导致大量粒子"挤"在同一个离散方案上。
5.2 电压剖面:优化前后对比
我把优化前后的24时段电压分布做了对比。优化前,晚高峰时段末端节点18和33的电压低到0.93 p.u.左右,明显越下限;午间光伏大发时,DG接入点电压抬升到1.06 p.u.左右,接近越上限。优化后,末端电压抬升到0.97 p.u.以上,午间高点被压回1.04 p.u.以内,全天所有节点电压都落在0.95~1.05 p.u.区间。
这里特别要强调DG的电压影响是"双刃剑":光伏接入解决末端低电压问题的同时,午间可能造成过电压。所以优化结果必须分时段看,如果只看全天平均值,午间过压和晚间欠压会互相抵消,让你误以为结果很好。
5.3 网损与节能量
我跑出的典型结果是:优化前全天网损电量约1900 kWh(对应各时段网损之和),优化后降到约1450 kWh,降幅约23%。这个数字和同类文献的量级一致,可作为结果是否合理的参考。电容器组和OLTC承担了大头,DG逆变器无功调节进一步压低了峰值时段的网损。需要提醒的是,网损降幅高度依赖DG渗透率和负荷曲线形状,不同接入方案之间不必强行比较绝对值。
5.4 动作次数校验:这才是动态的核心成果
结果里必须单独列一张表,统计OLTC和每台电容器的全天动作次数。我在算例中设的约束是:OLTC不超过5次,电容器组不超过6次。优化结果OLTC动作4次、电容器组动作5次,全部在限制内。这比网损数字更能说明"动态"的价值——因为如果拿静态优化逐时段独立求解,电容器组一天可能动作到10次以上,根本没法工程落地。
解读结果时我建议把这个动作次数表和网损结果放在一起讲:稍微牺牲零点几个百分点的网损,换来了设备动作次数大幅下降,这是动态优化相对静态优化的核心优势。
6. 实操中的坑与后续扩展方向
做这个课题时,我在程序层面踩过三个比较深的坑,每一个都花了不少时间排查,写在这里给大家排雷。
6.1 坑一:时段太少失真,时段太多维度爆炸
最开始我图省事把一天分成4个典型时段(峰、平、谷、晚高峰),跑起来飞快,但结果里电容器动作次数经常卡在边界上,电压曲线也出现明显阶梯跳变——因为时段太粗,忽略了时段内部的变化。后来换成T=24,结果合理多了。但如果直接上T=96,粒子维度会到500+,PSO收敛质量明显下降。 解决思路是分段编码:把一天按负荷特性分成几个连续的区间段,同一区间内控制变量保持不变,只允许在区间切换点动作。这样既保留了日内变化细节,又把维度压到可控范围,动作次数约束也天然满足。
6.2 坑二:离散变量取整导致算法末端震荡
连续位置取整成档位/组数之后,粒子速度更新在某些维度上会反复横跳:比如位置在2.49和2.51之间波动,取整结果就在2和3之间跳,导致适应度曲线尾段抖得厉害。这不是算法没收敛,而是取整操作制造的不连续响应。 我的处理办法:在迭代后期(比如后50代)缩小速度上限,并且对位置做小幅扰动后取整,优先让粒子稳定在某个离散方案附近;最终输出时再对gbest做一次局部枚举——在最优解附近依次尝试各控制变量的相邻整数值,选出真正最优的离散方案。这个小技巧让最终结果稳定了不少。
6.3 坑三:惩罚系数难调
罚函数里系数太小,电压越限和动作次数超限的方案会混进种群;系数太大,适应度函数被罚项主导,粒子会过度回避那些稍微越限但实际很优秀的区域。我调参时走了不少弯路,最后采用的做法是:电压越限罚系数取100,动作次数罚系数取50,并且先单独跑一次不带动罚函数的静态优化,看看自然越限程度,再反推罚系数量级。
6.4 进一步扩展的方向
如果这个课题要继续做深,我个人觉得值得尝试的方向有三个。第一是自适应PSO,让惯性权重根据种群多样性动态调整,缓解早熟收敛;第二是多目标化,把网损、电压偏差、设备动作成本同时作为目标,用MOPSO求Pareto前沿,让决策者自己权衡;第三是考虑DG出力的不确定性,把光伏和风电的预测误差建模为场景集,做鲁棒优化或随机优化。这些方向都是当前研究热点,而且都是从现有动态PSO框架上自然生长出来的,不会推倒重来。
最后再分享一点个人体会:做这类仿真课题,最容易卡住的往往不是算法本身,而是"模型和工程现实之间的翻译"。把动作次数约束、DG逆变器无功极限这些细节想清楚,程序反而跑得顺利。我的经验是:先把T=24、单DG接入的简化版本完整跑通,确认每个环节输出都合理,再逐步扩展场景。这样排查问题时,你只需要怀疑最近改动的那一行,而不是在几百行代码里大海捞针。