Bellman找到了一种方法来估计任何状态s的最佳状态值(*),记为V*(s),V*(s)是代理在达到状态s时(假设采取最佳行为)所期望的所有折价未来奖励的总和。 他表明,如果代理能发挥最佳作用,则适用Bellman最优性方程。 这个递归方程式表示,如果主体采取最佳行动,那么当前状态的最优值等于采取一项最佳行动后平均获得的报酬,加上该行动可能导致的所有可能的下一状态的预期最优值。即,
V
∗
(
s
)
=
m
a
x
a
∑
s
T
(
s
,
a
,
s
′
)
[
R
(
s
,
a
,
s
′
)
+
γ
V
∗
(
s
′
)
]
…
…
(
∗
)
V^*(s)=max_a\sum_s{T(s,a,s^{'})[R(s,a,s^{'})+\gamma V^*(s^{'})]}……(*)
V∗(s)=maxas∑T(s,a,s′)[R(s,a,s′)+γV∗(s′)]……(∗)
- T为在状态s采取了行为a后转移到状态s’的概率。
- R为在状态s采取了行为a后转移到状态s’的奖励。
- γ是折价系数。
该方程式直接导致可以精确估计每个可能状态的最佳状态值的算法:首先将所有状态值估计值初始化为零,然后使用值迭代算法(**)迭代更新它们,那么给定足够的时间,这些估计值可以保证收敛到最佳状态值
V
k
+
1
(
s
)
←
m
a
x
a
∑
s
′
T
(
s
,
a
,
s
′
)
[
R
(
s
,
a
,
s
′
)
+
γ
V
k
(
s
′
)
]
…
…
(
∗
∗
)
V_{k+1}(s) \leftarrow max_a\sum_{s^{'}}{T(s,a,s^{'})[R(s,a,s^{'})+\gamma V_k(s^{'})]}……(**)
Vk+1(s)←maxas′∑T(s,a,s′)[R(s,a,s′)+γVk(s′)]……(∗∗)
- Vk(s)为第k次迭代时的状态估计值。
知道最佳状态值时很有用的,特别是对于评估策略,但是它不能为我们提供代理的最佳策略。 幸运的是,贝尔曼找到了一种非常相似的算法来估算最佳状态作用值,通常称为Q值(质量值)。 状态动作对(s,a)的最佳Q值,记为Q*(s,a),是代理到达状态s并选择行为a(假定采取最佳行为),但是在它得到采取这一行为的结果之前,代理可以期望的折价未来奖励的总和的平均值。 这样,我们可以的出Q值迭代算法如下
Q
k
+
1
(
s
)
←
∑
s
′
T
(
s
,
a
,
s
′
)
[
R
(
s
,
a
,
s
′
)
+
γ
m
a
x
a
′
Q
k
(
s
′
,
a
′
)
]
…
…
(
∗
∗
∗
)
Q_{k+1}(s) \leftarrow \sum_{s^{'}}{T(s,a,s^{'})[R(s,a,s^{'})+\gamma{ max_{a^{'}}Q_k(s^{'},a^{'})}]}……(***)
Qk+1(s)←s′∑T(s,a,s′)[R(s,a,s′)+γmaxa′Qk(s′,a′)]……(∗∗∗)
通过最优Q值,很容易得到我们的最优策略:当代理处于状态s,它应该选择可以得到这个状态最高Q值得行为,即:
π
∗
(
s
)
=
a
r
g
m
a
x
a
Q
∗
(
s
,
a
)
…
…
(
∗
∗
∗
∗
)
\pi^*(s)=argmax_a{Q^*(s,a)}……(****)
π∗(s)=argmaxaQ∗(s,a)……(∗∗∗∗)
def QValueIteration(n_states,n_acitons,transition_probabilities,rewards,possible_actions,gamma=0.90,n_iteration=50):
"""note for choosing gamma:
The more you value future rewards,
the more you are willing to put up
with some pain now for the promise
of future bliss.
"""
Q_values = np.full((n_states,n_actions),-np.inf)
for state,actions in enumerate(possible_actions):
Q_values[state,actions] = 0.0
for iteration in range(n_iteration):
Q_prev = Q_values.copy()
for s in range(3):
for a in possible_actions[s]:
Q_values[s,a] = np.sum(
[transition_probabilities[s][a][sp]
*(rewards[s][a][sp]+gamma*np.max(Q_prev[sp]))
for sp in range(3)])
return Q_values
示例:
transition_probabilities = [
[[0.7, 0.3, 0.0], [1.0, 0.0, 0.0], [0.8, 0.2, 0.0]], # in s0, if action a0 then proba 0.7 to state s0 and 0.3 to state s1, etc.
[[0.0, 1.0, 0.0], None, [0.0, 0.0, 1.0]],
[None, [0.8, 0.1, 0.1], None],
]
rewards = [
[[+10, 0, 0], [0, 0, 0], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, -50]],
[[0, 0, 0], [+40, 0, 0], [0, 0, 0]],
]
possible_actions = [[0, 1, 2], [0, 2], [1]]
Q_values = QValueIteration(3,3,transition_probabilities,rewards,possible_actions,gamma=0.90)