实践Q Learning 实现走迷宫

本文介绍了使用Q Learning实现走迷宫的方法,包括环境构建、Q Learning算法的实现、训练过程以及Q表的解读。通过不断试错和更新Q表,最终找到从起点到终点的最优路径。在训练过程中,约在第25轮得到第一次奖励,第50轮能基本找到最短路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、环境构建

搭建一个简单的迷宫环境,红色位置出发,黑色位置代表失败,黄色位置代表成功,让红色块慢慢通过不断探索学习的方式走到黄色的位置


    #初始化迷宫
    def _build_maze(self):
        h = self.MAZE_H*self.UNIT
        w = self.MAZE_W*self.UNIT
        #初始化画布
        self.canvas = tk.Canvas(self, bg='white', height=h, width=w)
        #画线
        for c in range(0, w, self.UNIT):
            self.canvas.create_line(c, 0, c, h)
        for r in range(0, h, self.UNIT):
            self.canvas.create_line(0, r, w, r)

        # 陷阱
        self.hells = [self._draw_rect(3, 2, 'black'),
                     self._draw_rect(3, 3, 'black'),
                     self._draw_rect(3, 4, 'black'),
                     self._draw_rect(3, 5, 'black'),
                     self._draw_rect(4, 1, 'black'),
                     self._draw_rect(4, 5, 'black'),
                     self._draw_rect(1, 0, 'black'),
                     self._draw_rect(1, 1, 'black'),
                     self._draw_rect(1, 2, 'black'),
                     self._draw_rect(1, 3, 'black'),
                     self._draw_rect(1, 4, 'black')]
        self.hell_coords = []
        for hell in self.hells:
            self.hell_coords.append(self.canvas.coords(hell))

        # 奖励
        self.oval = self._draw_rect(4, 5, 'yellow')
        # 玩家对象
        self.rect = self._draw_rect(0, 0, 'red')

        self.canvas.pack()

然后就是实现走迷宫的动作了,“上下左右”走到对应的位置得到不同的结果,如果走到了黑块就得到-1的惩罚并结束回合,走到黄块得到1的奖励并结束回合,当然需要返回当前的行走策略得到的奖励(或惩罚)

    def step(self, action):
        s = self.canvas.coords(self.rect)
        base_action = np.array([0, 0])
        if action == 0:  # up
            if s[1] > self.UNIT:
                base_action[1] -= self.UNIT
        elif action == 1:  # down
            if s[1] < (self.MAZE_H - 1) * self.UNIT:
                base_action[1] += self.UNIT
        elif action == 2:  # right
            if s[0] < (self.MAZE_W - 1) * self.UNIT:
                base_action[0] += self.UNIT
        elif action == 3:  # left
            if s[0] > self.UNIT:
                base_action[0] -= self.UNIT

        #根据策略移动红块
        self.canvas.move(self.rect, base_action[0], base_action[1])
        s_ = self.canvas.coords(self.rect)

        #判断是否得到奖励或惩罚
        done = False
        if s_ == self.canvas.coords(self.oval):
            reward = 1
            done = True
        elif s_ in self.hell_coords:
            reward = -1
            done = True
        #elif base_action.sum() == 0:
        #    reward = -1
        else:
            reward = 0

        self.old_s = s
        return s_, reward, done

二、实现Q Learning

Q-Learning的原理很简单,就是用一张Q表来记录每个状态下取不同的策略(action)的权值,而权值是根据历史经验(得到的奖励、惩罚)来不断更新得到的

这是根据Q表来得到价值最高的步骤,当然为了有探索性所以给了一定权重进行完全随机

    #选择动作
    def choose_action(self, s):
        self.check_state_exist(s)
        if np.random.uniform() < self.e_greedy:

            state_action = self.q_table.ix[s, :]
            state_action = state_action.reindex(
                np.random.permutation(state_action.index))  #防止相同列值时取第一个列,所以打乱列的顺序
            action = state_action.argmax()
        else:
            action = np.random.choice(self.actions)
        return action

另外就是记录当前的状态,下一步的动作,这个动作得到的奖励或惩罚根据这个核心算法更新到Q表中


    #更新q表
    def rl(self, s, a, r, s_):
        self.check_state_exist(s_)
        q_predict = self.q_table.ix[s, a]       #q估计
        if s_ != 'terminal':
            q_target = r + self.reward_decay * self.q_table.ix[s_, :].max()     #q现实
        else:
            q_target = r

        self.q_table.ix[s, a] += self.learning_rate * (q_target - q_predict)

三、训练实验

训练的步骤是

1、根据当前的状态得到下一个步骤

2、执行这个步骤,得到执行后的状态

3、记录算法计算出的权值

def update():
    for episode in range(100):
        s = env.reset()
        while True:
            env.render()

            #选择一个动作
            action = RL.choose_action(str(s))

            #执行这个动作得到反馈(下一个状态s 奖励r 是否结束done)
            s_, r, done = env.step(action)

            #更新状态表
            RL.rl(str(s), action, r, str(s_))

            s = s_

            if done:
                print(episode)
                break

我在第25轮的时候得到第一次奖励,等到了第50轮基本就是走最短路径了

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值