值迭代算法使用贝尔曼最优方程来更新状态值函数。
贝尔曼最优方程表示最优状态值函数的递归关系,一个状态的最优值等于在该状态下采取最优动作后获得的即时奖励加上下一个状态的最优值的折现值。
对于一个状态 s,其最优状态值函数 V(s)* 和 最优状态-动作值函数 Q(s, a)* 的更新公式如下:
V*(s) = max[Q*(s, a)] = max[sum(P(s’|s, a) * (R(s, a) + γ * V*(s’)))]
Q*(s, a) = sum(P(s’|s, a) * (R(s, a) + γ * max[Q*(s’, a’)]))
其中,P(s’|s, a) 是在状态 s 执行动作 a 后转移到状态 s’ 的概率,R(s, a) 是在状态 s 执行动作 a 后的即时奖励,γ 是折扣因子,用于权衡当前奖励和未来奖励的重要性。
在值迭代算法中,我们通过迭代更新状态值函数,直到收敛收敛到最优值函数。具体而言,每次迭代中,我们对每个状态 s 计算最优值函数 V*(s)。对于每个状态,我们计算每个动作 a 的 Q 值(即即时奖励加上下一个状态值的折现值),然后选择最大的 Q 值作为该状态的最优值。
以下是一个简单的值迭代算法的伪代码,用于求解马尔可夫决策过程(MDP)中的最优值函数:
初始化状态值函数 V(s) 为任意值
重复直到状态值函数收敛:
对于每个状态 s:
对于每个可能的动作 a:
计算动作 a 在状态 s 下的即时奖励 R(s, a)
计算动作 a 在状态 s 下的转移概率 P(s'|s, a)
计算状态 s 的下一个状态值函数 V'(s):
V'(s) = max[sum(P(s'|s, a) * (R(s, a) + γ * V(s')))]
更新状态值函数 V(s) = V'(s)
其中,γ 是折扣因子,用于权衡当前奖励和未来奖励的重要性。
下面是一个简单的 Python 实现:
import numpy as np
def value_iteration(states, actions, rewards, transitions, gamma, epsilon):
num_states = len(states)
num_actions = len(actions)
V = np.zeros(num_states) # 初始化状态值函数为0
while True:
V_new = np.zeros(num_states) # 存储新的状态值函数
for s in range(num_states):
values = []
for a in range(num_actions):
next_state_values = [transitions[s][a][s_prime] * (rewards[s][a][s_prime] + gamma * V[s_prime]) for s_prime in range(num_states)]
value = np.sum(next_state_values)
values.append(value)
V_new[s] = max(values) # 更新状态 s 的值函数为最大值
if np.max(np.abs(V - V_new)) < epsilon: # 判断状态值函数是否收敛
break
V = V_new # 更新状态值函数
return V
# 状态、动作、奖励、转移概率等定义
states = [0, 1, 2]
actions = [0, 1]
rewards = np.array([
[[0, 0, 0], [0, 0, 0]],
[[0, 0, 0], [1, 1, 1]],
[[0, 0, 0], [0, 0, 0]]
])
transitions = np.array([
[[0.8, 0.1, 0.1], [0.1, 0.8, 0.1]],
[[0.8, 0.1, 0.1], [0.1, 0.8, 0.1]],
[[0.8, 0.1, 0.1], [0.1, 0.8, 0.1]]
])
gamma = 0.9 # 折扣因子
epsilon = 0.0001 # 收敛阈值
# 调用值迭代算法求解最优值函数
optimal_values = value_iteration(states, actions, rewards, transitions, gamma, epsilon)
print("Optimal value function:")
print(optimal_values)
该代码中的例子是一个简单的网格世界问题,包含 3 个状态和 2 个动作。奖励和转移概率是预先定义的。通过调用 value_iteration
函数,可以得到最优的状态值函数。