您的位置:首页 > 其它

深度优先搜索(DFS)-迷宫问题

2019-04-15 17:27 881 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/weixin_44494648/article/details/89316576

深度优先搜索:关于图的搜索

之前讲了使用深度搜索来做全排列(全排列),但深度搜索更主要的使用并不在全排列里面,对于该走索的研究,要先从简单的走迷宫问题开始。

对于走迷宫,我可以这样走:站在入口,考虑自己下一步可以走哪里,走到那个位置后,再考虑下一步怎么走,一直走下去,直到没有路,然后在返回最近的一个岔路口,选其它任一条没试过的路,如果不能走,再尝试其他的路,直到这个岔路口的路全部试完,再回到上一个路口,如果走到终点,记录使用的步数,再回退到上一个路口,直到尝试结束,输出最小值。

如上图,我在进入迷宫时,先规定好方向,每次在岔路口前,都先走右边,其次下边,然后左边,最后上边,并不是每个方向都可以走(有的位置没有路,有的位置已经走过)。比如在一号位置,先向右走,当右边试完后,发现下边,左边,上边都不能走,此时,搜索完毕。如果走在二号位置,先向右走,但不能走,然后再判断下边,左边,上边,能不能走;

使用上述的走迷宫规则,第一次到达终点时,应该是如下路径

由1处出发,按先右后下,即图中红色线的部分,至无路可走,再退回至上一个分叉,即为3处,再沿着绿线,重新出发,至终点,再返回4处,由于之前尝试(红线)已经走过下方,所以走4的左边,沿着蓝色线走,在回退……
至此思路就了解完了。
问题一,如何选择方向:

可以建立一个简单的二维数组;
int kk[4][2]={{0,1},{1,0},{-1,0},{0,-1}};

问题二:如何记录最优解:
每当到达终点,就将使用的步数保存并比较,去最小的;

代码实现

#include<stdio.h>

int kk[4][2]={{0,1},{1,0},{-1,0},{0,-1}};//方向数组

int min=999999;//最小步数

char map[6][6];//定义间的的地图6X6

int book[6][6];//标记是否走过
//深度优先搜索
void dfs(int x,int y,int tmp);
int main()
{

int a,b,i,j,k;
for(i=0;i<6;i++)
{
scanf("%s",map[i]);//初始化地图
}
//调用函数,(0,0),走了0步
dfs(0,0,0);
printf("%d",min);//输出最小步数
return 0;
}

void dfs(int x,int y,int tmp)
{
int i,j,k,x1,x2,y1,y2;
book[x][y]=1;//标记该点,防止重复
if(map[x][y]=='*')//判断是否为终点(设置*处为终点)
{
if(tmp<min)//当前使用步数和之前去最小
{
min=tmp;
}
return;
}
//有序查找四个方向
for(i=0;i<4;i++)
{

x1=x+kk[i][0];
y1=y+kk[i][1];
if(x1<0||x1>5||y1<0||y1>5)//查看是否越界
{
continue;
}
if(map[x1][y1]!='x'&&book[x1][y1]==0)//查看此处是否有障碍或已经走过
{
dfs(x1,y1,tmp+1);
book[x1][y1]=0;//去除标记
}
}
return;
}

补充

对于该代码,可以自己控制地图的大小,自己修改起点和终点的位置,只需要将地图初始为一个较大的二维数组,再读取地图大小,再根据地图大小,读取地图的布置,再设置起始点。

printf("请输入地图大小:\n");
scanf("%d%d",&m,&n);
for(i=0;i<m;i++)
{
scanf("%s",a[i]);
}
printf("\n请输入起点与终点坐标:\n");
scanf("%d%d%d%d",&startx,&starty,&endx,&endy);

地图的声明(设计稍微大一点)

char a[50][50];
int book[50][50]={};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: