【强化学习】03 ——马尔可夫决策过程

news2024/12/23 19:30:06

文章目录

  • 1. 马尔科夫决策过程(Markov Decision Process,MDP)
    • 1.1. 马尔科夫性质
    • 1.2. 状态转移矩阵
    • 1.3. 马尔可夫过程
      • 1.3.1. 一个简单的例子
  • 2. 马尔可夫奖励过程
    • 2.1. 回报
    • 2.2. 价值函数
  • 3. 马尔科夫决策过程
    • 3.1. MDP五元组
    • 3.2. 策略
    • 3.3. 价值函数
      • 3.3.1. 状态价值函数
      • 3.3.2. 动作价值函数
    • 3.4. 贝尔曼期望方程
    • 3.5. 最优策略
      • 3.5.1. 贝尔曼最优方程
      • 3.5.2. 最优策略求解
      • 3.5.3. 扩展MDP
    • 3.6 蒙特卡洛方法(Monte-Carlo method)
    • 3.7. 占有度量
  • 代码
  • 参考

在此推荐另一篇文章【自动驾驶决策规划】POMDP之Introduction

1. 马尔科夫决策过程(Markov Decision Process,MDP)

  • 提供了一套在结果部分随机部分在决策者的控制下的决策过程建模的数学框架。
  • MDP形式化地描述了一种强化学习的环境
    • 环境完全可观测
    • 当前状态可以完全表征过程(马尔科夫性质)
  • 几乎所有的RL问题都可以转换到MDP上进行解决
    • 最优控制主要处理连续MDP
    • 部分不可观的问题可以转为MDP
    • 多臂老虎机是单状态的MDP

1.1. 马尔科夫性质

“The future is independent of the past given the present”

未来状态的概率分布只与当前状态有关,而与过去状态无关

定义

  • 状态 S t S_t St是Markov的,当且仅当 P [ S t + 1 ∣ S t ] = P [ S t + 1 ∣ S 1 , . . . , S t ] \mathbb{P}\left[S_{t+1}\mid S_t\right]=\mathbb{P}\left[S_{t+1}\mid S_1,...,S_t\right] P[St+1St]=P[St+1S1,...,St]

性质

  • 状态捕获历史记录中的所有相关信息
  • 一旦知道了这个状态,可以抛弃历史
  • 即当前状态是对未来的充分统计

1.2. 状态转移矩阵

P s s ′ \boldsymbol{P}_{ss^{\prime}} Pss为从状态 s s s转移到状态 s ′ s' s的概率,又称一步状态转移概率。 P \boldsymbol{P} P为一步状态转移矩阵。

P [ S t + 1 ∣ S t ] = P [ S t + 1 ∣ S 1 , … , S t ] P s s ′ = P [ S t + 1 = s ′ ∣ S t = s ] P = [ P 11 P 12 … P 1 n P 21 P 22 … P 2 n … … P n 1 P n 2 … P n n ] \begin{gathered} P[S_{t+1}|S_t]=P[S_{t+1}|S_1,\ldots,S_t] \\ \boldsymbol{P}_{ss^{\prime}}=P[S_{t+1}=s^{\prime}|S_{t}=s] \\ \boldsymbol{P}=\begin{bmatrix}P_{11}&P_{12}&\ldots&P_{1n}\\P_{21}&P_{22}&\ldots&P_{2n}\\\ldots\\\ldots\\P_{n1}&P_{n2}&\ldots&P_{nn}\end{bmatrix} \end{gathered} P[St+1St]=P[St+1S1,,St]Pss=P[St+1=sSt=s]P= P11P21Pn1P12P22Pn2P1nP2nPnn

矩阵有以下性质:

  1. 非负性性质, P i j ≥ 0 P_{ij}\geq0 Pij0
  2. 行元素和为1, ∑ P i j = 1 , i = 1 , 2 , . . . , n \sum P_{ij}=1,i=1,2,...,n Pij=1,i=1,2,...,n

在这里插入图片描述
以上图为例, S 1 S_1 S1转移到自身和 S 2 S2 S2的概率分别为0.1,0.9; S 2 S_2 S2转移到自身和 S 1 S1 S1的概率分别为0.2,0.8。状态转移矩阵可表示为: P = [ 0.1 0.9 0.8 0.2 ] \boldsymbol{P}=\begin{bmatrix}0.1&0.9\\0.8&0.2\end{bmatrix} P=[0.10.80.90.2]

1.3. 马尔可夫过程

马尔可夫过程(Markov process)指具有马尔可夫性质的随机过程,也被称为马尔可夫链(Markov chain)。马尔可夫链可由二元组 ( S , P ) (S, P) (S,P)描述。状态转移概率不随时间发生变化。

1.3.1. 一个简单的例子

在这里插入图片描述

C l a s s 1 Class 1 Class1为起始状态, S l e e p Sleep Sleep为终止状态,之中的数字代表了各状态之间的转移概率,从每个状态出发转移到其他状态的概率总和为 1。

我们可以写出这个马尔可夫过程的状态转移矩阵:

在这里插入图片描述

给定一个马尔可夫过程,我们就可以从某个状态出发,根据它的状态转移矩阵生成一个状态序列(episode),这个步骤也被叫做采样(sampling)。例如,我们可能得到一下采样结果:

  • C1 C2 C3 Pass Sleep
  • C1 FB FB C1 C2 Sleep
  • C1 C2 C3 Pub C2 C3 Pass Sleep
  • C1 FB FB C1 C2 C3 Pub C1 FB FB
  • FB C1 C2 C3 Pub C2 Sleep

2. 马尔可夫奖励过程

