【问题标题】:Recursive Algorithm for 2D maze?2D迷宫的递归算法?
【发布时间】:2013-12-09 20:28:18
【问题描述】:

(这不是重复的)我们有一个 2D 迷宫,在所有 4 个面都被 X 包围,并且也有内部块。
迷宫的所有这些字符都存储在二维数组中。程序必须找到从开始'S'到目标'G'的路径。为此,使用名为“solve(int row, int col)”的布尔方法,并使用“S”的行和列索引进行初始化。该算法必须是递归的。如果它能够找到通向“G”的路径,它应该返回 true,否则返回 false。这是我尝试解决这个问题的方法,它显示“部分正确的结果”。

public boolean solve(int row, int col) {
  char right = this.theMaze[row][col + 1];
  char left = this.theMaze[row][col - 1];
  char up = this.theMaze[row - 1][col];
  char down = this.theMaze[row + 1][col];
  if (right == 'G' || left == 'G' || up == 'G' || down == 'G') {
    return true;
  }
  System.out.println("position=>"+"("+row + ":" + col+")");
  if (right == ' ') {
    return solve(row,col+1);
  }
  if (down == ' ') {
    return solve(row+1,col);
  }
  if (left == ' ') {
    return solve(row,col-1);
  }
  if (up == ' ') {
    return solve(row-1,col);
  }
  return false;
}

这是它解决的输出:

   0 1 2 3 4 5 6 7 8 9 10 
0  X X X X X X X X X X X 
1  X X S X X X X X   X X 
2  X X   X X X X X   X X 
3  X X   X X X X X   X X 
4  X X   X X X X X   X X 
5  X X   X X X X X   X X 
6  X X   X X X X X   X X 
7  X X   X X X X X G X X 
8  X X               X X 
9  X X X X X X X X X X X 

position=>(1:2)
position=>(2:2)
position=>(3:2)
position=>(4:2)
position=>(5:2)
position=>(6:2)
position=>(7:2)
position=>(8:2)
position=>(8:3)
position=>(8:4)
position=>(8:5)
position=>(8:6)
position=>(8:7)
true

但是当我将“G”上移一步时(在 6,8 处)。它显示 stackOverflow 错误。原因是在这种状态下,递归发生在 2 个点之间(有点像间接递归)。

我该如何解决这个问题。反正有没有告诉程序向上移动而不是向下移动?但是,改变条件语句的位置是行不通的。想想一个有不止一条路要走但只有一条通往“G”的职位。如何回到初始位置并尝试另一条路径?提前致谢。

更新:

Here is a Github Repo link to the complete solution of this problem by me.

