A* 启发式,高估/低估?

Posted

技术标签:

【中文标题】A* 启发式,高估/低估?【英文标题】:A* heuristic, overestimation/underestimation? 【发布时间】:2010-11-04 00:05:32 【问题描述】:

我对高估/低估这两个词感到困惑。我完全了解 A* 算法的工作原理,但我不确定高估或低估启发式算法的影响。

直接鸟瞰线的平方是不是高估了?为什么它会使算法不正确?所有节点都使用相同的启发式。

当您取直接鸟瞰线的平方根时是否低估了?为什么算法仍然正确?

我找不到一篇解释清楚的文章,所以我希望这里有人能给出一个好的描述。

【问题讨论】:

【参考方案1】:

简答

@chaos 的回答有点误导 imo(可以突出显示)

高估并不会使算法“不正确”;这意味着您不再具有可接受的启发式,这是保证 A* 产生最佳行为的条件。使用不可接受的启发式算法,该算法可能最终会做大量多余的工作

@AlbertoPL 暗示

你可以通过高估更快地找到答案,但你可能找不到最短路径。

最终(除了数学最优),最优解很大程度上取决于您是否考虑计算资源、运行时间、特殊类型的“地图”/状态空间等。

长答案

作为一个例子,我可以想到一个实时应用程序,其中机器人通过使用高估启发式算法来更快地到达目标,因为提前开始的时间优势大于采取最短路径但等待更长的时间来计算的时间优势解决方案。

为了给你一个更好的印象,我分享一些我用 Python 快速创建的示例性结果。结果源于相同的 A* 算法,只是启发式不同。每个节点(网格单元)都有边缘到所有八个邻居,除了墙壁。对角边成本 sqrt(2)=1.41

第一张图片显示了一个简单示例案例的算法返回路径。您可以从高估启发式(红色和青色)中看到一些次优路径。另一方面,有多个最优路径(蓝色、黄色、绿色),这取决于先找到哪一个的启发式。

当达到目标时,不同的图像会显示所有展开的节点。颜色显示使用此节点的估计路径成本(考虑从起点到此节点的“已经采用”路径;从数学上讲,它是迄今为止的成本加上该节点的启发式)。该算法在任何时候都会扩展具有最低估计总成本的节点(如前所述)。

1.零(蓝色)

对应于 Dijkstra 算法 扩展节点数:2685 路径长度:89.669

2。乌鸦飞翔时(黄色)

扩展节点数:658 路径长度:89.669

3.理想(绿色)

无障碍最短路径(如果您遵循八个方向) 在不高估的情况下尽可能高的估计(因此是“理想的”) 扩展节点数:854 路径长度:89.669

4.曼哈顿(红色)

没有障碍物的最短路径(如果您不沿对角线移动;换句话说:“沿对角线移动”的成本估计为 2) 高估 扩展节点数:562 路径长度:92.840

5.乌鸦飞十次(青色)

高估 扩展节点数:188 路径长度:99.811

【讨论】:

【参考方案2】:

将启发式视为f(x)=g(x)+h(x),其中g(x) 是从start-nodecurrent-node 的实际成本,h(x) 是从current-nodegoal 的预测成本。假设最优成本为R,则:

    h(x) 在搜索的早期发挥作用。给定三个节点 A,B,C

    (*)                               => current pos: A
     A -------> B - 。。。 -> C
     |_______________________|        => the prediction range of h(x)
    

    一旦你踩到B,从A到B的代价是真相,预测h(x)不再包含它:

               (*)                    => current pos: B
     A -------> B - 。。。 -> C
                |____________|        => the prediction range of h(x)
    

    当我们说低估时,这意味着您的h(x) 将在通往goal 的途中为所有x 引起f(x) < R

    高估确实使算法不正确

    假设R19。鉴于2021 这两个成本是已经达到目标的路径的成本:

    Front                  Rear
     -------------------------        => This is a priority queue PQ.
    | 20 | 20 | 30 | ... | 99 |
      ^--------                       => This is the "fake" optimal.
    

    但是说f(y)=g(y)+h(y)y 确实在实现最优成本R 的正确道路上,但是由于h(y)高估,所以f(y)当前是PQ 中的30,因此在我们将30 更新为19 之前,该算法已经从PQ 中弹出20,并错误地认为它是一个“最佳”解决方案。

【讨论】:

【参考方案3】:

直观答案

要使 A* 正常工作(始终找到“最佳”解决方案,而不仅仅是任何解决方案),您的估计函数需要乐观

这里的乐观意味着您的期望总是优于现实。

