之前我們已經討論了採用回溯(backtracking)方法來解決西洋棋中馬的遍歷問題。
為了讓大家更加熟悉回溯方法,我們將在後面的課程中再分析幾個例子。
今天先看乙個使用回溯方法解決老鼠走迷宮的問題。
下圖是乙個迷宮,其中塗上灰色的方格,老鼠不能進入,請找出老鼠從起點到終點的線路。老鼠只能向兩個方向移動:向前和向下,在下面的例子中也就是只能向右或向下移動。(注意,這是迷宮問題的乙個簡單版本。 而在更複雜的版本中,老鼠可以在4個方向上移動或甚至可以跳著走)
下圖表示一條從起點到終點的可行路徑。
演算法思路
我們把老鼠迷宮問題做乙個抽象。
假設迷宮是乙個n*n的二維矩陣(矩陣簡稱為m),矩陣中的每個元素m[i][j](0≤i≤n-1,0≤j≤n-1)是乙個單元格方塊。
其中最左上方的塊,即m[0][0]是老鼠出發的格仔,而最右下的格仔m[n-1][n-1]是它的出口。
問題就變成從格仔m[0][0]開始,尋找到達m[n-1][n-1]的路徑。
在老鼠闖蕩迷宮矩陣的過程中,我們用0和1來表示老鼠是否可以進入某個方格。如果某方格m[i][j]被標註為0,那麼表示它是乙個死胡同,老鼠無法進入該方格;而如果它被標註為1,則表示老鼠可以進入它。
因此上面的例子對應的抽象矩陣為:
樸素演算法的思路
樸素演算法生成從起點格仔到終點格仔的所有路徑,並逐個檢查每個路徑是否能滿足約束條件。
如有還有未經驗證的路徑
}樸素演算法需要列舉所有可行的路徑,可能效率會不高,特別是迷宮比較大的時候。
回溯演算法的思路
下面是回溯演算法的解題思路。
從起點方格開始,如果當前所在的方格已經是終點方格
列印輸出找到的路徑矩陣,結束
否則a)將當前方格標記為1
b)在水平方向向右移動乙個方格並遞迴檢查是否該移動可以找到解
c)如果在上述步驟中選擇的移動沒有找到解
那麼向下移動乙個方格並並遞迴檢查此移動是否可以找到解
d)如果上述方法都不起作用,則將該方格標記為0,表示需要回退(backtracing)並返回false
**實現
以下是老鼠迷宮問題的c/c++**實現。 它以二維矩陣形式列印出一種可能的解決方案。 最後的輸出是乙個矩陣,顯示為1的格仔是老鼠經過的格仔。
#include
// 迷宮大小
#define n 4
bool solvemazeutil(int maze[n][n], int x, int y, int sol[n][n]);
/* 該函式可以輸出找到的解矩陣[n][n] */
void printsolution(int sol[n][n])
} /* 該函式檢查座標(x,y)是否是乙個有效的方格 */
bool issafe(int maze[n][n], int x, int y)
/*使用回溯演算法解決迷宮問題。主要思路:
使用solvemazeutil()來尋找路徑。 如果沒有找到可行的路徑,則返回false
否則返回true並列印出找到的路徑(採用1來表示)
請注意,可能有多個解決方案,這裡只找出乙個可行的解決方案
*/bool solvemaze(int maze[n][n])
, ,
, };
if (solvemazeutil(maze, 0, 0, sol) == false)
printsolution(sol);
return true;
} /*採用遞迴函式來解決迷宮問題*/
bool solvemazeutil(int maze[n][n], int x, int y, int sol[n][n])
//檢查(x,y)是否是乙個合法的方格
if (issafe(maze, x, y) == true)
return false;
} // 主程式
int main()
, ,
, };
solvemaze(maze);
return 0;
} 輸出的樣子如下:
1 0 0 0
1 1 0 0
0 1 0 0
0 1 1 1
請你試著執行看看是否能得到正確的答案。
C 老鼠迷宮
include 輸入輸出流 include 檔案標頭檔案 include include 時間的標頭檔案 include 使用系統標頭檔案 include 字串標頭檔案 include 棧標頭檔案 include 數學函式標頭檔案 include 命名函式 define time 12 規定的遊戲時...
老鼠走迷宮
說明 老鼠走迷宮是遞迴求解的基本題型,我們在二維陣列中使用2表示迷宮牆壁,使用1來表示老鼠的行走路徑,試以程式求出由入口至出口的路徑。解法 老鼠的走法有上 左 下 右四個方向,在每前進一格之後就選乙個方向前進,無法前進時退回選擇下乙個可前進方向,如此在陣列中依序測試四個方向,直到走到出口為止,這是遞...
老鼠走迷宮
老鼠走迷官 一 說明 老鼠走迷宮是遞迴求解的基本題型,我們在二維陣列中使用2表示迷宮牆壁,使用1來表 示老鼠的行走路徑,求出由入口至出口的路徑。解法 老鼠的走法有上 左 下 右四個方向,在每前進一格之後就選乙個方向前進,無法前 進時退回選擇下乙個可前進方向,如此在陣列中依序測試四個方向,直到走到出口...