☰
配电网光伏储能双层优化配置模型及粒子群算法实现
2026/11/3 5:58:54 网站建设 项目流程

做了挺久的配电网优化项目,今天把这个“粒子群优化算法的配电网光伏储能双层优化配置模型”完整拆开讲一遍。这是个很典型的选址定容问题,测试系统用的IEEE33节点,工具是Matlab,核心算法是粒子群。文章里我会把模型怎么建、代码怎么写、实际调试会踩哪些坑,全部过一遍。

先给不了解背景的朋友说一下这个项目在干什么:配电网里要接入光伏和储能,但光伏装在哪、装多大,储能又该放哪、容量多少,以及投运之后储能每天怎么充放电,这其实是一个互相耦合的两层决策问题。传统做法要么只做规划层忽略运行层,要么只做运行调度不考虑投资成本,结果都不够准。这里用双层优化把“选址定容”和“运行调度”拆开,上层用粒子群算法寻优,下层做24小时运行优化,整体在IEEE33节点系统上验证,Matlab代码可以完整复现。

1. 为什么配电网光伏储能必须用双层优化

1.1 “双高”背景下选址定容问题的本质

配电网接入高比例分布式光伏之后,最直接的问题就是电压越限和反向潮流。光伏出力集中在中午,而负荷高峰通常在晚上,这种时间上的错配导致如果不加储能,光伏渗透率稍微上去一点,末端节点电压就可能超过上限。储能的作用就是削峰填谷:中午光伏大发时充电,晚上负荷高峰时放电。

但储能和光伏的成本都很高,不能随便乱装。光伏装在哪里、装多大的容量,储能放哪个节点、容量和额定功率怎么搭配,直接决定了项目的经济性和电网运行的安全水平。这就是选址定容问题,本质上是一个带约束的非线性组合优化问题:位置是离散变量,容量是连续变量,目标函数要考虑投资成本、运维成本、网损费用和购电费用,还要满足电压、电流、功率平衡等一堆约束。

这类问题用解析法基本没戏,因为决策变量混合了整数和连续量,目标函数也没有凸性可言。启发式算法是主流选择,粒子群、遗传算法、灰狼优化都有人用。粒子群实现简单、参数少、收敛快,在这个问题上性价比很高。

1.2 单层优化为什么会失真

很多初学的人会问:我直接把所有变量放一起,用粒子群一次搜出来不就行了?位置、容量、储能24小时充放电功率全部作为决策变量,理论上是可以的,但实际跑起来问题很大。

首先是变量维度爆炸。假设储能要优化24小时的充放电功率,那一个粒子就要包含2个位置变量、2个容量变量、24个储能功率变量,总共28维。粒子群在高维空间中搜索效率下降很快,而且充放电功率之间有时间耦合(荷电状态逐时递推),很难保证每个粒子都满足储能SOC约束,罚函数会变得很重,算法基本就在乱搜。

其次是目标函数的尺度差异。投资成本一算就是几百万,运行费用每天几百块,如果放一个目标函数里,运行层的信息会被淹没,粒子群很难感知到运行调度的优劣,最终选出来的方案经济性会很差。

所以单层优化不是不能做,而是做出来的结果对工程指导意义不大。

1.3 双层模型如何分工协作

双层优化的思路是把决策拆成层次结构,上层做规划,下层做运行,下层在给定上层方案的基础上求解,再把运行结果反馈给上层作为目标函数的组成部分。

对应到这个项目里:

  • 上层:决定光伏安装节点和容量、储能安装节点和容量。目标函数是年综合费用最小,包括等年值投资成本、运维费用、年网损费用和向上级电网购电的费用。
  • 下层:给定一套选址定容方案后,做典型日(通常是24小时)的运行优化,决定储能每个时刻充放电多少。目标函数可以设为当日运行成本最小,包括购电费用和网损费用。

下层的运行结果算成费用后,回到上层参与目标函数评价。这样粒子群搜索每个方案时,用的都是经过运行优化后的经济指标,比单纯按“容量越大越好”或者“电压改善越多越好”更接近实际。

2. IEEE33节点系统建模与潮流计算

2.1 测试系统的参数和特点

IEEE33节点系统是配电网优化研究最常用的辐射状测试系统,最早来自IEEE的配电系统测试基准。系统基准电压12.66kV,基准容量常取10MVA,首端节点1接在上级变电站,相当于平衡节点,其余32个节点都是PQ节点。系统总负荷约3715kW加2300kvar,支路总共32条,呈辐射状结构。

