前一篇文章https://blog.csdn.net/qq_35694280/article/details/106446214介绍了使用Matlab代码如何利用Q-learning或者SARSA在一维空间实现探索,并且训练机器如何自动达到目标。这篇文章在此基础上将一维空间延伸至二维空间,将算法应用到二维空间的探索与训练上,最终实现规划的目标。这篇文章也承接上一篇,通过在二维环境中Q-learning与SARSA的表现来展示二者的区别。

一、问题描述

本文针对的二维环境如图所示

是一个二维网格模型,我们将其描述为迷宫,因为在此基础上可以延伸至任何一个二维网格模型。网格一共分为6行7列共 6 × 7 6\times7 6×7个网格,其中左下角蓝色格子为探索的起点,红色格子为我们的目的地,即希望机器能够最终到达这个出口,黑色的格子表示陷阱,只要落入黑色格子则本轮结束以失败告终。在每个格子中机器可以朝上、右、下、左四个方向移动,对应的动作分别为 A = 1 , 2 , 3 , 4 A=1,2,3,4 A=1,2,3,4,在边缘的格子则只能朝相邻的格子移动,不可以超出边界。

二、模型定义

为了将环境描述为程序易于表达的形式,我们将每个格子进行编号,从1至42,第一行从左至右分别是 1 , 2 , 3 , 4 , 5 , 6 , 7 1,2,3,4,5,6,7 1,2,3,4,5,6,7,第二行从左至右则分别是 8 , 9 , 10 , 11 , 12 , 13 , 14 8,9,10,11,12,13,14 8,9,10,11,12,13,14,以此类推,将所有格子进行编号,这个编号也方便与每个格子对应的坐标进行换算。在中间的格子有四个动作选择,可以往上、下、左、右任意一个方向移动,在边缘的格子则只能选择三个动作,在角落的格子则只有两个选择。

为了使机器能够自主学习,我们需要对环境的reward进行定义,暂时将出口处的reward设置为1,陷阱处的reward则设置为-1,其他任何格子reward为0。至此模型的定义完成。

三、算法

本文所用的算法就是最基础的Q-learning与SARSA算法,相关的理论知识可以参考别的教程,这里不再赘述。如果感兴趣可以参考上一篇文章,将RL应用在一维环境中,之后再来读这篇文章可能会更加容易理解,因为两者的算法基本相同,不同之处只在于环境的改变,以及状态空间维数变大,求解更加费时。话不多说,直接上代码。

四、代码

与前文相同,本文代码依然是分为三块,分别是主程序 Maze_main \texttt{Maze\_main} Maze_main以及动作函数 choose_action \texttt{choose\_action} choose_action和环境函数 get_env_feedback \texttt{get\_env\_feedback} get_env_feedback.其中主程序代码如下

clear; clc; close all;
% RL implementation on a finite-state maze exploration
% 设置参数:状态量个数,动作的个数,最大循环数
global Maze_row Maze_col epsilon goal_num;
Maze_row = 6; Maze_col = 7; epsilon = 0.9;
state_num = Maze_row*Maze_col;
action_num = 4;
episode_max = 20000;
% 这两个参数很重要,适当的调节可以更好地学习最优解
Gama = 0.8; % discout factor
Alpha = 0.2; % 学习速率
% 初始化Q值表
Q_table = zeros(state_num, action_num);
% 目标点的坐标,以及位置编号;起始点的位置及编号
goal = [1, 7]; goal_num = (goal(1)-1)*Maze_col+goal(2);
start = [1, 1]; start_num = (start(1)-1)*Maze_col+start(2);for i=1:episode_max% 每次训练的初始化step_counter = 0;S = start_num;is_terminal = false;choices = Q_table(S, :);action = [];
%     A = choose_action(S, choices); % SARSA对初始状态采取的动作的初始化while ~is_terminal% 选择动作,更新状态,更新Q表
%         action = [action A]; % SARSA动作收集step_counter = step_counter + 1;choices = Q_table(S, :);A = choose_action(S, choices); % Q-learning采用的动作[S_, R, flag] = get_env_feedback(S, A);
%         A_ = choose_action(S_, choices); % SARSA中对下一状态的动作选择Q_predict = Q_table(S, A);% 根据下一步是否是终点来更新flag参数以及Q值if S_ ~= goal_num && flag == 0% 当下的reward加上下一步的discounted Q-valueQ_target = R + Gama * max(Q_table(S_, :)); % Q-learning更新
%             Q_target = R + Gama * Q_table(S_, A_); % SARSA更新,下一状态采用A_elseif flag == 1 % 落入陷阱,直接终止Q_target = R;Q_table(S, A) = Q_table(S, A) + Alpha * (Q_target - Q_predict);break;else% 如果是终点就没有下一步,直接赋值Q_target = R;is_terminal = true;endQ_table(S, A) = Q_table(S, A) + Alpha * (Q_target - Q_predict);S = S_; % 更新状态量
%         A=A_; % 更新动作值,SARSA选择的下一动作-说到做到if step_counter > 10000breakend
%         action = [action A]; % Q-learning动作收集endif S==goal_numfprintf('%d: Succeed! total step: %d\n', i, step_counter);
%         if step_counter<12
%             disp(action);
%         endelseif flag == 1fprintf('%d: Danger, failed! total step: %d\n', i, step_counter);elsefprintf('Emergency break\n');end
end
Q_table

