基于RL(Q-Learning)的迷宫寻路算法

这篇具有很好参考价值的文章主要介绍了基于RL(Q-Learning)的迷宫寻路算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

强化学习是一种机器学习方法,旨在通过智能体在与环境交互的过程中不断优化其行动策略来实现特定目标。与其他机器学习方法不同,强化学习涉及到智能体对环境的观测、选择行动并接收奖励或惩罚。因此,强化学习适用于那些需要自主决策的复杂问题,比如游戏、机器人控制、自动驾驶等。强化学习可以分为基于价值的方法和基于策略的方法。基于价值的方法关注于寻找最优的行动价值函数,而基于策略的方法则直接寻找最优的策略。强化学习在近年来取得了很多突破,比如 AlphaGo 在围棋中战胜世界冠军。

强化学习的重要概念:

  1. 环境:其主体被嵌入并能够感知和行动的外部系统
  2. 主体:动作的行使者
  3. 状态:主体的处境
  4. 动作:主体执行的动作
  5. 奖励:衡量主体动作成功与否的反馈

问题描述

给定一个N*N矩阵,其中仅有-1、0、1组成该矩阵,-1表示障碍,0表示路,1表示终点和起点:

# 生成迷宫图像
def generate_maze(size):
    maze = np.zeros((size, size))
    # Start and end points
    start = (random.randint(0, size-1), 0)
    end = (random.randint(0, size-1), size-1)
    maze[start] = 1
    maze[end] = 1
    # Generate maze walls
    for i in range(size*size):
        x, y = random.randint(0, size-1), random.randint(0, size-1)
        if (x, y) == start or (x, y) == end:
            continue
        if random.random() < 0.2:
            maze[x, y] = -1
        if np.sum(np.abs(maze)) == size*size - 2:
            break
    return maze, start, end

上述函数返回一个numpy数组类型的迷宫,起点和终点

生成迷宫图像:

基于RL(Q-Learning)的迷宫寻路算法

使用BFS进行寻路:

# BFS求出路径
def solve_maze(maze, start, end):
    size = maze.shape[0]
    visited = np.zeros((size, size))
    solve = np.zeros((size,size))
    queue = [start]
    visited[start[0],start[1]] = 1
    while queue:
        x, y = queue.pop(0)
        if (x, y) == end:
            break
        for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
            nx, ny = x + dx, y + dy
            if nx < 0 or nx >= size or ny < 0 or ny >= size or visited[nx, ny] or maze[nx, ny] == -1:
                continue
            queue.append((nx, ny))
            visited[nx, ny] = visited[x, y] + 1
    if visited[end[0],end[1]] == 0:
        return solve,[]
    path = [end]
    x, y = end
    while (x, y) != start:
        for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
            nx, ny = x + dx, y + dy
            if nx < 0 or nx >= size or ny < 0 or ny >= size or visited[nx, ny] != visited[x, y] - 1:
                continue
            path.append((nx, ny))
            x, y = nx, ny
            break

    points = path[::-1]  # 倒序
    for point in points:
        solve[point[0]][point[1]] = 1
    return solve, points

上述函数返回一个numpy数组,和点组成的路径,图像如下:

基于RL(Q-Learning)的迷宫寻路算法

BFS获得的解毫无疑问是最优解,现在使用强化学习的方法来解决该问题(QLearning、DQN)

QLearning

该算法核心原理是Q-Table,其行和列表示State和Action的值,Q-Table的值Q(s,a)是衡量当前States采取行动a的重要依据

具体步骤如下:

  1. 初始化Q表
  2. 执行以下循环:
    1. 初始化一个Q表格,Q表格的行表示状态,列表示动作,Q值表示某个状态下采取某个动作的价值估计。初始时,Q值可以设置为0或随机值。
    2. 针对每个时刻,根据当前状态s,选择一个动作a。可以根据当前状态的Q值和某种策略(如贪心策略)来选择动作。
    3. 执行选择的动作a,得到下一个状态s'和相应的奖励r$
    4. 基于下一个状态s',更新Q值。Q值的更新方式为:
      1. 初始化一个状态s。
      2. 根据当前状态s和Q表中的Q值,选择一个动作a。可以通过epsilon-greedy策略来进行选择,即有一定的概率随机选择动作,以便于探索新的状态,否则就选择Q值最大的动作。
      3. 执行选择的动作a,得到下一个状态s'和奖励r。
      4. 根据s'和Q表中的Q值,计算出最大Q值maxQ。
      5. 根据Q-learning的更新公式,更新Q值:Q(s, a) = Q(s, a) + alpha * (r + gamma * maxQ - Q(s, a)),其中alpha是学习率,gamma是折扣因子。
      6. 将当前状态更新为下一个状态:s = s'。
      7. 如果当前状态为终止状态,则转到步骤1;否则转到步骤2。
      8. 重复执行步骤1-7直到收敛,即Q值不再发生变化或者达到预定的最大迭代次数。最终得到的Q表中的Q值就是最优的策略。
    5. 重复执行2-4步骤,直到到达终止状态,或者达到预设的最大步数。
    6. 不断执行1-5步骤,直到Q值收敛。
    7. 在Q表格中根据最大Q值,选择一个最优的策略。

