当前位置: 首页 > news >正文

基于 Q - learning 算法的迷宫导航

这段 Python 代码实现了一个基于 Q - learning 算法的迷宫导航系统。代码通过定义迷宫环境、实现 Q - learning 算法来训练智能体,使其能够在迷宫中找到从起点到终点的最优路径,同时利用训练好的 Q 表来测试智能体的导航能力。

在这个代码实现的迷宫环境和  Q-learning  算法中, Q  表存储的是每个状态(即迷宫中的每个格子位置)下对于每个可能动作(上、下、左、右四个方向)的  Q  值。
 
迷宫的大小由  size  参数决定,状态空间是由  size  确定的所有格子位置的集合,即  [(i, j) for i in range(size) for j in range(size)] ,动作空间固定为  ['up', 'down', 'left', 'right']  这四个动作。
 
因此,总的  Q  值的数量就是状态空间中状态的数量(也就是格子的个数,等于  size * size )乘以动作的数量(这里是 4) ,即  size * size * 4  个  Q  值。每个状态都对应着四个动作的  Q  值,算法的目的就是通过不断的学习和更新这些  Q  值,找到从起始状态到目标状态的最优策略。

 

在  Q-learning  算法中, 经过不断的更新学习后,每个状态下的各个动作都有了对应的  Q  值。

当要确定最佳运行策略时,对于每个状态,我们会选择具有最大  Q  值的那个动作。因为最大的  Q  值意味着从这个状态执行该动作,在后续过程中能获得相对更多的累计奖励,也就是更优的选择。

从起始状态开始,不断按照每个状态下最大  Q  值对应的动作移动,最终形成的路径就是智能体在当前学习成果下找到的近似最佳运行策略。

 

模块导入

python

import numpy as np

导入numpy库,它是 Python 中用于科学计算的基础库,在代码中主要用于生成随机数以及数值计算。

迷宫环境类 MazeEnvironment

类初始化 __init__ 方法

python

class MazeEnvironment:
    def __init__(self, size=4):
        self.size = size
        self.state_space = [(i, j) for i in range(size) for j in range(size)]
        self.action_space = ['up', 'down', 'left', 'right']
        
        # 定义障碍物和目标位置
        self.obstacles = [(1, 2), (2, 1)]  # 障碍物的位置
        self.goal = (size - 1, size - 1)   # 终点
        
        # 初始状态设置为左上角
        self.start = (0, 0)
        self.reset()

 

  • 功能:初始化迷宫环境的各种属性。
  • 参数
    • size:迷宫的大小,默认为 4x4 的迷宫。
  • 属性说明
    • size:迷宫的边长。
    • state_space:一个列表,包含迷宫中所有可能的状态(位置),通过嵌套循环生成。
    • action_space:一个列表,包含智能体可以采取的所有动作,即向上、向下、向左、向右移动。
    • obstacles:一个列表,存储迷宫中障碍物的位置。
    • goal:迷宫的终点位置,位于迷宫的右下角。
    • start:迷宫的起点位置,位于迷宫的左上角。
    • 调用reset方法将环境重置到初始状态。

重置环境 reset 方法

python

    def reset(self):
        """重置环境到初始状态"""
        self.current_state = self.start
        return self.current_state

 

  • 功能:将环境的当前状态重置为起点位置,并返回该状态。
  • 返回值:当前状态(起点位置)。

执行动作 step 方法

python

    def step(self, action):
        """执行一步操作,并返回下一状态、奖励以及是否完成标志"""
        row, col = self.current_state
        
        if action == 'up':     row -= 1
        elif action == 'down': row += 1
        elif action == 'left': col -= 1
        elif action == 'right':col += 1
        
        next_state = (row, col)
        
        # 检查边界条件
        if not (0 <= row < self.size and 0 <= col < self.size):
            next_state = self.current_state  # 超出边界的移动无效
            
        reward = -1  # 默认每步都有负奖励鼓励快速达到目标
        done = False
        
        if next_state in self.obstacles:
            reward = -10  # 碰撞障碍物给予较大惩罚
        elif next_state == self.goal:
            reward = 10   # 达到目标给予正向奖励
            done = True
        
        self.current_state = next_state
        return next_state, reward, done

 

  • 功能:根据智能体选择的动作,更新环境的状态,并返回下一状态、奖励和是否完成的标志。
  • 参数
    • action:智能体选择的动作,取值为'up''down''left''right'之一。
  • 步骤说明
    1. 根据动作更新当前位置的行和列。
    2. 检查更新后的位置是否超出迷宫边界,如果超出则将下一状态设置为当前状态。
    3. 初始化奖励为 -1,鼓励智能体尽快到达终点。
    4. 如果下一状态是障碍物,给予 -10 的惩罚;如果是终点,给予 10 的奖励并将完成标志设置为True
    5. 更新当前状态为下一状态,并返回下一状态、奖励和完成标志。

