简单例子入门q learning附代码

参考于:Step-By-Step Tutorial
极简Qlearning教程

假设有这样的大房间,
在这里插入图片描述
有门表示相互连通,将房间表示为点,连通关系表示为线,则上图可以建模为:
在这里插入图片描述
假设有个机器人处在任意某一个房间,它的最终目标是走到房间5。为了表示能走到房间5,我们在能直接到达房间5的边权重设为100,其他不能到达的边设为0,不存在的边设为-1(比如0和2之间不在直达路径)。则该问题就抽象为:
在这里插入图片描述
在Qlearning中,最重要的就是“状态”和“动作”,状态表示处于图中的哪个房间,比如2房间,而动作则表示从一个节点到另一个节点的操作,如从2房间到3房间。
Q learning
在这里插入图片描述

  • 1.S表示当前的状态
  • 2.a表示当前的动作 (在本例中实际上指的是下一个状态)
  • 3.s~表示下一个状态
  • 4.a~表示下一个动作
  • 5.λ为贪婪因子,0<λ<1,一般设置为0.8
    下面是Q learning 算法步骤
    在这里插入图片描述
    当Q表学习完之后,就可以根据q表来选择最优的路径了。
    例子
    首先根据上图生成一个reward矩阵:
    在这里插入图片描述
    同时我们创建一个Q表,与R同阶,Q表初始化为0矩阵。
    取学习参数γ为0.8,刚开始随机选择一个状态如1,这时查看R表可知,s=1时下一步可以到达3和5,随机地,选取状态5,而状态5的下一个状态可能为1,4,5。根据状态转移方程,我们有
    在这里插入图片描述
    注意这里Q表初始化为0。
    所以,Q表更新为:
    在这里插入图片描述
    这样,现在状态5变成了当前状态,一次episode结束。
    下一次尝试,也就是下一个episode,随机选择一个状态s=3,其下一个为1 or 2 or 4。随机选取状态1,下一步为3 or 5。所以有:
    在这里插入图片描述
    这样,Q表为:
    在这里插入图片描述
    现在状态为1,同上,再选择3or5 ,假设选5,5的下一个状态是1,4,5。有:
    在这里插入图片描述
    q表不变。
    至此第二次episode结束。若执行更过的episode,矩阵Q将最终收敛为:
    在这里插入图片描述
    一旦矩阵Q足够接近于收敛状态,agent便学习到了转移至目标函数的最佳路径。在得到Q表后,可根据下列方法得到最佳路径:
    在这里插入图片描述
    例如,假设初始状态为2,那么根据Q表,选2-3。到达s=3之后,可选的有1,2,4。根据Q表,选最大的价值,所以选3-1。到达s=1之后,再选择1-5。所以路径为2-3-1-5。
    代码如下:
import numpy as np
import random
# 建立 Q 表
q = np.zeros((6, 6))
# 建立 R 表
r = np.array([[-1, -1, -1, -1, 0, -1],
              [-1, -1, -1, 0, -1, 100],
              [-1, -1, -1, 0, -1, -1],
              [-1, 0, 0, -1, 0, -1],
              [0, -1, -1, 0, -1, 100],
              [-1, 0, -1, -1, 0, 100]])
# 衰减指数
gamma = 0.8
# 训练
for i in range(1000): #训练1000次
    # 对每一个训练,随机选择一种状态
    state = random.randint(0, 5)
    while state != 5:#(这里就是每次episode,即每次尝试,直到5为止)
        # 选择r表中非负的值的动作
        r_pos_action = []
        for action in range(6):
            if r[state, action] >= 0:
                r_pos_action.append(action)
        next_state = r_pos_action[random.randint(0, len(r_pos_action) - 1)]
        q[state, next_state] = r[state, next_state] + gamma * q[next_state].max()
        state = next_state
print(q)
# 验证
for i in range(10):
    print("第{}次验证".format(i + 1))
    state = random.randint(0, 5)
    print('机器人处于{}'.format(state))
    count = 0
    while state != 5:
        if count > 20:
            print('fail')
            break
        # 选择最大的q_max
        q_max = q[state].max()

        q_max_action = []
        for action in range(6):
            if q[state, action] == q_max:
                q_max_action.append(action)

        next_state = q_max_action[random.randint(0, len(q_max_action) - 1)]
        print("the robot goes to " + str(next_state) + '.')
        state = next_state
        count += 1

输出结果:

[[  0.    0.    0.    0.   80.    0. ]
 [  0.    0.    0.   64.    0.  100. ]
 [  0.    0.    0.   64.    0.    0. ]
 [  0.   80.   51.2   0.   80.    0. ]
 [ 64.    0.    0.   64.    0.  100. ]
 [  0.    0.    0.    0.    0.    0. ]]1次验证
机器人处于0
the robot goes to 4.
the robot goes to 5.2次验证
机器人处于1
the robot goes to 5.3次验证
机器人处于54次验证
机器人处于1
the robot goes to 5.5次验证
机器人处于2
the robot goes to 3.
the robot goes to 4.
the robot goes to 5.6次验证
机器人处于4
the robot goes to 5.7次验证
机器人处于3
the robot goes to 4.
the robot goes to 5.8次验证
机器人处于0
the robot goes to 4.
the robot goes to 5.9次验证
机器人处于0
the robot goes to 4.
the robot goes to 5.10次验证
机器人处于0
the robot goes to 4.
the robot goes to 5.

输出Q表和计算的q表不一致,是因为存在while !=5,即5已经是目标状态。
另一种代码


import numpy as np
import random
q= np.zeros((6, 6))
# 回报函数,在状态state采用action转移到next_state的回报,横纵坐标分别为state和next_state
reward = np.array([[-1, -1, -1, -1, 0, -1],
              [-1, -1, -1, 0, -1, 100],
              [-1, -1, -1, 0, -1, -1],
              [-1, 0, 0, -1, 0, -1],
              [0, -1, -1, 0, -1, 100],
              [-1, 0, -1, -1, 0, 100]])

legal_action = [[4],     #每个状态所能进行的操作
                [3, 5],
                [3],
                [1, 2, 4],
                [0, 3, 5],
                [1, 4, 5]]
GAMMA = 0.8
TRAINING_STEP = 1000
for i in range(1, TRAINING_STEP + 1):
    state = random.randint(0, 4) #0-5随机状态
    # 百分百探索,随机产生next_state
    next_state = random.choice(legal_action[state])
    q[state, next_state] = reward[state, next_state] + GAMMA * q[next_state].max()
print(q)
for i in range(10):
    print("第{}次验证".format(i + 1))
    state = random.randint(0, 5)
    print('机器人处于{}'.format(state))
    count = 0
    while state != 5:
        if count > 20:
            print('fail')
            break
        # 选择最大的q_max
        q_max = q[state].max()

        q_max_action = []
        for action in range(6):
            if q[state, action] == q_max:
                q_max_action.append(action)

        next_state = q_max_action[random.randint(0, len(q_max_action) - 1)]
        print("the robot goes to " + str(next_state) + '.')
        state = next_state
        count += 1


  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

通信仿真爱好者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值