这个系统的特点是负荷分布在主干线路和几条分支上,末端节点离电源点比较远,网损相对较高,非常适合用来做分布式电源接入的仿真实验。光伏和储能接入位置的选择空间大,不同位置对网损和电压的影响差异明显,能很好地检验优化算法的寻优能力。

需要说明的是,IEEE33的标准数据里没有包含分布式电源,接入光伏和储能时需要自己设置候选节点。一般做法是排除首端平衡节点,剩余32个节点都可以作为候选,或者根据工程经验限定在负荷较重、电压偏低的末端区域,这样可以缩小搜索空间、加快收敛。

2.2 前推回代法潮流计算的实现逻辑

配电网潮流计算和输电网不一样,线路电阻和电抗比值偏大,传统PQ分解法在配电网里收敛性不好。辐射状配电网最主流的方法是前推回代法,思路非常直观:已知首端电压和所有节点负荷,从末端往首端推支路功率(前推),再从首端往末端推节点电压(回代),两个过程交替进行,迭代到电压变化小于阈值为止。

固定节点编号的IEEE33系统尤其适合用矩阵化方式实现。把支路首末端节点编号存入数组,支路阻抗做成向量,负荷功率做成数组,前推回代的核心循环就那么几行Matlab代码。实际编码时要注意单位和基准值统一,全部折算成标幺值计算,避免数值溢出。

每次潮流计算完成后,可以顺便算出全网的网损功率和各节点电压偏移。网损功率用于计算损耗费用,电压偏移可以用于判断约束是否越限。

2.3 光伏与储能的数学建模

光伏的出力模型这里取的是典型日出力曲线,本质上是把一天24小时的光伏最大出力功率给出来。如果是夏天晴天,曲线大致是早6点到晚18点之间有出力,中午12点到14点达到峰值,峰值大小由装机容量决定。实际运行时光伏出力可以在0到最大值之间调节,意味着“弃光”是允许的,这在下层优化里是个重要决策变量。

储能模型核心是荷电状态递推方程:

SOC(t+1) = SOC(t) + (P_char(t) * eta_char - P_dis(t) / eta_dis) * dt / E_bess

其中P_char和P_dis分别是充电和放电功率,eta_char和eta_dis是充放电效率,E_bess是储能容量。约束条件包括充放电功率上下限、SOC上下限、充放电不能同时进行。初始SOC一般取0.5,日末SOC可以约束回到初始值附近,保证储能第二天能继续调度。

储能额定功率P_bess和容量E_bess成比例关系,通常取0.2C到0.5C倍率,比如500kWh的储能配100kW到250kW的功率变流器。我在代码里把储能额定功率设为容量乘以某个倍率系数,这样下层优化不用额外再优化功率变量。

3. 双层优化模型怎么设计才合理

3.1 上层规划层的目标函数与约束

上层目标函数是年综合费用最小,包含四个部分:

C_total = C_inv_pv + C_inv_bess + C_om + C_year_loss + C_year_buy

  • C_inv_pv:光伏等年值投资成本。单位造价乘以安装容量,再乘以资金回收系数CRF。CRF = r(1+r)^n / ((1+r)^n - 1),r是折现率,n是设备寿命,光伏取20年,储能取10年。
  • C_inv_bess:储能等年值投资成本。储能单位造价按容量(kWh)计,同样乘CRF,寿命按10年算。
  • C_om:年运维费用。光伏和储能的运维成本按装机容量比例估算,一般取初始投资的一定百分比。
  • C_year_loss:年网损费用。把典型日网损电量乘以365天(或按季节加权),再乘以购电电价。
  • C_year_buy:年购电费用。把典型日从上级电网买入的电量乘以365天,再乘以分时电价对应的电价。

约束条件包括:光伏安装容量不超过渗透率上限(例如不超过总负荷的50%保证不倒送严重),储能容量在一定范围内,安装节点不能重复,所有节点的电压幅值保持在0.95到1.05标幺值之间,支路电流不越限。

3.2 下层运行层的优化模型

下层的任务是在给定光伏容量、储能位置和容量之后,算出典型日的最优运行策略。决策变量是储能24小时的充放电功率和光伏各时刻的实际出力。目标函数是当日运行费用最小,主要是购电费用和网损费用,分时电价的峰谷差是储能套利的主要来源。

下层约束比上层多一个时间维度的动态约束,储能SOC的递推方程就是核心。充电和放电功率要分别限制在0到额定功率之间,SOC限制在0.1到0.9之间。光伏实际出力要在0和预测最大值之间。

