A∗算法

\(A*\) 算法

这个算法其实就是 dijkstra 的变种,是对于一般的 bfs 的一种优化手段。

首先需要设置一个东西叫做估价函数。普通的 bfs 的估价函数一般取 \(0\)。这个东西如果你要保证一定正确,记起点到当前点的距离为 \(d[i]\),到末尾的真实距离为 \(g[i]\),设你的估价函数是 \(f[i]\),则 \(f[i]\le g[i]\) 就能保证正确。下面我们来证明一下这个结论:

反证法,假设不成立,即当前出队的终点距离不是最优解,即 \(dist>d_{\text{最优}}\),我们设最优解路径上有一点 \(u\),则必有 \(d[u]+f[u]\le d[u]+g[u]=d_{\text{最优}}\),所以 \(dist>d_{\text{最优}}\ge f[u]\)

而且 A* 算法只能保证终点是最优的,但不能保证中途其他点是最优的。(入队、出队都不一定是最优,且最多保证路径上的点)
img
如图所示,如果某一个点的估价距离等于它的真实距离都为 \(L\),其他点的估价都是 \(0\),那么就会先从上面一圈绕过来走到后面很远很远的点才发现是错的,所以那个圈和直线交界的位置第一次出队的结果就不是最优解。

可以加一个优化:当一个点的最短距离更新时将其塞入堆中。

估价函数必须非 负

bfs dijkstra \(A*\)
判重 入队判重 出队判重 不能判重
posted @ 2023-05-10 22:31  wscqwq  阅读(17)  评论(0编辑  收藏  举报