深度优先搜索应用:走迷宫

时间:2021-11-13 20:31:57

走迷宫问题是深度优先搜索的一个典型应用,通常迷宫的形状如下


深度优先搜索应用:走迷宫

0为可走的道路,1为墙壁。通常情况下一些变种的模型,会加入一些特殊项,有别的意思,比如数字5代表钥匙,当然复杂模型先不讨论,从最简单的开始。

深度优先搜索的思想其实就是枚举式的递归,不断的对当前状态下进行对下一状态转移的进行枚举,直到找到解。在迷宫问题中,任意一个可以走的点都有4种转移状态(往上,往下,往左,往右),当然不是每一种状态的转移都是合法的,比如,以左上角(假设)点为起点,起点状态无法转移到:上,左,右这三种状态。只有往下是可以进行转移的,当我们往下转移时,转移时合法的,就递归进一层,此时,我们在新的状态下,重复进行枚举可转移状态并进一步递归进去,然后对合法的状态进行递归来搜索解,当搜索到某一状态搜索完所有可转移的状态时依然无法找到解,就进行回溯到上一层状态,递归转移到下一状态。
深度优先搜索可以用树的前序遍历来理解,我们一直往深处走,走到头了就往回走,然后选则另外一条路继续往深处走,直到全部走完或这找到我们要的条件
下面结合代码来理解

#include<iostream> 
#include<math.h>
#include<memory.h>
#include<stack>
using namespace std;
//这是设定的状态转移变量,分为上下左右4组,每一组的值分别代表X,Y的偏移
int dst[4][2]={//上下左右
-1,0,
1,0,
0,-1,
0,1
};
//迷宫,终点设置为数字3,已经走过的节点设置为4
int maze[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, 3,

};

void dfs(int x,int y)
{

if(maze[x][y]==3)//判断是否走到了终点,走到了就是输出找到的解
{//if里面是对可行解的一个判断表达式,里面的话就执行我们得到一个解后要进行的操作。
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
{
cout<<maze[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
return ;
}

for(int i=0;i<4;i++)//枚举转移状态
{

int nextx = x+dst[i][0];//计算转移状态
int nexty = y+dst[i][1];
//下面这里就是DFS的核心部分了,判断转移是否合法,合法的递归进去,不合法的,不进行搜索,if需要包含全部判断条件,不可缺一,否则搜索回出问题
if(nextx>=0 && nextx<=4 && nexty>=0 && nexty<=4&&(maze[nextx][nexty]!=1)&&(maze[nextx][nexty]!=4))//判断下一个要走的点是否合法,在迷宫的题目里面主要是判断转移的点能不能走
{
maze[x][y] = 4;//设置当前点为走过
dfs(nextx,nexty);//进一步搜索
maze[x][y] = 0;//退出来设置为没有走过,这样在回溯进行后续搜索时,不会影响对路径的搜索
}
}

return ;
}
int main()
{

dfs(0,0);//初始调用

return 0;

}

输出结果
深度优先搜索应用:走迷宫