注意,将注释中含有Q-learning的代码行注释掉,并且将注释中含有SARSA的代码去注释,则可以实现两种算法的切换,反之亦然。主程序部分与一维情况下的代码差别不大,主要是环境函数与动作函数有所不同,分别如下

function A = choose_action( S, choices )
% 选择动作1,2,3,4,分别对应上下左右的动作
%   greedy policy
global Maze_row Maze_col epsilon;
% 找到S对应的坐标
col = mod(S, Maze_col); % 列
if col == 0col = Maze_col;
end
row = ceil(S/Maze_col); % 行a = rand;if col>1 && col<Maze_col && row>1 && row<Maze_rowif a>epsilon || ~any(choices)% 在初始状态都为0的时候保证随机选取,而不是总选择第一个A = ceil(4*rand);returnelse[maximum ,A] = max(choices); returnend
elseif row == 1if col == 1  % 在坐标(1,1), A=1 or 2S_choices = [choices(1), choices(2)];if a>epsilon || ~any(S_choices)A = ceil(2*rand);returnelse[maximum ,A] = max(S_choices); returnendelseif col == Maze_col % position(1,7), A = 1 or 4S_choices = [choices(1), choices(4)];if a>epsilon || ~any(S_choices)A = ceil(2*rand);else[maximum ,A] = max(S_choices); endif A == 2A = 4;returnelsereturnendelse  % position between from (1,1) to (1,7) , action 1, 2, or 4S_choices = [choices(1), choices(2), choices(4)];if a>epsilon || ~any(S_choices)A = ceil(3*rand);else[maximum ,A] = max(S_choices); endif A == 3A = 4;returnelsereturnendend
elseif row == Maze_rowif col == 1  % 在坐标(6,1), A=2 or 3S_choices = [choices(2), choices(3)];if a>epsilon || ~any(S_choices)A = ceil(2*rand);A = A+1;returnelse[maximum ,A] = max(S_choices);A = A+1;returnendelseif col == Maze_col % position(6,7), A = 3 or 4S_choices = [choices(3), choices(4)];if a>epsilon || ~any(S_choices)A = ceil(2*rand);A = A+2;returnelse[maximum ,A] = max(S_choices); A = A+2;returnendelse  % position between from (6,1) to (6,7) , action 2, 3, or 4S_choices = [choices(2), choices(3), choices(4)];if a>epsilon || ~any(S_choices)A = ceil(3*rand);A = A+1;returnelse[maximum ,A] = max(S_choices); A = A+1;returnendend
elseif col == 1  % 不包括顶点 A=1,2 or 3S_choices = [choices(1), choices(2), choices(3)];if a>epsilon || ~any(S_choices)A = ceil(3*rand);returnelse[maximum ,A] = max(S_choices); returnendelseif col == Maze_col % 不包括顶点 A=1,3 or 4S_choices = [choices(1), choices(3), choices(4)];if a>epsilon || ~any(S_choices)A = ceil(3*rand);else[maximum ,A] = max(S_choices); endif A == 1returnelse A = A+1;returnend
end
end

