动态编程过程

时间:2017-08-04 16:12:09

标签: java recursion dynamic-programming

我正在尝试实施此问题的解决方案,但我遇到了一些问题。

问题是:

  

“网格的左上角有一个机器人,有r行和c列。机器人只能向右或向下移动,某些单元格是”不受限制“,这意味着机器人无法踩到它们。算法从左上角到右下角找到机器人的路径。“

解决方案如下所示:

public static ArrayList<Point> getPath(boolean[][] maze){
   if(maze == null || maze.length==0) return null;
      ArrayList<Point> path = new ArrayList<Point>();
      HashSet<Point> failedPoints = new HashSet<Point>();
   if(getPath(maze, maze.length-1,maze[0].length-1,path,failedPoints)){
      return path;
   }
   return null;
}

public static boolean getPath(boolean[][] maze, int row, int col, 
   ArrayList<Point> path, HashSet<Point> failedPoints){
   /*if out of bounds or not available, return*/
   if(col<0 || row<0 || !maze[row][col]){
      return false;
   }
   Point p = new Point(row,col);
   /*If we've already visited this cell return*/
   if(failedPoints.contains(p)){
      System.out.println("Worked");
      return false;
   }

   boolean isAtOrigin = (row == 0) && (col == 0);

   /*If there's a path from start to my current location, add my location.*/

   if(isAtOrigin || getPath(maze,row,col -1, path, failedPoints) || getPath(maze,row-1, col, path,failedPoints)){
      path.add(p);
      return true;
   }
   failedPoints.add(p); //Cache result
   return false;
}

让我感到困惑的是动态编程的尝试。

  

if(failedPoints.contains(p))永远不会评估为true

我已经重写了我的Point类中的equalshashCode方法,因此每当被比较的对象具有相同的row和col值时,failedPoints.contains(object)的计算结果为true。

也许这与我正在使用的迷宫输入有关:

    boolean[][] maze = new boolean[4][4];
    java.util.Arrays.fill(maze[0],true);
    java.util.Arrays.fill(maze[1],true);
    java.util.Arrays.fill(maze[2],true);
    java.util.Arrays.fill(maze[3],true);

    maze[0][1] = false;
    maze[3][2] = false;
    ArrayList<Point> path =  getPath(maze);

但我不确定。最后,我看不出failedPoints.contains(p)如何将计算机保存在任何执行步骤

这是点类:

public class Point {
    int row;
    int col;

    Point(int row1,int col1) {
        row = row1;
        col = col1;
    }

    public boolean equals(Object o) {
        if (!(o instanceof Point)) return false;
        Point comp = (Point) o;
        return comp.row == row && comp.col == col;
    }

    public int hashCode() {
        return row;
    }
}

1 个答案:

答案 0 :(得分:2)

这是你迷宫的设计。

这是你的迷宫,根据你在问题中写的输入:

  

E O O O

     

O O O O

     

O O X X

     

O O X S

您从S开始,并尝试触及E,其中X为非限制位置。

因此,您可以看到S完全被限制点覆盖,您无法触及E。因此,第一个点S是一个永不重复使用的失败点,因为在评估S之后算法停止。

也许如果您将0 th 行和1 st 列中的点设置为关闭限制,您将有多个探索将达到这一点并利用缓存以确定这一点不能再用于探索迷宫。

<强>更新

在您更新迷宫之后,我意识到您的实施存在两个问题,而不是一个。

更改行

if(isAtOrigin || getPath(maze,row,col -1, path, failedPoints) || getPath(maze,row-1, col, path,failedPoints))

if(isAtOrigin || getPath(maze,row-1,col, path, failedPoints) || getPath(maze,row,col-1, path,failedPoints))

并且代码实际上将与新的迷宫一起使用。

问题是,一旦找到路径,您就会从getPath()返回。并且因为你首先要离开然后再上升,所以点[0,2](这是一个失败的点)根本没有被击中,因此没有被缓存,因此也没有被使用。

更改if条件会导致算法首先搜索,然后向左搜索。这会导致您多次点击[0,2],导致它被缓存并在进一步的路径搜索中重复使用。