1. 程式人生 > 其它 >BFS求解迷宮問題並輸出路線(C語言)

BFS求解迷宮問題並輸出路線(C語言)

1.問題的提出

    用二維矩陣表示一個迷宮,0表示可通行,1表示有障礙,請給出最短路徑的路線。

    給出迷宮:

   [0,0,1,0;

    0,0,0,0

    0,1,1,0

    0,1,0,0]

    (0,0)為起始點,(3,3)為終點

2.問題求解的思路

    題目要求求得最短路徑,顯然要用BFS的方法求解。

3.BFS

    廣度優先搜尋(也稱寬度優先搜尋,縮寫BFS,以下采用廣度來描述)是連通圖的一種遍歷策略。因為它的思想是從一個頂點V0開始,輻射狀地優先遍歷其周圍較廣的區域,因此得名。一般可以用它做什麼呢?一個最直觀經典的例子就是走迷宮,我們從起點開始,找出到終點的最短路程,很多最短路徑演算法就是基於廣度優先的思想成立的。

    在廣度優先搜尋演算法中,解答樹上結點的擴充套件是按它們在樹中的層次進行的。首先生成第一層結點,同時檢查目標結點是否在所生成的結點中,如果不在,則將所有的第一層結點逐一擴充套件,得到第二層結點,並檢查第二層結點是否包含目標結點,……,對層次為n+1的任一結點進行擴充套件之前,必須先考慮層次完層次為n的結點的每種可能的狀態。因此,對於同一層結點來說,求解問題的價值是相同的,可以按任意順序來擴充套件它們。通常採用的原則是先生成的結點先擴充套件。

4.如何儲存最短路徑

    這也是我在求解BFS問題的中遇到的最大的問題,在查閱資料後,我選擇了記錄每一個節點的前驅節點,然後再回溯的方法作為我們的解決方案。    

    我選擇了用陣列的方法記錄每一個節點的前驅節點:

     int route[4][4][2];

     (route[i][j][0],route[i][j][1])表示(i,j)的前驅節點。

5.具體程式碼

#include<stdio.h>
#include<stdlib.h>
#include<stack>
#include<queue>
using namespace std;
 
int record[4][4] = {0};
int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
int maze[4
][4] = {{0,0,1,0}, {0,0,0,0}, {0,1,1,0}, {0,1,0,0}}; stack <int> s; int visit(int a,int b) { if(record[a][b] == 0&&maze[a][b] == 0&&a >= 0&&a <= 3&&b >= 0&&b <= 3) { return 1; } else { return 0; } } /*void traverse() { int len = s.size()/2; int b[15][2]; for(int i = len;i > 0;i--) { b[i][1] = s.top(); s.pop(); b[i][0] = s.top(); s.pop(); } for(int i = 1;i < len;i++) { printf("(%d,%d)->",b[i][0],b[i][1]); } printf("(%d,%d)",b[len][0],b[len][1]); printf("已到達終點!"); } void DFS(int maze[4][4],int start[2],int end[2]) { int p[2]; p[0] = start[0]; p[1] = start[1]; record[start[0]][start[1]] = 1; if(start[0] == end[0]&&start[1] == end[1]) { traverse(); exit(0); } for(int i = 0;i < 4;i++) { int x,y; x = start[0] + dir[i][0]; y = start[1] + dir[i][1]; if(visit(x,y)) { s.push(x); s.push(y); p[0] = x; p[1] = y; DFS(maze,p,end); } } s.pop(); s.pop(); }*/ void printRoute(int route[4][4][2],int start[2],int end[2]) { int i = end[0]; int j = end[1]; while(1) { printf("(%d,%d)<-",i,j); int a = route[i][j][0]; int b = route[i][j][1]; i = a; j = b; if(i == start[0] && j == start[1]) { break; } } printf("(%d,%d)",i,j); } void BFS(int maze[4][4],int start[2],int end[2]) { queue<int> que; que.push(start[0]); que.push(start[1]); int route[4][4][2] = {0}; while(que.empty() == false) { int i = que.front(); que.pop(); int j = que.front(); que.pop(); if(i == end[0]&&j == end[1]) { printRoute(route,start,end); printf("已找到終點!"); break; } if(visit(i+dir[0][0],j+dir[0][1])) { record[i+dir[0][0]][j+dir[0][1]] = 1; que.push(i+dir[0][0]); que.push(j+dir[0][1]); route[i+dir[0][0]][j+dir[0][1]][0] = i; route[i+dir[0][0]][j+dir[0][1]][1] = j; } if(visit(i+dir[1][0],j+dir[1][1])) { record[i+dir[1][0]][j+dir[1][1]] = 1; que.push(i+dir[1][0]); que.push(j+dir[1][1]); route[i+dir[1][0]][j+dir[1][1]][0] = i; route[i+dir[1][0]][j+dir[1][1]][1] = j; } } } int main() { int start[2] = {0,0}; int end[2] = {3,3}; /*s.push(start[0]); s.push(start[1]); DFS(maze,start,end); printf("無法到達終點"); */ BFS(maze,start,end); return 0; }

6.執行結果