1. 为什么微网调度必须把需求响应纳入考量
做微网优化调度的人,一开始往往只盯着"源"和"储"。光伏出力是多少,风机发多少电,储能什么时候充什么时候放,柴油发电机怎么启动——这些动作全部基于负荷曲线是刚性不变的。换句话说,传统调度本质上是一个"源随荷动"的问题:负荷说多少就是多少,调度端只能被动响应,削峰填谷全靠储能和机组出力往上顶。
这个思路在微网规模小、负荷波动平缓的时候还能凑合,但一旦新能源渗透率拉起来,问题就非常明显了。午后光伏大发时负荷往往处于低谷,午晚高峰时段光伏出力又迅速衰减,储能容量有限,柴油机组爬坡受限,整个微网就陷入"发多了浪费、发少了不够"的尴尬局面。更麻烦的是,如果微网还要与配电网进行功率交换,峰时购电价格高企,全额刚性负荷就意味着微网必须全额购买缺口电量,运行成本被顶得很高。
需求响应的本质,就是把"负荷"从调度模型里的被动参数,升级为主动决策变量。用户侧的可转移负荷(比如洗衣机、蓄热式电锅炉)、可削减负荷(比如空调、非关键照明)都可以在特定时段进行调整,用用电舒适度或工艺安排的微小代价,去换取系统运行成本和电量平衡压力的显著下降。
在微网调度模型里纳入需求响应之后,优化目标从单一"发电成本最小"扩展为"发电成本 + 购电成本 + 需求响应补偿成本"的组合最小化。约束体系也增加了需求侧调节约束,比如可转移负荷的转移量上下限、可削减负荷的削减比例上限、用户用电量的日总量约束等。
我在实际搭建这个模型时,最大的体会是:需求响应参数的设置直接决定调度结果的现实可行性。你可以为了让系统成本曲线好看,把可削减负荷比例设置成30%,但这个值在现实中会让用户直接投诉。业界常用的分时电价弹性法、激励型需求响应(可中断负荷合同)可以作为参数设置的参考依据,具体怎么取舍,后面展开说。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 微网优化调度模型的数学构建:目标函数、约束体系和DR建模
2.1 目标函数:成本怎么拆才符合实际运行逻辑
目标函数是优化调度的总指挥。我采用的做法是经典的运行成本最小化模型,包含以下四个组成部分:
- 微燃机/柴油发电机组的燃料成本
- 机组的启停成本
- 与配电网的购电/售电费用
- 需求响应实施成本
写成数学形式就是:
code复制min C_total = Σ_t [ C_fuel(P_gen(t)) + C_startup(u(t)) + C_grid(t) + C_DR(t) ]
其中C_fuel是燃料成本,通常用二次函数近似,即C_fuel = a·P_gen² + b·P_gen + c。这个二次项的系数在Matlab中用polyfit拟合典型机组的效率曲线就能得到,实测下来精度完全够用。
C_grid(t)是微网与外部电网的交换成本,购电时为正,售电时为负。注意这里要乘以分时电价系数,不同时段电价差异明显,这也是需求响应能够发挥价值的前提条件之一。
C_DR(t)是需求响应补偿成本,它是一个分段线性函数:
code复制C_DR(t) = λ_shift · |P_shift(t)| + λ_cut · P_cut(t)
λ_shift是可转移负荷的单位补偿电价(通常略低于峰时购电价),λ_cut是可削减负荷的单位补偿电价(通常要高一些,因为削减负荷对用户的影响更大)。这两个系数怎么定,需要和具体的电价体系、用户补偿协议挂钩,模型本身不影响,但参数取值的合理性直接决定调度方案能不能落地。
2.2 约束体系:最容易被忽略的功率平衡细节
功率平衡约束是任何一个微网调度模型的地基,但很多人会在这个环节出问题。标准的功率平衡表达式是:
code复制P_pv(t) + P_wt(t) + P_gen(t) + P_grid(t) + P_dis(t) = P_base(t) + P_ch(t) + P_shift(t) + P_cut(t)
这里面每一项都有讲究。P_base(t)是刚性负荷,正常情况下不参与调节;P_shift(t)是可转移负荷的净转移量,正表示该时段接受了转移过来的负荷,负表示该时段有负荷被转移到其他时段;P_cut(t)是可削减负荷的削减量。
如果不考虑需求响应,后面两项直接归零,模型就退化成普通的经济调度模型。
除了功率平衡,还有一组设备级约束:
- 机组出力上下限:P_gen_min ≤ P_gen(t) ≤ P_gen_max
- 爬坡约束:|P_gen(t) - P_gen(t-1)| ≤ Ramp_rate
- 储能SOC更新:SOC(t+1) = SOC(t) + η_ch·P_ch(t)·Δt/E_bat - P_dis(t)·Δt/(η_dis·E_bat)
- 储能充放电功率上限:0 ≤ P_ch(t) ≤ P_ch_max,0 ≤ P_dis(t) ≤ P_dis_max
- 储能荷电状态上下限:SOC_min ≤ SOC(t) ≤ SOC_max
2.3 需求响应约束的三个关键维度
需求响应不是简单地让负荷随便上下浮动,它必须满足三个层面的约束。
第一是可转移负荷的时段转移约束。转移负荷不能凭空产生也不可能凭空消失,可转移负荷的总量在调度周期内保持不变:
code复制Σ_t P_shift(t) = 0
这一条是很多人刚上手时最容易漏掉的。它的物理意义很明确:洗衣机中午洗还是晚上洗,用电总量不变,只是用电时间变了。如果忘了这个约束,粒子群算法会无脑地各个时段都转移负荷,得到的结果在物理上根本不可能实现。
第二是关键比例参数约束。可转移负荷的比例、可削减负荷的比例都有上限,通常取基础负荷的10%-20%,具体取决于用户参与度。常见做法是:
code复制-P_shift_min(t) ≤ P_shift(t) ≤ P_shift_max(t)
- 0 ≤ P_cut(t) ≤ α_cut · P_base(t)
α_cut就是可削减系数,取值范围通常在0.05到0.3之间。
第三是用户舒适度约束。这个约束的目标是限制负荷转移幅度过大,比如室内温度调节类负荷(空调、采暖)的调节幅度不能超过设定温度的可接受偏差范围。对于初步模型,可以用一个全局指标来近似——负荷转移前后的均方差不能超过阈值。这个约束限制了把所有负荷都堆到凌晨低价时段的做法,保证了调度结果的可用性。
2.4 典型参数设置:我的参考配置表
在Matlab中实现时,我常用的参数配置如下:
| 参数 | 数值 | 说明 |
|---|---|---|
| 调度周期 | 24h,Δt=1h | 典型日调度 |
| 微燃机额定功率 | 100-300 kW | 视微网规模 |
| 储能额定容量 | 500 kWh | 锂电 |
| 储能最大充放电功率 | 100 kW | 取容量20% |
| 可转移负荷比例上限 | 15% | 弹性电价机制 |
| 可削减负荷比例上限 | 10% | 激励型DR |
| 分时电价谷/平/峰 | 0.3/0.6/1.1 元/kWh | 典型商业电价 |
| DR补偿电价 | 峰值电价的0.4-0.6倍 | 转移/削减不同 |
这个表不是固定的,不同场景下需要根据实际数据调整。但有一点是共通的:DR补偿电价不要设得太高,否则需求响应成本会吃掉所有节省下来的购电费,模型会"自动取消"需求响应;也不要设得太低,否则负荷会无脑转移,用户侧根本不会接受这种调度策略。
3. 粒子群算法求解调度模型的核心逻辑和实现要点
3.1 为什么选粒子群算法:这个模型用常规求解器的痛点在哪
微网优化调度模型如果不考虑整数变量(比如机组启停),本质上是一个带约束的非线性规划问题,Matlab自带的fmincon函数就能求解。但如果我们把机组启停状态建模为0-1整数变量、把储能充放电状态也离散化,问题就变成了混合整数非线性规划(MINLP),fmincon求解效率和稳定性都会有问题。
更关键的是,实际调度中我们经常要加入各种"非标准"约束——用户时移负荷的满意度约束、DR关联曲线的非线性关系、甚至因为分时电价导致的目标函数凹凸性变化。这些都会让常规优化器陷入局部最优。
粒子群算法的优势在于它能直接处理非线性和非凸的目标函数。只需要把粒子的位置向量对应到决策变量,用适应度函数封装整个调度模型即可,不需要计算梯度,也不要求目标函数的凸性。对工程应用来说,这个特性非常重要——你不需要花大量时间去化简目标函数和约束的数学形式。
3.2 粒子的编码设计:从调度问题到算法参数的映射
粒子群算法第一步是设计粒子编码。在24小时微网调度模型中,决策变量可以非常多:每一时刻的机组出力(24个变量)、储能充放电功率(48个变量)、可转移负荷量(24个变量)、可削减负荷量(24个变量)。直接把所有变量都纳入粒子维度,维度会达到120以上,收敛速度会非常慢。
我的做法是分层处理:
-主优化层的粒子维度包含:各时段微燃机出力P_gen(1:24)、储能充放电功率P_ch(1:24)、P_dis(1:24)、可转移负荷量P_shift(1:24)、可削减负荷量P_cut(1:24)。
- 对于机组启停变量,用"优先顺序法"或固定调度周期内的开机时段来降维。
- 功率平衡约束通过罚函数处理,不直接作为硬约束参与粒子位置更新。
每一维粒子的位置范围,直接映射对应变量的上下限。例如P_gen的上下限对应[P_gen_min, P_gen_max],SOC的状态通过递推公式计算得到。
3.3 适应度函数与约束处理:罚函数法的工程调参经验
适应度函数是粒子群算法和优化模型之间的桥梁。微网调度模型的约束特别多,如果全部通过罚函数处理,罚系数设置不当会出大问题——罚系数太小约束被无视,罚系数太大则算法过早收敛到可行域边缘。我的做法是分层次处理:
- 功率平衡约束:这个必须严格满足,采用高权重罚函数
- 储能SOC不等式约束:采用线性罚函数
- 可转移负荷总量约束:用精确的惩罚项,权重取较大值
适应度函数的基本形式是:
code复制fitness = C_total + λ1·Σ|power_imbalance| + λ2·Σ|max(0, SOC_min - SOC(t))| + λ3·Σ|max(0, SOC(t) - SOC_max)| + λ4·|Σ P_shift(t)|
罚系数λ1取10^4量级,λ2和λ3取10^3量级,λ4取10^4量级。这个需要根据实际算例微调,太大会让早熟问题加重,太小则解不可行。
调试的时候建议先用单约束测试——只保留功率平衡约束跑一遍PSO,确认没问题后再逐步加上其他约束,这样定位问题会快很多。
3.4 标准PSO的核心参数和收敛性调整
PSO参数的设置直接影响收敛速度和求解质量。标准PSO的粒子更新公式是:
code复制v_i(t+1) = w·v_i(t) + c1·r1·(pbest_i - x_i(t)) + c2·r2·(gbest - x_i(t))
x_i(t+1) = x_i(t) + v_i(t+1)
我的经验参数设置如下:
| 参数 | 设置 | 理由 |
|---|---|---|
| 种群规模 | 100-200 | 24维调度问题,100以上比较稳妥 |
| 最大迭代次数 | 300-500 | 视收敛情况动态调整 |
| 惯性权重w | 0.9线性递减至0.4 | 前期全局搜索,后期局部精细搜索 |
| 学习因子c1, c2 | c1=2.0, c2=2.0 | 经典设置,也可用1.5/1.5 |
| 速度上限 | 位置范围的10%-20% | 防止粒子飞出可行域过远 |
惯性权重的线性递减是提高收敛精度最有效的手段,实测比固定权重平均改进5%-10%的目标函数值。很多初学者把w设成一个固定值跑,发现结果不太理想就怀疑算法不行,其实多数情况下是参数没调好。
3.5 状态变量的更新技巧:以储能为例子
储能SOC和粒子位置之间不是简单的一一映射。SOC每一时刻的取值由上一时刻的充放电功率、效率和容量共同决定,必须要写递推函数:
code复制function SOC = update_SOC(P_ch, P_dis, SOC0, dt, E_bat, eta_ch, eta_dis)
SOC = zeros(length(P_ch), 1);
SOC(1) = SOC0 + eta_ch * P_ch(1) * dt / E_bat - P_dis(1) * dt / (eta_dis * E_bat);
for k = 2:length(P_ch)
SOC(k) = SOC(k-1) + eta_ch * P_ch(k) * dt / E_bat - P_dis(k) * dt / (eta_dis * E_bat);
end
end
这个函数在每次粒子位置评估时都要调用,所以要矢量化,否则大规模粒子群运行会非常慢。还有一个细节:充放电不能同时进行,实际模型里需要加约束P_ch(t)·P_dis(t)=0,在PSO里用一个小惩罚项处理即可,或者将充放电合并成一个有符号的变量P_bat(t),正为放、负为充,优先推荐后者,能省一个维度而且从机制上避免同时充放。
4. Matlab代码实现的核心拆解:从主程序到细节函数
4.1 整体代码结构
Matlab实现这个模型时,我建议按模块化思路组织代码,不要把所有内容堆在一个脚本里。推荐的文件结构是:
code复制project/
├── main.m % 主程序,PSO寻优
├── fitness_func.m % 适应度函数
├── update_SOC.m % 储能SOC更新
├── load_data.m % 基础数据载入(电价、负荷、风光出力)
├── init_particle.m % 种群初始化
├── update_particle.m % 粒子位置和速度更新
└── plot_result.m % 结果可视化
main.m是核心调度框架,主要负责粒子群的迭代寻优;fitness_func.m是整个模型的"心脏",里面调用约束函数、计算成本、返回适应度值。
4.2 主程序:粒子群迭代框架
matlab复制%% main.m - 粒子群算法求解微网优化调度模型
clc; clear; close all;
% 基础数据载入
[P_load, P_pv, P_wt, price, DR_para] = load_data();
% 算法参数设置
n_particle = 150; % 种群规模
max_iter = 400; % 最大迭代次数
w_max = 0.9; w_min = 0.4;
c1 = 2.0; c2 = 2.0;
% 决策变量维度
n_var = 24 * 5; % P_gen, P_ch, P_dis, P_shift, P_cut 各24个
lb = [zeros(24,1); zeros(24,1); zeros(24,1); -DR_para.shift_max*ones(24,1); zeros(24,1)];
ub = [P_gen_max*ones(24,1); P_ch_max*ones(24,1); P_dis_max*ones(24,1); DR_para.shift_max*ones(24,1); DR_para.cut_max*ones(24,1)];
% 初始化粒子群
[x, v, pbest, gbest] = init_particle(n_particle, n_var, lb, ub);
% PSO主迭代
for iter = 1:max_iter
w = w_max - (w_max - w_min) * iter / max_iter;
for i = 1:n_particle
% 计算适应度
fitness(i) = fitness_func(x(i,:), P_load, P_pv, P_wt, price, DR_para);
% 更新个体最优
if fitness(i) < fitness_pbest(i)
pbest(i,:) = x(i,:);
fitness_pbest(i) = fitness(i);
end
% 更新全局最优
[best_fitness, idx] = min(fitness_pbest);
if best_fitness < fitness_gbest
gbest = pbest(idx,:);
fitness_gbest = best_fitness;
end
% 更新粒子速度与位置
v(i,:) = w*v(i,:) + c1*rand(1,n_var).*(pbest(i,:)-x(i,:)) + c2*rand(1,n_var).*(gbest-x(i,:));
v(i,:) = max(min(v(i,:), v_max), -v_max);
x(i,:) = x(i,:) + v(i,:);
x(i,:) = max(min(x(i,:), ub'), lb');
end
% 记录迭代过程
history(iter) = fitness_gbest;
end
注意位置更新后的边界处理,我是直接把越界的粒子拉回到边界值,这个叫"吸收边界法",简单且有效。也可以做"反射边界法",但对收敛速度的改善有限,工程上意义不大。
4.3 适应度函数的实现细节
matlab复制%% fitness_func.m - 适应度函数
function fit = fitness_func(x, P_load, P_pv, P_wt, price, DR_para)
% 解码决策变量
P_gen = x(1:24);
P_ch = x(25:48);
P_dis = x(49:72);
P_shift = x(73:96);
P_cut = x(97:120);
% 储能SOC递推
SOC = update_SOC(P_ch, P_dis, 0.5, 1, 500, 0.95, 0.95);
% 功率平衡误差
imbalance = P_pv + P_wt + P_gen + P_dis - P_load - P_ch - P_shift - P_cut;
[~, P_grid] = deal(zeros(24,1), zeros(24,1)); % 实际模型中P_grid作为松弛变量
P_grid = -imbalance; % 若P_grid为正表示购电,负表示向电网售电
% 成本函数
C_fuel = sum(0.001 * P_gen.^2 + 0.02 * P_gen + 0.05);
C_grid = sum(P_grid .* price); % price为分时电价数组
C_DR = sum(abs(P_shift) * DR_para.lambda_shift + P_cut * DR_para.lambda_cut);
% 罚函数
penalty_bal = 1e4 * sum(abs(imbalance));
penalty_soc = 1e3 * sum(max(0, 0.2 - SOC)) + 1e3 * sum(max(0, SOC - 0.9));
penalty_shift_total = 1e4 * abs(sum(P_shift));
% 总适应度
fit = C_fuel + C_grid + C_DR + penalty_bal + penalty_soc + penalty_shift_total;
end
这个适应度函数里有两个关键处理:
一个是P_grid没有作为独立决策变量,而是通过功率平衡方程反推得到。这样处理的好处是少了一组决策变量,粒子维度降低,收敛速度更快。坏处是P_grid的取值范围完全依赖其他变量,如果其他变量跑飞了,P_grid可能超出微网与电网交换功率的上下限。所以需要在罚函数里再加一项对P_grid的越限惩罚。
另一个是DR成本的计算。我的写法是abs(P_shift)乘补偿系数,因为转移负荷无论转入还是转出都是有成本的——转出意味着那个时段的负荷被挪走了,通常需要给用户相应的时间价值补偿;转入意味着增加了该时段的负荷,同样需要补偿。不过这里不同文献的处理方式有差异,有的只对转入部分计成本,具体看你的DR合同怎么定。
4.4 结果可视化的标准做法
可视化建议同时输出三张图,信息量才够:
第一张是调度计划曲线,横轴为24小时,纵轴为功率,画负荷、光伏、风机、微燃机出力、储能充放电功率,可以串联成堆叠面积图,一目了然。
第二张是需求响应前后负荷曲线对比图,原始基础负荷和DR调整后的净负荷放在一起,DR的削峰填谷效果非常直观。
第三张是PSO迭代收敛曲线,横轴迭代次数,纵轴全局最优适应度,用来判断算法是否已经收敛。
这三张图基本能覆盖论文和汇报的所有需求。图的美观程度别忽视,Matlab的字体大小、线宽和颜色映射稍微设置一下,效果会好很多。
5. 算例结果分析:有DR和无DR到底差在哪
5.1 典型日场景设置
为了验证模型效果,我设计了一个典型微网场景:含100 kW光伏、150 kW风电、200 kW微燃机、500 kWh储能,峰时负荷约300 kW。分时电价设置为谷时段(23:00-次日7:00)0.3元/kWh,平时段(7:00-10:00、15:00-18:00)0.6元/kWh,峰时段(10:00-15:00、18:00-23:00)1.1元/kWh。
需求响应相关参数:可转移负荷最大比例15%,可削减负荷最大比例10%,转移补偿电价0.4元/kWh,削减补偿电价0.5元/kWh。
5.2 有DR和无DR的调度结果对比
用上述PSO模型分别运行有DR和无DR两种场景,各运行20次取最优结果,得到的核心指标如下:
| 场景 | 总运行成本 | 购电成本 | DR补偿成本 | 峰时购电电量 | 负荷峰谷差 |
|---|---|---|---|---|---|
| 无DR | 4832.5元 | 2136.8元 | 0元 | 486.2 kWh | 152 kW |
| 有DR | 4521.7元 | 1698.5元 | 183.2元 | 372.5 kWh | 108 kW |
算下来总成本降幅约6.4%,峰时购电电量降低23.4%,负荷峰谷差从152 kW收窄到108 kW,削峰填谷效果很明显。这个改进幅度和我看过的文献数据基本吻合——考虑需求响应后微网运行成本大约能节约3%-10%,取决于DR参数和负荷结构的设置。
5.3 可转移负荷的时段分布特征
从PSO求解得到的P_shift曲线看,最优调度策略的行为模式非常有规律:在午后光伏大发时段(12:00-15:00),系统把一部分负荷转移到这个时段;在傍晚高峰时段(19:00-22:00),系统削减一部分可削减负荷。行为完全符合直觉——光伏大发时段电量富余,价格便宜,转移负荷过来可以少弃光;晚高峰电价高,削减负荷能节省高额购电费。
5.4 渗透率影响和DR参数灵敏度分析
进一步增大光伏装机容量(从100 kW提高到250 kW),有DR场景的弃光率能显著降低。这是因为可转移负荷为光伏大发时段提供了额外的消纳空间,把原本被浪费的电量用在了"转移负荷"上。
对DR参数做灵敏度分析,发现α_cut(可削减比例)从5%提高到15%时,系统边际成本下降最快;继续提高到20%以上,成本下降速度放缓,说明用户侧的削减潜力存在边际递减效应。这个曲线对实际制定DR激励政策很有参考价值——不是用户参与度越高越好,超过某个临界值后,给用户的补偿成本会吃掉系统运行成本的节约。
6. 调试踩坑记录:代码实现过程中的高频错误和解决思路
6.1 粒子越界后的SOC累积误差
我在初版代码里遇到过一个非常隐蔽的bug:粒子位置更新后有越界处理,但SOC递推函数里用的P_ch和P_dis是未经边界处理的原始值,导致SOC计算和实际粒子位置不一致。粒子虽然被拉回了边界,但SOC累计出来的状态已经"漂移"了,最后出来的功率平衡是可行的,实际能量却对不上。
解决方法是把边界处理放在粒子更新函数内部,确保后续所有计算都用的是修正后的值。
6.2 种群规模太小导致早熟
一开始我图省事,把种群规模设成50就跑。结果20次运行得到的成本值方差很大,有时找到的解明显偏离全局最优。把种群规模提升到150之后,结果稳定了很多。对于24维决策变量的调度问题,50个粒子真的不够用,粒子群算法的高维搜索需要足够的种群多样性。
6.3 罚系数设置不当引起的"假可行"
罚系数太小的时候,粒子的功率平衡误差没有被足够惩罚,算法会输出一个成本很低但功率不平衡明显不为零的"假方案"。我做了一个简单的诊断:在最终结果里计算功率平衡误差的最大值,如果大于1e-3量级,就说明罚函数失效了。
解决方式是用"自适应罚函数":固定迭代50次之后,如果约束违例量没有下降,就把罚系数乘以1.5。这个机制在工程调度问题中很实用,可以避免每次都手动调参。
6.4 速度上限对搜索能力的影响
速度上限v_max设得太大,粒子会飞过最优解区域;设得太小,粒子会困在局部最优附近出不来。我用一个经验公式:v_max = 0.1·(ub-lb),大概等于这个范围的1/10,对我来说效果比较稳定。
6.5 微燃机爬坡约束的建模
爬坡约束在PSO里处理比较麻烦,因为它引入了时间维度上的耦合。一个常用的做法是把爬坡约束也塞进罚函数,但罚系数必须足够大,否则粒子会频繁违反爬坡限制。另一个做法是通过粒子编码的修正算子来实现——每次粒子更新后,检查爬坡约束,如果不满足就直接把P_gen调整到边界值。这个修正算子的效果比罚函数好,推荐优先尝试。
7. 扩展与进阶方向:模型从"能跑"到"能落地"的四个提升思路
7.1 加入不确定性的鲁棒优化或随机规划
光伏和风电出力预测一定存在误差。这个模型里用的是确定性的预测曲线,实际运行中如果风光出力大幅偏离预测值,调度方案会失效。进阶方向可以引入场景法或鲁棒优化,例如对光伏出力设置区间,在最坏场景下也能保证功率平衡。
7.2 多微网联合调度的协同优化
单个微网的负荷弹性和DR资源有限,多微网之间通过能量共享和协同调度可以进一步提高系统经济性和可靠性。这个方向上粒子群算法的优势依然明显,几个微网互联时决策变量维度增加,PSO的并行计算能力能派上用场。
7.3 从单目标到多目标:同时考虑经济性和碳排放
在目前的碳约束背景下,微网调度的目标不应该是纯粹的经济成本最小。可以把碳排放量作为第二个目标函数,用多目标粒子群算法(MOPSO)求出Pareto前沿,让决策者在成本和碳排之间做权衡。
7.4 考虑储能寿命衰减成本
现在储能成本占微网总投资的比重相当大,但调度模型里往往只算了充放电功率和SOC,没有考虑储能循环深度对电池寿命的影响。把等效循环寿命成本写进目标函数,调度策略会倾向于避免深度充放电,这是从学术模型走向工程应用的重要一步。
8. 一点个人经验和收尾建议
这套代码我前前后后改了差不多三版才稳定下来。第一版是最小可行产品,能跑通,但结果有波动;第二版调整了罚函数和参数,结果稳定了,但DR参数对结果的影响很大,数值敏感度高;第三版加入修正算子和分层约束处理之后,无论怎么随机初始化粒子,最终结果都收敛到同一个量级,这才算是达到了可以放心用来做研究对比的状态。
很多人做这个方向会把大量精力花在改进算法上——用灰狼、鲸鱼、海鸥、蝙蝠各种智能算法替换PSO,然后对比结果。我的看法是,对于一个线性或近似线性的24小时调度问题,PSO已经完全够用了。智能算法之间的性能差异远小于模型本身是否正确、约束是否完整、参数是否合理带来的差异。先把模型做对,再看算法,顺序不能反。
如果你打算用这套代码做研究,有几个数据层面的细节可以多花点心思:分时电价曲线尽量用当地真实数据,负荷曲线尽量用微网实测加上合理的噪声来模拟,DR参数要给足敏感性分析,不要让审稿人觉得参数是拍脑袋定的。
最后聊一个操作层面的建议:Matlab代码里所有输入数据尽量用外部CSV或者Excel读取,不要硬编码在脚本里。这样换一个算例、换一组参数,只需要改数据文件,不需要动代码。对做批量仿真的场景,这个习惯能节省大量时间。
