基于强化学习QLearing的走迷宫

要学习强化学习,首先要学习马尔科夫决策过程(MDP),几乎所有的强化学习问题都可以建模为MDP

MDP

什么是MDP呢,马尔科夫特性表明了未来只取决于当前而与过去无关。马尔科夫链是一个概率模型,它依赖于当前状态来进行预测下一个状态,而与之前的状态没有什么关系,也就是未来与过去无关,马尔科夫链严格遵循马尔科夫特性。

比如说,如果已知当前是多云天气,那么可以预测下一个状态可能是下雨。由此得出结论:下一个状态可能会下雨只考虑当前状态也就是多云,而与过去的状态没有关系,过去的状态可能是晴天啊,刮风啊等等。当然,马尔科夫特性并不是对于所有的过程都是适用的,比如投掷筛子,下一个数与当前的数没有什么关系,因为是等概率出现的。

从一种状态转移到另外一种状态叫做转移,其概率是转移概率,可以通过表的形式来进行表达

多云->下雨 0.6
下雨->下雨 0.2
多云->晴天 0.4
后面的数字代表的是转移概率

而MDP是马尔科夫链的一种扩展,提供了一个用于对策情景建模的数学框架
MDP主要由五个关键要素表示:

  • 智能体能够真正处于的一组状态(S)
  • 智能体从一种状态转移到另外一种状态所执行的一组行为(A)
  • 转移概率(Pa ss’):指的是执行某一行为a,从一个状态s转移到另外一个状态s’的概率
  • 奖励概率(R a ss’):指的是智能体执行某一个行为a,从一个状态s转移到另一个状态s’获得奖励lamba的概率
  • 折扣因数(gama):指的是及时奖励和未来奖励的重要性,将在之后的讲解中指出
状态行为值函数Q函数

Q(s,a)指的是在某一状态下执行a的值函数

时序差分算法TD

啊啊啊啊啊强行先看代码,我用的QL,下次更新在进行解释

import numpy as np
import random

def initmaze_r():#初始化迷宫和奖励函数
    maze=np.array([[1,1,1,0],
                   [1,0,1,0],
                   [1,0,1,1],
                   [1,1,0,2]])
    reward=np.zeros(16)
    for i in range(4):
        for j in range (4):
            if maze[i][j]==1:
                reward[4*i+j]=0
            if maze[i][j]==2:
                reward[4*i+j]=100
            if maze[i][j]==0:
                reward[4*i+j]=-100  #不可走地方设值不可很小
    return maze,reward
def initqtable():#初始化Qtable
    qtable=np.zeros((16,4))
    for i in range(16):
            x=i//4
            y=i%4
            if x==0and(y in range(4)):
                qtable[i][0]=-2
            if y==0:
                qtable[i][2]=-2
            if y==3:
                qtable[i][3]=-2
            if x==3and(y in range (4)):
                qtable[i][1]=-2
    return qtable
def epsilon_greedy_choose_action(qtable,prev_state,epsilon):
    x = prev_state // 4
    y = prev_state %4
    if random.uniform(0, 1) < epsilon:
        if x == 0 and y!=0and y!=3:   #第一行首尾
            return random.choice([1,2,3])
        elif y==0 and x!=0 and x!=3:  #第一列
            return random.choice([0,1,3])
        elif y==3 and x!=0 and x!=3:   #最后一列
            return random.choice([0,1,2])
        elif x==3 and y!=0 and y!=3:   #最后一行
            return random.choice([0,2,3])
        elif x==0and y==0:   #四个角
            return random.choice([1,3])
        elif x==0 and y==3:
            return random.choice([1,2])
        elif x==3 and y==0:
            return random.choice([0,3])
        elif x==3 and y==3:
            return random.choice([0,2])
        else:   #其他位置
            return random.randint(0,3)
    else:
        if (np.argwhere(qtable[prev_state]==max(qtable[prev_state]))).shape[0]>1:   #由于初始的时候qtable均为0,所以max有多个值   需要将不能走的点索引删去   然后在选择
            a=np.argwhere(qtable[prev_state]==max(qtable[prev_state]))
            if x == 0 and y != 0 and y != 3:  # 同上
                a = np.delete(a, np.where(a == 0))
                return random.choice(a)
            elif y == 0 and x != 0 and x != 3:
                a = np.delete(a, np.where(a == 2))
                return random.choice(a)
            elif y == 3 and x != 0 and x != 3:
                a = np.delete(a, np.where(a == 3))
                return random.choice(a)
            elif x == 3 and y != 0 and y != 3:
                a = np.delete(a, np.where(a == 1))
                return random.choice(a)
            elif x == 0 and y == 0:
                a = np.delete(a, np.where(a == 0))
                a = np.delete(a, np.where(a == 2))
                return random.choice(a)
            elif x == 0 and y == 3:
                a = np.delete(a, np.where(a == 0))
                a = np.delete(a, np.where(a == 3))
                return random.choice(a)
            elif x == 3 and y == 0:
                a = np.delete(a, np.where(a == 1))
                a = np.delete(a, np.where(a == 2))
                return random.choice(a)
            elif x == 3 and y == 3:
                a = np.delete(a, np.where(a == 1))
                a = np.delete(a, np.where(a == 3))
                return random.choice(a)
            else:
                return random.choice(a)
        else:
            return int(np.argwhere(qtable[prev_state]==max(qtable[prev_state])))    #只有一个最大值索引
def update_state(prev_state,action):
    x = prev_state // 4
    y = prev_state  % 4
    if action==0:
        return  (x-1)*4+y
    elif action==1:
        return  (x+1)*4+y
    elif action==2:
        return  x*4+y-1
    elif action==3:
        return x*4+y+1
first_state=0#这个指的是将迷宫展开成一位数组的横坐标索引
alpha = 0.3#学习系数
gamma = 0.9#gamma
epsilon = 0.3#epsilon
Maze,Reward=initmaze_r()
Qtable=initqtable()
pre_state=first_state
for m in range (100000):
    action=epsilon_greedy_choose_action(Qtable,pre_state,epsilon)
    state=update_state(pre_state,action)
    Qtable[pre_state][action]=Qtable[pre_state][action]+alpha*(Reward[state]+gamma*max(Qtable[state])-Qtable[pre_state][action])  #update
    if state==15:
        pre_state==first_state
    else :
        pre_state=state
# print(Maze)
# print(Reward)
print(Qtable)
P=np.array([first_state+1])
pre_state=first_state
action=int(np.argwhere(Qtable[pre_state]==max(Qtable[pre_state])))
state=update_state(pre_state,action)
while(state!=15):
    P=np.append(P,state+1)
    pre_state=state
    action = int(np.argwhere(Qtable[pre_state] == max(Qtable[pre_state])))
    state = update_state(pre_state, action)
P=np.append(P,16)
print(P)

诺结果如图
在这里插入图片描述
咱定义的迷宫不是这个吗
在这里插入图片描述
结果的意思就是说:
(1,1)->(1,2)->(1,3)->(2,3)->(3,3)->(3,4)->(4,4)

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值