乐观主义者会尝试许多最终可能令人失望的事情,但他们会找到所有好的机会。

悲观者期待糟糕的结果,因此不会尝试很多事情。因此,他们可能会错过一些黄金机会。

因此,对于 A* 而言,乐观意味着始终低估成本(即“可能不会那么远”)。当你这样做时,一旦你找到了一条路,那么你可能仍然会对几个未探索的选择感到兴奋,这可能会更好。 这意味着您不会停留在第一个解决方案上,而是仍然尝试其他解决方案。大多数可能会令人失望(不是更好),但它保证您总能找到最佳解决方案。当然,尝试更多选项需要更多的工作(时间)。

悲观 A* 总是会高估成本(例如“那个选项可能很糟糕”)。一旦它找到了解决方案并且知道了路径的真实成本,其他所有路径都会看起来更糟(因为估计总是比实际情况更糟),一旦找到目标,它就永远不会尝试任何替代方案。

最有效的 A* 是一种从不低估的 A*,它要么完美地估计,要么略微过度乐观。那你就不会天真去尝试太多不好的选择了。

对每个人来说都是一个很好的教训。永远保持乐观!

【讨论】:

【参考方案4】:

来自Wikipedia A* article,算法描述的相关部分是:

算法继续进行,直到目标节点的 f 值低于队列中的任何节点(或直到队列为空)。

关键思想是,在低估的情况下,A* 只有在知道路径的总成本将超过通向目标的已知路径的成本时才会停止探索通往目标的潜在路径。由于路径成本的估计值总是小于或等于路径的实际成本,因此只要估计成本超过已知路径的总成本,A* 就可以丢弃路径。

由于高估,A* 不知道何时可以停止探索潜在路径,因为可能存在实际成本更低但估计成本高于当前已知目标路径的路径。

【讨论】:

点了,但我引用的部分是正确的并且与我的答案相关。【参考方案5】:

当启发式的估计值高于实际的最终路径成本时,您就高估了。当它较低时,您低估了(您不必低估,您只需不要高估;正确 估计是可以的)。如果您的图的边成本都是 1,那么您给出的示例将提供高估和低估,尽管普通坐标距离在笛卡尔空间中也很有效。

高估并不会使算法“不正确”;这意味着您不再有一个可接受的启发式,这是保证 A* 产生最佳行为的条件。如果采用不可接受的启发式算法,该算法最终可能会做大量多余的工作来检查它应该忽略的路径,并且可能会因为探索这些路径而找到次优路径。这是否真的发生取决于您的问题空间。之所以会发生这种情况,是因为路径成本与估计成本“脱节”,这基本上让算法搞砸了哪些路径比其他路径更好的想法。

我不确定您是否会找到它,但您可能想查看Wikipedia A* article。我提到(和链接)主要是因为谷歌几乎不可能找到它。

【讨论】:

使用高估的启发式算法应该比使用低估的启发式算法更快地找到(次优)解决方案,不是吗?使用极其低估的启发式算法(例如总是返回 0),可以获得最佳解决方案,但本质上只是进行广度搜索。 @chtz 是的,这是真的。尽管不是最佳解决方案,但您会更快地获得解决方案。相反,这也是 Djisktra 通常比 A* 算法慢的原因,因为启发式始终为 0(我知道,晚了 3 年,但将来可能会帮助其他人阅读本文)。 @chtz:不,它被低估了,这使得搜索可能不是最优的解决方案更快。 Rainning 发表评论时我没有被 ping 通,但今天又重新访问了。低估不会“更快地搜索次优解决方案”。低估实际上提供了最佳解决方案。【参考方案6】:

据我所知,您通常希望低估,以便您仍然可以找到最短路径。您可以通过高估更快地找到答案,但您可能找不到最短路径。因此,为什么高估是“不正确的”,而低估仍然可以提供最佳解决方案。

很抱歉,我无法提供有关鸟瞰线的任何见解...

【讨论】:

如果一个人高估了潜在成本,这意味着该分支的预测成本更大并且不太可能被选择。您确定这会加快搜索速度吗?

以上是关于A* 启发式,高估/低估?的主要内容,如果未能解决你的问题,请参考以下文章

低估和高估的不同成本

王石退休感言:我们往往高估了目前 低估了未来

我们是低估了百度地图,还是高估了高德?

这是一块被低估了的主板!技嘉Z390 AORUS PRO WIFI评测

R语言DALEX包的explain函数生成指定分类预测机器学习模型的解释器predict_diagnostics函数执行残差的局部诊断可视化指定预测变量的局部稳定性图判断预测的稳定性以及高估低估

Node.js被高估了吗