A*算法,作为启发式搜索算法中的一种,这是一种在图形平面上,有多个节点的路径,求出最低通过成本的算法。A*算法是把启发式方法(heuristic approaches)如BFS(完全使用贪心策略),和常规方法如Dijsktra算法结合在一起的算法。有点不同的是,类似BFS的启发式方法经常给出一个近似解而不是保证最佳解。然而,尽管A star基于无法保证最佳解的启发式方法,A star却能保证找到一条最短路径。
A*算法最为核心的部分,就在于它的一个估值函数的设计上: f(n)=g(n)+h(n)
其中f(n)是每个可能试探点的估值,它有两部分组成:
1)一部分,为g(n),它表示从起始搜索点到当前点的代价(通常用某结点在搜索树中的深度来表示);
2)另一部分,即h(n),它表示启发式搜索中最为重要的一部分,即当前结点到目标结点的估值;
h(n)设计的好坏,直接影响着具有此种启发式函数的启发式算法的是否能称为A*算法。
一种具有f(n)=g(n)+h(n)策略的启发式算法能成为A*算法的充分条件是:
1、搜索树上存在着从起始点到终了点的最优路径。
2、问题域是有限的。
3、所有结点的子结点的搜索代价值>0。
4、h(n)=<h*(n) (h*(n)为实际问题的代价值)。
当此四个条件都满足时,一个具有f(n)=g(n)+h(n)策略的启发式算法能成为A*算法,并一定能找到最优解。
对于一个搜索问题,显然,条件1,2,3都是很容易满足的,而条件4: h(n)<=h*(n)是需要精心设计的,由于h*(n)显然是无法知道的,所以,一个满足条件4的启发策略h(n)就来的难能可贵了。
算法流程
我们可以按照如下步骤,执行A*搜索算法:
- 将起点a放入到“开放列表”(open list)中,
- 重复如下过程:
①遍历开放列表,计算列表中每一个节点s的评价函数f(s)。查找f(n)值最小的节点n,把它作为当前要处理的节点。
②对当前节点n中,与之相邻的其他所有节点,做如下操作:
- 若节点b是不可抵达的(unreachable),或者在关闭列表(closed list)中,忽略它。否则,做如下操作。
- 若节点c不在开放列表中,则将其加入开放列表,并将当前节点n设置为其父亲节点。计算节点b的和f(b),g(b)和ℎ(b)。
- 若节点d已经在开放列表中,则需要检查这条路径(节点n到节点d的路径)是否更好。参考指标为g值,若g更小,则说明该路径更好。若这条路径更好,则将它的父亲节点(设为节点e)设置为当前节点,并重新计算和f(e)和g(e)。
③将n移动到“关闭列表”(closed list)中。关闭列表中的所有元素已经不需要被关注。
3. 当满足如下条件中的一个时,程序终止。
- 将终点加入到了开放列表中(此时路径已经找到了)。
- 无法查找到终点,并且此时开放列表是空列表(此时没有路径)。
4. 若终点已经找到,查找最短路径:从终点开始,每个节点都沿着父亲节点移动,直到起点。