繁体   English   中英

Java中的迷宫求解器问题

[英]Maze Solver problems in Java

现在,我已经停止无限重复,但是它只是不断地反复尝试相同的错误路径。 有谁知道让它尝试不同路径的方法?

数字的关键: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();
    }
  }
}

我已将调试输出添加到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)

...等等

您需要跟踪已经访问过的职位。 一种简单的方法是拥有一个与迷宫大小相同的二维布尔数组,并在递归方法首次命中它时将位置标记为true。 除了墙壁支票,您还需要添加wasVisited支票。

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

我最近一直在编写迷宫应用程序,发现上述站点对于了解概念非常有用。 我创建了一些类,以将图的迷宫,单元和边缘表示为单元(节点)和边缘的集合。 在某一时刻,我还遇到了一个问题,就是没有完成对路径的搜索,并且需要更好地管理已经访问了哪些单元。 由于我的算法无法跟踪Cell已经被访问,我一再陷入困境。 这听起来与您的问题非常相似。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM