资讯详情

Q-Learning入门实战:16格网格世界MATLAB源码详解

📅 2026/11/4 18:22:41 | 华诺云谱 👁 阅读
Q-Learning入门实战:16格网格世界MATLAB源码详解
简介这份资源面向强化学习入门者与需要动手复现经典算法的学习者以一份带详细注释的 MATLAB 源码解决 Q-Learning 从理论到代码落地的问题。压缩包共 1 个 doc 文件约 33KB内容为可直接运行的脚本与逐行中文注释涵盖可移动矩阵 TT、奖赏矩阵 R、Q 矩阵初始化、折扣因子 gamma 与 epsilon-greedy 策略等核心模块。案例以 16×1 网格世界中王子寻找公主为场景设置障碍物、陷阱与终点奖励训练循环中随机初始化状态、按策略选动作并依据贝尔曼方程更新 Q 值每 100 次迭代输出训练进度结束后回溯最优路径。已有 1380 人学习适合希望理解环境建模、奖励机制与策略选择完整流程的读者对照研读与二次实验。1. 从一张 16 格地图说起这套 Q-Learning 源码要解决什么强化学习入门最难受的地方不是公式看不懂而是看完贝尔曼方程之后仍然不知道第一行代码该写在哪。这份 Q-Learning 源代码及注释matlab就是冲着这个痛点来的它把「王子找公主」抽象成一个 16×1 的网格世界用不到一百行 MATLAB 把环境建模、奖励设计、ε-greedy 策略、Q 值更新、路径回溯五件事一次讲透。适合两类人——正在做强化学习课程设计、需要一份能跑通能讲清的最小闭环的学生以及要给团队做算法入门培训、想要一个可改参数的 demo 的工程师。它不追求工程完备追求的是每一步都能对上公式注释密度高到可以当伪代码读。2. 环境建模用两个矩阵把网格世界说清楚这套方案最值得抄的地方是它没有引入任何工具箱纯靠两个 16×16 矩阵就把「世界长什么样」和「走一步值多少」定义完了。理解这两个矩阵后面所有代码都是水到渠成。2.1 可移动矩阵 T状态转移的硬约束T(i,j)1表示可以从位置 i 走到位置 j0 表示走不通。构造逻辑是先用四个方向铺一遍邻接关系再用障碍物和跳跃规则覆盖掉。clear % 定义可移动矩阵 T T zeros(16); % T(i,j)0 表示不可从 i 位置移动至 j 位置1 则为可移动 for i 1:16 % 上行动作 N不在第一行才能往上走 if not(ismember(i,[1,5,9,13])) T(i,i-1) 1; end % 下行动作 S不在最后一行才能往下走 if not(ismember(i,[4,8,12,16])) T(i,i1) 1; end % 左行动作 W编号大于 4 才有左侧邻居 if i 4 T(i,i-4) 1; end % 右行动作 E编号小于 13 才有右侧邻居 if i 13 T(i,i4) 1; end end % 定义不可到达区域障碍物 T(:,[10,11,14]) 0; % 定义跳跃13 号位只能跳到 15 号位 T(13,:) 0; T(13,15) 1;这段代码的关键在于「先铺后砍」的顺序。先把 16 个格子按 4×4 排布的四邻接关系全部连上再统一把第 10、11、14 列清零——这三列对应的是障碍格任何状态都不能转移到它们。最后单独处理 13 号位先清空它整行再只保留T(13,15)1等于给这个格子开了一条单向传送通道。这里有个容易忽略的细节T(:,[10,11,14])0清的是「列」也就是禁止任何状态转移到 10、11、14但 10、11、14 作为出发点的行并没有被清。实际运行时因为初始状态会主动避开这三个格子所以不会出问题但如果你的改造版本允许从障碍格出发就得补一行T([10,11,14],:)0。我一般会在注释里显式写明这个假设避免后面接手的人踩坑。2.2 奖赏矩阵 R把「想让它做什么」翻译成数字% 定义奖赏矩阵 R R -1 * ones(16); R(:,6) 0; % 第 6 列中性区域不奖不罚 R(:,7) -5; % 第 7 列陷阱重罚 R(:,16) 10; % 第 16 列公主所在终局大奖 R(13,15) 5; % 13 跳到 15 的传送奖励R的默认值是 -1意味着每走一步都要付出代价这会逼着智能体去找最短路径而不是在地图里绕圈。第 6 列给 0 是留了一块「喘气区」第 7 列 -5 是明确的陷阱信号第 16 列 10 是唯一的正终局奖励。注意R(13,15)5这一行写在R(:,16)10之后顺序不能反否则会被列赋值覆盖——这种赋值顺序问题在 MATLAB 里非常隐蔽血泪经验是凡是按列批量赋值之后还要改单点的单点赋值一定放最后。提示奖励量级直接决定收敛速度。10 与 -5 的比值约 2:1配合 γ0.8大约 300500 轮就能稳定如果把陷阱改成 -50前期探索会被吓住收敛反而变慢。3. 训练循环ε-greedy 与贝尔曼更新的最小实现环境定义完剩下的就是让智能体在里面反复试错。这一章是整个方案的核心也是答辩时最容易被追问的部分——为什么用这个更新式、ε 取多少、训练多少轮够。3.1 参数初始化与探索策略% 将 Q 矩阵初始化为 0 Q zeros(16); % 折扣因子γ gamma 0.8; % 策略选择概率也就是探索率 epsilon 0.3;Q全零初始化代表「一无所知」这是最朴素也最稳妥的做法。gamma0.8表示未来一步的奖励打八折两步打 0.64 折这个值偏保守适合 16 格这种小地图地图一大就该往 0.9 以上调。epsilon0.3意味着 30% 的动作是随机探索、70% 走当前最优这个比例在入门 demo 里够用但要注意它是个固定值——真实项目里通常做成随训练轮次衰减比如从 0.9 线性降到 0.05前期多探索、后期多利用。for episode 1:900 % 随机化初始状态 state unidrnd(16); % 避开障碍物直到状态不在 10、11、14 上 while ismember(state,[10,11,14]) state unidrnd(16); end % 如果不是最终状态 while state ~ 16 % 找出 state 下所有可能到达的位置 possible_actions find(T(state,:) 1); possible_Q Q(state,possible_actions); if rand() epsilon % 小于探索率随机选一个动作 choose unidrnd(length(possible_actions)); action possible_actions(choose); else % 否则选 Q 值最大的动作 [~,index] max(possible_Q); action possible_actions(index); end % 贝尔曼更新 Q(state,action) R(state,action) gamma * max(Q(action,:)); % 进入下一状态 state action; end if mod(episode,100) 0 fprintf(训练的次数为:%d\n,episode) end end逐行拆一下。unidrnd(16)是 MATLAB 统计工具箱里的均匀整数采样等价于randi(16)如果你的环境没装统计工具箱直接换成randi就行这是最常见的报错来源。内层while是标准的回合制只要没到 16 号位就一直走每一步先算可选动作集再按 ε-greedy 二选一最后用Q(s,a) R(s,a) γ·max Q(s,·)更新。这里有个理论上的简化值得说清楚标准 Q-Learning 的更新式是Q(s,a) ← Q(s,a) α[r γ·max Q(s,a) - Q(s,a)]带学习率 α。这份代码把 α 直接取成了 1也就是完全用新估计覆盖旧值。对确定性环境、小状态空间来说这没问题收敛还更快但一旦环境有随机性比如同样的动作有时成功有时失败α1 会导致 Q 值剧烈震荡这时候必须把 α 降到 0.10.3 并保留旧值加权。答辩时如果被问到「你的学习率在哪」这就是标准答案。3.2 路径回溯训练完之后怎么把路线读出来start_0 1; % 设置起始点 path start_0; % 路径向量从起点开始 while path(end) ~ 16 [~,next] max(Q(start_0,:)); % 当前状态下 Q 值最大的动作 path [path,next]; % 追加到路径 start_0 next; % 移动到下一状态 end disp(path)训练结束后Q 矩阵就是一张「每个格子往哪走最划算」的查询表。回溯时不需要再探索直接每步取max(Q(state,:))对应的列号作为下一站直到命中 16。这段代码有个隐含前提Q里不能出现「某状态下所有动作 Q 值都相等」的死锁否则max会返回第一个索引可能原地打转。实际跑的时候如果发现路径长度异常比如超过 20 步先检查是不是某个状态的 Q 行全零——那说明这个状态在 900 轮里从没被访问到属于探索不充分把episode加到 2000 或把epsilon提到 0.4 通常能解决。注意path用[path,next]动态扩容在 MATLAB 里会触发反复内存分配。16 格无所谓但如果把地图扩到几百格建议预分配path zeros(1,100)再按索引写入这是 MATLAB 性能优化里最老生常谈的一条。4. 参数调优与改造让这份 demo 撑起你的课程设计原版代码能跑通但直接交作业会显得单薄。真正拉开差距的是你能不能讲清楚「改哪个参数、为什么改、改了之后现象怎么变」。这一章给三组可验证的改造方向。4.1 关键参数对照表参数原值可调范围调大后的现象适用场景gammaγ0.80.50.99更看重远期奖励路径更短但收敛慢地图大、目标远epsilonε0.30.050.9探索变多前期路径乱后期更可能找到全局最优障碍复杂、易陷局部最优episode训练轮数9003005000收敛更稳但边际收益递减状态空间扩大时同步加陷阱奖励-5-1-20绝对值越大越早学会绕开过大则不敢探索陷阱密集时适度加大这张表建议直接放进你的设计文档「实验与分析」一节每改一个参数跑一次把路径长度和收敛轮次记下来做成折线图就是现成的实验数据。4.2 把固定 ε 改成衰减 ε固定探索率的问题是后期还在瞎走浪费训练轮次。改成随回合衰减收敛通常能快 20%30%epsilon_start 0.9; epsilon_end 0.05; decay_episodes 600; % 前 600 轮线性衰减 for episode 1:900 % 线性衰减前期多探索后期多利用 if episode decay_episodes epsilon epsilon_start - (epsilon_start - epsilon_end) * (episode / decay_episodes); else epsilon epsilon_end; end % ... 后续训练逻辑不变 end改动的核心是把epsilon从循环外的常量挪进循环内每轮重算。decay_episodes取总轮数的 2/3 左右比较稳太短会导致探索不足、Q 表覆盖不全太长则后期还在随机游走。这个改动在答辩时很好讲它对应的是「探索-利用困境」这个强化学习的核心矛盾比单纯说「我调了个参数」有说服力得多。4.3 从 16 格扩到 N×N 网格如果课程设计要求更大的地图T的构造逻辑要泛化。核心是把「编号」换成「行列坐标」再映射回编号N 6; % 6x6 网格 n_states N * N; T zeros(n_states); for r 1:N for c 1:N idx (r-1)*N c; % 行列转编号 if r 1, T(idx, idx-N) 1; end % 上 if r N, T(idx, idxN) 1; end % 下 if c 1, T(idx, idx-1) 1; end % 左 if c N, T(idx, idx1) 1; end % 右 end end % 之后同样用列清零的方式挖障碍、设终点这段改造的价值在于它把「硬编码 16」变成了「参数化 N」你的设计文档里就可以写「本方案支持任意 N×N 网格扩展仅需修改 N 与障碍列索引」。注意编号规则必须和原版保持一致行优先、从上到下、从左到右否则路径回溯那段max(Q(start_0,:))的语义会错位。5. 避坑与排查这份代码最容易翻车的五个地方跑不通的时候别急着怀疑算法九成问题出在环境配置和矩阵语义上。下面五条按出现频率排序每条都给出「现象 → 原因 → 解决」。现象一报错Undefined function unidrnd。原因unidrnd属于 Statistics and Machine Learning Toolbox纯净版 MATLAB 或 Octave 里没有。解决全局替换为randiunidrnd(16)改成randi(16)unidrnd(length(possible_actions))改成randi(length(possible_actions))语义完全等价。现象二训练跑完回溯出的路径在原地打转或长度爆炸。原因某个状态的 Q 行全零max返回索引 1导致来回跳。解决训练后加一句sum(Q,2)检查哪些行全零对全零状态说明探索没覆盖到把episode提到 2000 以上或把epsilon临时调到 0.5 重跑。现象三路径能到终点但明显绕远不走近路。原因gamma偏小或训练轮数不足远期奖励被折扣吃掉智能体学成了「贪心短视」。解决先把gamma从 0.8 提到 0.9 试一次再观察 300 轮和 900 轮的路径差异如果 900 轮还在变短说明没收敛加轮数。现象四改了奖励矩阵后智能体宁愿踩陷阱也不去终点。原因赋值顺序错了R(:,16)10被后面的列赋值覆盖或者陷阱惩罚绝对值远大于终点奖励。解决检查R的赋值顺序单点赋值永远放最后同时保证终点奖励绝对值大于单步惩罚否则「活着扣分」会压过「到达得分」。现象五把代码贴进 Word 交作业中文注释全变乱码。原因MATLAB 默认编码与文档编码不一致。解决.m文件统一存成 UTF-8Word 里粘贴时选「只保留文本」再重新设字体更稳的做法是代码用等宽字体单独排版注释另起一行写别混排。提示这五条里前两条占了实际求助的绝大多数。我一般会在代码开头加一段「运行前检查」注释把工具箱依赖和编码要求写死省得每次换机器重踩一遍。6. 验收与答辩怎么证明这套 Q-Learning 真的学到了东西代码能跑只是及格线验收要看的是「学习曲线」和「策略合理性」两个证据。我的习惯是准备三样东西一张收敛曲线、一张路径对比图、一份参数敏感性表。收敛曲线用每 100 轮记录一次「本回合步数」或「累计奖励」画出来应该看到前期波动大、后期趋于平稳。如果曲线一直抖说明epsilon太大或alpha该降如果曲线早早躺平但路径不是最优说明陷入了局部最优得加探索。路径对比图更直观把训练 100 轮、300 轮、900 轮各自回溯出的路径画在同一张 4×4 网格上能清楚看到「从乱走到走最短」的演化过程这张图放进答辩 PPT 比任何文字都有说服力。参数敏感性表就按第 4 章那张表来填每个参数取三档记录收敛轮次和最终路径长度。答辩时被问「为什么 γ 取 0.8」你可以直接指着表说「0.8 时 420 轮收敛、路径 6 步0.95 时 780 轮收敛、路径 5 步综合考虑选了 0.8」——有数据支撑的回答和「书上这么写的」是两种待遇。还有一个容易被忽略的验收点策略的确定性。训练好的 Q 表应该是确定的同一个起点跑十次回溯路径必须完全一致。如果每次不一样说明你的回溯逻辑里混进了随机探索检查是不是误把训练循环里的 ε-greedy 带进了回溯段。这个检查花不了一分钟但能挡掉「结果不可复现」这种致命质疑。最后说个我自己的教训。早年做第一个强化学习课设我把所有精力花在调参上结果答辩时被问「你的奖励函数为什么这么设计」当场卡壳——因为我只是照抄了示例从没想过 -1 和 -5 的比值意味着什么。从那以后我每次交方案前都强制自己用一句话解释每个超参数的物理含义解释不通的就回去重读代码。这套 16 格的 Q-Learning 源码正好适合练这个习惯格子少、逻辑短每个数字都能追到源头。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