动作函数这里比较麻烦,因为针对每一个格子可选择的动作不同,所以有很多的判断语句,并且由于使用了 ϵ -greedy \epsilon\textrm{-greedy} ϵ-greedy的探索方式,每一种情况下都要比较随机数进行概率判断。相比之下环境函数则比较简单,只需要在坐标的基础上直接加减即可。

function [S_, R, flag] = get_env_feedback(S, A)
%GET_ENV_FEEDBACK 此处显示有关此函数的摘要
%   此处显示详细说明
global Maze_row Maze_col goal_num
trap = [3,4,5,17,18,19];
% 找到S对应的坐标
col = mod(S, Maze_col); % 列
if col == 0col = Maze_col;
end
row = ceil(S/Maze_col); % 行flag = 0;
if A == 1  % 向上移动row = row+1;
elseif A == 2 % 向右移动col = col+1;
elseif A == 3 % 向下移动row = row-1;
elseif A == 4 % 向左移动col = col-1;
endS_ = Maze_col*(row-1) + col;if S_ == goal_numR = 1;
elseif ismember(S_, trap)R = -1;flag = 1;
elseR=0;
end
end

注意在环境函数与动作函数中都需要先将格子的编号转换为坐标,然后再进行运算。代码全部完成。

五、仿真结果

首先是Q-learning的结果

大概在100次训练之后基本上就已经收敛到最优,通过分析Q-table可以判断Q-learning选择的最优路径为

相比之下,SARSA的训练结果为

可以发现SARSA的收敛更慢,而且达到的最优解只不过是次优。另外,在仿真的过程中,SARSA很容易训练失败,无法达到目标。因为一旦落入陷阱,机器就会“一朝被蛇咬,十年怕井绳”,从此止步不前,特别是在环境比较恶劣的情况下,比如从 ( 1 , 2 ) (1,2) (1,2)到 ( 1 , 6 ) (1,6) (1,6)全部为陷阱时。但是同样情况下Q-learning更加稳定。SARSA的最优路径为:

对比发现,Q-learning算法相比SARSA更加大胆,用于尝试,SARSA则显得比较谨慎,故而二者的区别在这里就更加明显地体现出来了。值得一提的是,学习速率 α \alpha α与discount factor γ \gamma γ对于学习的结果影响较大,当设置 α = 0.1 , γ = 0.9 \alpha=0.1, \gamma=0.9 α=0.1,γ=0.9时,机器比较不容易学习到最优解,当设置为 α = 0.2 , γ = 0.8 \alpha=0.2, \gamma=0.8 α=0.2,γ=0.8之后,情况则有所改善,故参数的设置对于学习的影响不能忽略,大家在实际应用的过程中也是要注意这一点,适当地调节参数改善学习。最后,本文提供了较为基础的模型,感兴趣的朋友可以将二维环境做任意的改变,发掘更多有意思的现象。另外如果有什么问题欢迎交流讨论,觉得这篇文章有用的话不要忘了点个赞~

