news 2026/6/16 14:10:18

强化学习实战:从零构建Q表格与Sarsa的迷宫寻路智能体

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
强化学习实战:从零构建Q表格与Sarsa的迷宫寻路智能体

1. 强化学习与迷宫寻路初探

第一次接触强化学习的朋友可能会觉得这个概念有点抽象,但其实它就像教小孩学走路一样自然。想象一下,你把一个小机器人放在迷宫里,它一开始完全不知道该怎么走,但通过不断尝试和获得反馈(比如撞墙扣分、找到出口加分),慢慢就能学会最优路径。这就是强化学习的核心思想 - 通过环境反馈来优化行为策略。

在这个实战项目中,我们要用最经典的Q表格方法来解决迷宫寻路问题。Q表格就像是一本"行动指南",记录着在每个位置采取不同动作的预期收益。比如在迷宫的(2,3)位置,表格会告诉我们:往上走预计得5分,往右走预计得8分 - 那当然选择往右更划算。这种方法特别适合初学者,因为它足够直观,7x7的迷宫对应49个状态(每个格子一个状态),每个状态有4个动作(上下左右),整个Q表格就是49行4列的矩阵。

我刚开始学的时候犯过一个典型错误:把Q值理解成了即时奖励。其实Q值代表的是长期收益的预估,包含当前动作带来的即时奖励,以及后续可能获得的所有奖励的折现。这个概念理解清楚后,后面的算法实现就顺畅多了。

2. 搭建迷宫训练场

2.1 自定义迷宫环境

很多教程一上来就用现成的Gym环境,但我发现从零搭建环境反而更能理解底层逻辑。我们的迷宫用7x7的网格表示,其中:

  • 0代表可通行的路径
  • 1是危险区域(走上去扣50分)
  • -1是终点(到达得50分)
  • 智能体初始位置在(0,0)

用Python实现这个环境特别简单:

import numpy as np class MazeEnv: def __init__(self): self.grid = np.zeros((7,7)) self.agent_pos = [0,0] self.danger_zone = [(1,1),(1,2),(2,1),(2,2)] # 危险区域坐标 self.goal = (5,5) # 终点坐标 # 初始化危险区域 for x,y in self.danger_zone: self.grid[x,y] = 1 self.grid[self.goal] = -1

2.2 设计奖励机制

奖励函数是强化学习的指挥棒,设计不当会导致智能体学偏。经过多次调试,我采用了这样的奖励方案:

  • 每走一步:-1(鼓励尽快找到终点)
  • 进入危险区:-50
  • 到达终点:+50
  • 撞墙:-5(保持当前位置不变)

这种设计让智能体既要考虑路径效率,又要规避风险。实际项目中,奖励函数往往需要反复调整,这也是强化学习工程师的重要工作之一。

3. Q-learning算法实现

3.1 Q表格更新原理

Q-learning的核心是下面这个更新公式:

Q(s,a) ← Q(s,a) + α[r + γ*max(Q(s',a')) - Q(s,a)]

其中:

  • α是学习率(我设为0.1)
  • γ是折扣因子(设为0.9)
  • s'是下一个状态
  • a'是下一个动作

这个公式的意思是:用当前获得的奖励r加上预估的未来最大收益γ*max(Q(s',a')),来调整当前Q值的估计。经过足够多次的迭代,Q值会收敛到最优值。

3.2 代码实现细节

在实现时有几个关键点需要注意:

  1. 探索-利用平衡:我设置了10%的探索概率,让智能体有时随机选择动作,避免陷入局部最优
  2. 状态编码:将二维坐标(x,y)转换为一维状态码x*7+y
  3. 边界处理:当撞墙时保持位置不变

完整实现如下:

class QLearningAgent: def __init__(self): self.q_table = np.zeros((49,4)) # 49个状态,4个动作 self.learning_rate = 0.1 self.discount_factor = 0.9 self.epsilon = 0.1 def choose_action(self, state): if np.random.rand() < self.epsilon: # 探索 return np.random.randint(4) else: # 利用 return np.argmax(self.q_table[state]) def learn(self, state, action, reward, next_state, done): current_q = self.q_table[state, action] if done: target_q = reward else: target_q = reward + self.discount_factor * np.max(self.q_table[next_state]) self.q_table[state, action] += self.learning_rate * (target_q - current_q)

4. Sarsa算法对比实现

4.1 算法差异解析

Sarsa与Q-learning的主要区别在于更新公式:

Q(s,a) ← Q(s,a) + α[r + γ*Q(s',a') - Q(s,a)]

注意这里用的是下一个实际采取的动作a',而不是最大价值的动作。这使得Sarsa更加"谨慎",因为它会考虑实际执行动作的风险。

在悬崖漫步(Cliff Walking)问题中,这种差异表现得特别明显:

  • Q-learning会学习到贴着悬崖走的最短路径
  • Sarsa则会选择更安全的绕行路线

4.2 代码调整要点

只需修改learn方法即可实现Sarsa:

def learn(self, state, action, reward, next_state, next_action, done): current_q = self.q_table[state, action] if done: target_q = reward else: target_q = reward + self.discount_factor * self.q_table[next_state, next_action] self.q_table[state, action] += self.learning_rate * (target_q - current_q)

