bfs迷宫问题讲解

  • 广度优先搜索解决迷宫寻路问题
    • 一、问题概述
    • 二、问题分析
      • (一)、手动模拟
      • (二)、如何用计算机来解决
        • (1)、地图表示
        • (2)、如何找通路
        • (3)、==如何找最短路(难点)==
    • 三、代码分析
      • (一)、需要开的数组
      • (二)、判断一个点附近那个点可以走
      • (三)、队列操作
    • 四、代码全览
    • 五、作者相关
      • (一)、作者简介
      • (二)、联系方式

广度优先搜索解决迷宫寻路问题

一、问题概述

已知一个矩形迷宫,该迷宫的出口和入口,通过编写程序来找到该迷宫是否存在一条通路,或者走出该迷宫的最小步数或最短路径。这儿我们分析的是最小步数的问题。
先上例题链接:https://www.acwing.com/problem/content/846/

以下内容来自ACwing,也就是上面那个网站!
给定一个 n×m 的二维整数数组,用来表示一个迷宫,数组中只包含 0 或 1,其中 0 表示可以走的路,1 表示不可通过的墙壁。
最初,有一个人位于左上角 (1,1) 处,已知该人每次可以向上、下、左、右任意一个方向移动一个位置。
请问,该人从左上角移动至右下角 (n,m) 处,至少需要移动多少次。
数据保证 (1,1) 处和 (n,m) 处的数字为 0,且一定至少存在一条通路。

输入样例:
5 5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
输出样例:
8

二、问题分析

(一)、手动模拟

在想如何写代码之前我们先手动模拟一波这个找步数的操作。
左上角是起点,右下角是终点
首先,我们可以一眼(或者稍加分析)在图中找到最短路,A–>B–>C–>F–>J–>M–>P–>Q–>R这条通路;
接着,试着重现刚才这个过程,发现我们其实是先从左上角开始,逐层的向右下角找零来找到最短路的;
再进一步,我们在遍历每层的时候,其实是遍历零周围是否还有零
这样,在脑中这个问题就有最短路解了。

(二)、如何用计算机来解决

现在来思考如何用计算机来解决这个问题。

(1)、地图表示

显然,如题所示,我们可以用一个二维数组来表示一个迷宫,0代表通路,1代表墙;

(2)、如何找通路

假如当前我们在起点,当然是找起点四周(上下左右)有没有路(也就是0)来看通路。在计算机中,我们可以用该点分别往上下左右的偏移量来判断该点是否可走(这儿看文字理解不了,待会儿一看代码就理解了)。

(3)、如何找最短路(难点)

为了方便阅读,再把图片放附近。


知道了在一个点如何找附近可以去哪儿之后,如何选择往那条通路走呢?
如左边那张图,表示从起点到终点的路径(中间那条没有画全),显而易见有三条路,两条通路。由于我们找的是最短路,又鉴于刚才的分析,逐层的找(就是在左边图中横着找,从上往下)才是正解。
仔细看一下,一层一层下来想到了什么(忽略掉每层可能有多个元素),是不是一个队列呢!(A), (B), (C ), (D, F), (E, J)…
知道是队列的话那就好办了,接下来的操作就是模拟一波队列的操作,(见右图):

  • 先将A点放入对头,然后看A后边哪一个点可走,发现B点并将其入队;
  • A点出队,对头是B点,然后看B点后边哪一个点可走,发现C点将其入队;
  • B点出队,对头是C点,然后看C点后边哪一个点可走,发现D, F两点将其入队;
  • C点出队,对头是D点,然后看D点后边哪一个点可走,发现(F已在队列中), E点将其入队;

  • 就这样,我们就找见了可行的最短路,至于步数,也就这样很容易得到了。

三、代码分析

(一)、需要开的数组

  • 首先地图是需要存储的;
  • 为了防止找路的过程一直转圈圈,还需要一个看看该点是否走过的数组(不过这个题不需要,但是也是写上了);
  • 保存各个可行点是第几步的数组(一个变量也行,不过数组更方便一点)。
  • 然后记录偏移量(也就是如何表示一个点的上下左右)也需要两个小数组。
// 地图
int map[MAXN][MAXN];
// 标记地图上的路是否已经被走过了
bool hasUsed[MAXN][MAXN];
// 记录经过每个点的步数
int steps[MAXN][MAXN];
// 遍历一个点时的偏移量
const int dx[4] = {0, -1, 0, 1};
const int dy[4] = {1, 0, -1, 0};

(二)、判断一个点附近那个点可以走

也就是判断四周是不是路,有没有被走过。

if (x >= 1 && y >= 1 && x <= row && y <= col && !hasUsed[x][y] && map[x][y] == 0)

(三)、队列操作

也就是如果这个点附近有路可走,则将其入队。这个就不贴代码了,越贴越乱。

四、代码全览

其实注释已经加的足够清晰了。

// 给定一个迷宫,找最短的出去的路
// 例题来源 : Acwing 844. 走迷宫
// 链接 : https://www.acwing.com/problem/content/846/
#include <iostream>
#include <queue>
#define MAXN 120
#define pii pair<int, int>
using namespace std;// 地图的起点为(1, 1)不是0
int map[MAXN][MAXN];// 标记地图上的路是否已经被走过了
bool hasUsed[MAXN][MAXN];// 记录经过每个点的步数
int steps[MAXN][MAXN];// 遍历一个点时的偏移量
const int dx[4] = {0, -1, 0, 1};
const int dy[4] = {1, 0, -1, 0};
int bfs(int row, int col, int startx, int starty, int endx, int endy);int main(void)
{int row, col;cin >> row >> col;// 读入迷宫for (int i = 1; i <= row; i++)for (int j = 1; j <= col; j++)cin >> map[i][j];// 标记第一行,第一列为已经走过for (int i = 0; i < MAXN; i++){hasUsed[0][i] = true;hasUsed[i][0] = true;}// 广度优先搜索找答案cout << bfs(row, col, 1, 1, row, col) << endl;return 0;
}// 广搜最短路径
// 参数 : 地图行数 | 地图列数 | 起点横坐标 | 起点纵坐标 | 终点横坐标 | 终点纵坐标
int bfs(int row, int col, int startx, int starty, int endx, int endy)
{// 使用队列记录路径queue<pii> path;int x, y;// 将起点入队,并且标记起点已经走过path.push({startx, starty});hasUsed[startx][starty] = true;// 当队列不为空时遍历各个可行的点找路径while (!path.empty()){// 取出当前要遍历的点pii temp = path.front();path.pop();// 如果该点就是要遍历的点,那么就提前结束if (temp.first == endx && temp.second == endy)break;// 如果该点不是终点,看看该点可以往那儿走for (int i = 0; i < 4; i++){x = temp.first + dx[i];y = temp.second + dy[i];// 查看当前的点是否可以走,如果可以走的话将其入队if (x >= 1 && y >= 1 && x <= row && y <= col && !hasUsed[x][y] && map[x][y] == 0){hasUsed[x][y] = true;path.push({x, y});steps[x][y] = steps[temp.first][temp.second] + 1;} // end if} // end for} // end while// 最后返回要求的点的步数return steps[endx][endy];
}

五、作者相关

  • (一)、作者简介

    • 作者:馗顺先生
    • 简介:一个热爱程序设计与电子技术的预备猿。后续也会不定期更新一些有趣的代码,以及一些有用的算法实现。大家可以关注以下哦。最后,若有不足,希望各位大佬们不吝赐教。
  • (二)、联系方式

    • 邮箱:2727144006@qq.com
    • 博客地址: https://blog.csdn.net/qq_33519837?spm=1001.2100.3001.5113

