2013-11-25 101 views
2

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

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)。它显示堆栈溢出错误。原因是因为递归发生在这个状态的2个点之间(不知怎的,就像间接递归一样)。

我该如何解决这个问题。无论如何要让程序向上移动而不是向下移动?改变条件语句的位置不会工作。并且认为一个有多条路径但只有一条导致'G'的位置。如何回到初始位置并尝试另一条路径?提前致谢。

更新:

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

回答

1

在你目前的代码中有你回到了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; 
+0

我会尝试,看看它是否工作。 –

+0

绝对,它现在工作! –

5

你可以在你通过加强空间的替代符号填写已经使你的程序就知道它在那里了。

+0

对我来说听起来不错,imma试试。谢谢! –

0

您可以使用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/

0

下面是一个伪代码为您解决了迷宫,也追溯解决方案: -

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

柜面您正在寻找完整的解决方案,我已经上传它在我的Github Repository

0

本文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)); 
 

 
\t 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 = [ 
 
\t [1,0], 
 
    [1,1], 
 
    [2,1], 
 
    [0,0], 
 
    [5,5] 
 
]; 
 

 
testStart.forEach(function(start, i) { 
 
\t console.log("Test Case:",i); 
 
    console.log("\tStart -", start, "Path -", findPath(maze, start)); 
 
})