Matlab代码实现强化学习(Reinforcement Learning) 二维迷宫探索——Q-learning与SARSA对比相关推荐

  1. 【强化学习笔记】从 “酒鬼回家” 认识Q Learning算法

    1.背景 现在笔者来讲一个利用Q-learning 方法帮助酒鬼回家的一个小例子, 例子的环境是一个一维世界, 在世界的右边是酒鬼的家.这个酒鬼因为喝多了,根本不记得回家的路,只是根据自己的直觉一会向 ...

  2. 强化学习 Reinforcement Learning(三)——是时候用 PARL 框架玩会儿 DOOM 了!!!(下)

    强化学习 Reinforcement Learning(三)-- 是时候用 PARL 框架玩会儿 DOOM 了!!!(下) 本文目录 强化学习 Reinforcement Learning(三)-- ...

  3. 强化学习Reinforcement Learning

    Abstract Abstract 背景 强化学习算法概念 背景 (1) 强化学习的历史发展 1956年Bellman提出了动态规划方法. 1977年Werbos提出只适应动态规划算法. 1988年s ...

  4. 强化学习(Reinforcement Learning)入门学习--01

    强化学习(Reinforcement Learning)入门学习–01 定义 Reinforcement learning (RL) is an area of machine learning in ...

  5. 强化学习 (Reinforcement Learning)

    强化学习: 强化学习是机器学习中的一个领域,强调如何基于环境而行动,以取得最大化的预期利益.其灵感来源于心理学中的行为主义理论,即有机体如何在环境给予的奖励或惩罚的刺激下,逐步形成对刺激的预期,产生能 ...

  6. 强化学习(Reinforcement Learning)中的Q-Learning、DQN,面试看这篇就够了!

    文章目录 1. 什么是强化学习 2. 强化学习模型 2.1 打折的未来奖励 2.2 Q-Learning算法 2.3 Deep Q Learning(DQN) 2.3.1 神经网络的作用 2.3.2 ...

  7. 强化学习(Reinforcement Learning)入门知识

    强化学习(Reinforcement Learning) 概率统计知识 1. 随机变量和观测值 抛硬币是一个随机事件,其结果为**随机变量 X ** 正面为1,反面为0,若第 i 次试验中为正面,则观 ...

  8. 【四】多智能体强化学习(MARL)近年研究概览 {Learning cooperation(协作学习)、Agents modeling agents(智能体建模)}

    相关文章: [一]最新多智能体强化学习方法[总结] [二]最新多智能体强化学习文章如何查阅{顶会:AAAI. ICML } [三]多智能体强化学习(MARL)近年研究概览 {Analysis of e ...

  9. 强化学习系列文章(二十七):VPG+Beta分布在CartPoleContinuous环境中的应用

    强化学习系列文章(二十七):VPG+Beta分布在CartPoleContinuous环境中的应用 在第七篇笔记(https://blog.csdn.net/hhy_csdn/article/deta ...

最新文章

  1. 【硬核干货 | 程序的编译、链接、装载与运行】
  2. R构建lasso回归模型并获得最佳正则化系数
  3. 独家 | 数据科学家指南:梯度下降与反向传播算法
  4. jdk历史各个版本下载
  5. vijos 1448 校门外的树 树状数组
  6. 创建可按比例调整的布局的 Windows 窗体
  7. 极光推送经验之谈-Java后台服务器实现极光推送的两种实现方式
  8. mysql删除bin-log_删除MYSQl BIN-LOG 日志
  9. 1081. Rational Sum (20) -最大公约数
  10. 潜水员(信息学奥赛一本通-T1271)
  11. 谷歌不是 Web 界的上帝!
  12. 计算机考研雷区,考研的五大雷区是什么 如何避免
  13. DBeaver——一款替代Navicat的数据库可视化工具
  14. Spring Aop详解(无参和带参)
  15. Could not load file or assembly 'XXXXXXXX' or one of its dependencies. 试图加载格式不正确的程
  16. 大数据管理技术 Hadoop-JavaAPI程序案例1
  17. python绘制对比分析图(柱状图、折线图)
  18. 全球及中国建筑弹性体行业发展形势及竞争前景调研报告2022-2027年
  19. Session实现网站在线人数统计
  20. Java基础学习经验分享

热门文章

  1. python 使用jieba.analyse提取句子级的关键字
  2. 快速幂与矩阵快速幂学习笔记
  3. React教程之使用create-react-app构建你的第一个react应用
  4. android 网易视频无法播放器,没错,这就是目前功能最强第三方播放器
  5. 常在河边湿鞋系列---终于见到真正的Java人了
  6. 2021建筑电焊工模拟考试单选题库及答案解析
  7. 吉大计算机物联网工程学院,许德智
  8. CF卡打开时出现USB乱码文件名的恢复方法
  9. 机器人无限火力无限e符文_LOL无限火力青龙刀机器人黑科技套路 无限晕加超高伤害...
  10. 【Unity2D】实现敌人掉血的粒子特效