下层求解我用了两种方式,一种是直接调用Matlab的fmincon内点法,对于单个典型日的运行优化问题,内点法效率高且稳定;另一种是继续用粒子群做内层寻优。实测下来fmincon在这个规模的问题上比粒子群快很多,所以完整代码里内层用的是fmincon,外层粒子群只负责选址定容。如果你想把两层都用粒子群,结构上也没问题,就是计算时间会成倍增加。

3.3 上下层联动与费用折算的细节

上下层联动的要点在于:上层每评估一个粒子,都要调用一次下层优化,下层返回的最优运行费用作为该粒子的运行成本项。这个嵌套结构在Matlab里就是两层for循环,外层遍历粒子,内层执行优化。

费用折算里最容易出错的是时间尺度的统一。上层投资成本是“年均”的,下层算出来的是“典型日”的运行费用,要乘上365(或加权天数)才能组装成年综合费用。同时储能的全寿命周期和光伏不同,CRF分别计算,不能混用一个折现系数。我第一次实现时就把储能用光伏的CRF算了,结果储能投资被严重低估,寻优出来的储能容量偏大,后来改成独立计算才正常。

另一个细节是下层优化得到的最小运行费用是在该选址定容方案下的理想值。粒子的适应度越高说明这个方案越好。如果某个方案导致潮流不收敛或电压越限,要给它一个很大的罚函数值,让粒子群自动避开这类区域。

4. 粒子群算法在双层模型中的完整实现

4.1 PSO核心机制与参数选择

粒子群算法的思想是模拟鸟群觅食。每个粒子代表搜索空间中的一个候选解,有位置和速度两个属性,位置就是决策变量的取值,速度决定位置更新的方向和步长。每次迭代中,粒子根据自身历史最优位置(个体极值pbest)和群体全局最优位置(全局极值gbest)来更新速度,再更新位置。

速度更新公式:

v(i+1) = w * v(i) + c1 * r1 * (pbest - x(i)) + c2 * r2 * (gbest - x(i))

位置更新:

x(i+1) = x(i) + v(i+1)

参数方面,我实测下来对配电网选址定容问题比较稳定的配置是:种群规模40,迭代次数100,惯性权重w从0.9线性递减到0.4,学习因子c1和c2都取1.5。惯性权重线性递减是个非常关键的操作,前期w大保证全局搜索能力,后期w小加速收敛。

粒子编码时要混合整数和连续变量。光伏安装节点、储能安装节点是1到33之间的整数,光伏容量、储能容量是连续变量。处理整数变量有一个常见的做法:粒子更新后对位置取整或四舍五入,但要注意取整后可能超出节点编号范围,要做边界修正。

4.2 Matlab代码框架与核心函数

代码整体分为几个模块:主程序、参数初始化、粒子群主体循环、适应度函数、潮流计算、下层运行优化。下面是主循环的核心逻辑伪代码:

% 初始化粒子群 for i = 1:N_pop x(i,:) = initialization(); v(i,:) = zeros(1, dim); fitness(i) = calculate_fitness(x(i,:), systemData, price); pbest(i,:) = x(i,:); pbest_fitness(i) = fitness(i); end [gbest_fitness, idx] = min(pbest_fitness); gbest = pbest(idx,:); for iter = 1:maxIter w = 0.9 - 0.5 * (iter / maxIter); for i = 1:N_pop v(i,:) = w * v(i,:) + c1*rand(1,dim).*(pbest(i,:)-x(i,:)) ... + c2*rand(1,dim).*(gbest - x(i,:)); x(i,:) = x(i,:) + v(i,:); x(i,:) = boundary_check(x(i,:)); x(i, pvIndex) = round(x(i, pvIndex)); % 位置取整 x(i, bessIndex) = round(x(i, bessIndex)); fitness(i) = calculate_fitness(x(i,:), systemData, price); if fitness(i) < pbest_fitness(i) pbest(i,:) = x(i,:); pbest_fitness(i) = fitness(i); end end [best_fitness_current, idx] = min(pbest_fitness); if best_fitness_current < gbest_fitness gbest_fitness = best_fitness_current; gbest = pbest(idx,:); end record(iter) = gbest_fitness; end

适应度函数是整个嵌套优化的核心,内部依次完成:解析粒子位置和容量,把光伏和储能接入配电网,对典型日24个时刻做潮流计算并运行下层优化,最后把投资、运维、网损、购电费用汇总成适应度值。迭代完以后输出最优解和收敛曲线。

潮流计算模块基于前推回代法。为了支持分布式电源,节点注入功率要叠加光伏出力(作为负的负荷)和储能充放电功率(充电是增加负荷,放电是减少负荷)。每个时刻都要重新生成节点注入功率向量,再调用潮流函数。

4.3 收敛性调试与典型结果

这个模型跑起来之后,典型结果是:光伏倾向于安装在负荷较大的中后段节点,储能也分布在末端电压薄弱区域附近。网损相比无分布式电源的初始状态明显下降,电压最低点的数值从0.9标幺值左右提升到0.95以上。

收敛曲线一般是前30代快速下降,后面逐渐平缓。如果曲线在很早期就出现平台且很久不动,说明粒子群早熟了。调整方向有两个:一是增大初始惯性权重,二是把粒子数加大到60左右。如果收敛曲线波动剧烈、忽高忽低,通常是罚函数权重太小,粒子在搜索越限区域时没有感受到足够惩罚,适当加大罚函数系数即可。

内层使用fmincon时要注意,每个粒子都要调用一次fmincon,每调用一次就要进行24次潮流计算。整体计算量不低,但IEEE33系统规模小,前推回代单次计算只需要毫秒级,整套下来几分钟内能出结果。

5. 避坑指南:实测最容易翻车的几个点

5.1 潮流不收敛与数值量纲问题

前推回代法在IEEE33上本身很稳定,不收敛通常是自己代码的问题。最常见的原因是负荷单位不统一,比如把kW直接当成标幺值算,导致注入功率巨大,迭代发散。

我在写代码时统一约定:所有功率用标幺值,基准功率10MVA,基准电压12.66kV;负荷数据里3715kW转成0.3715标幺值。支路阻抗也换算成标幺值。调用潮流函数时传入的是标幺值数组,输出也是标幺值。

另一个容易忽略的问题是接入光伏和储能之后,某些节点可能出现注入功率为负(即净出力大于负荷),这在配电网潮流里是允许的,但前推回代时要注意支路功率方向可能翻转,算法本身能处理,不需要特殊干预。

如果遇到潮流发散,我的排查顺序是:先跑不含分布式电源的原始33节点验证潮流正确性,再单独接一个光伏校验单点接入,最后才整套模型联调。逐层排查定位问题,比直接查整套代码快很多。

5.2 粒子群早熟和离散变量处理

粒子群在配电网选址问题里最大的坑是早熟,尤其是整数变量(安装节点编号)处理不当的时候。如果直接把节点编号当成连续量,粒子经常会在两个整数之间震荡,导致位置在不断变化但是适应度始终上不去。

解决办法是粒子更新后强制取整,同时对取整后的越界值进行修正。另外,同一个节点不能同时装光伏和储能,这个约束要在初始化时强制避免,否则粒子搜索空间里存在大量不可行解,白白消耗迭代次数。

还有一种工程化改进是限制候选节点集合,比如只允许末端15个节点作为安装位置,而不是所有32个节点可选。搜索空间小了,收敛速度和结果稳定性都会明显改善。

5.3 双层嵌套计算量大怎么优化

做双层嵌套优化最大的现实障碍是计算时间。外层粒子数40,迭代100次,就要评估4000个方案;每个方案内部做24小时运行优化。粗算下来就是4000次fmincon调用,再乘上每次调用里的潮流迭代次数,普通笔记本可能要跑几个小时。

我的实测优化组合是:外层粒子数降到30,迭代次数80;下层fmincon的容差放宽到1e-4;潮流收敛阈值设置为1e-6。这样精度损失很小,时间能压缩到原来的三分之一左右。此外还可以用Matlab的parfor对粒子循环做并行加速,多核机器上效果明显。

还有一个容易被忽视的点:下层运行优化的可重复调用。fmincon每次从默认初始点开始是没有问题的,但如果给定一个合理的初始SOC轨迹,比如让储能先充电后放电,fmincon收敛速度会更快,而且更容易避开局部最优。

最后分享一点实际体会

这个项目做完最大的感受是:光有算法远远不够,问题建模的合理性才是决定结果是否可用的关键。粒子群说到底只是个通用寻优器,把约束写清楚、把目标函数算准,算法才能给你一个站得住的方案。另外建议所有刚入坑的朋友,不要一上来就追求复杂的模型和花哨的改进策略,先把IEEE33+光伏+储能这套基线跑通,拿到一组合理的选址定容结果,再逐步加约束、加场景,这样出了问题也好定位。

代码实现上我会优先保证结构清晰而不是极致优化,每个模块单独函数实现,注释写明白输入输出。模型本身后续可以扩展的地方还挺多的,比如多典型日场景、考虑负荷和光伏的不确定性、加入需求响应等,底子打好了,往上加东西都是水到渠成的事。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询