马尔科夫决策过程
马尔科夫决策过程
概念与公式
1.收获:一个马尔科夫过程中从某一状态开始直到终止状态时所有奖励的有衰减之和(R为奖励,gamma为衰减系数)。
2.价值:马尔科夫奖励过程中状态收获的期望。
3.价值函数:价值函数建立了从状态到价值的映射。
4.贝尔曼方程:它提示一个状态的价值由该状态的奖励以及后续状态价值按概率分布求和按一定的衰减比例联合组成。
贝尔曼方程可以写成矩阵形式
求解得的式子可以用矩阵计算得出某状态的价值。
5.策略:在给定状态下从行为集中选择一个行为的依据。是某一状态下基于行为集合的一个概率分布。
6.最优状态价值函数:所有策略下产生的众多状态价值函数中的最大者。
7.最优行为价值函数:所有策略下产生的众多行为价值函数中的最大者。一旦找到最优行为函数,最优策略就找到了。
8.一个状态的最优价值是该状态下所有行为对应的最有行为价值的最大值。可以通过后续可能状态的最优价值计算得到。
9.一个行为的最优价值可由该行为可能进入的所有后续状态的最优状态价值来计算得到。
代码实现
import numpy as np
num_states = 7
i_to_n = {} #索引到状态名的字典{‘0’:‘C1’,...,'3':'PASS','4':'PUB','5':'FB','6':'SLEEP'}
i_to_n["0"] = "C1"
i_to_n["1"] = "C2"
i_to_n["2"] = "C3"
i_to_n["3"] = "Pass"
i_to_n["4"] = "Pub"
i_to_n["5"] = "FB"
i_to_n["6"] = "Sleep"
n_to_i = {} #状态名到索引的字典
for i,name in zip(i_to_n.keys(),i_to_n.values()):
n_to_i[name] = int(i)
Pss = [ # 状态转移概率矩阵
[ 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 ]
]
Pss = np.array(Pss)
#奖励函数,分别与状态对应
rewards = [-2,-2,-2,10,1,-1,0]
gamma = 0.5 #衰减因子
def compute_return(strat_index = 0,chain = None,gamma = 0.5):
'''求一个马尔科夫奖励过程的收获
start_index 要计算的状态在链中的位置
chain 要计算的马尔科夫过程
gamma 衰减系数
ret 收获值
'''
ret ,power,gamma = 0.0,0,gamma
for i in range(strat_index,len(chain)):
ret += np.power(gamma,power)*rewards[n_to_i[chain[i]]]
power += 1
return ret
chains =[
["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"]
]
def compute_value(Pss,rewards,gamma):
'''求解矩阵得到状态价值(page7)
:param Pss:状态转移概率矩阵
:param rewards:奖励
:param gamma:衰减因子
:return:价值矩阵
'''
# reshape():-1为缺省值,可自动从另一个参数和已知维度推算
rewards = np.array(rewards).reshape((-1,1)) #变为一列
#np.dot():矩阵乘法
#inv():求逆矩阵
#np.eye():单位矩阵
values = np.dot(np.linalg.inv(np.eye(7,7) - gamma*Pss),rewards) #由公式计算
return values
print(compute_return(0, chains[3], gamma = 0.5))
print(compute_value(Pss, rewards, gamma = 0.99999))