bfs迷宫寻路问题(一看就懂的讲解)相关推荐

  1. dfs入门排列数字问题(一看就懂的讲解)

    dfs入门排列数字问题 dfs入门排列数字问题 一.问题概述 二.问题分析 三.代码分析 (一).如何表示填写完成 (二).如何判断该填哪个数 (三).如何表示填空 (四).实现dfs 四.代码全览 ...

  2. java动画迷宫寻路_[人工智能] 迷宫生成、寻路及可视化动画

    前言 数据结构准备 迷宫生成算法 迷宫寻路算法 前言 本次带来迷宫相关的算法,迷宫的算法涉及到不少经典的图论算法,在游戏中NPC这些算法被大量的运用,深入了解和学习这些算法是为开发游戏打下坚实的基础. ...

  3. 人工智能大作业——A*算法迷宫寻路问题

    项目设计的目的 利用A*算法实现迷宫寻路功能,利用启发式函数的编写以及各类启发式函数效果的比较. 相关原理知识介绍 A*(A-Star)算法是一种静态路网中求解最短路最有效的方法.公式表示为:f(n) ...

  4. 迷宫寻路系列常用算法逻辑探究

    前言: 又到了人才流动的高峰季节,"金三银四",过了这个村,就没那个店,面试者勤奋地准备题典,面试官也在奋笔疾书, 有些面试官喜欢广度的知识覆盖,而有些面试官喜欢深度的知识探求. ...

  5. 迷宫生成算法和迷宫寻路算法

    迷宫生成算法和迷宫寻路算法 大学二年级的时候,作为对栈这个数据结构的复习,我制作了一个迷宫生成算法的小程序,当时反响十分好,过了几天我又用自己已经学的DirectX技术制作了DirectX版的程序.这 ...

  6. 【强化学习】Q-Learning算法求解迷宫寻路问题 + Java代码实现

    文章目录 前言 一.Q-Learning算法简介 1.1 更新公式 1.2 预测策略 1.3 详细资料 二.迷宫寻路问题简介 三.Java代码 3.1 环境说明 3.2 参数配置 3.3 迷宫环境类 ...

  7. 迷宫寻路 (25分)

    迷宫寻路 (25分) 给定一个M行N列的迷宫图,其中 "0"表示可通路,"1"表示障碍物,无法通行.在迷宫中只允许在水平或上下四个方向的通路上行走,走过的位置不 ...

  8. c++ 结构体赋值_《零基础看得懂的C语言入门教程》—(十二)结构体是这么回事

    一.学习目标 了解C语言的结构体的使用方法 了解C语言结构体的结构的赋值 了解多种C语言结构体变量的赋值方法和取值方法 目录 <零基础看得懂的C语言入门教程>--(二)简单带你了解流程 & ...

  9. 前端app调起摄像头 只显示在页面_猫也能看得懂的教程之一分钟使用Vue搭建简单Web页面...

    本教程适合人群: 已经了解过过html.js.css,想深入学习前端技术的小伙伴 有前端开发经验.但是没有使用过Vue的小伙伴 有过其他编程经验,对前端开发感兴趣的小伙伴 学习本教程之后你将会: 了解 ...

最新文章

  1. LeetCode 202. Happy Number--Python解法--数学题
  2. 你真的会用java注解吗?
  3. Ajax和JSON-学习笔记04【JSON_解析器】
  4. Springfox-swagger使用详解
  5. 中国首富们三十而立的年纪都在干什么
  6. SpringBoot 工程目录 整合mybatis-neo4j(注解类型)-增删改查
  7. ftp 200 227 451linux,FTP无法链接
  8. vscode eslint插件对vue文件无效
  9. 机器学习基石第十三讲笔记
  10. 计算机科学与技术U盘,速度竟差9倍!6款32GB USB3.0优盘横评
  11. android 安装APP缓存文件在哪,APP的缓存文件到底应该存在哪?看完这篇文章你应该就自己清楚了...
  12. wps序号打乱重新排序_wps序号怎么自动排列
  13. 【强化学习】悬崖寻路:Sarsa和Q-Learning
  14. App进程被回收问题总结
  15. ERROR 2000 (HY000): Unknown MySQL error
  16. Macbook电池使用问题——电池充电管理
  17. Java项目论文+PPT+源码等]基于javaweb的网上订餐管理系统|点餐餐饮餐厅
  18. AudioTrack 分析
  19. Torchtext下的AG_NEWS数据集进行分类(官方文档代码)
  20. 从VB来看-InsertionSort(VB插入排序)

热门文章

  1. c#对象集合去重_《C#编程入门》概览
  2. excel求期望_商务数据分析考试:决策树分析(Excel)-安聪
  3. matlab支持的文件类型,MATLAB可以读取的数据文件类型有()
  4. python脚本如何监听终止进程行为,如何通过脚本名获取pid
  5. 大厂首发!java敏捷开发模式面试题
  6. 全卷积神经网路【U-net项目实战】U-Net源码上实现自己数据集的分割任务
  7. java集群调度_Cuckoo-Schedule
  8. 点击调用ajax,jQuery ajax在点击时调用,仅工作一次
  9. java 反复器_Java数组去掉反复的方法集
  10. 网站关键词优化首先要学会分类!