【发布时间】:2018-04-29 10:26:59
【问题描述】:
我最近学习了 A 星算法的 Java 实现,其中输入数据是 20 * 20 网格的形式。
根据A星算法伪代码,选择open list中最终成本最低的节点作为当前要前往的节点。
在真正用 Java 实现算法之前,我经历了许多其他语言的不同实现,比如 ruby、python 和 c++。
在其他语言的实现中常见的一点是,它在遍历路径时坚持将最终成本最低的节点作为新的当前节点的算法方法。
我使用了一个优先级队列来实现这个算法的开放列表,在下面添加了比较器,它给最终成本较低的节点更高的优先级
PriorityQueue<GridPiece> unvisitedNodes = new PriorityQueue<>(10,
(gridPie1, gridPie2) -> ((GridPiece) gridPie1).getFinalCost() >
((GridPiece) gridPie2).getFinalCost()? -1
: ((GridPiece) gridPie1).getFinalCost() < ((GridPiece)
gridPie2).getFinalCost() ? 1 : 0);
但是当我运行算法时,我得到了可能的最长路径。 两个图像的图例是,路径是橙色的,源是粉红色的,目的地是紫色的。
当我针对基于网格的输入研究该算法的 Java 实现时,如果使用优先级队列,它们总是将更高的优先级分配给最终成本较高的节点。我通过将比较器更改为此尝试了这种方法
PriorityQueue<GridPiece> unvisitedNodes = new PriorityQueue<>(10,
(gridPie1, gridPie2) -> ((GridPiece) gridPie1).getFinalCost() <
((GridPiece) gridPie2).getFinalCost()? -1
: ((GridPiece) gridPie1).getFinalCost() > ((GridPiece)
gridPie2).getFinalCost() ? 1 : 0);
然后我会得到更好的路径;
我的简单请求是一个简短的解释,解释为什么当实现完全遵循伪代码时算法没有按预期运行,以及为什么需要切换节点的优先级(更高的最终成本首先到达)在 java 实现中工作的算法?
项目的完整代码可以在here找到。
【问题讨论】:
-
99%ofA*是一个普通的Dijkstra。唯一的区别是它使用 启发式函数 来进行更好的猜测,而不是猜测节点的0成本。一个常见的启发式是 as-the-crow-flies,一个非常好的启发式是 landmarks(例如,贪婪的最远选择)。