DFS求解迷宮問題

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][N] = {
    { 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(); it++)
        {
            cout<< *it << " ";
        }
        cout << endl;
    }
    system("pause");
}

運行結果爲這裏寫圖片描述
實際還可以求解所有路徑中最小的路徑,只要在終點判斷的邏輯中加入一個變量存儲路徑的長度即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章