zoukankan      html  css  js  c++  java
  • 算法:迷宫问题

    一、迷宫问题介绍

      给定一个方阵表示迷宫,其中 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
  • 相关阅读:
    如何设置PPT,演示者能看到备注而观众看不到
    面向对象的设计原则-类设计原则
    C#路径
    MyEclipse汉化
    XML
    C#读取Excel文件
    预处理指令
    c/c++有些函数之前有export
    动态内存
    模板
  • 原文地址:https://www.cnblogs.com/magic-sea/p/12104920.html
Copyright © 2011-2022 走看看