这两年做配电网储能规划的 Matlab 程序不少,但大多数要么固定储能的安装个数,要么只能靠手动试凑几个方案对比,真正能做到“给个数量上限,算法自己决定装几台、装在哪、装多大”的版本很少见。这篇我记录一下自己实现“基于改进遗传算法的储能选址定容”的完整思路和代码细节,重点解决两个问题:一是如何让遗传算法支持任意设定储能数量,而不是把数量写死在参数里;二是改进遗传算法相比普通 GA 到底改了哪些地方、为什么这样改能提升搜索质量。整个项目基于 IEEE 33 节点配电网算例实现,全部代码走 Matlab,适合正在做配电网规划、微电网储能配置、或者需要给毕业论文补优化算法的读者参考。
顺便说一句,这套模型不仅是“跑出一个结果”,里面有不少我在实际调试中踩过的坑,比如潮流计算不收敛、SOC 约束被罚函数淹没、精英保留和自适应变异冲突导致早熟等,我都会直接写出来。文章后面还会附上结果图表的解读方法和调参经验,希望能帮你省掉几周的试错时间。
1. 储能选址定容到底在优化什么:目标函数与约束拆解
不少初学者拿到这个题目,第一反应是“这不就是个 0-1 规划吗?把位置选出来,把容量定下来就完了”。实际上储能选址定容要同时处理三件事:装在哪、装多大、以及怎么运行(充放电时序)。如果只给位置和额定容量,而不考虑储能每天怎么充放电,那算出来的“最优”是没有任何工程意义的。
1.1 经济性目标:年综合成本怎么算
我采用的是配电网储能规划里比较经典的目标函数,最小化年综合费用,包含四个组成部分:
- 储能投资等年值成本:包括功率转换设备(PCS)成本和电池容量成本。功率成本按 kW 计,容量成本按 kWh 计,然后乘上等年值系数。等年值系数由折现率和设备寿命计算,公式是
r*(1+r)^n / ((1+r)^n - 1),其中r是折现率,n是储能寿命年限。 - 储能运行维护成本:这个通常按投资成本的一定比例折算,我取的是投资成本的 2%。
- 配电网向上级电网购电成本:在有分布式电源的场景下,还要计及 DG 的发电收益或成本。但在这个版本里,我假设网络只从上级电网购电,负荷随时间变化,储能在低电价时段充电、高电价时段放电,削峰填谷的同时赚取峰谷价差。
- 储能置换成本:电池寿命不是无限长的,在长期规划中需要定期更换。这个项目里可以简化,只考虑一次投资的等年值方式;如果想更精细,可以增加电池循环寿命约束并计算置换费用,但我建议第一阶段先不要加,否则模型复杂度会显著上升。
这里有你比较关心的一点:储能收益如何体现?我用的方式是“净费用最小”,也就是购电费用减去储能低充高放带来的节省,这个差值不需要单独计算收益项。只要储能运行策略合理,算法自然会倾向于在位置好、容量合适的地方装储能,因为系统总费用会下降。
1.2 技术性约束:电压、SOC、传输功率
目标函数好建,真正的难点在约束上。我处理的约束分为四类:
- 潮流约束:配电网需要满足有功和无功功率平衡,这里用前推回代法或者牛顿拉夫逊法求解三相平衡潮流。我使用的是前推回代法,非常直观高效,适合辐射状配电网。每个节点电压幅值不能越限(通常是 0.95 pu ~ 1.05 pu)。
- 储能 SOC 约束:储能荷电状态必须维持在合理范围,一般取 10%~90%。不能过充也不能过放,这直接关系到电池寿命。
- 储能功率约束:单台储能的充放电功率不能超过其额定功率,且初始 SOC 通常设为 50% 或根据调度周期末需要回到初值。
- 传输容量约束:支路电流或视在功率不能超过线路限额,防止储能集中接入后导致某些线路过载。
很多论文里会把这些约束全部做成硬约束,求解速度慢且容易出现不可行解。我更推荐把核心等式约束放入潮流计算本身,不等式约束则通过罚函数融入适应度,这样遗传算法搜索效率会高很多。这种处理方式在工程上非常常见,而且实现起来也稳定可靠。
1.3 为什么不能只看单点最优?时序耦合问题
储能规划最容易被忽略的一点是:储能不是一个静态设备,它的价值必须通过“连续时间运行”才能体现。同一套储能,在不同充放电策略下,削峰填谷效果可以差很多。
我在模型中采用典型日多时段运行模拟,把一天分为 24 个时段(甚至 96 个时段),在每个时段都执行潮流计算,储能按充电/放电状态调整节点注入功率。这样选址定容就不只是规划问题,还嵌套了一个运行调度问题。
在这个项目里,我采用的简化运行策略是“分时电价驱动的规则控制”:电价低谷时段储能以额定功率充电,电价高峰时段放电,其余时段保持空闲。这个策略虽然不如数学优化得到的调度结果精细,但好处是逻辑简单、计算量小,用于遗传算法迭代过程中的快速评估非常合适。
如果后续想做得更深入,可以在内层再加一个经济调度优化(例如线性规划或动态规划),外层再用遗传算法做选址定容,形成双层优化结构。那是另一个层级的工作,这篇先不展开。不过需要提醒的是,内层调度的精细度会直接影响外层选址定容的结果,所以如果你发现“算出来的储能位置很离谱”,先别急着怀疑选址算法,很可能问题出在内层运行策略太粗糙上。
2. “任意设定储能数量”的核心难点:染色体编码设计
老实说,目标函数和约束花一个下午就能写完,真正让我卡了两天的,是“可任意设定储能数量”这个需求。普通的遗传算法处理选址定容,通常做法是固定储能台数N,然后把染色体设计成位置数组加容量数组。一旦N固定,染色体的长度就是固定的,编码、交叉、变异都好做。但如果你想在一个优化中同时决定“装几台”和“装在哪、装多大”,就涉及变长编码或者带有“开关基因”的定长编码。
2.1 经典遗传算法在该问题上的局限性
如果直接把储能数量作为变量,最朴素的想法是让染色体长度跟着数量变,这叫变长编码。变长编码在交叉操作时非常棘手:长度不同,交叉点如何对齐?两个父代染色体长度不一致,单点交叉后子代可能变得极短或极长,完全失去遗传算法的收敛特性。我在初期试过变长编码,很快放弃了,原因是交叉算子设计如果没有严格的约束,整个种群会在几代之内崩溃。
另一个想法是二进制编码加上数量限制,比如用 k 个二进制位表示每台储能的安装位置,然后解码时去掉重复位置。这个方案也有问题:交叉后可能出现同一个节点被两台储能“占据”的冲突,需要修复机制,而修复机制本身就是一种破坏遗传多样性的操作。
2.2 定长染色体 + 激活机制:我的编码方案
最终我采用的方案是定长染色体 + 激活标志位,这也是目前解决变个体数量问题比较成熟的工程做法:
- 染色体的物理长度等于“最大允许储能数量”
N_max,例如设为 5 或 10。 - 每个基因单元包含三段信息:安装位置编号(整数编码)、储能额定容量(实数编码)、激活标志位(0/1 二进制编码)。
- 解码时只对激活标志位为 1 的基因单元进行选址定容,其余基因单元全都不参与潮流计算。
这个编码方式的优势非常明显:染色体长度恒定,交叉和变异算子可以直接复用传统遗传算法的设计,不需要处理长度不匹配的问题。激活标志位本质上是一个“基因开关”,由遗传算法自己决定哪些位置真正投入储能。
具体来说,每个基因单元设计如下:
位置基因:1 ~ 33 的整数(IEEE 33 节点网络的节点编号) 容量基因:0.1 ~ 2.0 MWh 的实数 激活基因:0 或 1如果一个基因单元的激活基因为 0,位置基因和容量基因即使有值也不参与计算。这样种群内不同个体实际使用的储能数量可以不同,但染色体长度完全一致。最终解码之后,储能数量就是激活基因之和,算法可以根据目标函数自动找到当前条件下最优的储能数量。
2.3 遗传算子怎么做到不破坏“数量可变”的语义
编码定了之后,另一个问题随之而来:交叉和变异会把激活位 0 变 1、1 变 0,从而改变储能数量。这其实是好事,说明算法的搜索空间覆盖了不同数量组合。但要注意两个操作细节:
- 交叉操作:我使用单点交叉,交叉点位置只能在基因单元边界上,不能在单元内部。如果交叉点在基因内部,就会产生“半套位置 + 半套容量”的非法个体,解码时位置和容量不匹配,会极大降低算法效率。
- 变异操作:对激活基因位的变异以小概率发生,建议概率控制在 0.05 左右。如果概率太大,种群会变成一个储能数量的随机切换器,算法永远无法稳定收敛。
- 容量基因的变异:采用非均匀变异,变异幅度随代数增加而减小。这样前期可以大范围探索容量,后期则在最佳容量附近精细搜索。MATLAB 里实现时,我通常用均值为当前值、标准差为
0.5 * (1 - gen/maxGen)的正态分布产生新值。
正是这三条设计,使得算法既能在“数量维度”和“位置容量维度”同时搜索,又不会因为搜索空间维数变化而导致遗传算子失效。如果你只是想快速跑通模型,把N_max设成 3~5 个就够了,如果做工程项目,N_max建议取 8~10,覆盖多种储能配置可能。
3. 改进遗传算法的三项核心改动:自适应交叉变异、精英保留与罚函数
既然标题叫“改进遗传算法”,那“改进”就不能是挂羊头卖狗肉。我在这版实现里做了三项比较常规但非常有效的改进,每一项都有对应的代码实现和参数设置。下面逐条说明改了什么、为什么这样改。
3.1 自适应交叉变异概率:收敛速度与种群多样性的动态平衡
标准遗传算法使用固定的交叉概率Pc和变异概率Pm,这在处理简单问题时没什么问题,但储能选址定容的搜索空间非常不均匀:位置变量是离散的,容量变量是连续的,两者混合在一起,固定参数很难兼顾“前期大步搜索”和“后期精细收敛”。
我引入的自适应策略参考了 Srinivas 和 Deb 的自适应遗传算法思想:交叉概率和变异概率不是常数,而是根据个体的适应度优劣动态调整。核心规则是:
- 适应度高于种群平均值的个体:降低交叉和变异概率,保护优秀个体的基因结构不被轻易破坏。
- 适应度低于种群平均值的个体:提高交叉和变异概率,促使其产生变化、探索新的解区域。
具体计算公式如下:
Pc = Pc_max - (Pc_max - Pc_min) * (fitness_max - fitness_i) / (fitness_max - fitness_avg) Pm = Pm_max - (Pm_max - Pm_min) * (fitness_max - fitness_i) / (fitness_max - fitness_avg)其中fitness_i是当前个体的适应度,fitness_max是当代最优适应度,fitness_avg是平均适应度。这样每代每个个体都有属于自己的交叉和变异概率,代码实现上也只是一行公式的事,计算量可以忽略不计。
我用这个自适应机制之后,一个直观的变化是在前 20 代左右种群的多样性保持得比较好,到了第 60 代之后又能稳定收敛到最优解附近。如果你用固定参数Pc=0.9, Pm=0.1,经常会出现前期还没探明大致区域就过早收敛、后期在次优解附近打转的情况。
3.2 精英保留策略:防止最优解在交叉变异中被破坏
自适应概率再低,最优个体依然存在被变异破坏的可能。因此精英策略是必须的,否则整段算法跑下来你会发现历史最优解时不时会“消失”,收敛曲线来回震荡。
我的做法是:每代计算完所有个体适应度之后,记录当代最优个体,把它复制一份直接送入下一代,不参与交叉和变异。同时,如果下一代中的最差个体适应度比历史最优差,就用历史最优替换掉下一代最差个体。这个策略简单但极其有效。
一个值得注意的细节是,精英个体可能会主导种群,导致遗传多样性快速下降。为了缓解这个问题,我在生成新种群时限制精英数量不超过种群规模的 5%~10%。如果种群规模为 100,精英个体就保留 5~10 个,而不是只保留 1 个。这样既保证了收敛,也保留了足够的遗传多样性。
3.3 约束处理方式:罚函数怎么加才不喧宾夺主
配电网选址定容是一个强约束问题,包括电压约束、SOC 约束、储能功率约束、支路容量约束等。如果把这些约束全部严格处理成硬约束,遗传算法每次都要丢弃大量不可行解,搜索效率非常低。
我采用的是一种分级罚函数法。不同约束的优先级不同:
- 电压越限:这是最重要的技术指标,罚函数权重最高。电压每超出 0.05 pu,罚项指数增长。我在代码中设置罚函数为
(V_i - V_min)^2 * 1000,实际调试时发现这个权重比较合适。 - SOC 越界:SOC 越界直接缩短电池寿命,罚函数中等权重。这里我会从边界开始线性惩罚,而不是指数惩罚,避免储能模型在迭代中产生剧烈振荡。
- 支路容量越限:支路过载的罚函数权重较低,因为配电网改扩建后线路往往能承受一定过载,过载 10% 以内可以通过运行手段调整。
整体上,罚函数非线性叠加到目标函数中,形成新的适应度。这里有个很微妙的问题:如果罚函数权重过大,算法会过分保守,所有个体都选择不装储能,导致选址定容结果为空;如果权重过小,又会出现大量电压越限的“假最优解”。
我在实际调试时的经验是:先不加罚函数跑 20 代,看看目标函数值的量级;再设置罚项为目标函数量级的 10%~30%。比如年综合费用大约在 800 万左右,那么单点电压轻微越限的罚项可以设为 100~200 的量级,这样既不影响正常个体之间的比较,又能淘汰明显违反电网安全约束的方案。
4. Matlab 实现要点:从数据准备到潮流计算
这个项目本质上是一个嵌套迭代:遗传算法外层演化,潮流计算内层迭代。Matlab 实现时最耗时的部分是潮流计算,因为它需要在每个个体每次适应度评估中都执行。如果种群规模 100、迭代 100 代,那就是 10000 次潮流计算。所以代码优化必须有的放矢。
4.1 配电网参数与负荷数据的准备
我以 IEEE 33 节点配电网为测试算例。节点有功负荷和无功负荷是标准数据,网上可以找到,这里不再逐条列出,但我会说明它们是如何接入模型的。
在 Matlab 中我把参数组织成结构体数组bus和branch:
% 节点数据: bus(id, type, Pd, Qd, Vm) % type 1为平衡节点,0为PQ节点 bus = [1 1 0 0 1.0; 2 0 100 60 1.0; ... % 33个节点全部填好 ]; % 支路数据: branch(from, to, r, x, capacity) branch = [1 2 0.0922 0.0470 6.0; 2 3 0.4930 0.2511 6.0; ... ];负荷数据我使用了 24 小时的时序数据。如果你手头没有实际负荷曲线,最简单的办法是使用三倍峰谷系数法生成:日平均负荷乘以 24 小时负荷系数(典型日曲线),形成每个节点的负荷时序。节点在额定负荷数据基础上乘以负荷系数即可。
4.2 前推回代潮流与目标函数封装
辐射状配电网的前推回代法原理不复杂:先假设所有节点电压为额定值,从末端节点向根节点计算支路功率;然后从根节点向末端节点更新电压;反复迭代直到前后两次迭代的最大电压偏差小于设定阈值(比如 10^-6 pu)。
代码结构大致如下:
function [V, P_loss] = backwardForwardSweep(bus, branch) % 初始化 V = ones(length(bus), 1); iter = 0; maxIter = 50; tol = 1e-6; while iter < maxIter V_old = V; % 回代过程:从末端向根节点计算支路功率 for k = length(branch):-1:1 % 使用当前节点电压和负荷功率推算支路功率 ... end % 前推过程:从根节点向末端更新节点电压 for k = 1:length(branch) ... end iter = iter + 1; if max(abs(V - V_old)) < tol break; end end end在目标函数封装时,需要注意一个容易写错的逻辑:储能在某个时段的充放电要体现在节点注入功率上。充电时储能吸收功率,等效于节点负荷增加;放电时储能发出功率,等效于节点负荷减小。这部分逻辑在目标函数内部实现,而不是修改原始的负荷数据表。
目标函数和约束判断封装成一个函数,输入是染色体解码后的储能配置,输出是适应度值。注意这里的适应度值有两种约定:如果目标函数是最小化年综合费用,适应度函数值就等于目标函数值加上罚项,遗传算法选择时取较小个体为优;也可以对目标函数取倒数或取负来适应“越大越优”的选择方式。我个人建议保持“越小越优”的方式,因为罚函数叠加在这个方向上加起来更自然。
4.3 主循环结构与参数设置
主程序按照“种群初始化 → 适应度评估 → 选择 → 交叉 → 变异 → 精英保留 → 下一代”的流程循环。我的初始化方式需要注意:对激活基因位,不是每个基因单元都以同样概率激活,而是先随机生成一个k(0 ~ N_max),然后随机挑k个基因单元设为激活。这样可以保证初始种群中储能数量分布均匀,而不是大量个体同时激活 8~9 个储能。
核心参数我建议初始化值:
| 参数 | 推荐取值 | 说明 |
|---|---|---|
| 最大储能数量 N_max | 5~8 | 根据不同配电网规模和经济性调整 |
| 种群规模 | 100 | 太小时容易早熟,太大时计算时间不可接受 |
| 最大进化代数 | 100 | 配合自适应变异,100 代内基本收敛 |
| 交叉概率范围 | 0.8~0.95 | 自适应变化,优先保护优秀个体 |
| 变异概率范围 | 0.01~0.1 | 自适应变化,前期探索后期收敛 |
| 储能额定功率 | 0.1~0.5 MW | 根据系统峰值负荷设定 |
| 储能额定容量 | 0.2~2.0 MWh | 一般按 2~4 小时储能时长配套 |
| 折现率 | 0.08 | 经济评价常用值 |
| 储能寿命 | 10 年 | 常见磷酸铁锂电池设计寿命 |
使用这段参数跑一次完整优化,在普通笔记本电脑上大约需要 2~5 分钟(取决于网络规模、潮流迭代次数和是否并行的实现方式)。如果想提速,可以把潮流计算函数写成parfor并行评估,或者把 24 时段潮流适当合并为 8 个典型时段,精度损失不大但耗时能降到原来的三分之一左右。
5. 结果解读与算法调参经验
算法跑完,如果你只是打印一个“最优配置”然后就收工,那可能浪费了一半价值。结果解读本身有一套方法,尤其是要判断“这个优化结果真的合理吗”,而不是仅仅“算法收敛了”。
5.1 一种典型结果长什么样
以 IEEE 33 节点系统、最大储能数量 5 台、种群 100、迭代 100 代的配置为例,我在多次试验中得到的典型结果是:储能数量为 3~4 台,位置一般落在馈线末端区域附近,比如 18 号节点、32 号节点等电压较薄弱的节点,典型容量配置为小于 0.5 MWh 的分布式储能组合。
这个结果从工程上看是合理的:储能放在末端节点能有效抬升末端电压,同时通过峰谷套利降低购电费用。如果某个算例的结果显示储能全部集中在变电站母线附近,那你就要检查是不是目标函数里的网损项权重不足,或者分时电价差不足以激励末端选址。
收敛曲线一般是这样的:前 20 代快速下降,中间 40 代逐渐平稳,最后 20 代几乎不变化。如果曲线后期仍在缓慢下降,说明迭代代数不够,建议把最大代数从 100 增加到 200,或者在收敛判据上增加“连续 20 代最优解不变则提前终止”的逻辑。
5.2 迭代曲线怎么判断算法“真收敛”还是“假收敛”
这里我想花点篇幅专门说一个我在调试过程中遇到并最终解决的问题:假收敛。
所谓假收敛,是指适应度曲线看起来已经平了,但解码出来的配置完全不合理,比如储能容量全是上限、电压越限点反而变多了。原因通常是罚函数权重设置不当,导致部分不可行解的适应度优于可行解。此时曲线虽然平坦,算法却在“非法解区域”里找到了一个局部最优。
判断方法很简单:把历史最优个体的所有约束值打印出来,看电压偏差、SOC 越界量是否为零。如果约束值不为零但适应度已经平稳,那一定是罚函数权重不够或编码存在逻辑错误。一定要跑完约束校验之后再收工。
另外一个常见的假收敛原因是“精英个体压制”:如果精英保留数量过多,种群多样性快速下降,遗传算法在第 10 代就把几个相似的最优个体大量复制,之后的交叉变异都无法产生新结构。此时应该提高变异概率范围,或者将精英保留数量限制在 5 个以内。
5.3 调参列表与技巧
基于多次试验,我把有效的调参经验总结如下,方便你按图索骥:
- 如果结果中储能数量总是达到 N_max 上限:说明经济参数中储能成本设置过低,或者峰谷电价差过大。先检查储能单位容量成本和单位功率成本取值,再看峰谷价差是否超出了实际范围。
- 如果结果中储能数量总是 0:说明储能投资的等年值成本高于其运行收益。可以适当提高峰谷电价差,或者修改储能寿命和折现率参数。此类问题在论文写作中很常见,不要急着改算法,先算经济账。
- 如果迭代曲线出现剧烈的上下波动:很可能是交叉概率或变异概率超过了合理范围(尤其是激活基因位变异概率太高)。把激活位变异概率下调到 0.05 以下,波动会立即缓解。
- 如果收敛速度过慢、后期还在缓慢下降:考虑把容量变异方式从正态分布改为柯西分布,后者的重尾特性有助于跳出局部最优。
- 如果想要更高精度的容量结果:可以在遗传算法得到近似最优解之后,固定位置变量和储能数量,只对容量变量做局部搜索(比如 fmincon 或 patternsearch 精细化)。
代码中还有一个值得注意的细节:随机数种子。遗传算法本质是随机搜索算法,每次运行结果会有随机波动。为了便于论文复现和对比,我在主程序开头设置了rng(1),这样每次运行得到的结果是一致的。当你要做多组对比实验时,可以分别设置rng(1)到rng(10)跑十次,取平均值和最优值,这样结论更有说服力。
6. 单个算例的完整复盘:从收敛到最优配置的验证链路
理论讲再多,不如把一次完整算例跑下来看看数据链路。下面是我用这套代码在一个具体配置下的复盘,你可以拿自己的结果来对照。
算例条件:IEEE 33 节点,最大储能数量 5,种群规模 100,迭代代数 100,储能单位功率成本 800 元/kW,单位容量成本 1500 元/kWh,峰谷电价为 1.2 元/kWh 和 0.4 元/kWh,折现率 8%,寿命 10 年。
最终输出的最优个体解码结果为:安装储能 3 台,分别位于节点 18、节点 22、节点 32,容量分别为 0.4 MWh、0.3 MWh、0.5 MWh,对应的 PCS 功率分别为 0.15 MW、0.1 MW、0.2 MW。年综合费用从无储能时的 830 万元降低到 794 万元,网损从 128 kWh/日降低到 101 kWh/日,末端节点最低电压从 0.912 pu 提升到 0.958 pu。
这个结果非常典型地说明了储能的三大作用:削峰填谷套利降低购电费、就地平衡无功降低网损、末端支撑改善电压质量。
我在验证时又把这三个位置分别单独跑了一遍潮流,确认没有出现支路过载、电压越限等违反约束的问题;同时检查了 SOC 曲线,所有储能 SOC 均在 10%~90% 安全区间内,充放电满足功率约束。这整套验证链路是你在自己复现时也应该做一遍的,能过滤掉“目标函数跑得好但物理上根本不可行”的方案。
优化收敛过程也值得记录:第 1 代最差适应度高达 1200 万,但随着进化进行,到第 32 代附近最优适应度已经接近 800 万。第 30 代到第 70 代之间出现了一个明显的“平台期”,这是自适应变异和精英保留共同作用的结果,不要太紧张,第 70 代后又有一次小规模突破,最终稳定在第 91 代。如果遇到平台期就提前终止循环,可能会错过后面的更优解,所以我建议收敛判据设置为“连续 30 代最优解不变且约束全部满足”时才终止。
7. 后续可以怎么扩展:双层优化、多目标与更大网络
最后想说说这套代码的扩展空间。储能选址定容这个题目在学术界和工程界都有大量变体,你完全可以在当前版本基础上做自然的延伸,而不必从零开始。
第一个方向是双层优化。外层仍然使用改进遗传算法做选址定容,内层使用线性规划或动态规划做 24 时段储能充放电调度。这样得到的储能配置是“考虑最优运行策略”的,更加贴近实际,但计算时间会显著增加。我自己在测试版本中把运行策略换成完整调度优化后,单次适应度评估时间从 0.02 秒增加到 0.2 秒左右,整体耗时大约增长 10 倍,对于毕业设计或小规模工程还是可以接受的。
第二个方向是多目标优化。当前版本把经济性作为唯一目标,其他指标作为约束处理。如果你的研究重心是容量规划与电压质量的权衡,可以考虑使用 NSGA-II 或 MOEA/D 来处理“年综合费用最小”和“电压偏移最小”的双目标问题,得到帕累托前沿之后再做决策。这个方向我实验过,和改进遗传算法的主框架完全兼容,只需要把选择算子替换为基于非支配排序的选择即可。
第三个方向是扩展到大网络。IEEE 33 节点只是验证算例,实际配电网可能有几百上千个节点,每个节点都可能是储能候选位置。此时位置基因编码要从“节点编号取整”改成“按贡献度筛选的候选节点集合”,先把候选节点通过灵敏度分析缩到 10~20 个,再让遗传算法在其中选址。直接对所有节点编码会让搜索空间爆炸,收敛速度急剧下滑。
第四个可以尝试的方向是不确定性场景。负荷和新能源出力的随机性对储能规划结果影响很大,可以考虑用蒙特卡洛模拟生成多个典型场景,把目标函数改写成各场景期望值。这个方向会增加计算负担,但写出的论文或项目报告会更有说服力。
如果你需要把代码改成以上任一种扩展版本,注意最小化对主循环的改动,尽量通过修改目标函数和适应度评估函数来实现,遗传算法主体框架可以保持不变。我每次扩展功能时都会先保证基准场景结果不变,再叠加新模块,这种增量开发方式能大幅减少排错成本。
写了这么多,最后回到最初的出发点:任意设定储能数量并让算法自己去优化,看起来是一个很小的功能改动,实际上牵涉编码设计、遗传算子适配、约束管理三个层面的调整。希望这篇复盘笔记能帮你少走一些弯路。如果你在实际运行中遇到潮流不收敛、罚函数权重难调或者结果不合理的问题,欢迎对照文中的调参表逐项排查——大部分问题都出在参数配置,而不是代码逻辑本身。