算法:迷宮問題


一、迷宮問題介紹

  給定一個方陣表示迷宮,其中 1 表示能走的路,0 為障礙或走不通(死胡同),迷宮左上為出發點,迷宮右下角為終點。在迷宮中的移動方式只能橫着走或豎着走,不能斜着走,找出沖出發點到達出口有效路徑的迷宮(maze problem)問題。

二、回溯法簡單求解

  給定迷宮:

  迷宮的二維矩陣表示:

                {1,0,0,0}
                {1,1,0,1}
                {0,1,0,0}
                {1,1,1,1}        

  以下是具有突出解決方案路徑的迷宮。

 

   以下是上述輸入矩陣的解決方案矩陣(程序的輸出):

1                 {1,0,0,0}
2                 {1,1,0,0}
3                 {0,1,0,0}
4                 {0,1,1,1}    

回溯算法思想:

  如果到達目的地,打印解決方案矩陣。若沒有到達目的地,則:

  a)在解決方案矩陣中將當前單元格標記為 1;

  b)沿水平方向向前移動並遞歸檢查是否這次移動解決了問題;

  c)如果在上述步驟中選擇的舉動沒有導致解決方案 然后向下移動並檢查此舉是否可以解決;

  d)如果以上解決方案均無效,則將該單元格取消標記為 0 (回溯)並返回 false。

 1     /**
 2      * 回溯法遞歸求解迷宮問題
 3      *
 4      * @param maze
 5      * @param x
 6      * @param y
 7      * @param sol
 8      * @return
 9      */
10     private boolean solveMazeUtil(int[][] maze, int x, int y, int[][] sol) {
11         /* 到達終點 */
12         if (x == (N - 1) && y == (N - 1)) {
13             sol[x][y] = 1;
14             return true;
15         }
16 
17         /* 每次檢查(x, y)是否能走 */
18         if (isSafe(maze, x, y)) {
19             /* 能走則標記該位置 */
20             sol[x][y] = 1;
21 
22             /* 沿x方向向前移動 */
23             if (solveMazeUtil(maze, x + 1, y, sol)) {
24                 return true;
25             }
26 
27             /* 如果沿x方向移動沒有給出解,則沿y方向向下移動 */
28             if (solveMazeUtil(maze, x, y + 1, sol)) {
29                 return true;
30             }
31 
32             /* 如果以上動作均無效,則回溯:將(x,y)標記為解決方案路徑的一部分記為不可行 */
33             sol[x][y] = 0;
34             return false;
35         }
36 
37         return false;
38     }

本文源代碼:

  1 package algorithm;
  2 
  3 public class RatMaze {
  4     /* 迷宮規模 */
  5     private static int N;
  6 
  7     /**
  8      * 打印解矩陣
  9      *
 10      * @param sol
 11      */
 12     private void printSolution(int[][] sol) {
 13         for (int i = 0; i < N; i++) {
 14             for (int j = 0; j < N; j++) {
 15                 System.out.print(" " + sol[i][j] + " ");
 16             }
 17             System.out.println();
 18         }
 19     }
 20 
 21     /**
 22      * 判斷當前路勁是否可行
 23      *
 24      * @param maze
 25      * @param x
 26      * @param y
 27      * @return
 28      */
 29     private boolean isSafe(int[][] maze, int x, int y) {
 30         return (x >= 0 && x < N && y >= 0 && y < N && maze[x][y] == 1);
 31     }
 32 
 33     /**
 34      * 解決迷宮問題, 有則打印解矩陣
 35      *
 36      * @param maze
 37      * @return
 38      */
 39     private boolean solveMaze(int[][] maze) {
 40         int[][] sol = new int[N][N];
 41         if (!solveMazeUtil(maze, 0, 0, sol)) {
 42             System.out.println("Solution doesn't exist");
 43             return false;
 44         }
 45         printSolution(sol);
 46         return true;
 47     }
 48 
 49     /**
 50      * 回溯法遞歸求解迷宮問題
 51      *
 52      * @param maze
 53      * @param x
 54      * @param y
 55      * @param sol
 56      * @return
 57      */
 58     private boolean solveMazeUtil(int[][] maze, int x, int y, int[][] sol) {
 59         /* 到達終點 */
 60         if (x == (N - 1) && y == (N - 1)) {
 61             sol[x][y] = 1;
 62             return true;
 63         }
 64 
 65         count++;
 66         /* 每次檢查(x, y)是否能走 */
 67         if (isSafe(maze, x, y)) {
 68             /* 能走則標記該位置 */
 69             sol[x][y] = 1;
 70 
 71             /* 沿x方向向前移動 */
 72             if (solveMazeUtil(maze, x + 1, y, sol)) {
 73                 return true;
 74             }
 75             
 76             /* 如果沿x方向移動沒有給出解,則沿y方向向下移動 */
 77             if (solveMazeUtil(maze, x, y + 1, sol)) {
 78                 return true;
 79             }
 80 
 81             /* 如果以上動作均無效,則回溯:將(x,y)標記為解決方案路徑的一部分記為不可行 */
 82             sol[x][y] = 0;
 83             return false;
 84         }
 85 
 86         return false;
 87     }
 88 
 89     public static void main(String[] args) {
 90         RatMaze ratMaze = new RatMaze();
 91         int[][] maze = {
 92                 { 1, 0, 0, 0 },
 93                 { 1, 1, 1, 0 },
 94                 { 0, 1, 0, 0 },
 95                 { 1, 1, 1, 1 }
 96         };
 97         N = maze.length;
 98         ratMaze.solveMaze(maze);
 99     }
100 }
View Code


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM