回溯 - 在二维网格中找到最佳路径

时间:2018-03-02 14:49:29

标签: java recursion optimization path-finding backtracking

输入:

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

目标是找到从开始(S)到目标(G)的最佳路径。

我们可以向上,向下,向左和向右移动。

成本是路径上所有元素的总和。

我的想法是使用回溯,但到目前为止我只设法找到一条路径,但它远非最佳。

public List<Point> getNeighbours(Point p, int[][] grid) {
    List<Point> neighbours = new LinkedList<>();
    if (p.getX() > 0) {
        neighbours.add(new Position(p.getX() - 1, p.getY()));
    }
    if (p.getX() < grid.length - 1) {
        neighbours.add(new Position(p.getX() + 1, p.getY()));
    }
    if (p.getY() > 0) {
        neighbours.add(new Point(p.getX(), p.getY() - 1));
    }
    if (p.getY() < grid[p.getX()].length - 1) {
        neighbours.add(new Point(p.getX(), p.getY() + 1));
    }
    return neighbours;
}

private class IntBox {
    int value;

    public IntBox(int value) {
        this.value = value;
    }

}

private boolean findPath(int[][] grid, Point current, Point goal LinkedList<Point> path, Set<Point> visited, IntBox minDist, int dist) {
    if (current.getX() == goal.getX() && current.getY() == goal.getY()) {
        minDist.value = Math.min(dist, minDist.value);
        return true;
    }
    for (Point neighbour : getNeighbours(current, grid)) {
        if (visited.contains(neighbour)) {
            continue;
        }
        visited.add(nachbar);
        if (findPath(grid, neighbour, goal, path, visited, minDist, dist+grid[neighbour.getX()][neighbour.getY()])) {
            path.addFirst(nachbar);
            return true;
        }
    }
    return false;
}

1 个答案:

答案 0 :(得分:1)

查看Dijkstra's algorithm或其他shortest path problem solutions

解决方案可能是这样的:

  1. 网格中的每个节点都有两个额外的字段 - 从开始的最小成本和到达起点的最近节点(在最小成本路径上)。
  2. 为可直接从__init__访问的所有节点计算新字段值,然后移至具有最低最低成本值的节点。有关动画示例,请参阅Wikipedia
  3. 当您计算所有节点的值时,您将获得S的值,并且您可以使用新字段跟踪成本最低的路径。