查找网格中2个节点之间路径的最有效方法

时间:2012-02-12 17:26:23

标签: java algorithm path-finding

我一直很好奇这个特殊问题是如何得到最好的解决的。关于我的问题,我可以找到关闭的东西是管道游戏概念,see screenshot

我有一个10x10的网格。网格的每个矩形都可以连接到网格左侧有1到4条边(没有对角线,只有顶部,机器人,左,右)的相邻字段,可以有10个起点,每行一个,然后打开右边的10个端点在网格的每一行中也是1个。

现在我的问题是:找到从起点到任何终点的所有可能路径以及所有死路径(有几个点连接到起点的路径)的最有效方法是什么点,但没有连接到任何终点)?

我已经尝试过广度优先的搜索算法来查找它们之间的所有路径,但是有没有更好的选择我可以试用?

2 个答案:

答案 0 :(得分:2)

通常A*比BFS快得多,用于在图表上找到最短路径

A *要求你有一个admissible heuristic function [manhattan distance启发式通常可以应用于网格],并且通常比BFS快得多,因为它被告知 - 因此它优先考虑调查节点这更有可能带来更好的解决方案。

请注意,A *也是完整的[找到路径,如果有的话],也是最优的[找到短路路径]。

修改
A *还允许更多的时间/性能交易:例如:通过使用weighted A*,您将获得非最佳解决方案,但您可能会更快地获得它。

注意,对于不知情的A * [h=0],通过调用A *得到一个dijkstra,这正是非加权边缘的BFS

答案 1 :(得分:1)

如果从广度优先开始,则首先收集长度为1的路径,然后是2,3,4等等。在从长度k到k + 1的下一步中,只有在某个路径中尚未使用终点时,才将端点添加到某个路径。这可以保证您丢弃较少或同样最佳的路径。

在原点旁边,所有路径点都有一个明确的进入边缘。因此,作为数据结构,可以存储每个点的进入边缘(或no_incoming)。 这会丢弃同样最佳的路径。

案例:路径同等优化 同样最佳的路径可以在数据中表示为具有多个进入边缘的点。 从长度k到k + 1收集所有新的终点。

  • 如果候选终点存在于路径中但不存在于新的(k + 1)个长终点中,则它是次优路径,并且被丢弃。递归失败。
  • 如果候选终点是新鲜的,则找到新的最佳路径。递归继续。
  • 如果候选终点仅存在于新的终点中,则找到替代的最佳路径。递归也会停止。

一些代码

public void determineAllPaths(Grid grid, Point origin) {
    this.grid = grid;
    this.origin = origin;
    grid.setOnPath(origin, null); // to, from
    Set<Point> priorEndPoints = Collections.singleton(origin);
    determinePaths(priorEndPoints);
}

private void determinePaths(Set<Point> priorEndPoints) {
    if (priorEndPoints.isEmpty())
        return;
    Set<Point> nextEndPoints = new HashSet<Point>();
    for (Point priorEndPoint : priorEndPoints) {
        for (Point nextEndPoint : priorEndPoint.naybours()) {
            if (grid.isOnPath(nextEndPoint)
                    && !nextEndPoints.contains(nextEndPoint)) {
                continue;
            }
            //if (nextEndPoints.contains(nextEndPoint)) {
            //    continue;
            //}
            grid.setOnPath(nextEndPoint, priorEndPoint); // to, from
            nextEndPoints.add(nextEndPoint);
        }
    }
    determinePaths(nextEndPoints);
}