代码实现

实现QLearningAgent类:

class QLearningAgent:
    def __init__(self,actions,size):
        self.actions = actions
        self.learning_rate = 0.01
        self.discount_factor = 0.9
        self.epsilon = 0.1  # 贪婪策略取值
        self.num_actions = len(actions)

        # 初始化Q-Table
        self.q_table = np.zeros((size,size,self.num_actions))

    def learn(self,state,action,reward,next_state):
        current_q = self.q_table[state][action]  # 从Q-Table中获取当前Q值
        new_q = reward + self.discount_factor * max(self.q_table[next_state])  # 计算新Q值
        self.q_table[state][action] += self.learning_rate * (new_q - current_q) # 更新Q表

    # 获取动作
    def get_action(self,state):
        if np.random.rand() < self.epsilon:
            action = np.random.choice(self.actions)
        else:
            state_action = self.q_table[state]
            action = self.argmax(state_action)
        return action

    @staticmethod
    def argmax(state_action):
        max_index_list = []
        max_value = state_action[0]
        for index,value in enumerate(state_action):
            if value > max_value:
                max_index_list.clear()
                max_value = value
                max_index_list.append(index)
            elif value == max_value:
                max_index_list.append(index)
        return random.choice(max_index_list)

类的初始化:

def __init__(self,actions,size):
    self.actions = actions
    self.learning_rate = 0.01
    self.discount_factor = 0.9
    self.epsilon = 0.1  # 贪婪策略取值
    self.num_actions = len(actions)

    # 初始化Q-Table
    self.q_table = np.zeros((size,size,self.num_actions))

上述代码中,先初始化动作空间,设置学习率,discount_factor是折扣因子,epsilon是贪婪策略去值,num_actions是动作数

def learn(self,state,action,reward,next_state):
    current_q = self.q_table[state][action]  # 从Q-Table中获取当前Q值
    new_q = reward + self.discount_factor * max(self.q_table[next_state])  # 计算新Q值
    self.q_table[state][action] += self.learning_rate * (new_q - current_q) # 更新Q表

该方法是QLearning的核心流程,给定当前状态、动作、赏罚和下一状态更新Q表

# 获取动作
def get_action(self,state):
    if np.random.rand() < self.epsilon:
        # 贪婪策略 随机选取动作
        action = np.random.choice(self.actions)
    else:
        # 从Q-Table中选择
        state_action = self.q_table[state]
        action = self.argmax(state_action)
    return action

该方法首先使用贪婪策略来决定是随机选择一个动作,还是选择 Q-Table 中当前状态对应的最大 Q 值对应的动作

@staticmethod
def argmax(state_action):
    max_index_list = []
    max_value = state_action[0]
    for index,value in enumerate(state_action):
        if value > max_value:
            max_index_list.clear()
            max_value = value
            max_index_list.append(index)
        elif value == max_value:
            max_index_list.append(index)
    return random.choice(max_index_list)

该方法首先获取最大值对应的动作,遍历Q表中的所有动作,找到最大值所对应的所有动作,最后从这些动作中随机选择一个作为最终的动作。

定义环境

下述定义了一个迷宫环境:

class MazeEnv:
    def __init__(self,size):
        self.size = size
        self.actions = [0,1,2,3]
        self.maze,self.start,self.end = self.generate(size)
	
    # 重置状态
    def reset(self):
        self.state = self.start
        self.goal = self.end
        self.path = [self.start]
        self.solve = np.zeros_like(self.maze)
        self.solve[self.start] = 1
        self.solve[self.end] = 1
        return self.state

    def step(self, action):
        # 执行动作
        next_state = None
        if action == 0 and self.state[0] > 0:
            next_state = (self.state[0]-1, self.state[1])
        elif action == 1 and self.state[0] < self.size-1:
            next_state = (self.state[0]+1, self.state[1])
        elif action == 2 and self.state[1] > 0:
            next_state = (self.state[0], self.state[1]-1)
        elif action == 3 and self.state[1] < self.size-1:
            next_state = (self.state[0], self.state[1]+1)
        else:
            next_state = self.state

        if next_state == self.goal:
            reward = 100
        elif self.maze[next_state] == -1:
            reward = -100
        else:
            reward = -1

        self.state = next_state  # 更新状态
        self.path.append(self.state)
        self.solve[self.state] = 1

        done = (self.state == self.goal)  # 判断是否结束

        return next_state, reward, done

    @staticmethod
    # 生成迷宫图像
    def generate(size):
        maze = np.zeros((size, size))
        # Start and end points
        start = (random.randint(0, size-1), 0)
        end = (random.randint(0, size-1), size-1)
        maze[start] = 1
        maze[end] = 1
        # Generate maze walls
        for i in range(size * size):
            x, y = random.randint(0, size-1), random.randint(0, size-1)
            if (x, y) == start or (x, y) == end:
                continue
            if random.random() < 0.2:
                maze[x, y] = -1
            if np.sum(np.abs(maze)) == size*size - 2:
                break
        return maze, start, end

    @staticmethod
    # BFS求出路径
    def solve_maze(maze, start, end):
        size = maze.shape[0]
        visited = np.zeros((size, size))
        solve = np.zeros((size,size))
        queue = [start]
        visited[start[0],start[1]] = 1
        while queue:
            x, y = queue.pop(0)
            if (x, y) == end:
                break
            for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
                nx, ny = x + dx, y + dy
                if nx < 0 or nx >= size or ny < 0 or ny >= size or visited[nx, ny] or maze[nx, ny] == -1:
                    continue
                queue.append((nx, ny))
                visited[nx, ny] = visited[x, y] + 1
        if visited[end[0],end[1]] == 0:
            return solve,[]
        path = [end]
        x, y = end
        while (x, y) != start:
            for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
                nx, ny = x + dx, y + dy
                if nx < 0 or nx >= size or ny < 0 or ny >= size or visited[nx, ny] != visited[x, y] - 1:
                    continue
                path.append((nx, ny))
                x, y = nx, ny
                break

        points = path[::-1]  # 倒序
        for point in points:
            solve[point[0]][point[1]] = 1
        return solve, points

执行

下面生成一个32*32的迷宫,并进行30000次迭代

maze_size = 32

# 创建迷宫环境
env = MazeEnv(maze_size)

# 初始化QLearning智能体
agent = QLearningAgent(actions=env.actions,size=maze_size)

# 进行30000次游戏
for episode in range(30000):
    state = env.reset()
    while True:
        action = agent.get_action(state)
        next_state,reward,done = env.step(action)
        agent.learn(state,action,reward,next_state)
        state = next_state
        if done:
            break
print(agent.q_table)  # 输出Q-Table

定义一个函数,用于显示迷宫的路线:

from PIL import Image

def maze_to_image(maze, path):
    size = maze.shape[0]
    img = Image.new('RGB', (size, size), (255, 255, 255))
    pixels = img.load()
    for i in range(size):
        for j in range(size):
            if maze[i, j] == -1:
                pixels[j, i] = (0, 0, 0)
            elif maze[i, j] == 1:
                pixels[j, i] = (0, 255, 0)
    for x, y in path:
        pixels[y, x] = (255, 0, 0)
    return np.array(img)

接下来显示三个图像:迷宫图像、BFS求解的路线、QLearning求解路线:

plt.figure(figsize=(16, 10))

image1 = maze_to_image(env.maze,[])
plt.subplot(1,3,1)
plt.imshow(image1)
plt.title('original maze')

_,path = env.solve_maze(env.maze,env.start,env.end)
image2 = maze_to_image(env.maze,path)
plt.subplot(1,3,2)
plt.imshow(image2)
plt.title('BFS solution')

image3 = maze_to_image(env.maze,env.path)
plt.subplot(1,3,3)
plt.imshow(image3)
plt.title('QL solution')

# 显示图像
plt.show()

显示:
基于RL(Q-Learning)的迷宫寻路算法文章来源地址https://www.toymoban.com/news/detail-420574.html

