【问题标题】:Is A* really better than Dijkstra in real-world path finding?在现实世界的寻路中,A* 真的比 Dijkstra 更好吗?
【发布时间】:2013-04-07 20:53:45
【问题描述】:

我正在开发一个寻路程序。理论上说A*优于Dijkstra。事实上,后者是前者的特例。但是,在现实世界中进行测试时,我开始怀疑 A* 真的更好吗?

我使用了纽约市的数据,来自9th DIMACS Implementation Challenge - Shortest Paths,其中给出了每个节点的经纬度。

在应用A*时,我需要计算两点之间的球面距离,使用Haversine Formula,其中涉及sin、cos、arcsin、平方根。所有这些都非常非常耗时。

结果是,

使用 Dijkstra:39.953 毫秒,扩展 256540 个节点。

使用 A*,108.475 毫秒,扩展 255135 个节点。

注意到在 A* 中,我们扩展了更少的 1405 个节点。但是,计算启发式的时间远比节省的时间多。

据我了解,原因是在一个非常大的实数图中,启发式的权重会非常小,其影响可以忽略不计,而计算时间占主导地位。

【问题讨论】:

  • It is said theoretically that A* is better than Dijkstra -- 请引用。另外,“更好”是指更快,对吧?你的意思是比 Big O 更快吗?
  • @RobertHarvey,取 A* 并给出启发式为h(node) = 1 and h(goal) = 0。然后将 A* 简化为 dijkstra。因此,由于 A* 可以模拟 dijkstra,因此它要么同样强大,要么更好。
  • 我已经在 J​​ava 中为现实世界的道路网络实现了 A* 和 Dijkstra(参见 graphhopper)。 A* 快了近 2 倍。双向 A* 到 bidir Dijkstra 并没有给我带来如此大的提升
  • 算法的性能很大程度上取决于它的实现
  • @HanXu A* “仅”比普通的 Dijkstra 好,前提是只需要检查一小部分节点。这就是启发式的全部目的。但是您的数字表明,您使用两种算法检查的节点数量大致相同。这对我来说听起来很假。

标签: algorithm dijkstra a-star


【解决方案1】:

我认为您或多或少错过了 A* 的要点。它旨在成为一种性能非常好的算法,部分原因是故意做更多的工作,但使用廉价的启发式算法,当你用繁重的极其准确的预测启发式算法对其进行负担时,你有点把它撕成碎片。

对于 A* 中的节点选择,您应该只使用距离的近似值。简单地使用 (latdiff^2)+(lngdiff^2) 作为近似距离应该会使您的算法比 Dijkstra 更高效,并且在任何现实世界场景中都不会给出更糟糕的结果。实际上,如果您使用 Haversine 正确计算 selected 节点上的行进距离,结果甚至应该完全相同。只需使用便宜的算法来选择潜在的下一次遍历。

【讨论】:

  • 除此之外,A* 对启发式算法的所有要求就是它永远不会高估距离。因此,对于启发式方法,使用欧几里得距离是完美的admissible
  • 作为我自己答案的一个小补充:请注意,我什至不建议取近似距离的平方根 - 这是 CPU 不必要的负担,因为您需要的只是相对距离,而不是绝对的,所以为了比较,它同样可用。
  • @Niels 不会将“不精确”与“启发式”混为一谈。如果启发式是可接受的,A* 可以是 100% 准确的(对于我的 graphhopper 实验来说更快)!
  • @Karussell 正确,这就是为什么我说“结果应该完全相同”。
  • @Niels:为了允许 A* 启发式算法,它绝不能高估到目标的距离。您提出的启发式 (dx^x+dy^2) 通常高估距离,除非您取平方根 - 因此,如果您使用该函数,则不再保证找到最佳解决方案作为你的启发式。
【解决方案2】:

A* 可以通过设置一些琐碎的参数来简化为 Dijkstra。在 Dijkstra 上没有改进的三种可能方式:

  1. 使用的启发式方法不正确:它不是所谓的可接受启发式方法。 A* 应使用不会高估目标距离的启发式算法作为其成本函数的一部分。
  2. 启发式计算成本太高。
  3. 现实世界的图结构是特殊的。

对于后者,您应该尝试以现有研究为基础,例如Abraham 等人的“高速公路维度、最短路径和可证明有效的算法”

【讨论】:

    【解决方案3】:

    就像宇宙中的所有事物一样,需要权衡取舍。您可以使用 dijkstra 的算法精确计算启发式,但这会破坏目的,不是吗?

    A* 是一种很棒的算法,因为它使您倾向于具有一般首先扩展哪个方向的目标。也就是说,您应该使启发式方法尽可能简单,因为您所需要的只是一个大方向。

    其实,不基于实际数据的更精确的几何计算,不一定能给你更好的方向。只要它们不是基于数据,所有这些启发式方法都会为您提供一个同样(不)正确的方向。

    【讨论】:

      【解决方案4】:

      一般而言,A* 比 Dijkstra 的性能更高,但它确实取决于您在 A* 中使用的启发式函数。您需要一个乐观的 h(n) 并找到最低成本路径,h(n) 应该小于真实成本。如果 h(n) >= cost,那么您最终会遇到您所描述的情况。

      你能发布你的启发式函数吗?

      【讨论】:

        【解决方案5】:

        还要记住,这些算法的性能很大程度上取决于图的性质,这与启发式的准确性密切相关。

        如果您在导航出迷宫时比较 Dijkstra 与 A*,其中每个通道对应于单个图形边缘,性能可能几乎没有差异。另一方面,如果图在“远”节点之间有许多边,则差异可能非常显着。想象一个机器人(或人工智能控制的计算机游戏角色)在几乎开放的地形中航行,有一些障碍物。

        我的观点是,尽管您使用的纽约数据集绝对是“真实世界”图的一个很好的例子,但它并不能代表所有真实世界的寻路问题。

        【讨论】:

          猜你喜欢
          • 2011-02-20
          • 2012-03-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-19
          • 2013-11-19
          • 1970-01-01
          相关资源
          最近更新 更多