【问题讨论】:

    标签: java algorithm recursion multidimensional-array maze


    【解决方案1】:

    您可以在您已经通过的空格中填写一个替代符号,以便您的程序知道它已经存在。

    【讨论】:

      【解决方案2】:

      您可以使用 DFS 或 BFS。 DFS 是最简单的一种。您只需进行递归,在所有 4/8 方向上导航并将该地点 (X,Y) 标记为已访问。如果是你的命运 'G',则返回 true 否则继续。

      提示:

      • 不要使用相同的矩阵来读取地图并将其标记为已访问,KISS
      • 您必须经常检查您是否发现了 G。您可以通过始终返回 FALSE 或 TRUE 来做到这一点,或者您可以使用全局变量。

      如果您在实现它时遇到问题,请尝试谷歌搜索有关此问题的一些源代码: http://en.wikipedia.org/wiki/Flood_fill

      http://www.geeksforgeeks.org/ford-fulkerson-algorithm-for-maximum-flow-problem/

      【讨论】:

        【解决方案3】:

        在您当前的代码中,您可能会返回 false 而不会查看其他连接的位置

        在从if 状态返回之前,您应该查看其他可能性。
        此外,您应该检查该位置是否已被访问以避免无限递归。

        将您的代码更改为:

        bool solved = false;
        visited[row][col] = true;
        
        if (right == ' ' && !visited[row][col+1]) {
            solved = solve(row,col+1);
        }
        if (down == ' ' && !solved && !visited[row+1][col]) {
            solved = solve(row+1,col);
        }
        if (left == ' ' && !solved && !visited[row][col-1]) {
            solved = solve(row,col-1);
        }
        if (up == ' ' && !solved !visited[row-1][col]) {
            solved = solve(row-1,col);
        }
        return solved;
        

        【讨论】:

          【解决方案4】:

          受本文Solving a 2D Maze启发,递归解决方案

          const CORRIDOR = 0;
          const WALL = 1;
          const EXIT = 2;
          
          // board - 2D array
          // start - [row, column] location of start point
          
          function findPath(board, start) {
            let seenPath = new Set();
          
            findPathRecur(board, start, seenPath)
          
            return Array.from(seenPath);
          }
          
          function findPathRecur(board, point, seenPath) {
            let row = point[0],
              column = point[1];
              
            // Base Case
            if (!isValidPathPoint(board, point, seenPath)) {
              return false;
            }
          
            if (board[row][column] === EXIT) {
              seenPath.add(point.toString());
              return true;
            }
          //  console.log("Curr -", point, ", Seen -", Array.from(seenPath));
          
          	seenPath.add(point.toString());
          
            let leftColumn = [row, column - 1],
              rightColumn = [row, column + 1],
              topRow = [row - 1, column],
              bottomRow = [row + 1, column];
          
            if (findPathRecur(board, leftColumn, seenPath)) {
              return true;
            }
            if (findPathRecur(board, rightColumn, seenPath)) {
              return true;
            }
            if (findPathRecur(board, topRow, seenPath)) {
              return true;
            }
            if (findPathRecur(board, bottomRow, seenPath)) {
              return true;
            }
          
            seenPath.delete(point.toString());
          
            return false;
          }
          
          // Check if the point is on valid path
          function isValidPathPoint(board, point, seenPath) {
            let row = point[0];
            let column = point[1];
          
            // Check if point exists
            if (board[row] != null && board[row][column] != null) {
          
              // To avoid cycle
              if (!seenPath.has(point.toString())) {
                // Not a Wall
                if (board[row][column] !== WALL) {
                  return true;
                }
              }
            }
            return false;
          }
          
          // Test Program
          let maze = [
            [1, 1, 1],
            [0, 0, 1],
            [1, 2, 1]
          ];
          
          let testStart = [
          	[1,0],
            [1,1],
            [2,1],
            [0,0],
            [5,5]
          ];
          
          testStart.forEach(function(start, i) {
          	console.log("Test Case:",i);
            console.log("\tStart -", start, "Path -", findPath(maze, start));
          })

          【讨论】:

            【解决方案5】:

            如果您正在寻找完整的解决方案,我已将其上传到我的Github Repository

            【讨论】:

              【解决方案6】:

              这是一个伪代码,供您解决迷宫并回溯解决方案:

              boolean Solve(int x,int y) {
              
                 if(isTarget(x,y)) 
                     return(true)
              
                 if(valid(x+1,y)&&Map[x+1][y]==' ') {
                    Map[x][y] = 'D'
                    if(Solve(x+1,y))
                       return(true)
                    Map[x][y] = ' '
                 }
                 if(valid(x-1,y)&&Map[x-1][y]==' ') {
                    Map[x][y] = 'U'
                    if(Solve(x-1,y))
                       return(true)
                    Map[x][y] = ' '
                 }
                 if(valid(x,y+1)&&Map[x][y+1]==' ') {
                    Map[x][y] = 'R'
                    if(Solve(x,y+1))
                       return(true)
                    Map[x][y] = ' '
                 }
                 if(valid(x,y-1)&&Map[x][y-1]==' ') {
                    Map[x][y] = 'L'
                    if(Solve(x,y-1))
                       return(true)
                    Map[x][y] = ' '
                 }
              
                 return(false);
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2014-06-25
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-12-14
                • 1970-01-01
                相关资源
                最近更新 更多