Q - learning 算法函数 q_learning

python

def q_learning(env, episodes=500, alpha=0.8, gamma=0.95, epsilon=0.1):
    # 初始化 Q 表
    q_table = {}
    for state in env.state_space:
        q_table[state] = {action: 0 for action in env.action_space}
    
    rewards_per_episode = []
    
    for episode in range(episodes):
        total_reward = 0
        current_state = env.reset()
        
        while True:
            # ε-greedy 策略选择动作
            if np.random.uniform(0, 1) < epsilon:
                action = np.random.choice(env.action_space)  # 探索
            else:
                action = max(q_table[current_state], key=q_table[current_state].get)  # 利用
                
            next_state, reward, done = env.step(action)
            
            # 更新 Q 值
            best_next_action = max(q_table[next_state], key=q_table[next_state].get)
            td_target = reward + gamma * q_table[next_state][best_next_action]
            td_error = td_target - q_table[current_state][action]
            q_table[current_state][action] += alpha * td_error
            
            total_reward += reward
            current_state = next_state
            
            if done:
                break
        
        rewards_per_episode.append(total_reward)
    
    return q_table, rewards_per_episode

 

  • 功能:实现 Q - learning 算法,训练智能体在迷宫环境中找到最优策略。
  • 参数
    • env:迷宫环境实例。
    • episodes:训练的回合数,默认为 500。
    • alpha:学习率,控制 Q 值更新的步长,默认为 0.8。
    • gamma:折扣因子,衡量未来奖励的重要性,默认为 0.95。
    • epsilon:探索率,用于 ε - greedy 策略,默认为 0.1。
  • 步骤说明
    1. 初始化 Q 表:创建一个字典q_table,键为状态,值为另一个字典,存储该状态下每个动作的 Q 值,初始值都为 0。
    2. 训练循环:进行episodes个回合的训练。
    • 在每个回合开始时,重置环境并初始化总奖励为 0。
    • 使用 ε - greedy 策略选择动作:以epsilon的概率随机选择动作(探索),以1 - epsilon的概率选择 Q 值最大的动作(利用)。
    • 执行动作,获取下一状态、奖励和完成标志。
    • 更新 Q 值:计算时间差分目标(TD target)和时间差分误差(TD error),并根据学习率更新当前状态 - 动作对的 Q 值。
    • 累加总奖励,更新当前状态。
    • 如果达到终点,结束当前回合。
    1. 返回结果:返回训练好的 Q 表和每个回合的总奖励列表。

测试智能体函数 test_agent

python

def test_agent(env, q_table):
    current_state = env.reset()
    path = [current_state]
    
    while True:
        action = max(q_table[current_state], key=q_table[current_state].get)
        next_state, _, done = env.step(action)
        path.append(next_state)
        
        if done:
            break
        
        current_state = next_state
    
    return path

 

  • 功能:使用训练好的 Q 表测试智能体在迷宫中的导航能力,记录智能体走过的路径。
  • 参数
    • env:迷宫环境实例。
    • q_table:训练好的 Q 表。
  • 步骤说明
    1. 重置环境并初始化路径列表,将起点添加到路径中。
    2. 在循环中,根据 Q 表选择 Q 值最大的动作。
    3. 执行动作,获取下一状态和完成标志,并将下一状态添加到路径中。
    4. 如果达到终点,结束循环。
    5. 返回智能体走过的路径。

主程序

python

# 创建环境实例并运行 Q-Learning
env = MazeEnvironment(size=4)
q_table, _ = q_learning(env)

print("最终的 Q 表:")
for state, actions in q_table.items():
    print(f"{state}: {actions}")

path = test_agent(env, q_table)
print("智能体走过的路径:", path)

 

  • 功能:创建迷宫环境实例,调用q_learning函数训练智能体,打印最终的 Q 表,然后调用test_agent函数测试智能体,并打印智能体走过的路径。

 

通过以上步骤,代码实现了智能体在迷宫环境中通过 Q - learning 算法学习最优策略,并利用该策略找到从起点到终点的路径。

 

完整代码

import numpy as np

