我一直很好奇这个特殊问题是如何得到最好的解决的。关于我的问题,我可以找到关闭的东西是管道游戏概念,see screenshot
我有一个10x10的网格。网格的每个矩形都可以连接到网格左侧有1到4条边(没有对角线,只有顶部,机器人,左,右)的相邻字段,可以有10个起点,每行一个,然后打开右边的10个端点在网格的每一行中也是1个。现在我的问题是:找到从起点到任何终点的所有可能路径以及所有死路径(有几个点连接到起点的路径)的最有效方法是什么点,但没有连接到任何终点)?
我已经尝试过广度优先的搜索算法来查找它们之间的所有路径,但是有没有更好的选择我可以试用?
答案 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收集所有新的终点。
一些代码
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);
}