为啥A-star算法需要g(n)?

Posted

技术标签:

【中文标题】为啥A-star算法需要g(n)?【英文标题】:Why does the A-star algorithm need g(n)?为什么A-star算法需要g(n)? 【发布时间】:2018-09-20 08:30:14 【问题描述】:

Dijkstra 的算法是f(n) = g(n) A* 是f(n) = g(n) + h(n)

g(n) 是从起始节点到 n 的路径成本。 h(n) 是一个启发式函数,它估计从 n 到目标的最便宜路径的成本。

需要g(n)吗?没有g(n)就不能找到最短路径吗?

为什么 A* 需要 g(n)?

【问题讨论】:

目的是为了更快地实现目标,因此您以您期望朝着正确方向的方式影响它。但当然,解决方案必须相同。 我不知道为什么它更快,你能举个例子吗? 对不起,没有。试想一下,算法沿着边界前进,并且知道该边界内的最佳成本。如果边框向各个方向扩展,则填充它需要更长的时间。 【参考方案1】:

我们需要g(n)

考虑当h(n)0 对于某个给定路径上的所有节点到目标(这是一个完全有效的,即可接受的,启发式的)和所有其他节点非零的情况。

如果我们忽略到目前为止的成本 (g(n)),显然我们将选择这条路径上的节点,无论 实际 成本是多少,所以我们最终得到的路径可以有成本比其他路径高得多。

               start
       g(n)=0    O --
               5 |   \ 1
h(n)=0,g(n)=5    O    O h(n)=1,g(n)=1
               5 |   / 1
h(n)=0,g(n)=10   O --
               goal

在上面的例子中,我们将选择左边的节点,然后是目标,因为h(n) = 0 代表两者(大于h(n) = 1 代表右边的节点)。这将为我们提供一条成本为10 的路径,其中最便宜的路径涉及选择右侧的节点,成本为2

这可能是一个极端的例子,但同样的想法也适用于许多其他情况。例如,您还可以在我的示例中为所有值添加 10,并将其作为更大图表的一部分,但最终仍会错误地选择左侧高于右侧。

这里更一般的结论是,您可以在n1n2 两个节点之间进行选择,其中h(n1) < h(n2),因此我们将选择n1,但n2 是最便宜的路径,而不是n1.

如果我们包含g(n),我们也会选择错误的节点。但是,在这种情况下,对于包含n1 的路径上的某些节点nf(n) 将大于最便宜的路径(在最坏的情况下,n 将是目标,f(n) 将是真实的通过n1 到达它的成本,这显然比实际最便宜的路径更昂贵),因此也高于f(n2)(因为启发式需要低估成本),所以我们将在到达之前探索n2目标。

如果h(n) 是真正的成本(而不是估计

那么我们确实不需要g(n)

但仅考虑h(n) 在这种情况下将使其成为一个贪心算法(假设非负边权重),因为h(n) 会随着我们选择的每个节点而减少(因为我们正在接近目标),所以在我们将在最佳路径上选择一个起始节点(因为它将具有最低的h(n)),然后我们将继续在最佳路径上选择节点。

【讨论】:

您只考虑极端情况“h 是无用的”和“h 是完美的”,但同样适用于例如h 对于队列中的两个节点来说是相同的值,但是这些节点的 g 是不同的。 @tobias_k 已编辑。

以上是关于为啥A-star算法需要g(n)?的主要内容,如果未能解决你的问题,请参考以下文章

在协调无向图上计算 A*(A-star) 算法中的 f 成本

A*算法基本原理

Dijkstra 的算法和 A-Star 的比较如何?

A*算法导航网格路径点寻路对比(A-Star VS NavMesh VS WayPoint)

一次性算法(需要说明) 为啥空间复杂度为 O(1)?

弗洛伊德(Floyd)算法