Java中的迷宫解算器问题

时间:2014-03-06 21:38:23

标签: java recursion

我现在已经让它停止无限重复,但它只是一遍又一遍地尝试相同的错误路径。有没有人知道如何让它尝试不同的路径?

数字的关键: 0是开放的 1是墙 2是路径的一部分 3是迷宫的终点

    public class Maze{
  public static void main(String[] args){
    int[][] maze = {{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
      {0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1},
      {1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,0,1},
      {1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,1,0,1,0,1},
      {1,0,1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,0,1,0,1,1,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,1},
      {1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1},
      {1,0,1,1,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,1,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,0,1},
      {1,0,0,0,0,0,1,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1},
      {1,1,1,0,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,1,1,1,1,0,1},
      {1,0,1,0,1,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,1},
      {1,0,1,0,1,0,1,1,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,0,1,1,1,0,1,0,1,1,1},
      {1,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1},
      {1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1},
      {1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1},
      {1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,0,1},
      {1,0,0,0,1,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,1},
      {1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,1,1,1,1,0,1,1,1,0,1},
      {1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,1},
      {1,1,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,0,1,0,1,0,1,0,1,1,1,1,1,0,1,0,1},
      {1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1},
      {1,0,1,1,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,1,1,0,1,0,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1},
      {1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,1,0,1,0,1,0,1,0,1},
      {1,1,1,0,1,0,1,1,1,0,1,1,1,0,1,0,1,1,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1},
      {1,0,0,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1},
      {1,0,1,1,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1},
      {1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1},
      {1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,1,1,0,1,0,1,1,1,0,1,0,1,0,1},
      {1,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1},
      {1,0,1,1,1,1,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,1,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,1,1,0,1},
      {1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,1},
      {1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,0,1,0,1},
      {1,0,0,0,1,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,1},
      {1,0,1,1,1,0,1,1,1,0,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,0,1,0,1,0,1},
      {1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1},
      {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1}};
    boolean[][] posCheck = new boolean[maze.length][maze[0].length];
    int r = 0;
    int c = 0;
    for(int row = 0; row < maze.length; row++){
      for(int col = 0; col < maze[row].length; col++){
        if(maze[row][col]==0){
          r = row;
          c = col;
        }
      }
    }
    maze[r][c] = 3;
    mazeSolver(1, 0, maze, posCheck);
  }

  public static boolean mazeSolver(int r, int c, int[][]maze, boolean[][] posCheck){
    posCheck[r][c] = true;
    maze[r][c] = 2;

    if(maze[r][c] == 3){
      print(maze);
      return true;
    }

    if((c+1 < maze.length) && maze[r][c+1]==0 && !posCheck[r][c+1] && (mazeSolver(r, c + 1, maze, posCheck))){
      maze[r][c] = 2;
      return true;
    }

    if((r-1 >= 0) && maze[r-1][c]==0 && !posCheck[r-1][c] && (mazeSolver(r - 1, c, maze, posCheck))){
      maze[r][c] = 2;
      return true;
    }

    if((c-1 >= 0) && maze[r][c-1]==0 && !posCheck[r][c-1] && (mazeSolver(r, c - 1, maze, posCheck))){
      maze[r][c] = 2;
      return true;
    }

    if((r+1 < maze.length) && maze[r+1][c]==0 && !posCheck[r+1][c] && (mazeSolver(r + 1, c, maze, posCheck))){
      maze[r][c] = 2;
      return true;
    }

    print(maze);
    return false;
  }

  public static void print(int[][] maze){
    for(int row = 0; row<maze.length; row++){
      for(int col = 0; col<maze[row].length; col++)
        System.out.print(maze[row][col]);
      System.out.println();
    }
  }
}

3 个答案:

答案 0 :(得分:3)

我已将调试输出添加到mazeSolver函数中的每个分支。正如您所看到的,从未调用任何分支,因为第三个if块中的递归调用永远不会完成评估。因此它是一个无限递归,这是StackOverflowError的原因。它还表明它只在两个不同的值之间来回反弹,这可能是一个问题。

您需要确定mazeSolver实际正在做什么 - 为什么无限递归永远不会展开,并更改它以满足其他条件之一。

换句话说,你需要修复你的“递归终结符”,并弄清楚除了[1,1]和[0,1]之外没有其他值的原因。

public static boolean mazeSolver(int r, int c, int[][] maze){
System.out.println("mazeSolver(" + r + ", " + c + ", maze)");

   if(maze[r][c] == 3)  {
System.out.println("  Equals 3 -- return true");
      return true;
   }  else if((c+1 < maze.length) && maze[r][c+1]==0 && (mazeSolver(r, c + 1, maze)))  {
      maze[r][c] = 2;
System.out.println("  Set to 2 (a) -- return true");
      return true;
   }  else if((r-1 >= 0) && maze[r-1][c]==0 && (mazeSolver(r - 1, c, maze)))  {
      maze[r][c] = 2;
System.out.println("  Set to 2 (b) -- return true");
      return true;
   }

System.out.println(" Between first and second if-block");


   if((c-1 >= 0 && maze[r][c-1]==0) && (mazeSolver(r, c - 1, maze)))  {
      maze[r][c] = 2;
System.out.println("  Set to 2 (c) -- return true");
      return true;
   }

System.out.println(" Between second and third if-block");

   if((r+1 < maze.length) && maze[r+1][c]==0 && (mazeSolver(r + 1, c, maze))){
      maze[r][c] = 2;
System.out.println("  Set to 2 (d) -- return true");
      return true;
   }

System.out.println("  return false");
   return false;
}

}

