1.宽度优先搜索解决迷宫最小步数问题
在迷宫问题中,除了找到从起点到终点的路径外,有时我们还关心如何以最小的步数到达终点。宽度优先搜索(BFS)是一种非常适合解决这类问题的算法。BFS从起点开始,逐层向外扩展搜索,直到找到终点。由于它首先探索离起点最近的节点,因此找到的路径通常是步数最少的。
2.宽度优先搜索的基本原理
宽度优先搜索是一种用于遍历或搜索树或图的算法。在迷宫问题中,我们可以将迷宫看作一个图,其中每个单元格都是一个节点,可通行的单元格之间用边相连。BFS使用队列数据结构来保存待探索的节点,并按照它们离起点的距离逐层探索。
3.BFS解决迷宫最小步数问题的步骤
-
初始化:
- 创建一个迷宫地图,表示每个单元格是否可以通行。
- 设置起点和终点。
- 创建一个队列用于保存待探索的节点。
- 创建一个与迷宫大小相同的距离数组,用于记录从起点到每个单元格的最短距离。初始时,所有单元格的距离都设为无穷大(或一个很大的数),起点的距离设为0。
-
开始搜索:
- 将起点加入队列。
- 标记起点为已访问。
-
广度搜索:
- 从队列中取出一个节点。
- 检查该节点是否为终点。如果是,则结束搜索,此时的步数即为从起点到终点的最小步数。
- 如果不是终点,则遍历该节点的所有邻居节点(即可以通行的单元格)。
- 对于每个未访问过的邻居节点,执行以下操作:
- 更新其距离值为当前节点距离值加1。
- 将其加入队列。
- 标记为已访问。
- 如果邻居节点已经被访问过,并且其距离值不小于当前计算出的距离值,则忽略该节点,避免重复计算。
- 对于每个未访问过的邻居节点,执行以下操作:
-
输出结果:
- 如果找到终点,则可以输出从起点到终点的最小步数,以及可能的路径。
- 如果没有找到终点,则说明起点和终点不可达。
4.BFS解决迷宫最小步数问题的优势
- BFS能够保证找到的路径是最短的,因为它首先探索离起点最近的节点。
- 相比于深度优先搜索,BFS在解决迷宫最小步数问题时通常更加高效,因为它避免了不必要的深入搜索。
5.注意事项
- BFS的空间复杂度较高,因为它需要存储待探索的节点和已访问的节点信息。对于大型迷宫,可能会导致内存消耗较大。
- 在实现BFS时,要注意避免重复访问已经探索过的节点,以免造成不必要的计算。
6.代码实现
#include<iostream>
using namespace std;
int t[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//右下左上向量
struct node
{
int x;
int y;
//int f;//父编号
int s;//step
};
int main(){
struct node que[2501];
int a[51][51]={0},book[51][51]={0};
int head,tail;
int i,j,k,m,n,startx,starty,p,q,tx,ty,flag;
cin>>n>>m;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)//起始条件=1,终止条件<=
cin>>a[i][j];
cin>>startx>>starty>>p>>q;
//队列初始化
head=tail=1;
que[tail].x=startx;
que[tail].y=starty;
//que[tail].f=0;
que[tail].s=0;
tail++;
book[startx][starty]=1;
flag=0;
while (head<tail)
{
for(k=0;k<=3;k++){
tx=que[head].x+t[k][0];
ty=que[head].y+t[k][1];
if (tx<1||tx>n||ty<1||ty>m)continue;//检查越界
if (a[tx][ty]==0&&book[tx][ty]==0)//未走过且非障碍
{
book[tx][ty]=1;
que[tail].x=tx;
que[tail].y=ty;
//que[tail].f=que[head].f+1;
que[tail].s=que[head].s+1;
tail++;
}
if (tx==p&&ty==q)
{
flag=1;
break;
}
}
if (flag==1)break;
head++;
}
cout<<"step="<<que[tail-1].s;
return 0;
}
/* 5 4
0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1
1 1 4 3 */
另一种写法
#include<iostream>
#define MAX 101
using namespace std;
int t[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//右下左上向量
struct node
{
int x;
int y;
int s;//step
}que[MAX*MAX];
int main(){
int n,m,sx,sy,ex,ey,map[MAX][MAX],book[MAX][MAX];
cin >> n >> m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>map[i][j];
cin>> sx >> sy;
cin>> ex >> ey;
//chushihua
int head=1,tail=1;
que[1].x=sx;
que[1].y=sy;
que[1].s=0;
book[sx][sy]=1;
tail++;
int flag=0;
while(head<tail){
for (int i = 0; i < 4; i++)
{
que[tail].x=que[head].x+t[i][0];
que[tail].y=que[head].y+t[i][1];
que[tail].s=que[head].s+1;
if (que[tail].x==ex&&que[tail].y==ey)
{
flag=1;
break;
}
if(que[tail].x<1||que[tail].y<1||que[tail].x>m||que[tail].y>n||map[que[tail].x][que[tail].y]==1||book[que[tail].x][que[tail].y]==1)continue;
book[que[tail].x][que[tail].y]=1;
tail++;
}
if (flag)break;
head++;
}
if (flag)cout<<que[tail].s<<endl;
else cout<<"no";
return 0;
}
7.补充
如果起点和终点重合,以上方法算出来最小步数为2。如果没有确保起点和终点不能重合,可以单独用if判断一下。
本文详细介绍了宽度优先搜索(BFS)在寻找迷宫中从起点到终点的最小步数问题中的应用,包括基本原理、步骤、优势以及代码实现,同时提到了注意事项和特殊情况处理。
&spm=1001.2101.3001.5002&articleId=136103256&d=1&t=3&u=af48487af50b42a49b9468db40014415)
4335

被折叠的 条评论
为什么被折叠?