在马尔可夫过程的基础上加入奖励函数 r r r 和折扣因子 γ \gamma γ,就可以得到马尔可夫奖励过程(Markov reward process)。一个马尔可夫奖励过程由 ⟨ S , P , R , γ ⟩ \langle\mathcal{S},\mathcal{P},\color{red}{\mathcal{R}},\gamma\rangle S,P,R,γ构成,各个组成元素的含义如下所示。

  • S S S:状态集合, S = { s 1 , s 2 , . . . , s n } S=\{s_1, s_2, ..., s_n\} S={s1,s2,...,sn}
  • P ( s ′ ∣ s ) P(s'|s) P(ss):状态转移概率,表示在当前状态 s s s 下,采取动作 a a a 后转移到状态 s ′ s' s 的概率, s ′ ∈ S s'\in S sS s , s ′ ∈ S s, s'\in S s,sS P s s ′ = P [ S t + 1 = s ′ ∣ S t = s ] \mathcal{P}_{ss^{\prime}}=\mathbb{P}\left[S_{t+1}=s^{\prime}\mid S_t=s\right] Pss=P[St+1=sSt=s]
  • R ( s , s ′ ) R(s, s') R(s,s):即时奖励函数,表示在当前状态 s s s 下,采取动作 a a a 后转移到状态 s ′ s' s 所获得的即时奖励, s , s ′ ∈ S s, s'\in S s,sS R s = E [ R t + 1 ∣ S t = s ] \mathcal{R}_s=\mathbb{E}\left[R_{t+1}\mid S_t=s\right] Rs=E[Rt+1St=s]
  • γ ∈ ( 0 , 1 ) γ\in(0,1) γ(0,1):折扣因子,表示当前奖励和未来奖励的权重比例。
    • 如果 γ → 1 γ\rightarrow1 γ1,则代表更相信现在的状态,即“短视myopic”;
    • 如果 γ → 0 γ\rightarrow0 γ0,则代表更相信未来的状态,即“远见far-sighted”;

2.1. 回报

定义
在一个马尔可夫奖励过程中,从第 t t t时刻状态 S t S_t St开始,直到终止状态时,所有奖励的衰减之和称为回报(Return) G t G_t Gt,公式如下:

G t = R t + 1 + γ R t + 2 + . . . = ∑ k = 0 ∞ γ k R t + k + 1 G_t=R_{t+1}+\gamma R_{t+2}+...=\sum_{k=0}^\infty\gamma^kR_{t+k+1} Gt=Rt+1+γRt+2+...=k=0γkRt+k+1

仍然沿用上面的例子:
例如,进入状态 C l a s s 2 Class2 Class2可以得到奖励 − 2 -2 2,表明我们不希望进入,进入 P a s s Pass Pass可以获得最高的奖励 10 10 10,但是进入 S l e e p Sleep Sleep之后奖励为零,并且此时序列也终止了。一个计算例子: C l a s s 1 → C l a s s 2 → C l a s s 3 → P a s s → S l e e p Class1\rightarrow Class2\rightarrow Class3\rightarrow Pass \rightarrow Sleep Class1Class2Class3PassSleep − 2 + 0.5 × ( − 2 ) + ( 0.5 ) 2 × ( − 2 ) + ( 0.5 ) 3 × 10 = − 2.25 -2 + 0.5\times(-2)+(0.5)^2\times(-2)+(0.5)^3\times 10=-2.25 2+0.5×(2)+(0.5)2×(2)+(0.5)3×10=2.25
在这里插入图片描述
用代码进行表示:

import numpy as np

# Define the transition Matrix
P = [
    [0.0, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0],
    [0.0, 0.0, 0.8, 0.0, 0.0, 0.0, 0.2],
    [0.0, 0.0, 0.0, 0.6, 0.4, 0.0, 0.0],
    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
    [0.2, 0.4, 0.4, 0.0, 0.0, 0.0, 0.0],
    [0.1, 0.0, 0.0, 0.0, 0.0, 0.9, 0.0],
    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
]
P = np.array(P)
RewardVector = [-2, -2, -2, 10, 1, -1, 0]

# 给定一条序列,计算从某个索引(起始状态)开始到序列最后(终止状态)得到的回报
def ComputeSequenceReward(Start_idx, Sequence, RewardVector, gamma=0.5):
    TotalReward = 0.0
    for i in reversed(range(Start_idx, len(Sequence))):
        TotalReward = gamma * TotalReward + RewardVector[Sequence[i] - 1]
    return TotalReward

def test01():
    chain = [1, 2, 3, 4, 7]
    start_index = 0
    print("根据本序列计算得到回报为:%s。"% ComputeSequenceReward(start_index, chain, RewardVector, gamma=0.5))
    
if __name__ == "__main__":
    test01()
根据本序列计算得到回报为:-2.25

γ = 0 , 0.9 , 1 \gamma=0,0.9,1 γ=00.91时的例子(图中数字为各节点的价值):
在这里插入图片描述
在这里插入图片描述

2.2. 价值函数

在马尔可夫奖励过程中,一个状态的期望回报(即从这个状态出发的未来累积奖励的期望)被称为这个状态的价值(value)。所有状态的价值就组成了价值函数(value function),价值函数的输入为某个状态,输出为这个状态的价值。我们将价值函数写成 v ( s ) = E [ G t ∣ S t = s ] v(s)=\mathbb{E}\left[G_t\mid S_t=s\right] v(s)=E[GtSt=s],展开为 V ( s ) = E [ G t ∣ S t = s ] = E [ R t + 1 + γ R t + 2 + γ 2 R t + 3 + . . . ∣ S t = s ] = E [ R t + 1 + γ ( R t + 2 + γ R t + 3 + . . . ) ∣ S t = s ] = E [ R t + 1 + γ G t + 1 ∣ S t = s ] = E [ R t + 1 + γ V ( S t + 1 ) ∣ S t = s ] \begin{aligned} V(s)& =\mathbb{E}\left[G_t\mid S_t=s\right] \\ &=\mathbb{E}\left[R_{t+1}+\gamma R_{t+2}+\gamma^2R_{t+3}+...\mid S_t=s\right] \\ &=\mathbb{E}\left[R_{t+1}+\gamma\left(R_{t+2}+\gamma R_{t+3}+...\right)\mid S_t=s\right] \\ &=\mathbb{E}\left[R_{t+1}+\gamma G_{t+1}\mid S_t=s\right] \\ &=\mathbb{E}\left[R_{t+1}+\gamma V(S_{t+1})\mid S_t=s\right] \end{aligned} V(s)=E[GtSt=s]=E[Rt+1+γRt+2+γ2Rt+3+...St=s]=E[Rt+1+γ(Rt+2+γRt+3+...)St=s]=E[Rt+1+γGt+1St=s]=E[Rt+1+γV(St+1)St=s]

在上式的最后一个等号中,一方面,即时奖励的期望正是奖励函数的输出,即 E [ R t + 1 ∣ S t = s ] = R s ] \mathbb{E}[R_{t+1}|S_t=s]=\mathcal{R}_s] E[Rt+1St=s]=Rs];另一
方面,等式中剩余部分 E [ γ V ( S t + 1 ) ∣ S t = s ] \mathbb{E}[\gamma V(S_{t+1})|S_t=s] E[γV(St+1)St=s]可以根据从状态 s s s出发的转移概率得到,即可以得到 V ( s ) = R s + γ ∑ s ′ ∈ S P s s ′ V ( s ′ ) V(s)=\mathcal{R}_s+\gamma\sum_{s^{\prime}\in\mathcal{S}}\mathcal{P}_{ss^{\prime}}V(s^{\prime}) V(s)=Rs+γsSPssV(s)

上式就是马尔可夫奖励过程中非常有名的贝尔曼方程(Bellman equation),对每一个状态都成立。我们可以将其写成矩阵形式:
V = R + γ P V \mathcal{V}=\mathcal{R}+\gamma\mathcal{P}\mathcal{V} V=R+γPV [ V ( s 1 ) ⋮ V ( s n ) ] = [ R 1 ⋮ R n ] + γ [ P 11 … P 1 n ⋮ P 11 … P n n ] [ V ( s 1 ) ⋮ V ( s n ) ] \begin{bmatrix}V(s_1)\\\vdots\\V(s_n)\end{bmatrix}=\begin{bmatrix}\mathcal{R}_1\\\vdots\\\mathcal{R}_n\end{bmatrix}+\gamma\begin{bmatrix}\mathcal{P}_{11}&\ldots&\mathcal{P}_{1n}\\\vdots\\\mathcal{P}_{11}&\ldots&\mathcal{P}_{nn}\end{bmatrix}\begin{bmatrix}V(s_1)\\\vdots\\V(s_n)\end{bmatrix} V(s1)V(sn) = R1Rn +γ P11P11P1nPnn V(s1)V(sn)
我们可以直接根据矩阵运算求解,得到以下解析解: V = R + γ P V ( I − γ P ) V = R V = ( I − γ P ) − 1 R \begin{aligned}\mathcal{V}&=\mathcal{R}+\gamma\mathcal{P}\mathcal{V}\\(I-\gamma\mathcal{P})\mathcal{V}&=\mathcal{R}\\\mathcal{V}&=(I-\gamma\mathcal{P})^{-1}\mathcal{R}\end{aligned} V(IγP)VV=R+γPV=R=(IγP)1R

以上解析解的计算复杂度是 O ( n 3 ) O(n^3) O(n3),其中 n n n是状态个数,因此这种方法只适用很小的马尔可夫奖励过程。求解较大规模的马尔可夫奖励过程中的价值函数时,可以使用动态规划(dynamic programming)算法、蒙特卡洛方法(Monte-Carlo method)(见3.6)和时序差分(temporal difference)

