您的位置:首页 > 其它

DFS求解迷宫问题

2017-09-25 21:41 781 查看
DFS求解迷宫问题

给定一个迷宫地图,实际就是一个二维的数组,其中0代表可通过,1代表有障碍不能通过,求出所有路径。这种搜索问题一般使用深度搜索DFS,从出口处开始,根据选择的不同方向(上下左右)来到达另一个位置,这时可以把新到达的位置看做是新的起点,这样就可以递归的求解同样的子问题,递归结束的条件是最后到达了终点。在搜索的过程中,我们可以进行剪枝操作,我们先沿着某个方向走,并沿途把走过的节点进行标记,沿着某个节点一直搜索下去,不中南墙不回头,直到碰到障碍,或者数组越界,走到了已经访问过的节点,这时就直接返回,不必再继续搜索下去,可以称之为回溯,实际是递归的返回。

下面为具体代码:

#include <iostream>
#include <stdlib.h>
#include <vector>
#include <string>
using namespace std;
//迷宫问题
#define M  5//行数
#define N  5//列数
int map[M]
= {
{ 0, 1, 0, 0, 0 },
{ 0, 0, 0, 0, 0 },
{ 1, 0, 0, 1, 1 },
{ 0, 1, 0, 1, 0 },
{ 1, 1 ,0 ,0, 0 },
};
//用一个数组来标记是否走过某个位置
int mark[5][5] = { 0 };//初始全部未标记
//终点
int di = 4, dj = 4;
int dir[4][2] = { { -1, 0 }, { 1, 0 }, { 0, 1 }, { 0, -1 } };//四个方向
static int num = 0;
//x,y代表起点坐标
bool DFS(int x, int y, vector<vector<int>> &vec, vector<int> &path)
{
if (x < 0 || x >= M || y < 0 || y >= N||mark[x][y]==1)//数组越界或者被标记了
{
return false;
}
if (map[x][y] == 1)//碰到障碍
return false;
if (x == di&&y == dj)//当起点坐标与终点相等时,返回真
{
path.push_back(5 * x + y);//终点存入路径中
vec.push_back(path);
//开始这里没有添加,终点自己要单独弹出,否则其余路径会对一个节点值
path.pop_back();//与push对应
num++;
cout << "找到了" << num << "条路径" << endl;
return true;
}
path.push_back(5 * x + y);//将该点存入路径中
mark[x][y] = 1;
for (int i = 0; i < 4;i++)
{
int tx = x + dir[i][0];
int ty = y + dir[i][1];
DFS(tx, ty, vec, path);//依次搜索该点周围的四个点,但在dfs中会处理
//比如 该点为障碍就返回,该点为访问过了的节点也返回,
}
mark[x][y] = 0;
path.pop_back();
}
//测试
int main(void)
{
vector<vector<int>> vec;
vector<int> path;
bool flag=DFS(0, 0, vec, path);
if (flag)
cout << "\n---------------yes-------------" << endl;
vector<int>::iterator it;
for (int i = 0; i < vec.size();i++)
{
for (it = vec[i].begin(); it != vec[i].end();
4000
it++)
{
cout<< *it << " ";
}
cout << endl;
}
system("pause");
}


运行结果为


实际还可以求解所有路径中最小的路径,只要在终点判断的逻辑中加入一个变量存储路径的长度即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息