1. 微电网日前经济调度概述
在能源转型的大背景下,微电网作为分布式能源消纳的重要载体,其经济调度问题日益受到关注。传统微电网调度往往只考虑电源侧优化,忽视了用户侧需求响应和储能系统的协同作用,导致资源配置效率低下。本文将详细介绍如何利用Python实现一个考虑风光储能和需求响应的微电网日前经济调度系统。
2. 系统建模与问题描述
2.1 微电网系统架构
典型的"风光储能+需求响应"微电网系统包含以下主要组件:
-
电源侧:
- 风力发电机:出力受风速影响,具有波动性
- 光伏组件:出力呈现明显的昼夜周期性
- 大电网连接:作为备用电源或电能消纳渠道
-
储能侧:
- 锂电池/液流电池储能系统
- 充放电功率和SOC管理
-
负荷侧:
- 可调节负荷(参与需求响应)
- 不可调节负荷(必须满足的基本用电需求)
2.2 调度问题数学描述
微电网日前经济调度的核心是在满足各种约束条件下,最小化系统运行成本:
code复制min F = F₁ + F₂ + F₃ - F₄
其中:
- F₁:风光电源运维成本
- F₂:储能系统运行与寿命损耗成本
- F₃:大电网购电成本
- F₄:需求响应激励收益与可再生能源消纳补贴
3. Python实现关键步骤
3.1 数据准备与预处理
python复制import pandas as pd
import numpy as np
# 读取风光出力预测数据
def load_generation_data():
wind_power = pd.read_csv('wind_forecast.csv')
pv_power = pd.read_csv('pv_forecast.csv')
return wind_power, pv_power
# 读取负荷预测数据
def load_load_data():
base_load = pd.read_csv('base_load.csv')
flexible_load = pd.read_csv('flexible_load.csv')
return base_load, flexible_load
# 读取电价和激励数据
def load_price_data():
grid_price = pd.read_csv('grid_price.csv')
dr_incentive = pd.read_csv('dr_incentive.csv')
return grid_price, dr_incentive
3.2 约束条件实现
python复制class Constraints:
def __init__(self):
# 储能参数
self.soc_min = 0.2
self.soc_max = 0.8
self.charge_eff = 0.95
self.discharge_eff = 0.95
self.max_charge_power = 100 # kW
self.max_discharge_power = 100 # kW
# 需求响应参数
self.dr_max_reduction = 0.3 # 最大削减比例
self.dr_max_increase = 0.2 # 最大增加比例
def check_power_balance(self, solution, t):
"""
检查功率平衡约束
"""
total_generation = solution.wind[t] + solution.pv[t] + solution.grid[t]
if solution.ess_discharge[t] > 0:
total_generation += solution.ess_discharge[t]
else:
total_generation -= solution.ess_charge[t]
total_load = solution.base_load[t] + solution.flex_load[t]
return abs(total_generation - total_load) < 1e-3
def check_ess_constraints(self, solution):
"""
检查储能系统约束
"""
soc = solution.initial_soc
for t in range(24):
# SOC更新
if solution.ess_charge[t] > 0:
soc += solution.ess_charge[t] * self.charge_eff
else:
soc -= solution.ess_discharge[t] / self.discharge_eff
# SOC边界检查
if soc < self.soc_min or soc > self.soc_max:
return False
# 充放电功率检查
if solution.ess_charge[t] > self.max_charge_power:
return False
if solution.ess_discharge[t] > self.max_discharge_power:
return False
# 充放电互斥检查
if solution.ess_charge[t] > 0 and solution.ess_discharge[t] > 0:
return False
# SOC周期一致性检查
final_soc = soc
if abs(final_soc - solution.initial_soc) > 1e-3:
return False
return True
3.3 目标函数实现
python复制class ObjectiveFunction:
def __init__(self):
# 成本系数
self.wind_cost = 0.05 # 元/kWh
self.pv_cost = 0.03 # 元/kWh
self.ess_cost = 0.1 # 元/kWh
self.dr_cost = 0.15 # 元/kWh
def calculate(self, solution):
"""
计算目标函数值
"""
total_cost = 0
# 风光运维成本
wind_cost = sum(solution.wind) * self.wind_cost
pv_cost = sum(solution.pv) * self.pv_cost
# 储能成本
ess_cost = 0
for t in range(24):
if solution.ess_charge[t] > 0:
ess_cost += solution.ess_charge[t] * self.ess_cost
else:
ess_cost += solution.ess_discharge[t] * self.ess_cost
# 电网购电成本
grid_cost = 0
for t in range(24):
if solution.grid[t] > 0:
grid_cost += solution.grid[t] * solution.grid_price[t]
# 需求响应收益
dr_revenue = 0
for t in range(24):
if solution.flex_load[t] < solution.original_flex_load[t]:
reduction = solution.original_flex_load[t] - solution.flex_load[t]
dr_revenue += reduction * solution.dr_incentive[t]
total_cost = wind_cost + pv_cost + ess_cost + grid_cost - dr_revenue
return total_cost
4. 优化算法实现
4.1 粒子群优化(PSO)算法
python复制class Particle:
def __init__(self, dim):
self.position = np.random.rand(dim)
self.velocity = np.random.rand(dim) * 0.1
self.best_position = self.position.copy()
self.best_cost = float('inf')
class PSO:
def __init__(self, n_particles, dimensions, constraints, obj_func):
self.n_particles = n_particles
self.dimensions = dimensions
self.constraints = constraints
self.obj_func = obj_func
self.particles = [Particle(dimensions) for _ in range(n_particles)]
self.global_best_position = None
self.global_best_cost = float('inf')
# PSO参数
self.w = 0.7 # 惯性权重
self.c1 = 1.5 # 个体学习因子
self.c2 = 1.5 # 全局学习因子
def update(self):
for particle in self.particles:
# 更新速度
r1 = np.random.rand(self.dimensions)
r2 = np.random.rand(self.dimensions)
cognitive = self.c1 * r1 * (particle.best_position - particle.position)
social = self.c2 * r2 * (self.global_best_position - particle.position)
particle.velocity = self.w * particle.velocity + cognitive + social
# 更新位置
particle.position += particle.velocity
# 边界处理
particle.position = np.clip(particle.position, 0, 1)
# 评估粒子
solution = self.decode(particle.position)
if self.constraints.check(solution):
cost = self.obj_func.calculate(solution)
# 更新个体最优
if cost < particle.best_cost:
particle.best_cost = cost
particle.best_position = particle.position.copy()
# 更新全局最优
if cost < self.global_best_cost:
self.global_best_cost = cost
self.global_best_position = particle.position.copy()
def decode(self, position):
"""
将粒子位置解码为调度方案
"""
solution = Solution()
# 解码逻辑...
return solution
4.2 改进粒子群优化(IPSO)算法
python复制class IPSO(PSO):
def __init__(self, n_particles, dimensions, constraints, obj_func):
super().__init__(n_particles, dimensions, constraints, obj_func)
# 改进参数
self.w_max = 0.9
self.w_min = 0.4
self.iter_max = 100
def update_inertia(self, iteration):
"""
自适应惯性权重
"""
self.w = self.w_max - (self.w_max - self.w_min) * iteration / self.iter_max
def update(self, iteration):
self.update_inertia(iteration)
for particle in self.particles:
# 速度更新
r1 = np.random.rand(self.dimensions)
r2 = np.random.rand(self.dimensions)
cognitive = self.c1 * r1 * (particle.best_position - particle.position)
social = self.c2 * r2 * (self.global_best_position - particle.position)
particle.velocity = self.w * particle.velocity + cognitive + social
# 位置更新
particle.position += particle.velocity
# 边界处理
particle.position = np.clip(particle.position, 0, 1)
# 变异操作
if np.random.rand() < 0.1:
idx = np.random.randint(self.dimensions)
particle.position[idx] = np.random.rand()
# 评估粒子
solution = self.decode(particle.position)
if self.constraints.check(solution):
cost = self.obj_func.calculate(solution)
if cost < particle.best_cost:
particle.best_cost = cost
particle.best_position = particle.position.copy()
if cost < self.global_best_cost:
self.global_best_cost = cost
self.global_best_position = particle.position.copy()
5. 完整调度流程实现
5.1 主调度流程
python复制def main():
# 1. 数据准备
wind_power, pv_power = load_generation_data()
base_load, flex_load = load_load_data()
grid_price, dr_incentive = load_price_data()
# 2. 初始化约束和目标函数
constraints = Constraints()
obj_func = ObjectiveFunction()
# 3. 初始化优化算法
# 每个时段有6个决策变量:风电、光伏、电网、储能充、储能放、可调负荷
dimensions = 24 * 6
pso = IPSO(n_particles=50, dimensions=dimensions,
constraints=constraints, obj_func=obj_func)
# 4. 优化过程
for iteration in range(100):
pso.update(iteration)
# 打印当前最优解
if iteration % 10 == 0:
print(f"Iteration {iteration}, Best Cost: {pso.global_best_cost:.2f}")
# 5. 结果输出
best_solution = pso.decode(pso.global_best_position)
save_results(best_solution)
# 6. 可视化
plot_schedule(best_solution)
5.2 结果可视化
python复制import matplotlib.pyplot as plt
def plot_schedule(solution):
plt.figure(figsize=(12, 8))
# 1. 功率平衡图
plt.subplot(2, 1, 1)
time = range(24)
total_generation = solution.wind + solution.pv
total_generation[solution.ess_discharge > 0] += solution.ess_discharge[solution.ess_discharge > 0]
total_load = solution.base_load + solution.flex_load
plt.plot(time, total_generation, label='Total Generation')
plt.plot(time, total_load, label='Total Load')
plt.fill_between(time, 0, solution.grid, where=(solution.grid>0),
facecolor='green', alpha=0.3, label='Grid Purchase')
plt.fill_between(time, 0, -solution.grid, where=(solution.grid<0),
facecolor='red', alpha=0.3, label='Grid Sale')
plt.legend()
plt.title('Power Balance')
plt.xlabel('Hour')
plt.ylabel('Power (kW)')
# 2. 储能SOC曲线
plt.subplot(2, 1, 2)
soc = solution.initial_soc
soc_history = []
for t in range(24):
if solution.ess_charge[t] > 0:
soc += solution.ess_charge[t] * constraints.charge_eff
else:
soc -= solution.ess_discharge[t] / constraints.discharge_eff
soc_history.append(soc)
plt.plot(time, soc_history)
plt.axhline(y=constraints.soc_max, color='r', linestyle='--')
plt.axhline(y=constraints.soc_min, color='r', linestyle='--')
plt.title('ESS SOC Profile')
plt.xlabel('Hour')
plt.ylabel('SOC')
plt.tight_layout()
plt.show()
6. 实际应用中的注意事项
6.1 参数调优经验
-
PSO参数设置:
- 粒子数量:一般设置为问题维度的5-10倍
- 惯性权重:采用线性递减策略,初始值0.9,最终值0.4
- 学习因子:c1和c2通常设置为1.5-2.0
-
约束处理技巧:
- 对于违反约束的解,可以采用惩罚函数法
- 储能SOC约束处理时,建议采用修复策略而非直接丢弃
-
计算效率优化:
- 并行计算:评估粒子适应度时可以并行化
- 早期终止:如果连续多代没有改进,可以提前终止
6.2 常见问题排查
-
算法收敛问题:
- 现象:目标函数值波动大,难以收敛
- 解决方法:调整PSO参数,增加变异操作
-
约束违反问题:
- 现象:最优解违反某些约束条件
- 解决方法:加强约束处理逻辑,增加惩罚系数
-
计算时间过长:
- 现象:优化过程耗时太长
- 解决方法:减少粒子数量,简化约束检查逻辑
7. 扩展与改进方向
7.1 考虑不确定性的鲁棒优化
python复制class RobustOptimizer:
def __init__(self, scenarios):
self.scenarios = scenarios # 多个风光出力场景
def optimize(self):
# 实现鲁棒优化逻辑
pass
7.2 多时间尺度调度
python复制class MultiTimescaleScheduler:
def __init__(self):
self.day_ahead = DayAheadScheduler()
self.real_time = RealTimeScheduler()
def run(self):
# 日前调度
day_ahead_plan = self.day_ahead.schedule()
# 实时调度
for t in range(24):
actual_data = get_real_time_data()
adjustment = self.real_time.adjust(day_ahead_plan, actual_data)
execute_schedule(adjustment)
7.3 机器学习辅助预测
python复制from sklearn.ensemble import RandomForestRegressor
class GenerationPredictor:
def __init__(self):
self.wind_model = RandomForestRegressor()
self.pv_model = RandomForestRegressor()
def train(self, X, y_wind, y_pv):
self.wind_model.fit(X, y_wind)
self.pv_model.fit(X, y_pv)
def predict(self, X):
wind = self.wind_model.predict(X)
pv = self.pv_model.predict(X)
return wind, pv
8. 总结与实用建议
在实际微电网调度系统开发中,建议采用模块化设计思路:
- 数据模块:统一管理风光出力预测、负荷预测、电价等数据
- 模型模块:实现调度问题的数学建模和约束处理
- 算法模块:封装各种优化算法,便于比较和切换
- 可视化模块:提供直观的结果展示和系统状态监控
对于Python实现,可以考虑使用面向对象的设计模式,将微电网各组件抽象为类,便于扩展和维护。同时,对于大规模问题,可以考虑使用Pyomo等优化建模工具,或者调用专业的优化求解器如Gurobi、CPLEX等。