在电力市场研究中,如何准确模拟发电公司(GenCos)的竞价行为一直是个棘手的问题。传统博弈论方法虽然能分析纳什均衡,但仅限于完全信息静态博弈场景;而传统强化学习算法又受限于低维离散状态空间,收敛性难以保证。我们团队基于深度确定性策略梯度(DDPG)算法,开发了一套能够处理高维连续状态空间的电力市场仿真模型。
这个项目的核心价值在于:通过深度神经网络处理连续变量,我们不仅避免了传统方法中状态空间离散化带来的精度损失,还能通过调整"耐心参数"(patience parameter)定量分析不同默契合谋程度对市场的影响。在3节点和IEEE 30节点系统上的实验表明,即便在不完全信息环境下,模型仍能稳定收敛到完全信息纳什均衡。
提示:DDPG算法特别适合这类连续控制问题,它结合了策略梯度法和值函数法的优势,通过Actor-Critic架构同时学习策略和值函数。
DDPG(Deep Deterministic Policy Gradient)是一种基于Actor-Critic架构的无模型算法,特别适合处理连续动作空间问题。在我们的电力市场模型中,每个GenCo被视为一个智能体,其竞价策略通过以下组件实现:
python复制class Actor(nn.Module):
def __init__(self, state_dim, action_dim, max_action):
super(Actor, self).__init__()
self.layer1 = nn.Linear(state_dim, 400)
self.layer2 = nn.Linear(400, 300)
self.layer3 = nn.Linear(300, action_dim)
self.max_action = max_action
def forward(self, state):
x = F.relu(self.layer1(state))
x = F.relu(self.layer2(x))
x = self.max_action * torch.tanh(self.layer3(x))
return x
市场环境建模包含以下关键要素:
供给曲线:每个GenCo的报价函数为线性形式:p = α + β*q
需求曲线:节点负荷需求函数为线性形式:p = c + d*q
网络约束:考虑线路传输容量限制,通过直流最优潮流(DCOPF)进行市场出清
python复制def market_clearing(a_declare):
# 构建优化问题
prob = pulp.LpProblem("Market_Clearing", pulp.LpMinimize)
# 定义决策变量
p_g = [pulp.LpVariable(f"p_{i}", lowBound=p_min[i], upBound=p_max[i]) for i in range(6)]
q_d = [pulp.LpVariable(f"q_{j}", lowBound=q_min[j], upBound=q_max[j]) for j in range(20)]
# 目标函数:申报成本最小化
prob += pulp.lpSum([a_declare[i] * p_g[i] + 0.5 * b_declare[i] * p_g[i]**2 for i in range(6)])
# 添加约束:功率平衡、线路潮流等
# ...
prob.solve()
return [p_g[i].varValue for i in range(6)], [q_d[j].varValue for j in range(20)]
训练过程采用多智能体框架,每个GenCo独立学习策略,但共享市场环境:
python复制def train(self, replay_buffer, iterations, batch_size=100, discount=0.99, tau=0.005):
for it in range(iterations):
# 从回放池采样
state, action, reward, next_state, done = replay_buffer.sample(batch_size)
# Critic损失计算
target_Q = reward + (1-done) * discount * self.critic_target(next_state, self.actor_target(next_state))
current_Q = self.critic(state, action)
critic_loss = F.mse_loss(current_Q, target_Q.detach())
# Actor损失计算
actor_loss = -self.critic(state, self.actor(state)).mean()
# 网络更新
self.critic_optimizer.zero_grad()
critic_loss.backward()
self.critic_optimizer.step()
self.actor_optimizer.zero_grad()
actor_loss.backward()
self.actor_optimizer.step()
# 目标网络软更新
for param, target_param in zip(self.critic.parameters(), self.critic_target.parameters()):
target_param.data.copy_(tau*param.data + (1-tau)*target_param.data)
for param, target_param in zip(self.actor.parameters(), self.actor_target.parameters()):
target_param.data.copy_(tau*param.data + (1-tau)*target_param.data)
耐心参数γ(折扣因子)是控制GenCo策略长期考量的关键:
我们通过实验发现,当γ超过0.9时,GenCos的报价策略会显著偏离竞争均衡,趋向合谋均衡。这种机制为监管机构识别潜在市场力提供了量化工具。
在3节点测试系统上,我们对比了三种方法:
| 指标 | 博弈论解 | Q-learning | DDPG |
|---|---|---|---|
| 收敛迭代次数 | - | 8000+ | 3000 |
| α₁误差(%) | 0 | 5.2 | 1.1 |
| α₂误差(%) | 0 | 6.8 | 0.7 |
| 利润标准差 | 0 | 12.4 | 3.2 |
实验表明DDPG在收敛速度和稳定性上显著优于传统RL方法,且能更精确地逼近理论纳什均衡。
通过调节γ参数,我们观察到三种典型市场状态:
竞争市场(γ=0.3):
过渡状态(γ=0.7):
合谋倾向(γ=0.95):
注意:实际应用中需谨慎设置γ,过高值可能导致算法难以收敛。建议从0.6开始逐步增加,观察策略变化。
有效的状态表示应包含:
python复制def get_state(self):
state = np.concatenate([
self.history_prices[-self.window_size:],
self.history_my_bids[-self.window_size:],
[self.current_load / self.max_load],
[self.current_congestion]
])
return np.pad(state, (0, self.state_dim - len(state)), 'constant')
奖励函数引导智能体学习方向,我们采用平滑后的利润指标:
R_t = (π_t - π_min)/(π_max - π_min) - η*(α_t - α_{t-1})^2
其中第二项用于抑制报价剧烈波动,η建议取0.01-0.05。
基于大量实验,推荐以下参数范围:
| 参数 | 推荐值 | 作用说明 |
|---|---|---|
| 回放池大小 | 1e5-1e6 | 影响样本多样性 |
| 批大小 | 64-256 | 平衡训练效率稳定性 |
| Actor学习率 | 1e-4-3e-4 | 策略网络更新步长 |
| Critic学习率 | 1e-3-3e-3 | 值函数网络更新步长 |
| 软更新系数τ | 0.001-0.01 | 目标网络更新速度 |
| 探索噪声 | 0.1-0.3 | 初始探索强度 |
现象:Critic损失震荡或发散
解决方法:
python复制def weights_init(m):
if isinstance(m, nn.Linear):
nn.init.orthogonal_(m.weight.data)
m.bias.data.fill_(0.01)
现象:多个GenCo学习到相同策略
解决方法:
对于大规模节点系统(如IEEE 118节点),建议:
python复制scaler = torch.cuda.amp.GradScaler()
with torch.cuda.amp.autocast():
critic_loss = F.mse_loss(current_Q, target_Q)
scaler.scale(critic_loss).backward()
scaler.step(optimizer)
scaler.update()
本框架可扩展至以下场景:
一个典型的扩展案例是加入风电预测误差:
python复制class WindGenCo(GenCo):
def forecast_error(self):
# 使用ARIMA模型模拟预测误差
return 0.1 * np.random.normal() + 0.02 * np.random.randn(24).cumsum()[-1]
def get_reward(self):
actual_output = self.dispatched_p * (1 - self.forecast_error())
return calculate_profit(actual_output)
在实现这类扩展时,关键是保持状态空间的合理维度,必要时可以使用注意力机制或图神经网络来处理结构化数据。