输出:

[R:\jeffy\programming\sandbox\xbnjava]java Maze
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block

......等等......

mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
mazeSolver(1, 0, maze)
mazeSolver(1, 1, maze)
 Between first and second if-block
Exception in thread "main" java.lang.StackOverflowError
        at sun.nio.cs.SingleByte.withResult(Unknown Source)
        at sun.nio.cs.SingleByte.access$000(Unknown Source)
        at sun.nio.cs.SingleByte$Encoder.encodeArrayLoop(Unknown Source)
        at sun.nio.cs.SingleByte$Encoder.encodeLoop(Unknown Source)
        at java.nio.charset.CharsetEncoder.encode(Unknown Source)
        at sun.nio.cs.StreamEncoder.implWrite(Unknown Source)
        at sun.nio.cs.StreamEncoder.write(Unknown Source)
        at java.io.OutputStreamWriter.write(Unknown Source)
        at java.io.BufferedWriter.flushBuffer(Unknown Source)
        at java.io.PrintStream.write(Unknown Source)
        at java.io.PrintStream.print(Unknown Source)
        at java.io.PrintStream.println(Unknown Source)
        at Maze.mazeSolver(Maze.java:64)
        at Maze.mazeSolver(Maze.java:82)
        at Maze.mazeSolver(Maze.java:69)
        at Maze.mazeSolver(Maze.java:82)
        at Maze.mazeSolver(Maze.java:69)
        at Maze.mazeSolver(Maze.java:82)
        at Maze.mazeSolver(Maze.java:69)
        at Maze.mazeSolver(Maze.java:82)
        at Maze.mazeSolver(Maze.java:69)
        at Maze.mazeSolver(Maze.java:82)
        at Maze.mazeSolver(Maze.java:69)
        at Maze.mazeSolver(Maze.java:82)
        at Maze.mazeSolver(Maze.java:69)
    at Maze.mazeSolver(Maze.java:82)

......等等......

答案 1 :(得分:1)

您需要跟踪您已访问过的位置。一个简单的方法是使用与迷宫相同大小的2d布尔数组,并在递归方法首次命中时将位置标记为true。除了墙壁检查之外,您还需要添加一张wasVisited支票。

答案 2 :(得分:1)

http://www.astrolog.org/labyrnth/algrithm.htm http://weblog.jamisbuck.org/2011/2/7/maze-generation-algorithm-recap

我最近编写了一个迷宫应用程序,发现上述网站对于理解这些概念非常有用。我创建了代表Maze,Cell&amp; amp;作为单元格(节点)和集合的集合边缘到图形。边缘。有一次我也遇到了没有完成搜索路径的问题。需要更好地管理已访问过的细胞。由于我的算法没有跟踪Cell已经被访问过,所以我反复回到死胡同。这听起来与你的问题非常相似。