【问题标题】:A-star algorithm java implementation explainedA-star算法java实现讲解
【发布时间】: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% of A* 是一个普通的Dijkstra。唯一的区别是它使用 启发式函数 来进行更好的猜测,而不是猜测节点的 0 成本。一个常见的启发式是 as-the-crow-flies,一个非常好的启发式是 landmarks(例如,贪婪的最远选择)。

标签: java algorithm a-star


【解决方案1】:

优先级队列的头部是相对于给定顺序的最小元素。当第一个元素的成本大于第二个元素的成本时,您的比较器返回 -1。换句话说,您将最高成本元素放在首位。这就是为什么排在最前面的网格饼的成本最高。

在您的第二个实现中,当第一个元素的成本小于您想要的第二个元素的成本时,比较器返回 -1。

如果您只是按成本排序(大概是一个 int?),那么您可以这样做:

new PriorityQueue<GridPiece>(Comparator.comparingInt(GridPiece::getFinalCost));

很少有理由指定初始容量。对于像您这样的小网格,只需使用默认容量即可保持简单。

【讨论】:

  • 非常感谢!一定会调查的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-27
  • 1970-01-01
  • 1970-01-01
  • 2011-06-05
  • 1970-01-01
相关资源
最近更新 更多