class MazeEnvironment:
    def __init__(self, size=4):
        self.size = size
        self.state_space = [(i, j) for i in range(size) for j in range(size)]
        self.action_space = ['up', 'down', 'left', 'right']
        
        # 定义障碍物和目标位置
        self.obstacles = [(1, 2), (2, 1)]  # 障碍物的位置
        self.goal = (size - 1, size - 1)   # 终点
        
        # 初始状态设置为左上角
        self.start = (0, 0)
        self.reset()

    def reset(self):
        """重置环境到初始状态"""
        self.current_state = self.start
        return self.current_state
    
    def step(self, action):
        """执行一步操作,并返回下一状态、奖励以及是否完成标志"""
        row, col = self.current_state
        
        if action == 'up':     row -= 1
        elif action == 'down': row += 1
        elif action == 'left': col -= 1
        elif action == 'right':col += 1
        
        next_state = (row, col)
        
        # 检查边界条件
        if not (0 <= row < self.size and 0 <= col < self.size):
            next_state = self.current_state  # 超出边界的移动无效
            
        reward = -1  # 默认每步都有负奖励鼓励快速达到目标
        done = False
        
        if next_state in self.obstacles:
            reward = -10  # 碰撞障碍物给予较大惩罚
        elif next_state == self.goal:
            reward = 10   # 达到目标给予正向奖励
            done = True
        
        self.current_state = next_state
        return next_state, reward, done
    
def q_learning(env, episodes=500, alpha=0.8, gamma=0.95, epsilon=0.1):
    # 初始化 Q 表
    q_table = {}
    for state in env.state_space:
        q_table[state] = {action: 0 for action in env.action_space}
    
    rewards_per_episode = []
    
    for episode in range(episodes):
        total_reward = 0
        current_state = env.reset()
        
        while True:
            # ε-greedy 策略选择动作
            if np.random.uniform(0, 1) < epsilon:
                action = np.random.choice(env.action_space)  # 探索
            else:
                action = max(q_table[current_state], key=q_table[current_state].get)  # 利用
                
            next_state, reward, done = env.step(action)
            
            # 更新 Q 值
            best_next_action = max(q_table[next_state], key=q_table[next_state].get)
            td_target = reward + gamma * q_table[next_state][best_next_action]
            td_error = td_target - q_table[current_state][action]
            q_table[current_state][action] += alpha * td_error
            
            total_reward += reward
            current_state = next_state
            
            if done:
                break
        
        rewards_per_episode.append(total_reward)
    
    return q_table, rewards_per_episode

# 创建环境实例并运行 Q-Learning
env = MazeEnvironment(size=4)
q_table, _ = q_learning(env)

print("最终的 Q 表:")
for state, actions in q_table.items():
    print(f"{state}: {actions}")

def test_agent(env, q_table):
    current_state = env.reset()
    path = [current_state]
    
    while True:
        action = max(q_table[current_state], key=q_table[current_state].get)
        next_state, _, done = env.step(action)
        path.append(next_state)
        
        if done:
            break
        
        current_state = next_state
    
    return path

path = test_agent(env, q_table)
print("智能体走过的路径:", path)

 

 

相关文章:

  • <C#> 详细介绍.NET 依赖注入
  • WPF设计标准学习记录26
  • P8748 [蓝桥杯 2021 省 B] 时间显示
  • 【后端开发】初识Spring IoC与SpringDI、图书管理系统
  • 第十五届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组
  • 【实际项目分享】多相机取图存图问题
  • 红帽9运行容器一
  • UE5 在UE中创建骨骼动画
  • 二、TorchRec中的分片
  • 智能检索知识库​
  • 从入门到实战!Vue-router 的深度探索与高效应用
  • 数据结构与算法之ACM Fellow-算法4.3 最小生成树
  • docx文档转为pdf文件响应前端
  • 01-算法打卡-数组-二分查找-leetcode(704)-第一天
  • 两大奇妙的波-机械波-电磁波
  • 3D打印革新制造范式:CASAIM 3D打印解决方案
  • redis的基本使用
  • 大模型day1 - 什么是GPT
  • freecad内部python来源 + pip install 装包
  • 应用安全系列之四十五:日志伪造(Log_Forging)之三
  • 合肥商城网站建设多少钱/注册google账号
  • 民兵信息化网站建设/个人小白如何做手游代理
  • 石家庄做网站汉狮网络/热点营销案例
  • 越烽建设集团有限公司网站/谷歌广告投放步骤
  • wordpress调整语言/seo云优化软件破解版
  • 外贸电商做俄罗斯市场网站/竞价推广工作内容