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

BFS迷宫最小路径问题

给定一个迷宫,0表示空地可以走,1表示墙壁不能穿越;在迷宫中可以向(上下左右)四个方向行进;

找到从左上角到右下角的最短路径,并计算最短路径的长度。

迷宫示例如下:
在这里插入图片描述
算法步骤:

  • 1、从起始点出发,遍历四个方向,如果某个方向可以走,则先存储起来;
  • 2、按照四个方向中可以走网格进行尝试,如果该网格的四个方向仍可以走,则存储起来。
  • 3、直至到达网格的右下角,停止搜索。

从以上分析可以看出,该步骤是按照一个广度优先搜索的方式进行的,而广度优先搜索讲究的是先访问的亦先被访问。因此使用队列存储当前步骤下可以走的网格,并对可以走的网格进行上述的迭代。

由于我们需要求得左上角到右下角的最短路径,那么我们可以使用一个二维数组标记从哪个方向到达的当前网格(且可以通过该二维数组确认当前网格是否已经被访问,如果被访问过,则无需再次访问,因此第一次访问的就是最短的),最终通过从终点到起点的逆序搜索,即可得到最短的逆序路径。

使用栈存储该路径,最终栈的大小即为路径长度,出栈的序列即为最短路径序列;

void minPathBFS(vector<vector<int>> &maze) {
	//maze矩阵中,0表示可走,1表示墙不可走
	int rows = maze.size();
	int cols = maze[0].size();
	queue<pair<int, int>> poss;//存放当前可访问位置,先访问亦先被访问
	vector<vector<int>> visited(rows, vector<int>(cols));
	//记录从哪个方向到达当前该网格,默认-1为起点,0为没有走的默认值,1向上,2向下,3向左,4向右
	int jump[4][2] = { {-1,0},{1,0},{0,-1},{0,1} };//上下左右的跳跃方式
	pair<int, int> start(0, 0);
	poss.push(start);
	visited[0][0] = -1;
	while (!poss.empty()){
		int x = poss.front().first;
		int y = poss.front().second;
		poss.pop();
		if (x == rows - 1 && y == cols - 1){
			break;
		}
		//遍历四个方向,如果有可以走的,先将可走的位置放在队列中,如果到达了终点,则直接break
		for (int i = 0; i < 4; i++){
			int newX = x + jump[i][0];
			int newY = y + jump[i][1];
			//矩阵边界范围内,不是墙,且未被访问过
			if (newX >= 0 && newX < rows && newY >= 0 && newY < cols && maze[newX][newY] == 0 && visited[newX][newY] == 0){
				poss.push(pair<int, int>{newX, newY});
				visited[newX][newY] = i + 1;//标记从哪个方向过来
			}
		}
	}
	//根据历史路径矩阵画出原始路径
	int stX = rows-1, stY = cols-1;
	if (visited[stX][stY] == 0){
		cout << "不存在从左上角到右下角的路线" << endl;
		//return;
	}
	//由于从终点到起点是逆序的,因此需要使用栈进行存储
	stack<pair<int, int>> path;
	path.push(pair<int, int>{stX, stY});
	//存在这条路径的话,一定可以从右下角走到左上角
	while (stX!=0 || stY!=0){
		int aX = stX - jump[visited[stX][stY]-1][0];
		int aY = stY - jump[visited[stX][stY]-1][1];
		path.push(pair<int, int>{aX, aY});
		stX = aX; stY = aY;//更新当前位置
	}
	int pathLens = path.size();
	cout << "最短路径长度为:" << pathLens << endl;
	while (!path.empty()){
		cout <<"[" <<path.top().first << "," << path.top().second <<"]"<< endl;
		path.pop();
	}
}

http://www.kler.cn/news/304883.html

相关文章:

  • 【人工智能】OpenAI发布GPT-o1模型:推理能力的革命性突破,这将再次刷新编程领域的格局!
  • 二叉树(上)
  • 定时中断键盘灯闪烁
  • P2865 [USACO06NOV] Roadblocks G
  • C#使用TCP-S7协议读写西门子PLC(五)-测试程序
  • 【玩转贪心算法专题】452. 用最少数量的箭引爆气球是【中等】
  • Java中重写和重载
  • c++ 编辑器 和 编译器 的详细解释
  • Ubuntu20-xrdp与Windows-mstsc远程桌面连接
  • C语言-整数和浮点数在内存中的存储-详解-上
  • JavaEE:文件内容操作(一)
  • docker--刚开始学不知道如何操作拉取,或拉取失败(cmd)
  • EmguCV学习笔记 C# 11.5 目标检测
  • 期货量化现在是要比股票量化更适合高频交易,程序化交易
  • 电脑桌面数据误删如何恢复?提供一份实用指南
  • spark sql详解
  • MVC 控制器
  • Qt-QLCDNumber显示类控件(26)
  • 如何简化机器人模型,加速仿真计算与可视化
  • 基于less和scss 循环生成css
  • Java中的高级I/O操作:NIO和AIO的比较
  • 大数据-129 - Flink CEP 详解 Complex Event Processing - 复杂事件处理
  • 哪个虚拟机软件在 Mac 上更好用,Mac 虚拟机会影响性能吗?
  • 计算机网络30——Linux-gdb调试命令makefile
  • [Linux#48][网络] 令牌环网 | IPv4 | socket 套接字 | TCP | UDP | 网络字节序列
  • Pytest配置文件pytest.ini如何编写生成日志文件?
  • AI创意引擎:优化Prompt提示词的高效提问技巧
  • 相机光学(三十八)——VCM(Voice Coil Motor)音圈马达
  • 数据分析-20-时间序列预测之基于PyTorch的LSTM数据准备及模型训练流程
  • Java后端编程语言进阶篇