接下来编写代码来实现求解价值函数的解析解方法,并据此计算该马尔可夫奖励过程中所有状态的价值。

# Exploit Bellman equation to compute value of all states
def ComputeValue(RewardVector, Statesize, TransitionMatrix=P, gamma=0.5):
    RewardVector = np.array(RewardVector).reshape(-1, 1)
    Value = np.dot(np.linalg.inv(np.eye(Statesize, Statesize) - gamma * TransitionMatrix),
                   RewardVector)
    return Value

print("MRP中每个状态价值分别为\n", ComputeValue(RewardVector, 7))
MRP中每个状态价值分别为
 [[-2.90815722]
 [-1.55006913]
 [ 1.12482718]
 [10.        ]
 [ 0.62413589]
 [-2.08255975]
 [ 0.        ]]

3. 马尔科夫决策过程

3.1. MDP五元组

MDP(Markov Decision Process)是用于描述智能体与环境交互的数学模型。MDP 可以表示为五元组 ( S , A , P , R , γ ) (S, \textcolor{red}{A}, P, R, \gamma) (S,A,P,R,γ)

  • S S S:状态集合, S = { s 1 , s 2 , . . . , s n } S=\{s_1, s_2, ..., s_n\} S={s1,s2,...,sn},包含了车道、环境、世界模型等信息。
  • A A A:动作集合, A = { a 1 , a 2 , . . . , a m } A=\{a_1, a_2, ..., a_m\} A={a1,a2,...,am},车辆的决策空间,包含换道、跟随、超车等等。
  • P ( s ′ ∣ s , a ) P(s'|s, a) P(ss,a):状态转移概率函数,表示在当前状态 s s s 下,采取动作 a a a 后转移到状态 s ′ s' s 的概率, s ′ ∈ S s'\in S sS s , s ′ ∈ S s, s'\in S s,sS a ∈ A a\in A aA P s s ′ a = P [ S t + 1 = s ′ ∣ S t = s , A t = a ] \mathcal{P}_{\mathbf{ss}^{\prime}}^{\color{red}{a}}=\mathbb{P}\left[S_{t+1}=s^{\prime}\mid S_t=s,A_t=\textcolor{red}{a}\right] Pssa=P[St+1=sSt=s,At=a]
  • R ( s , a , s ′ ) R(s, a, s') R(s,a,s):即时奖励函数,表示在当前状态 s s s 下,采取动作 a a a 后转移到状态 s ′ s' s 所获得的即时奖励, s , s ′ ∈ S s, s'\in S s,sS a ∈ A a\in A aA R s a = E [ R t + 1 ∣ S t = s , A t = a ] \mathcal{R}_{\mathfrak{s}}^{\color{red}{a}}=\mathbb{E}\left[R_{t+1}\mid S_{t}=s,A_{t}=\textcolor{red}{a}\right] Rsa=E[Rt+1St=s,At=a]
  • γ ∈ ( 0 , 1 ) γ\in(0,1) γ(0,1):折扣因子,表示当前奖励和未来奖励的权重比例。

注意: 在上面 MDP 的定义中,我们不再使用类似 MRP 定义中的状态转移矩阵方式,而是直接表示成了状态转移函数

  • 这样做一是因为此时状态转移与动作也有关,变成了一个三维数组,而不再是一个矩阵(二维数组);
  • 二是因为状态转移函数更具有一般意义,例如,如果状态集合不是有限的,就无法用数组表示,但仍然可以用状态转移函数表示。

不同于马尔可夫奖励过程,在马尔可夫决策过程中,通常存在一个智能体来执行动作。马尔可夫决策过程是一个与时间相关的不断进行的过程,在智能体和环境 之间存在一个不断交互的过程。一般而言,它们之间的交互是如下图的循环过程:智能体根据当前状态 S t S_t St选择动作 A t A_t At;对于状态 S t S_t St和动作 A t A_t At,环境根据奖励函数和状态转移函数得到 S t + 1 S_{t+1} St+1 R t + 1 R_{t+1} Rt+1并反馈给智能体。智能体的目标是最大化得到的累计奖励。智能体根据当前状态从动作的集合中选择一个动作的函数,被称为策略(policy)。

在这里插入图片描述

3.2. 策略

智能体的策略(Policy)通常用字母 π \pi π表示。在输入状态 s s s情况下采取动作 a a a的概率的策略如下式所示。 π ( a ∣ s ) = P [ A t = a ∣ S t = s ] \pi(a|s)=\mathbb{P}\left[A_t=a\mid S_t=s\right] π(as)=P[At=aSt=s]

  • 策略只需要与当前状态有关,不需要考虑历史状态。
  • 策略是固定的(与时间无关) A t ∼ π ( ⋅ ∣ S t ) , ∀ t > 0 A_t\sim\pi(\cdot|S_t),\forall t>0 Atπ(St),t>0

3.3. 价值函数

3.3.1. 状态价值函数

我们用 V π ( s ) V^\pi(s) Vπ(s)表示在 MDP 中基于策略 π \pi π状态价值函数(state-value function),定义为从状态 s s s出发遵循策略 π \pi π能获得的期望回报,数学表达为:
V π ( s ) = E π [ G t ∣ S t = s ] V^\pi(s)=\mathbb{E}_\pi[G_t|S_t=s] Vπ(s)=Eπ[GtSt=s]

3.3.2. 动作价值函数

不同于 MRP,在 MDP 中,由于动作的存在,我们额外定义一个动作价值函数(action-value function)。我们用 Q π ( s , a ) Q^\pi(s,a) Qπ(s,a)表示在 MDP 遵循策略 π \pi π时,对当前状态 s s s执行动作 a a a得到的期望回报:
Q π ( s , a ) = E π [ G t ∣ S t = s , A t = a ] Q^\pi(s,a)=\mathbb{E}_\pi[G_t|S_t=s,A_t=a] Qπ(s,a)=Eπ[GtSt=s,At=a]

3.4. 贝尔曼期望方程

在贝尔曼方程中加上“期望”二字是为了与接下来的贝尔曼最优方程进行区分。

状态价值函数可以分解为当前时刻的奖励加上后继状态的经过折扣后的状态价值
V π ( s ) = E π [ R t + 1 + γ V π ( S t + 1 ) ∣ S t = s ] V_\pi(s)=\mathbb{E}_\pi\left[R_{t+1}+\gamma V_\pi(S_{t+1})\mid S_t=s\right] Vπ(s)=Eπ[Rt+1+γVπ(St+1)St=s]

动作价值函数同样也可以分解:
Q π ( s , a ) = E π [ R t + 1 + γ Q π ( S t + 1 , A t + 1 ) ∣ S t = s , A t = a ] Q_\pi(s,a)=\mathbb{E}_\pi\left[R_{t+1}+\gamma Q_\pi(S_{t+1},A_{t+1})\mid S_t=s,A_t=a\right] Qπ(s,a)=Eπ[Rt+1+γQπ(St+1,At+1)St=s,At=a]

状态价值函数和动作价值函数之间的关系:在使用策略 π \pi π中,状态 s s s的价值等于在该状态下基于策略 π \pi π采取所有动作 a i a_i ai的概率与相应的价值相乘再求和的结果:在这里插入图片描述
V π ( s ) = ∑ a ∈ A π ( a ∣ s ) Q π ( s , a ) V_\pi(s)=\sum_{a\in\mathcal{A}}\pi(a|s)Q_\pi(s,a) Vπ(s)=aAπ(as)Qπ(s,a)

使用策略 π \pi π时,状态 s s s下采取动作 a a a的价值等于即时奖励加上经过衰减后的所有可能的下一个状态的状态转移概率与相应的价值的乘积:

在这里插入图片描述
Q π ( s , a ) = R s a + γ ∑ s ′ ∈ S P s s ′ a V π ( s ′ ) Q_\pi(s,a)=\mathcal{R}_s^a+\gamma\sum_{s^{\prime}\in\mathcal{S}}\mathcal{P}_{ss^{\prime}}^aV_\pi(s^{\prime}) Qπ(s,a)=Rsa+γsSPssaVπ(s)

将两者叠加,于是可以得到
在这里插入图片描述
V π ( s ) = ∑ a ∈ A π ( a ∣ s ) ( R s a + γ ∑ s ′ ∈ S P s s ′ a V π ( s ′ ) ) V_\pi(s)=\sum_{a\in\mathcal{A}}\pi(a|s)\left(\mathcal{R}_s^a+\gamma\sum_{s^{\prime}\in\mathcal{S}}\mathcal{P}_{ss^{\prime}}^aV_\pi(s^{\prime})\right) Vπ(s)=aAπ(as)(Rsa+γsSPssaVπ(s))

以及
在这里插入图片描述
Q π ( s , a ) = R s a + γ ∑ s ′ ∈ S P s s ′ a ∑ a ′ ∈ A π ( a ′ ∣ s ′ ) Q π ( s ′ , a ′ ) Q_\pi(s,a)=\mathcal{R}_s^a+\gamma\sum_{s^{\prime}\in\mathcal{S}}\mathcal{P}_{ss^{\prime}}^a\sum_{a^{\prime}\in\mathcal{A}}\pi(a^{\prime}|s^{\prime})Q_\pi(s^{\prime},a^{\prime}) Qπ(s,a)=Rsa+γsSPssaaAπ(as)Qπ(s,a)
以上就是通过简单推导分别得到两个价值函数的贝尔曼期望方程

同样用一个例子进行解释:图中基于策略 π \pi π采取所有动作 a i a_i ai的概率为: π ( a ∣ s ) = 0.5 \pi(a|s)=0.5 π(as)=0.5。计算 C l a s s 3 Class3 Class3的状态价值需要计算其下一步的状态价值之和,因此可以得到图中式子所示: 7.4 = 0.5 ∗ ( 1 + 0.2 ∗ − 1.3 + 0.4 ∗ 2.7 + 0.4 ∗ 7.4 ) + 0.5 ∗ 10 7.4 = 0.5 * (1 + 0.2* -1.3 + 0.4 * 2.7 + 0.4 * 7.4) + 0.5 * 10 7.4=0.5(1+0.21.3+0.42.7+0.47.4)+0.510

在这里插入图片描述

同样可以利用MRP进行求解。我们可以将策略的动作选择进行边缘化(marginalization),就可以得到没有动作的 MRP 了。具体来说,对于某一个状态,我们根据策略所有动作的概率进行加权,得到的奖励和就可以认为是一个 MRP 在该状态下的奖励,即: R π = R s ′ = ∑ a ∈ A π ( a ∣ s ) R s a \mathcal{R}^\pi=\mathcal{R}_s^{'}=\sum_{a\in\mathcal{A}}\pi(a|s)\mathcal{R}_s^a Rπ=Rs=aAπ(as)Rsa
同理,我们计算采取动作的概率与使 s s s转移到 s ′ s' s的概率的乘积,再将这些乘积相加,其和就是一个 MRP 的状态 s s s从转移至 s ′ s' s的概率: P π = P s s ′ ′ = ∑ a ∈ A π ( a ∣ s ) P s s ′ a \mathcal{P}^\pi=\mathcal{P}_{ss^{\prime}}^{'}=\sum_{a\in\mathcal{A}}\pi(a|s)\mathcal{P}_{ss^{\prime}}^{a} Pπ=Pss=aAπ(as)Pssa

如此,便可以继续利用之前MRP的步骤了: V π = R π + γ P π V π V π = ( 1 − γ P π ) − 1 R π V_\pi=\mathcal{R}^\pi+\gamma\mathcal{P}^\pi V_\pi \\ V_\pi=(1-\gamma\mathcal{P}^\pi)^{-1}\mathcal{R}^\pi Vπ=Rπ+γPπVπVπ=(1γPπ)1Rπ

def test02():
    # Define the transition Matrix
    # C1 C2  Pass FB Sleep
    P_TransformMDP2MRP = [
        [0.0, 0.5, 0.0, 0.5, 0.0],
        [0.0, 0.0, 0.5, 0.0, 0.5],
        [0.1, 0.2, 0.2, 0.0, 0.5],
        [0.5, 0.0, 0.0, 0.5, 0.0],
        [0.0, 0.0, 0.0, 0.0, 1.0]
    ]
    P_TransformMDP2MRP = np.array(P_TransformMDP2MRP)
    R_TransformMDP2MRP = [-1.5, -1, 5.5, -0.5, 0.0]
    print("MDP中每个状态价值分别为\n", ComputeValue(R_TransformMDP2MRP, 5, P_TransformMDP2MRP, gamma=1))
MDP中每个状态价值分别为
 [[-1.30769231]
 [ 2.69230769]
 [ 7.38461538]
 [-2.30769231]
 [ 0.        ]]

3.5. 最优策略

强化学习的目标通常是找到一个策略,使得智能体从初始状态出发能获得最多的期望回报。我们首先定义策略之间的偏序关系:当且仅当对于任意的状态 s s s都有 V π ( s ) ≥ V π ′ ( s ) V^{\pi}(s)\geq V^{\pi^{\prime}}(s) Vπ(s)Vπ(s) ,记 π > π ′ \pi>\pi^{'} π>π。于是在有限状态和动作集合的 MDP 中,至少存在一个策略比其他所有策略都好或者至少存在一个策略不差于其他所有策略,这个策略就是最优策略(optimal policy)。最优策略可能有很多个,我们都将其表示为 π ∗ ( s ) \pi^*(s) π(s)

最优策略都有相同的状态价值函数,我们称之为最优状态价值函数,表示为:
V ∗ ( s ) = max ⁡ π V π ( s ) , ∀ s ∈ S V^*(s)=\max_\pi V^\pi(s),\quad\forall s\in\mathcal{S} V(s)=πmaxVπ(s),sS

同理,我们定义最优动作价值函数:
Q ∗ ( s , a ) = max ⁡ π Q π ( s , a ) , ∀ s ∈ S , a ∈ A Q^*(s,a)=\max_{\pi}Q^\pi(s,a),\quad\forall s\in\mathcal{S},a\in\mathcal{A} Q(s,a)=πmaxQπ(s,a),sS,aA

最优状态价值的例子
在这里插入图片描述
最优动作价值的例子

在这里插入图片描述
通过最大化 Q ∗ ( s , a ) Q^*(s,a) Q(s,a),我们可以找到最优策略:
π ∗ ( a ∣ s ) = { 1   i f   a = a r g m a x   q ∗ ( s , a ) 0 o t h e r w i s e \left.\pi_*(a|s)=\left\{\begin{array}{cc}1&\mathrm{~if~}a=\mathrm{argmax~}q_*(s,a)\\0&otherwise\end{array}\right.\right. π(as)={10 if a=argmax q(s,a)otherwise

  • 对于所有的MDP,都有一个确定的最优策略
  • 只要找到 Q ∗ ( s , a ) Q^*(s,a) Q(s,a),就能得到最优策略

下图红色弧线箭头部分代表了最优策略的选择

在这里插入图片描述

3.5.1. 贝尔曼最优方程

同样通过递归的方式推导方程:

最优状态价值是选择此时使最优动作价值最大的那一个动作时的状态价值:
在这里插入图片描述
V ∗ ( s ) = max ⁡ a Q ∗ ( s , a ) V_*(s)=\max_aQ_*(s,a) V(s)=amaxQ(s,a)

最优状态价值函数和最优动作价值函数之间的关系:
在这里插入图片描述
Q ∗ ( s , a ) = R s a + γ ∑ s ′ ∈ S P s s ′ a V ∗ ( s ′ ) Q_*(s,a)=\mathcal{R}_s^a+\gamma\sum_{s^{\prime}\in\mathcal{S}}\mathcal{P}_{ss^{\prime}}^aV_*(s^{\prime}) Q(s,a)=Rsa+γsSPssaV(s)
之后叠加,可得
在这里插入图片描述
V ∗ ( s ) = max ⁡ a ∈ A { R s a + γ ∑ s ′ ∈ S P s s ′ a V ∗ ( s ′ ) } V_*(s)=\max_{a\in\mathcal{A}}\{\mathcal{R}_s^a+\gamma\sum_{s^{\prime}\in\mathcal{S}}\mathcal{P}_{ss^{\prime}}^aV_*(s^{\prime})\} V(s)=aAmax{Rsa+γsSPssaV(s)}
在这里插入图片描述
Q ∗ ( s , a ) = R s a + γ ∑ s ′ ∈ S P s s ′ a max ⁡ a ′ ∈ A Q ∗ ( s ′ , a ′ ) Q_*(s,a)=\mathcal{R}_s^a+\gamma\sum_{s^{\prime}\in\mathcal{S}}\mathcal{P}_{ss^{\prime}}^a\max_{a^{\prime}\in\mathcal{A}}Q_*(s^{\prime},a^{\prime}) Q(s,a)=Rsa+γsSPssaaAmaxQ(s,a)
如此,我们便得到了贝尔曼最优方程(Bellman optimality equation)。

3.5.2. 最优策略求解

  • 贝尔曼最优方程是非线性的
  • 通常来说,没有闭式解
  • 一些迭代方法:
    • Value Iteration
    • Policy Iteration
    • Q-learning
    • Sarsa

3.5.3. 扩展MDP

  • Infinite and continuous MDPs
  • Partially observable MDPs(POMDP)
  • Undiscounted, average reward MDPs(Ergodic Markov Process)

3.6 蒙特卡洛方法(Monte-Carlo method)

求解较大规模的马尔可夫奖励过程中的价值函数时,可以使用动态规划(dynamic programming)算法、蒙特卡洛方法(Monte-Carlo method)和时序差分(temporal difference)。本小节介绍蒙特卡洛方法(Monte-Carlo method)。

蒙特卡洛方法(Monte-Carlo methods)也被称为统计模拟方法,是一种基于概率统计的数值计算方法。运用蒙特卡洛方法时,我们通常使用重复随机抽样,然后运用概率统计方法来从抽样结果中归纳出我们想求的目标的数值估计。一个简单的例子是用蒙特卡洛方法来计算圆的面积。例如,在下图所示的正方形内部随机产生若干个点,细数落在圆中点的个数,圆的面积与正方形面积之比就等于圆中点的个数与正方形中点的个数之比。如果我们随机产生的点的个数越多,计算得到圆的面积就越接近于真实的圆的面积。在这里插入图片描述
我们现在介绍如何用蒙特卡洛方法来估计一个策略在一个马尔可夫决策过程中的状态价值函数。回忆一下,一个状态的价值是它的期望回报,那么一个很直观的想法就是用策略在 MDP 上采样很多条序列,计算从这个状态出发的回报再求其期望就可以了,公式如下: V π ( s ) = E π [ G t ∣ S t = s ] ≈ 1 N ∑ i = 1 N G t ( i ) V^\pi(s)=\mathbb{E}_\pi[G_t|S_t=s]\approx\frac{1}{N}\sum_{i=1}^NG_t^{(i)} Vπ(s)=Eπ[GtSt=s]N1i=1NGt(i)

在一条序列中,可能没有出现过这个状态,可能只出现过一次这个状态,也可能出现过很多次这个状态。我们介绍的蒙特卡洛价值估计方法会在该状态每一次出现时计算它的回报。还有一种选择是一条序列只计算一次回报,也就是这条序列第一次出现该状态时计算后面的累积奖励,而后面再次出现该状态时,该状态就被忽略了。

假设我们现在用策略 π \pi π从状态 s s s开始采样序列,据此来计算状态价值。我们为每一个状态维护一个计数器和总回报,计算状态价值的具体过程如下所示。

  1. 使用策略 π \pi π采样若干条序列: s 0 ( i ) → a 0 ( i ) r 0 ( i ) , s 1 ( i ) → a 1 ( i ) r 1 ( i ) , s 2 ( i ) → a 2 ( i ) ⋯ → a T − 1 ( i ) r T − 1 ( i ) , s T ( i ) s_0^{(i)}\xrightarrow{a_0^{(i)}}r_0^{(i)},s_1^{(i)}\xrightarrow{a_1^{(i)}}r_1^{(i)},s_2^{(i)}\xrightarrow{a_2^{(i)}}\cdots\xrightarrow{a_{T-1}^{(i)}}r_{T-1}^{(i)},s_T^{(i)} s0(i)a0(i) r0(i),s1(i)a1(i) r1(i),s2(i)a2(i) aT1(i) rT1(i),sT(i)
  2. 对每一条序列中的每一时间步 t t t的状态 s s s进行以下操作:
  • 更新状态 s s s的计数器 N ( s ) = N ( s ) + 1 N(s)=N(s)+1 N(s)=N(s)+1
  • 更新状态 s s s的总回报 M ( s ) = M ( s ) + G t M(s)=M(s)+G_t M(s)=M(s)+Gt;
  • 或者采用增量式更新策略: V ( s ) ← V ( s ) + 1 N ( s ) ( G − V ( S ) ) V(s)\leftarrow V(s)+\frac1{N(s)}(G-V(S)) V(s)V(s)+N(s)1(GV(S))
  1. 每一个状态的价值被估计为回报的平均值 V ( s ) = M ( s ) / N ( s ) V(s)=M(s)/N(s) V(s)=M(s)/N(s)。根据大数定律,当 N ( s ) → ∞ N(s)\rightarrow \infty N(s),有 V ( s ) → V π ( s ) V(s)\to V_{\pi}(s) V(s)Vπ(s)

代码采样部分结果

[('C2', 'Study', -2, 'Pass'), ('Pass', 'Pub', 1, 'Pass'), ('Pass', 'Pub', 1, 'Pass'), ('Pass', 'Pub', 1, 'Pass'), ('Pass', 'Study', 10, 'Sleep')]
[('C1', 'Study', -2, 'C2'), ('C2', 'Sleep', 0, 'Sleep')]
[('FB', 'Quit', 0, 'C1'), ('C1', 'Facebook', -1, 'FB'), ('FB', 'Quit', 0, 'C1'), ('C1', 'Facebook', -1, 'FB'), ('FB', 'Quit', 0, 'C1'), ('C1', 'Study', -2, 'C2'), ('C2', 'Study', -2, 'Pass'), ('Pass', 'Pub', 1, 'Pass'), ('Pass', 'Pub', 1, 'Pass')]
[('C1', 'Study', -2, 'C2'), ('C2', 'Sleep', 0, 'Sleep')]
[('C2', 'Study', -2, 'Pass'), ('Pass', 'Pub', 1, 'C2'), ('C2', 'Sleep', 0, 'Sleep')]

可以看到最后结果还是比较接近的。

使用蒙特卡洛方法计算MDP的状态价值为
 {'C1': -1.6584167352261565, 'C2': 0.5744913689985154, 'Pass': 6.330419227770518, 'FB': -1.1820907116805823, 'Sleep': 0}
MDP中每个状态价值分别为
 [[-1.67666232]
 [ 0.51890482]
 [ 6.0756193 ]
 [-1.22555411]
 [ 0.        ]]

3.7. 占有度量

不同策略的价值函数是不一样的。这是因为对于同一个 MDP,不同策略会访问到的状态的概率分布是不同的。我们需要理解不同策略会使智能体访问到不同概率分布的状态这个事实,这会影响到策略的价值函数。

首先我们定义 MDP 的初始状态分布 ν 0 ( s ) \nu_0(s) ν0(s),在有些资料中,初始状态分布会被定义进 MDP 的组成元素中。我们用 P t π ( s ) P_t^\pi(s) Ptπ(s)表示采取策略 π \pi π使得智能体在时刻 t t t状态为 s s s的概率,所以我们有 P 0 π ( s ) = ν 0 ( s ) P_0^\pi(s)=\nu_0(s) P0π(s)=ν0(s),然后就可以定义一个策略的状态访问分布(state visitation distribution):

ν π ( s ) = ( 1 − γ ) ∑ t = 0 ∞ γ t P t π ( s ) \nu^\pi(s)=(1-\gamma)\sum_{t=0}^\infty\gamma^tP_t^\pi(s) νπ(s)=(1γ)t=0γtPtπ(s)
其中, 1 − γ 1-\gamma 1γ是用来使得概率加和为 1 的归一化因子。状态访问概率表示一个策略和 MDP 交互会访问到的状态的分布。需要注意的是,理论上在计算该分布时需要交互到无穷步之后,但实际上智能体和 MDP 的交互在一个序列中是有限的。不过我们仍然可以用以上公式来表达状态访问概率的思想,状态访问概率有如下性质: ν π ( s ′ ) = ( 1 − γ ) ν 0 ( s ′ ) + γ ∫ P ( s ′ ∣ s , a ) π ( a ∣ s ) ν π ( s ) d s d a \nu^\pi(s')=(1-\gamma)\nu_0(s')+\gamma\int P(s'|s,a)\pi(a|s)\nu^\pi(s)dsda νπ(s)=(1γ)ν0(s)+γP(ss,a)π(as)νπ(s)dsda
此外,我们还可以定义策略的占用度量(occupancy measure): ρ π ( s , a ) = ( 1 − γ ) ∑ t = 0 ∞ γ t P t π ( s ) π ( a ∣ s ) \rho^\pi(s,a)=(1-\gamma)\sum_{t=0}^\infty\gamma^tP_t^\pi(s)\pi(a|s) ρπ(s,a)=(1γ)t=0γtPtπ(s)π(as)
它表示动作状态对 ( s , a ) (s,a) (s,a)被访问到的概率。二者之间存在如下关系: ρ π ( s , a ) = ν π ( s ) π ( a ∣ s ) \rho^\pi(s,a)=\nu^\pi(s)\pi(a|s) ρπ(s,a)=νπ(s)π(as)
进一步得出如下两个定理。定理 1:智能体分别以策略 π 1 \pi_1 π1 π 2 \pi_2 π2和同一个 MDP 交互得到的占用度量 ρ π 1 \rho^{\pi_1} ρπ1 ρ π 2 \rho^{\pi_2} ρπ2满足 ρ π 1 = ρ π 2    ⟺    π 1 = π 2 \rho^{\pi_1}=\rho^{\pi_2}\iff\pi_1=\pi_2 ρπ1=ρπ2π1=π2
定理 2:给定一合法占用度量,可生成该占用度量的唯一策略是 π ρ = ρ ( s , a ) ∑ a ′ ρ ( s , a ′ ) \pi_\rho=\frac{\rho(s,a)}{\sum_{a^{\prime}}\rho(s,a^{\prime})} πρ=aρ(s,a)ρ(s,a)
注意:以上提到的“合法”占用度量是指存在一个策略使智能体与 MDP 交互产生的状态动作对被访问到的概率。

# Occupancy
def test04():
    # 策略2
    Policy_2 = {
        "C1-Study": 0.6,
        "C1-Facebook": 0.4,
        "FB-Facebook": 0.3,
        "FB-Quit": 0.7,
        "C2-Study": 0.5,
        "C2-Sleep": 0.5,
        "Pass-Study": 0.1,
        "Pass-Pub": 0.9,
    }
    MAXTimeStep = 8
    MDP, Policy_1 = Set_MDPParameterAndPolicy()
    Sequences1 = MonteCarloSampling(MDP, Policy_1, MAXTimeStep, SamplingNum=1000)
    Sequences2 = MonteCarloSampling(MDP, Policy_2, MAXTimeStep, SamplingNum=1000)
    # Sequences1 = sample(MDP, Policy_1, MAXTimeStep, 1000)
    # Sequences2 = sample(MDP, Policy_2, MAXTimeStep, 1000)
    rho1 = ComputeOccupancy("Pass", "Pub", Sequences1, MAXTimeStep, MDP)
    rho2 = ComputeOccupancy("Pass", "Pub", Sequences2, MAXTimeStep, MDP)
    print(rho1, rho2)

最后得到的占有度量有所不同

0.058 0.1145

代码

import numpy as np

# 给定一条序列,计算从某个索引(起始状态)开始到序列最后(终止状态)得到的回报
def ComputeSequenceReward(Start_idx, Sequence, RewardVector, gamma=0.5):
    TotalReward = 0.0
    for i in reversed(range(Start_idx, len(Sequence))):
        TotalReward = gamma * TotalReward + RewardVector[Sequence[i] - 1]
    return TotalReward

# Exploit Bellman equation to compute value of all states
def ComputeValue(RewardVector, Statesize, TransitionMatrix, gamma=0.5):
    RewardVector = np.array(RewardVector).reshape(-1, 1)
    try:
        Value = np.dot(np.linalg.inv(np.eye(Statesize, Statesize) - gamma * TransitionMatrix),
                   RewardVector)
    except:
        print("-------------状态转移矩阵为奇异矩阵,存在求解误差-------------")
        TransitionMatrix[Statesize - 1][Statesize - 1] += 1e-7
        I = np.eye(Statesize, Statesize)
        Value = np.dot(np.linalg.inv(I - gamma * TransitionMatrix),
                   RewardVector)
    return Value

def Set_MDPParameterAndPolicy():
    # 状态集合
    S = ["C1", "C2", "Pass", "FB", "Sleep"]
    # 动作集合
    A = ["Facebook", "Study", "Sleep", "Pub", "Quit"]
    # 状态转移函数
    P = {
        "C1-Study-C2": 1.0,
        "C1-Facebook-FB": 1.0,
        "FB-Facebook-FB": 1.0,
        "FB-Quit-C1": 1.0,
        "C2-Study-Pass": 1.0,
        "C2-Sleep-Sleep": 1.0,
        "Pass-Study-Sleep": 1.0,
        "Pass-Pub-C1": 0.2,
        "Pass-Pub-C2": 0.4,
        "Pass-Pub-Pass": 0.4,
    }
    # 奖励函数
    R = {
        "C1-Study": -2,
        "C1-Facebook": -1,
        "FB-Facebook": -1,
        "FB-Quit": 0,
        "C2-Study": -2,
        "C2-Sleep": 0,
        "Pass-Study": 10,
        "Pass-Pub": 1,
    }
    # 折扣因子
    gamma = 0.5
    MDP = (S, A, P, R, gamma)

    # 策略1,随机策略
    Pi_1 = {
        "C1-Study": 0.5,
        "C1-Facebook": 0.5,
        "FB-Facebook": 0.5,
        "FB-Quit": 0.5,
        "C2-Study": 0.5,
        "C2-Sleep": 0.5,
        "Pass-Study": 0.5,
        "Pass-Pub": 0.5,
    }
    # 策略2
    Pi_2 = {
        "C1-Study": 0.7,
        "C1-Facebook": 0.3,
        "FB-Facebook": 0.3,
        "FB-Quit": 0.7,
        "C2-Study": 0.5,
        "C2-Sleep": 0.5,
        "Pass-Study": 0.2,
        "Pass-Pub": 0.8,
    }
    return MDP, Pi_1

# 把输入的两个字符串通过“-”连接,便于使用上述定义的P、R变量
def join(str1, str2):
    return str1 + '-' + str2

def MonteCarloSampling(MDP, Policy, MAXTimeStep, SamplingNum):
    ''' 采样函数,策略Pi,限制最长时间步MaxTimeStep,总共采样序列数SamplingNum '''
    S, A, P, R, gamma = MDP
    StateNum = len(S)
    Sequences = []
    for _ in range(SamplingNum):
        Sequence = []
        TimeStep = 0
        # 随机选择一个除Sleep以外的状态s作为起点
        s = S[np.random.randint(StateNum - 1)]
        # 当前状态为终止状态或者时间步太长时,一次采样结束
        while s != "Sleep" and TimeStep <= MAXTimeStep:
            TimeStep += 1
            rand, temp = np.random.rand(), 0
            # 在状态s下根据策略选择动作
            for a_ in A:
                temp += Policy.get(join(s, a_), 0.0)
                if temp >= rand:
                    a = a_
                    r = R.get(join(s, a_), 0.0)
                    break
            rand, temp = np.random.rand(), 0
            # 根据状态转移概率得到下一个状态s_next
            for s_ in S:
                temp += P.get(join(join(s, a), s_), 0.0)
                if temp >= rand:
                    s_next = s_
                    break
            # 把(s,a,r,s_next)元组放入序列中
            Sequence.append((s, a, r, s_next))
            # s_next变成当前状态,开始接下来的循环
            s = s_next
        Sequences.append(Sequence)
    return Sequences

# 对所有采样序列计算所有状态的价值
def MonteCarloComputeValue(Sequences, MDP):
    gamma = MDP[4]
    V = {"C1": 0, "C2": 0, "Pass": 0, "FB": 0, "Sleep": 0}
    N = {"C1": 0, "C2": 0, "Pass": 0, "FB": 0, "Sleep": 0}
    for Sequence in Sequences:
        G = 0
        # 一个序列从后往前计算
        for i in reversed(range(len(Sequence))):
            s, r = Sequence[i][0], Sequence[i][2]
            G = r + gamma * G
            N[s] = N[s] + 1
            V[s] = V[s] + (G - V[s]) / N[s]
    return V

def ComputeOccupancy(s, a, Sequences, MAXTimeStep, MDP):
    ''' 计算状态动作对(s,a)出现的频率,以此来估算策略的占用度量 '''
    gamma = MDP[4]
    rho = 0
    total_times = np.zeros(MAXTimeStep)  # 记录每个时间步t各被经历过几次
    occur_times = np.zeros(MAXTimeStep)  # 记录(s_t,a_t)=(s,a)的次数
    for Sequence in Sequences:
        for i in range(len(Sequence)):
            try:
                s_, a_ = Sequence[i][0], Sequence[i][1]
                total_times[i] += 1
                if s_ == s and a_ == a:
                    occur_times[i] += 1
            except IndexError:
                continue
    for i in reversed(range(MAXTimeStep)):
        if total_times[i]:
            # 用频率来估算策略的占用度量
            rho = gamma ** i * occur_times[i] / total_times[i]
    return (1 - gamma) * rho

def SampleTEXT():
    MDP, Policy = Set_MDPParameterAndPolicy()
    Sequences = MonteCarloSampling(MDP, Policy, MAXTimeStep=8, SamplingNum=5)
    for Sequence in Sequences:
        print(Sequence)

def MonteCarloTEXT():
    MDP, Policy = Set_MDPParameterAndPolicy()
    Sequences = MonteCarloSampling(MDP, Policy, MAXTimeStep=8, SamplingNum=5000)
    V = MonteCarloComputeValue(Sequences, MDP)
    print("使用蒙特卡洛方法计算MDP的状态价值为\n", V)

def test01():
    # Define the transition Matrix
    # C1 C2 C3 Pass Pub FB Sleep
    P = [
        [0.0, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0],
        [0.0, 0.0, 0.8, 0.0, 0.0, 0.0, 0.2],
        [0.0, 0.0, 0.0, 0.6, 0.4, 0.0, 0.0],
        [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
        [0.2, 0.4, 0.4, 0.0, 0.0, 0.0, 0.0],
        [0.1, 0.0, 0.0, 0.0, 0.0, 0.9, 0.0],
        [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
    ]
    P = np.array(P)
    RewardVector = [-2, -2, -2, 10, 1, -1, 0]
    chain = [1, 6, 6, 1, 2, 7]
    start_index = 0
    print("根据本序列计算得到回报为:%s。"% ComputeSequenceReward(start_index, chain, RewardVector, gamma=0.5))
    print("MRP中每个状态价值分别为\n", ComputeValue(RewardVector, 7, P))

# MDP2MRP
def test02():
    # Define the transition Matrix
    # C1 C2  Pass FB Sleep
    P_TransformMDP2MRP = [
        [0.0, 0.5, 0.0, 0.5, 0.0],
        [0.0, 0.0, 0.5, 0.0, 0.5],
        [0.1, 0.2, 0.2, 0.0, 0.5],
        [0.5, 0.0, 0.0, 0.5, 0.0],
        [0.0, 0.0, 0.0, 0.0, 1.0]
    ]
    P_TransformMDP2MRP = np.array(P_TransformMDP2MRP)
    R_TransformMDP2MRP = [-1.5, -1, 5.5, -0.5, 0.0]
    print("MDP中每个状态价值分别为\n", ComputeValue(R_TransformMDP2MRP, 5, P_TransformMDP2MRP, gamma=0.5))

# MonteCarlo
def test03():
    # SampleTEXT(
    MonteCarloTEXT()
    test02()

# Occupancy
def test04():
    # 策略2
    Policy_2 = {
        "C1-Study": 0.6,
        "C1-Facebook": 0.4,
        "FB-Facebook": 0.3,
        "FB-Quit": 0.7,
        "C2-Study": 0.5,
        "C2-Sleep": 0.5,
        "Pass-Study": 0.1,
        "Pass-Pub": 0.9,
    }
    MAXTimeStep = 8
    MDP, Policy_1 = Set_MDPParameterAndPolicy()
    Sequences1 = MonteCarloSampling(MDP, Policy_1, MAXTimeStep, SamplingNum=1000)
    Sequences2 = MonteCarloSampling(MDP, Policy_2, MAXTimeStep, SamplingNum=1000)
    rho1 = ComputeOccupancy("Pass", "Pub", Sequences1, MAXTimeStep, MDP)
    rho2 = ComputeOccupancy("Pass", "Pub", Sequences2, MAXTimeStep, MDP)
    print(rho1, rho2)

if __name__ == "__main__":
    test04()

参考

[1] 伯禹AI
[2] https://www.deepmind.com/learning-resources/introduction-to-reinforcement-learning-with-david-silver
[3] 动手学强化学习
[4] Reinforcement Learning

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1038375.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MYSQL——命令大全

1.创建数据库&#xff1a; CREAT E DATABASE [IF NOT EXISTS] DATABASE_NAME; 2.查看数据库&#xff1a; SHOW DATABASES; 3.进入数据库 USE DATABASE_NAME; 4.指定字符集&#xff08;character&#xff09;和校对规则&#xff08;collation&#xff09;创建数据库 CREA…

Spring面试题18:Spring中可以注入一个null和一个空字符串吗?Spring中如何注入一个java集合?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:Spring中可以注入一个null和一个空字符串吗? 在Spring中是可以注入null和空字符串的。 注入null:可以使用@Value注解,将属性值设为null。例如:…

ChatGPT可以取代搜索引擎吗?

ChatGPT对于一些简单的问题&#xff0c;可以完美的完成任务。但是我让它写一篇完整的文章&#xff0c;看看它能否代替我进行写作地的时候&#xff0c;我确定它不能完全取代人类。 但是我们可以使用更多的指导来让AI在日常工作流程为我们工作&#xff0c;所以本文将讨论如何有效…

Spimes x5.0主题模板全开源源码

Spimes主题为博客、自媒体、资讯类的网站设计开发&#xff0c;自适应兼容手机、平板设备的团队&#xff0c;工作室门户主题&#xff0c;精心打磨的一处处细节。只为让您的站点拥有速度与优雅兼具的极致体验。小灯泡自媒体博客免授权 安装教程&#xff1a; 1.模板目录usr/them…

[管理与领导-102]:经营与管理的关系:攻守关系;武将文官关系;开疆拓土与守护城池的关系;战斗与练兵的关系;水涨船高,水落船低的关系。

目录 前言&#xff1a; 一、手中拿着锤子,一切看起来都像钉子 1.1 企业经营中过渡强调管理的表现&#xff1f; 1.2 企业经营中过渡强调管理的误区&#xff08;背后深层次的原因&#xff09; 二、无知者的无畏&#xff0c;独断者的自high 2.1 企业经营中过度忽律管理的表…

5个顶级的Blender生成式AI插件

推荐&#xff1a;用 NSDT编辑器 快速搭建可编程3D场景 Blender 以其强大的 3D 建模和动画工具而闻名。 但你知道它也可以用来制作令人难以置信的纹理和背景吗&#xff1f; 当然&#xff0c;使用正确的插件。 在本文中&#xff0c;我们将了解 Blender 的顶级 AI 插件。 这些插…

普通卷积、转置卷积详细介绍以及用法

转置卷积&#xff08;普通卷积、转置卷积详细介绍以及用法 1、普通卷积操作2、转置卷积2.1 Pytorch转置卷积实验 1、普通卷积操作 首先回顾下普通卷积&#xff0c;下图以stride1&#xff0c;padding0&#xff0c;kernel_size3为例&#xff0c;假设输入特征图大小是4x4的&#…

Kotlin只截取Float小数点后数值DecimalFormat

Kotlin只截取Float小数点后数值DecimalFormat import java.text.DecimalFormatfun main(args: Array<String>) {val pi 3.141516Fvar p pi - pi.toInt()println(p)val decimalFormat DecimalFormat("00.0000")val format decimalFormat.format(p)println(…

ajax method to retrieve images as a blob

go 服务端&#xff1a; 就是先把这个图片读出来 然后返回二进制的数据 byteFile, err : ioutil.ReadFile("." "/processed/" uuidStr"processed.png")if err ! nil {fmt.Println(err)}c.Header("Content-Disposition", "att…

[Linux] 2.Linux开发环境的搭建(Ubuntu)

虚拟机&#xff1a;VMare安装、Ubuntu、VitualBox 真机&#xff1a;公司的研发服务器 Linux虚拟机安装所需文件&#xff1a; 网盘资源&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1WN-tizjHpOgNF0tjbvcZsA?pwd2itd 提取码&#xff1a;2itd 文件解压&#xff…

聊聊设计模式——命令模式

目录 命令模式定义 优点 缺点 命令模式结构说明 工作流程 代码练习 应用场景 本质 涉及的设计原则 相关设计模式 开源框架中的应用 命令模式定义 将一个请求封装为一个对象&#xff0c;从而使你可用不同的请求对客户进行参数化&#xff1b;对请求排队或记录请求日志…

【内网穿透】隐蔽通信隧道技术之建立ICMP隧道

一、基础知识 1、概述 一般的网络通信、先在两台机器之间建立 TCP 连接&#xff0c;然后进行正常的数据通信。在知道P 地址的情况下、可以直接发送报文:如果不知道 P 地址&#xff0c;就需要将域名解析成P 地址。在实际的网络中、通常会通过各种边界设备、软/硬件防火墙甚至人…

React(react18)中组件通信06——redux-toolkit + react-redux

React&#xff08;react18&#xff09;中组件通信06——redux-toolkit react-redux 1 前言1.1 redux 和 react-redux1.2 关于redux-toolkit1.2.1 官网1.2.2 为什么要用Redux Toolkit&#xff1f; 1.3 安装 Redux Toolkit1.4 Redux Toolkit相关API 2. 开始例子——官网例子2.1 …

【Windows】 Windows 10 等系统如何关闭文件夹预览模式

在Windows系统进行文件操作时&#xff0c;由于屏幕尺寸有限&#xff0c;有时感觉文件夹右侧的预览模式很占位置&#xff0c;因此想预览时打开&#xff0c;想关闭时就关闭。 以下是两种解决方案&#xff1a; 方案一&#xff1a;彻底关闭预览模式 方案二&#xff1a;可通过快捷键…

Leetcode 1379.找出克隆二叉树中的相同节点

给你两棵二叉树&#xff0c;原始树 original 和克隆树 cloned&#xff0c;以及一个位于原始树 original 中的目标节点 target。 其中&#xff0c;克隆树 cloned 是原始树 original 的一个 副本 。 请找出在树 cloned 中&#xff0c;与 target 相同 的节点&#xff0c;并返回对…

JDK 21 — JDK 21发布及多项新特性!

一、JDK 21 新特性说明 JDK 21 已经于 2023 年 9 月 19 日正式发布&#xff0c;Java 21 / JDK 21 已正式 GA&#xff0c;此版本是继 JDK 17 后的长期支持版本 (LTS)&#xff0c;Oracle 将为其提供至少八年的技术支持和更新。本文总结了 JDK 21 发布的新特性。 二、JDK 21 正式…

基于PyTorch3D的GeoAI实现【ESRI】

Esri 的 AI 原型团队正在以 PyTorch3D API 的一系列 PR 的形式分享一些功能增强功能。 这些功能支持 obj 格式的网格的输入/输出 (I/O)&#xff0c;该网格具有多个纹理和代表真实世界几何形状的顶点坐标。 对于 GeoAI 任务&#xff0c;这些功能支持跨网格分割管道的任务&#x…

第36节——useDebugValue+React Developer Tools——了解

一、概念 勾住”React开发调试工具中的自定义hook标签&#xff0c;让useDebugValue勾住的自定义hook可以显示额外的信息。useDebugValue的目的是“在react开发者工具自定义hook标签中显示额外信息”&#xff0c;方便我们“一眼就能找到”对应的自定义hook。useDebugValue(valu…

信息安全:网络物理隔离技术原理与应用.

信息安全&#xff1a;网络物理隔离技术原理与应用. 随着网络攻击技术不断增强&#xff0c;恶意入侵内部网络的风险性也相应急剧提高。满足内外网信息及数据交换需求&#xff0c;又能防止网络安全事件出现的安全技术就应运而生了&#xff0c;这种技术称为“物理隔离技术” 基本原…

如何用Postman做接口自动化测试

前言 什么是自动化测试 把人对软件的测试行为转化为由机器执行测试行为的一种实践。 例如GUI自动化测试&#xff0c;模拟人去操作软件界面&#xff0c;把人从简单重复的劳动中解放出来。 本质是用代码去测试另一段代码&#xff0c;属于一种软件开发工作&#xff0c;已经开发完…