回溯法解決迷宮問題
今天在又一次看到了回溯法解決關於迷宮的問題,於是在這裡分享給大家。
回溯法:對一個包括有很多個結點,每個結點有若干個搜尋分支的問題,把原問題分解為若干個子問題求解的演算法;當搜尋到某個結點發現無法再繼續搜尋下去時,就讓搜尋過程回溯(回退)到該節點的前一個結點,繼續搜尋該節點外的其他尚未搜尋的分支;如果發現該結點無法再搜尋下去,就讓搜尋過程回溯到這個結點的前一結點繼續這樣的搜尋過程;這樣的搜尋過程一直進行到搜尋到問題的解或者搜尋完了全部可搜尋分支沒有解存在為止。
迷宮問題用這種方法簡直很完美,當我們尋找通路時,當前方無法通過返回到上一層繼續搜尋其他沒有搜尋的通路,就這樣一層一層的找通路,最終找到出口,還有一種情況就是迷宮本來就沒有通路,只能是返回到起點。當然還涉及到多條通路時我們如何找到最短通路。
回溯過程如下圖所示:
0表示牆壁,1表示通路,函式引數傳入迷宮起點,每次向前一步則把前一步設定為2,防止再次試探該位置。
本題我用迭代法和遞迴法分別實現了找出迷宮多條通路問題
迭代法程式碼:
void SearchMazePath(Pos entry) //求取通路 回溯法(迭代)
{
Stack *s;
Pos next = entry;
PushStack(&s,next);
do
{
Maze[next._x][next._y] = 2;
next = TopStack(s);
next._x += 1; //下
if (CheckCoord(next))
{
PushStack(&s,next);
continue;
}
next = TopStack(s);
next._x -= 1;//上
if (CheckCoord(next))
{
PushStack(&s,next);
continue;
}
next = TopStack(s);
next._y += 1;//右
if (CheckCoord(next))
{
PushStack(&s,next);
continue;
}
next = TopStack(s);
next._y -= 1;//左
if (CheckCoord(next))
{
PushStack(&s,next);
continue;
}
PopStack(&s); //改層沒有通路,則pop掉棧頂,返回到上一層繼續試探其他方向
next = TopStack(s);
}while (EmptyStack(s) && next._x != entry._x);
}
遞迴法實現程式碼:
void SearchMazePathR(Pos entry) //求取通路(遞迴)
{
Pos next = entry;
Maze[next._x][next._y] = 2;
next = entry;
next._x -=1;
if (CheckCoord(next))
SearchMazePathR(next);
next = entry;
next._x +=1;
if (CheckCoord(next))
SearchMazePathR(next);
next = entry;
next._y -=1;
if (CheckCoord(next))
SearchMazePathR(next);
next = entry;
next._y +=1;
if (CheckCoord(next))
SearchMazePathR(next);
}
條件判斷補充程式碼:
int CheckCoord(Pos pos)
{
if (pos._x >= 0 && pos._x<ROW
&& pos._y >=0 && pos._y<COL
&& Maze[pos._x][pos._y] == 1)
{
return 1;
}
else
return 0;
}
執行結果:
尋找最短通路:
此時思路還是利用回溯,一步一步試探通路,但是我們需要修改標記方法。當我們向下一個位置試探時發現該位置可通就把該位置標記為比前一個位置大一的數,當下一個位置是1或者比原位置大的數則確定為通路。當下一個位置是0或者比原位置小的數則確定通。這樣當我們遍歷完所有通路即可得到最短通路。
先看看試探通路的結果:
明顯可以看出遍歷了四條路,最短通路為10步。
程式碼如下:
void SearchShortPathR(Pos entry,Pos cur) //尋找最短路徑
{
Pos next = entry;
Pos prev = cur;
Maze[next._x][next._y] = Maze[prev._x][prev._y] + 1;
if (next._y == COL-1)
printf("Exit:(%d ,%d)\n",next._x,next._y); //列印出口
next = entry;
next._x += 1;
if (CheckCoordS(next,entry))
SearchShortPathR(next,entry);
next = entry;
next._x -= 1;
if (CheckCoordS(next,entry))
SearchShortPathR(next,entry);
next = entry;
next._y += 1;
if (CheckCoordS(next,entry))
SearchShortPathR(next,entry);
next = entry;
next._y -= 1;
if (CheckCoordS(next,entry))
SearchShortPathR(next,entry);
}
總結回溯法解題通常包含以下三個步驟:
1.針對所給問題,定義問題的解空間;
2.確定易於搜尋的解空間結構;
3.以深度優先方式搜尋解空間,並在搜尋過程中用必要的條件避免無效搜尋。
相關文章
- 回溯法求迷宮問題
- c++迷宮問題回溯法遞迴演算法C++遞迴演算法
- 用C語言解決迷宮問題C語言
- 寒假補充專案-回溯法走迷宮
- 回溯和遞迴實現迷宮問題(C語言)遞迴C語言
- 回溯法解決喝酒問題 (轉)
- 回溯法解決全排列問題總結
- POJ3984-迷宮問題
- dfs深度優先搜尋解決迷宮類問題(遍歷)
- 華為優招面試題---迷宮問題面試題
- 回溯法(排列樹)解決八(N)皇后問題
- 洛谷 p1605 迷宮問題 詳解
- 使用A*演算法解迷宮最短路徑問題演算法
- (回溯法)解決一系列組合問題
- 用python深度優先遍歷解迷宮問題Python
- 【dawn·資料結構】迷宮問題(C++)資料結構C++
- 迷宮問題——最短程式碼,不到70行
- C++實現迷宮的生成與解決C++
- 解密迷宮問題:三種高效演算法Java實現,讓你輕鬆穿越未知迷宮解密演算法Java
- [SDOI2012] 走迷宮 題解
- 走迷宮
- PHP 解迷宮之 H 最小PHP
- 迷宮問題【資料結構實驗報告】資料結構
- 八皇后之回溯法解決
- (C++)資料結構實驗二——迷宮問題C++資料結構
- PHP 解迷宮之 G + H 最小PHP
- 如何用程式解圖片迷宮?
- 509迷宮
- [省選聯考 2024] 迷宮守衛 題解
- 用棧+回溯+非遞迴解決N皇后問題遞迴
- 【力扣】排列問題(回溯法)(去重)力扣
- 回溯問題
- js使用遞迴回溯法解八皇后問題程式碼分享JS遞迴
- 簡單介紹Python迷宮生成和迷宮破解演算法Python演算法
- 使用回溯演算法解決N皇后問題以及間隔排列問題演算法
- PHP 生成迷宮路線PHP
- 【面試】如何找到迷宮出口面試
- 橡皮鴨子解決問題法