到了这里,关于基于RL(Q-Learning)的迷宫寻路算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 强化学习——Q-Learning算法原理

    一、Q-Learning :异策略时序差分控制 从决策方式来看,强化学习可以分为 基于策略 的方法( policy-based )和 基于价值 的方法( value-based )。基于策略的方法直接对策略进行优化,使制定的的策略能够获得最大的奖励。基于价值的强化学习方法中,智能体不需要制定显式的策略,

    2024年01月23日
    浏览(53)
  • 【强化学习】Q-Learning算法详解

    1 Q-Learning算法简介 1.1 行为准则 我们做很多事情都有自己的行为准则,比如小时候爸妈常说:不写完作业就不准看电视。所以我们在写作业这种状态下,写的好的行为就是继续写作业,知道写完他,我们还可以得到奖励。不好的行为就是没写完就跑去看电视了,被爸妈发现,

    2024年01月16日
    浏览(67)
  • 【强化学习】常用算法之一 “Q-learning”

      作者主页: 爱笑的男孩。的博客_CSDN博客-深度学习,活动,python领域博主 爱笑的男孩。擅长深度学习,活动,python,等方面的知识,爱笑的男孩。关注算法,python,计算机视觉,图像处理,深度学习,pytorch,神经网络,opencv领域. https://blog.csdn.net/Code_and516?type=blog 个人简介:打工人。 持续分

    2024年02月11日
    浏览(56)
  • 【强化学习】——Q-learning算法为例入门Pytorch强化学习

    🤵‍♂️ 个人主页:@Lingxw_w的个人主页 ✍🏻作者简介:计算机研究生在读,研究方向复杂网络和数据挖掘,阿里云专家博主,华为云云享专家,CSDN专家博主、人工智能领域优质创作者,安徽省优秀毕业生 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话

    2024年02月10日
    浏览(71)
  • 基于强化学习(Reinforcement learning,RL)的机器人路径规划MATLAB

    Q-learning算法是强化学习算法中的一种,该算法主要包含:Agent、状态、动作、环境、回报和惩罚。Q-learning算法通过机器人与环境不断地交换信息,来实现自我学习。Q-learning算法中的Q表是机器人与环境交互后的结果,因此在Q-learning算法中更新Q表就是机器人与环境的交互过程

    2024年02月11日
    浏览(53)
  • 强化学习基础篇[2]:SARSA、Q-learning算法简介、应用举例、优缺点分析

    【强化学习原理+项目专栏】必看系列:单智能体、多智能体算法原理+项目实战、相关技巧(调参、画图等、趣味项目实现、学术应用项目实现 专栏详细介绍 :【强化学习原理+项目专栏】必看系列:单智能体、多智能体算法原理+项目实战、相关技巧(调参、画图等、趣味项

    2024年02月07日
    浏览(41)
  • 强化学习应用(二):基于Q-learning的物流配送路径规划研究(提供Python代码)

    Q-learning是一种强化学习算法,用于解决基于马尔可夫决策过程(MDP)的问题。它通过学习一个值函数来指导智能体在环境中做出决策,以最大化累积奖励。 Q-learning算法的核心思想是使用一个Q值函数来估计每个状态动作对的价值。Q值表示在特定状态下采取某个动作所能获得

    2024年01月21日
    浏览(61)
  • 强化学习应用(六):基于Q-learning的无人机物流路径规划研究(提供Python代码)

    Q-learning是一种强化学习算法,用于解决基于马尔可夫决策过程(MDP)的问题。它通过学习一个价值函数来指导智能体在环境中做出决策,以最大化累积奖励。 Q-learning算法的核心思想是通过不断更新一个称为Q值的表格来学习最优策略。Q值表示在给定状态下采取某个动作所能

    2024年02月22日
    浏览(45)
  • 强化学习应用(四):基于Q-learning的无人机物流路径规划研究(提供Python代码)

    Q-learning是一种强化学习算法,用于解决基于马尔可夫决策过程(MDP)的问题。它通过学习一个价值函数来指导智能体在环境中做出决策,以最大化累积奖励。 Q-learning算法的核心思想是通过不断更新一个称为Q值的表格来学习最优策略。Q值表示在给定状态下采取某个动作所能

    2024年01月17日
    浏览(49)
  • 强化学习应用(一):基于Q-learning的无人机物流路径规划研究(提供Python代码)

    Q-learning是一种强化学习算法,用于解决基于马尔可夫决策过程(MDP)的问题。它通过学习一个价值函数来指导智能体在环境中做出决策,以最大化累积奖励。 Q-learning算法的核心思想是通过不断更新一个称为Q值的表格来学习最优策略。Q值表示在给定状态下采取某个动作所能

    2024年02月02日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包