Recursive Algorithm for 2D maze?

三世轮回 提交于 2019-12-05 04:48:08

问题


(This is not a duplicate) We have a 2D maze surrounded by X on all 4 sides and there are inner blocks too.
All these characters of the maze is stored in 2D array. The program must find the path from start 'S' to goal 'G'. For this, a boolean method called 'solve(int row, int col) is uses and is initialized with row and column index of 'S'. The algorithm must be recursive. It should return true if its able to find the path to 'G' and false other wise. Here's how I tried to approach this problem which shows "partial correct result".

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;
}

Here is the output it solved :

   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

But when I place 'G' one step up (at 6,8). It shows stackOverflow error. The reason is because the recursion occurs between 2 points at this state (somehow just like indirect recursion).

How can I solve this problem. Is there anyway to tell the program to move up instead of down? Changing the position of conditional statements wont work though. And think a position that has more than one path to go but only one leads to 'G'. How to come back to initial position and try anther path ? Thanks in advance.

Update:

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


回答1:


You could fill in an alternate symbol in the spaces you stepped through already so your program will know that it was there already.




回答2:


You can use a DFS or BFS. The DFS is the easiest one. You simply make a recursion, navigate in all 4/8-directions and mark that place (X,Y) as visited. If it's you destiny 'G', return true otherwise continue.

Tips:

  • Don't use the same matrix to read the map and mark it as visited, KISS
  • You have to constantly check if you have discovered G. You can make this by return always FALSE or TRUE, or you can use a global variable.

If you have trouble implementing it try to google for some source code about this problems: http://en.wikipedia.org/wiki/Flood_fill

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




回答3:


In your present code there is a possibility that you return out false without looking at other connected positions.

You should look through other possibilities before returning out from the if condition.
Also, you should check whether the position has been visited to avoid infinite recursion.

Change your code to:

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:


Here is a pseudo code for you to solve the maze and also retrace the solution : -

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);
}



回答5:


Incase you are looking for the complete solution, I have uploaded it on my Github Repository.




回答6:


Inspired by this article Solving a 2D Maze, a recursive solution

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));
})


来源:https://stackoverflow.com/questions/20187547/recursive-algorithm-for-2d-maze

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!