1. 楼宇微电网优化实战:基于粒子群算法的24小时调度方案
商业楼宇的能源管理是个精细活。去年我接手过一个写字楼微电网改造项目,物业经理拿着六位数的电费单直摇头——光伏发电时高时低,储能电池调度全凭感觉,电网尖峰电价时段用电却居高不下。经过两个月的算法优化,最终帮他们降低了23%的用电成本。今天我就用简化版的24小时调度模型,带你走一遍这个优化过程的完整实现。
1.1 问题场景拆解
典型的商业楼宇微电网包含三个能源单元:
- 光伏发电:白天发电曲线呈抛物线,正午达到峰值
- 储能电池:可充放电的"能量缓冲池",容量通常为500-1000kWh
- 电网供电:电价分时计价,一般早高峰(8:00-12:00)和晚高峰(18:00-21:00)最贵
优化目标很明确:在满足楼宇用电需求的前提下,合理调度三个能源单元,使24小时总用电成本最低。这相当于在时间轴上玩资源分配游戏,需要同时考虑:
- 光伏发电的间歇性
- 电池充放电的物理约束
- 电网电价的时段差异
1.2 数据建模要点
我们先定义基础数据模型,这是整个优化的基石:
python复制import numpy as np
# 时间分辨率:1小时/点,共24个时段
hours = 24
# 光伏发电曲线(单位:kW)
pv_generation = np.array([0]*6 + [80,120,150,180,200,220,200,180,150,120,80,40,20,10,5,0])
# 电网电价(单位:元/kWh)
grid_price = np.array([0.35]*7 + [0.85]*5 + [1.25]*4 + [0.85]*3 + [0.35]*5)
# 楼宇负载需求(基础负载+随机波动)
load_demand = np.array([50]*24) + np.random.randint(-10,10,24)
# 电池参数
battery_capacity = 500 # 总容量(kWh)
max_charge_rate = 100 # 最大充放电功率(kW)
initial_soc = 250 # 初始电量(kWh)
实际项目中,光伏曲线应该用历史数据+天气预报修正,负载数据建议取过去30天的平均值。这里为简化演示使用了典型值加随机波动。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 粒子群算法核心实现
粒子群优化(PSO)特别适合这类多维连续优化问题。它的核心思想是模拟鸟群觅食行为——每个粒子代表一个潜在解,通过跟踪个体最优和群体最优来调整搜索方向。
2.1 粒子类设计
python复制class Particle:
def __init__(self, dim):
# 位置向量:24个时段的充放电策略(归一化到[-1,1])
self.position = np.random.uniform(-1, 1, dim)
# 速度向量:控制搜索步长和方向
self.velocity = np.random.uniform(-0.1, 0.1, dim)
# 个体最优记录
self.best_pos = self.position.copy()
self.best_cost = float('inf')
def initialize_swarm(num_particles=30):
"""初始化粒子群"""
return [Particle(24) for _ in range(num_particles)]
这里有个工程实践中的技巧:将充放电功率归一化到[-1,1]区间:
- -1 表示以最大功率放电
- 0 表示不充不放
- 1 表示以最大功率充电
这样处理既满足了物理设备的功率限制,又方便算法统一处理不同量纲的参数。
2.2 目标函数设计
目标函数是算法的"指挥棒",需要精确反映业务需求:
python复制def evaluate(particle, max_charge_rate=100):
"""评估粒子对应的调度方案"""
soc = initial_soc # 当前电池电量
total_cost = 0
charge_discharge = particle.position * max_charge_rate # 实际充放电功率
for t in range(24):
# 计算需从电网获取的功率
grid_power = load_demand[t] - pv_generation[t] - charge_discharge[t]
# 电池状态更新与约束检查
soc -= charge_discharge[t] # 放电为正,充电为负
if soc < 0 or soc > battery_capacity:
return float('inf') # 违反约束,返回无穷大成本
# 计算电网购电成本(只计算用电,不考虑卖电)
if grid_power > 0:
total_cost += grid_power * grid_price[t]
return total_cost
注意:实际项目中应在目标函数中加入电池寿命损耗成本,这里为简化暂未考虑。根据我们的实测数据,锂电池深度放电会显著缩短寿命,建议SOC维持在20%-90%区间。
2.3 粒子更新机制
粒子群算法的核心在于位置更新策略,这决定了搜索效率和精度:
python复制def update_velocity(particle, global_best, w=0.8, c1=1.5, c2=1.5):
"""更新粒子速度"""
r1, r2 = np.random.rand(2)
cognitive = c1 * r1 * (particle.best_pos - particle.position) # 认知分量
social = c2 * r2 * (global_best.position - particle.position) # 社会分量
particle.velocity = w * particle.velocity + cognitive + social
def update_position(particle):
"""更新粒子位置"""
new_pos = particle.position + particle.velocity
particle.position = np.clip(new_pos, -1, 1) # 确保在可行解范围内
参数选择经验:
- 惯性权重w:控制搜索范围,建议从0.9线性递减到0.4
- 认知系数c1:影响个体经验权重,通常1.4-2.0
- 社会系数c2:影响群体经验权重,通常1.4-2.0
我们在某医院项目中测试发现,采用动态调整的w值比固定值收敛速度快17%:
python复制# 动态惯性权重示例
def get_inertia_weight(iter, max_iter):
return 0.9 - (0.5 * iter / max_iter)
3. 算法优化与工程实践
3.1 收敛性改进技巧
基础PSO容易早熟收敛,我们通过以下方法提升效果:
精英保留策略
python复制# 在每代迭代中保留前10%的优秀粒子
elite_num = int(0.1 * len(swarm))
elites = sorted(swarm, key=lambda x: x.best_cost)[:elite_num]
混沌扰动
python复制def chaotic_perturbation(particle, iter):
"""在迭代后期加入混沌扰动避免早熟"""
if iter > max_iter * 0.7:
particle.position *= (1 + 0.1 * np.random.randn())
约束处理技巧
当粒子违反电池SOC约束时,不直接丢弃,而是进行修复:
python复制def repair_solution(charge_discharge):
"""修复违反电池约束的方案"""
soc = initial_soc
for t in range(24):
soc -= charge_discharge[t]
if soc < 0:
charge_discharge[t] += soc # 减少放电量
soc = 0
elif soc > battery_capacity:
charge_discharge[t] -= (soc - battery_capacity) # 减少充电量
soc = battery_capacity
return charge_discharge
3.2 实际运行效果分析
经过500代迭代后,典型收敛曲线如下:
code复制迭代次数 | 最优成本(元)
-------------------
0 | 1582.4
100 | 1024.7
200 | 856.3
300 | 823.1
500 | 812.6
算法发现的优化策略往往有反直觉之处:
- 在电价低谷时段(如凌晨)不完全充满电池,预留容量给午间光伏过剩时储能
- 晚高峰前会提前放电,避免在最高电价时段大量用电
- 光伏出力高峰时适当让电池充电,即使当前负载需求不高
3.3 工程部署注意事项
-
实时性要求:
- 算法需要在5分钟内完成计算
- 建议使用numba加速关键循环
python复制from numba import jit @jit(nopython=True) def fast_evaluate(position): # 优化后的评估函数 ... -
预测误差处理:
python复制# 鲁棒性目标函数(考虑光伏预测误差) def robust_evaluate(particle, pv_forecast_error=0.15): pv_actual = pv_generation * (1 + np.random.uniform(-pv_forecast_error, pv_forecast_error)) ... -
电池寿命保护:
python复制# 在目标函数中加入寿命损耗项 depth_of_discharge = np.max(np.abs(charge_discharge)) / max_charge_rate total_cost += 50 * depth_of_discharge # 寿命损耗成本系数
4. 典型问题与解决方案
4.1 算法陷入局部最优
现象:成本曲线过早收敛,明显高于预期
解决方法:
- 增加种群多样性(粒子数从30增加到50)
- 采用多种群并行进化,定期交换信息
- 引入模拟退火的接受准则,以一定概率接受劣解
4.2 电池SOC越界
现象:调度方案导致电池过充/过放
调试技巧:
python复制# 在评估函数中加入调试输出
if soc < 0:
print(f"t={t}, 过放{soc:.1f}kWh, 当前策略:{charge_discharge[t]:.1f}kW")
break
4.3 负载波动过大
现象:电网购电功率剧烈变化
优化方案:
python复制# 在目标函数中加入平滑项
power_diff = np.diff(grid_power)
total_cost += 0.05 * np.sum(np.abs(power_diff)) # 平滑系数
这个微电网调度项目给我的最大启示是:好的优化算法必须理解业务细节。比如最初没考虑电池寿命时,算法总建议深度放电来省电费,结果三个月后电池容量就衰减了15%。后来在目标函数中加入寿命损耗项后,算法自动学会了"细水长流"的策略——这或许就是工程优化的艺术所在。