在训练循环中需要额外保存next_action:

next_action = agent.choose_action(next_state) agent.learn(state, action, reward, next_state, next_action, done)

5. 训练过程与结果分析

5.1 训练曲线可视化

我记录了150轮训练的总得分变化,使用matplotlib绘制学习曲线:

import matplotlib.pyplot as plt scores = [] for episode in range(150): score = run_episode(env, agent) scores.append(score) plt.plot(scores) plt.xlabel('Episode') plt.ylabel('Total Reward') plt.show()

典型的训练过程会呈现三个阶段:

  1. 初期:得分很低(经常走进危险区)
  2. 中期:得分波动上升(开始找到路径但不够稳定)
  3. 后期:得分趋于稳定(找到最优或次优路径)

5.2 策略可视化

训练完成后,我们可以打印每个位置的最优动作:

def visualize_policy(q_table): arrows = ['↑','↓','←','→'] for i in range(7): for j in range(7): state = i*7 + j best_action = np.argmax(q_table[state]) print(arrows[best_action], end=' ') print()

从结果中可以明显看出两种算法的策略差异:

  • Q-learning的路径更直接,但会紧贴危险区
  • Sarsa的路径更保守,会主动绕开危险区

6. 实战中的经验技巧

6.1 超参数调优心得

经过多次实验,我总结出这些参数设置经验:

  • 学习率α:0.1-0.3比较合适,太大容易震荡,太小学习太慢
  • 折扣因子γ:0.9是个不错的起点,对长期任务可以提高到0.99
  • 探索率ε:初期可以设0.2,后期逐渐衰减到0.01

可以尝试线性衰减探索率:

self.epsilon = max(0.01, 0.2 - 0.01*episode)

6.2 常见问题排查

遇到训练效果不好时,可以检查这些方面:

  1. 奖励函数设计是否合理
  2. 状态表示是否包含了足够信息
  3. 学习率是否过大/过小
  4. 探索率是否合适
  5. 训练轮次是否足够

我曾在项目中遇到过智能体"躺平"的问题 - 因为每步都有-1惩罚,智能体发现原地不动反而扣分最少。通过调整奖励函数(增加原地不动的惩罚)解决了这个问题。

7. 扩展与进阶方向

掌握了基础实现后,可以尝试这些进阶改进:

  1. 用神经网络替代Q表格(DQN)
  2. 添加经验回放机制
  3. 实现Double DQN解决过估计问题
  4. 尝试更复杂的环境(如8x8迷宫)

对于这个7x7迷宫,我还尝试过设置移动障碍物,这需要智能体学会动态调整策略。实现方法是每10步随机移动一个危险区域的位置,这显著增加了问题的复杂度。

在实际项目中,Q表格方法虽然简单,但在状态空间不大时仍然非常有效。我曾用类似的方法解决过一个仓库拣货路径优化问题,状态空间约2000左右,Q表格方法只用了几百次迭代就找到了接近最优的解决方案。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/12 8:26:12

通过用量看板清晰掌握虚拟机内各项目的AI API成本分布

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 通过用量看板清晰掌握虚拟机内各项目的AI API成本分布 对于在虚拟机环境中运行多个开发项目或微服务的团队而言&#xff0c;统一管…

作者头像 李华
网站建设 2026/6/16 14:07:49

散热膏(导热硅脂) 导热硅胶片 核心知识点汇总

一、散热膏&#xff08;导热硅脂/导热膏&#xff09;1. 原理以硅油为基础油&#xff0c;添加氧化铝、氧化锌、氮化硼等高导热填料&#xff1b;本身不固化、不粘接&#xff0c;填充芯片与散热器接触面的微观凹凸空气缝隙&#xff0c;替换空气&#xff08;空气导热极差&#xff0…

作者头像 李华
网站建设 2026/6/16 14:07:46

为OpenClaw智能体工作流配置持久化的大模型服务支持

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 为OpenClaw智能体工作流配置持久化的大模型服务支持 在构建基于OpenClaw的智能体工作流时&#xff0c;一个稳定、可靠的后端大模型…

作者头像 李华
网站建设 2026/5/12 23:07:14

AI科技热点日报 | 2026年5月12日

文章目录AI科技热点日报 | 2026年5月12日一、 行业标准与规范&#xff1a;AI终端迈入“标准化”时代二、 智能体&#xff08;Agent&#xff09;与具身智能&#xff1a;从云端走向实战三、 算力与基础设施&#xff1a;产业链的深度重构四、 产业融合与应用探索&#xff1a;AI fo…

作者头像 李华
网站建设 2026/5/12 23:07:02

别再手动切换了!教你用Python脚本批量转换Word文档里的全角半角符号

Python自动化&#xff1a;全角半角字符批量转换的终极解决方案 在日常文档处理中&#xff0c;全角与半角字符混用是个令人头疼的问题。想象一下&#xff0c;当你从不同来源复制粘贴内容到Word文档时&#xff0c;数字、标点符号和字母的宽度不一致&#xff0c;导致整篇文档看起来…

作者头像 李华