寻找递归迷宫的解决方案路径

时间:2015-10-17 06:41:16

标签: java recursion

我必须编写一个递归方法,找到从位置(行,列)到目标位置的路径,用' G'标记,并返回由字符' U&组成的字符串#39;,' R',' D',' L'以及最后的' G',表示解决方案路径。

我的代码适用于从角落和边缘开始但迷宫失败的迷宫,例如这个迷宫

##########
#        #
#   ###  #
#   #  G #
#   #    #
#        #
#        #
#  #######
#   S    #
##########

当我用如上所述的迷宫测试我的代码时,我得到这样的输出。路径将一直向右,直到它撞到墙壁然后停止。

Solution Path: RRRR
##########
#        #
#   ###  #
#   #  G #
#   #    #
#        #
#        #
#  #######
#   S... #
##########

我不明白如何制作,以便方法知道正确的解决方案路径不正确。我在这里读到,递归方法可以回溯到之前的调用,知道某个方向是错误的,但我不明白如何让我的方法做到这一点。

 public String findPathFrom(int row, int col){

    if(row > mapHeight || col > mapWidth){
        return "";
    }
    if(map[row][col] == '#' || map[row][col] == '.'){
        return "";
    }
    if(map[row][col] == 'G'){
        solved = true;
        return "G";
    }
    if(map[row][col] != 'S'){
        map[row][col] = '.';
    }
    if(map[row-1][col] == ' ' || map[row-1][col] == 'G'){
        return "U" + findPathFrom(row-1, col);
    }
    if(map[row][col+1] == ' ' || map[row][col+1] == 'G'){
        return "R" + findPathFrom(row, col+1) ;
    }
    if(map[row+1][col] == ' ' || map[row+1][col] == 'G'){
        return "D" + findPathFrom(row+1, col);
    }
    if(map[row][col-1] == ' ' || map[row][col-1] == 'G'){
        return "L" + findPathFrom(row, col-1);
    }
    else{
        map[row][col] = ' ';
        return "";
    }
}

我还是java的新手,很抱歉,如果我使用的条款不正确。

2 个答案:

答案 0 :(得分:2)

您的算法缺少探索不同路径的逻辑。 它总是沿着它看到的第一个可用方向(向上/向右/向下/向左)。也就是说,当向上和向右可用时,它会上升,而不是向右。如果后来发现up没有达到解决方案,它就会停止。这是一个更简单的网格来演示这个问题:

###
# #
#S#
#G#
###

你的算法会上升然后卡住, 没有其他地方可以从上升。 如果它从下降开始就会有所不同。 但从长远来看,不可能知道哪个方向最好。 (问题不在于检查可用空间的顺序。)

要解决此问题,请查看广度优先搜索。 我们的想法是同时跟踪所有可用的方向, 当任何路径到达解决方案时,问题就解决了。

答案 1 :(得分:1)

您的findPathFrom函数需要向其调用者指示它是否成功,并且只有在成功时才提前返回。我通常会将它设置为boolean函数并将路径存储在其他位置,但为了保持与代码的接近,您可以返回成功路径的字符串,以及失败的空字符串。

public String findPathFrom(int row, int col){

  // goal / out of bounds checks - same as existing code
  // ... "G" for success / "" for failure
  if(row > mapHeight || col > mapWidth){
    return "";
  }
  if(map[row][col] == '#' || map[row][col] == '.'){
    return "";
  }
  if(map[row][col] == 'G') {
    return "G";
  }

  // no special treatment for starting point - do that in the calling code
  map[row][col] = '.';

  // recursive path search
  String pu = findPathFrom(row-1, col);
  if (!pu.isEmpty()) {
    return "U" + pu;
  }
  String pr = findPathFrom(row, col+1);
  if (!pr.isEmpty()) {
    return "R" + pr;
  }
  String pd = findPathFrom(row+1, col);
  if (!pd.isEmpty()) {
    return "D" + pd;
  }
  String pl = findPathFrom(row, col-1);
  if (!pl.isEmpty()) {
    return "L" + pl;
  }

  // reset the current cell
  map[row][col] = ' ';
  return "";
}

关键是,如果其中一个找到解决方案,您只能从递归调用中提前返回。在您的代码中,无论是否成功,您总是直接从findPathFrom的呼叫返回,因此一旦失败,下一次将永远不会尝试。

有关类似问题,请参阅Java Recursive Maze Solver problems,并对该算法进行更多讨论。