如何计算*算法中的启发式值?

时间:2017-11-25 11:35:25

标签: algorithm graph

我正在做一个在最短路径问题中编码A *算法的项目。为了能够使用A *算法确定最短路径,我承认我们必须首先获得启发式值。有谁知道如何计算和确定每个节点的启发式值? [我自己制作了地图,因此没有给出启发式值]

2 个答案:

答案 0 :(得分:5)

A *和启发式

A*始终需要启发式,它是使用距离的启发式值定义的。 A*原则上只是普通的 Dijkstra算法,使用距离的启发式猜测。

启发式函数应该在O(1)查询时快速运行。否则你不会从中受益。作为启发式,您可以选择每个功能 h

  • h 可以接受h(u) <= dist(u, t)(永不高估)
  • h 单调h(u) <= cost(u, v) + h(v)(三角不等)

然而,在实践中经常使用一些启发式方法,如:

  • 直线距离(如同苍蝇)
  • 地标启发式(预计算所有节点到一组选定节点(地标)的距离)

根据您的应用程序,您可能还会发现其他有用的启发式函数。

直线启发式

直线距离(或苍蝇)很简单,易于计算。对于两个节点v, u,您知道确切的位置,即经度纬度

然后,您可以通过将h定义为Euclidean distance来计算直线距离,或者如果您想要更精确的结果,则不要忽略以下事实:地球是一个球体并使用Great-circle distance。这两种方法都在O(1)

中运行

地标启发式

在此处预先选择图表中的一些重要节点。理想情况下,您总是选择一个常用最短路径的节点。

但是,这些知识通常不可用,因此您只需选择距离其他所选地标最远的节点。您可以使用贪婪最远的选择(选择最大化min_l dist(l, u)的节点,其中l已经选定了地标)。因此,您可以从集合执行 Dijkstra,这非常容易实现。只需将多个节点一次添加到 Dijkstra 起始队列(所有当前地标)中。然后运行 Dijkstra 直到计算完所有距离并选择最短路径距离的节点作为下一个标志。因此,你的地标在整个图表中均匀分布。

选择地标后,您预先计算从所有地标到所有其他节点的距离,反之亦然(从所有节点到所有地标)和存储它们。因此,只需从地标开始运行 Dijkstra ,直到计算出所有距离。

任何节点h的启发式u,其中v是目标节点,然后定义如下

h(u) = max_l(max(dist(u, l) - dist(v, l), dist(l, v) - dist(l, u)))

或仅用于无向图

h(u) = max_l|dist(l, u) - dist(l, v)|

其中max_l是最大化论证的里程碑。

在预先计算所述距离后,该方法显然也会在O(1)中运行。但是,预计算可能需要一分钟或更长时间,但这应该没有问题,因为您只需要计算一次,然后再不需要在查询时再计算。

请注意,您还可以选择随机的地标,这样更快但结果可能会有所不同。

比较

前段时间我创建了一个图像,该图像比较了我实现的一些最短路径计算算法(PathWeaver at GitHub)。这是图像:

Comparison

您会看到从左上角到右下角(城市内)的查询。标记为使用的算法访问的所有节点。 标记越快算法找到最短路径。

比较算法

  • 普通Dijkstra(基线,访问具有该距离的所有节点)
  • 带有直线启发式的A *(不是对道路网络的良好估计)
  • 带地标的A *(随机计算)(好)
  • 带地标的A *(最贪婪选择)(好)
  • Arc-Flags(好的)

请注意, Arc-Flags 是一种不同的算法。它想拥有一个区域,就像一个城市周围的矩形。然后选择所有边界节点(矩形内部的节点,但最小化到外部节点的距离)。使用这些边界节点,它执行反向Dijkstra (反转所有边缘,然后运行Dijkstra)。通过它,您可以有效地预先计算从所有节点到边界的最短路径。然后标记作为这种最短路径的一部分的边缘(标记弧)。在查询时,您运行一个普通的Dijkstra但只考虑标记的边。因此,您遵循到边界的最短路径。

此技术可以与A*之类的其他技术结合使用,您可以选择许多不同的矩形,就像所有常用的城市一样。

还有我认识的另一种算法(但从未实施过),它被称为Contraction Hierarchies,它利用了这样一个事实:你通常从小镇道路开始,然后转向更大的道路,然后是高速公路,反之亦然,直到你到达目的地。因此,它为每个边缘提供级别,然后首先尝试尽可能快地达到高级别,并尝试尽可能长时间地保持它。

因此预先计算快捷方式,它们是表示最短路径的临时边缘,例如超级公路

底线

启发式算法以及一般算法的正确选择在很大程度上取决于模型

正如在道路网络中看到的那样,特别是在较小的城镇附近,直线启发式并不能很好地发挥作用,因为通常没有直线的道路。此外,对于长距离,您往往首先开车到高速公路上,这有时意味着向相反方向行驶几分钟。

然而对于游戏来说,你经常可以在你喜欢的地方移动直线表现得更好。但是,只要你引入可以更快行驶的道路(比如使用汽车),或者如果你有很多像大山一样的障碍物,那么它可能会再次变坏。

Landmark启发式在大多数网络上运行良好,因为它使用真实距离。但是,由于需要保存所有预先计算的数据,因此您需要预先计算并交换一些空间。

答案 1 :(得分:0)

启发式值完全依赖于域,尤其是可接受的值(A *需要)。因此,例如,在地理地图上找到最短路径可能涉及两个节点之间的直线距离的启发式,这可以通过计算两点的(纬度,经度)之间的欧几里德距离来很好地近似。