Astar算法

来源:互联网 发布:数据的最小单位是( ) 编辑:程序博客网 时间:2024/05/21 02:48

A Star算法是一智能找最短路径算法(下面简称A算法), 与 Dijkstra算法相比,A算法访问的节点比较少,因此可以缩短搜索时间。他的算法思想是:

这里有公式f

         最终路径长度f = 起点到该点的已知长度h + 该点到终点的估计长度g。

         O表(open):

                待处理的节点表。

         C表(close):

                已处理过的节点表。

算法流程:

1. 从起点开始,起点的f = 1 + g,  1表示此节点已走过的路径是1,g是此节点到终点的估计距离, 放入链表O中。

可以假设g值的计算使用勾股定理公式来计算此点到终点的直线距离。

2. 当O不为空时,从中取出一个最小f值的节点x。

3.如果x等于终点,找到路径,算法结束。否则走第4步.

4. 遍历x的所有相邻点,对所有相邻点使用公式f,计算出f值后,

先检查每个相邻节点y是否在链表O和C中,

如果在O中的话的话,更新y节点的f值,保留最小的f值,

如果在C中的话,并且此时f值比C中的f值小,则更新f值,将y节点从C中移到O中。否则不做操作。

如果不在以上两表中,按最小顺序排序将y插入链表O。最后将x插入C表中。

例如:

     起点是 (1,1), 终点是(5,5), 取一个相邻点(0,1), 这时这个点的h=1+1 = 2, g可以用勾股定理公式来计算此点到终点的直线距离,就是 (5-0)*(5-0) - (5-1) *(5-1) = 9, 再开平方等于3,这样f就等于2+3 = 5.然后将此点插入链表O中。

如果相邻点不是路径,比如是障碍,那就跳过。

5.继续2,3,4步直到找到终点, 或者直到O为空表示没找到路径。

上面检查O和C表的原因是:

        如果图是一个不规则的图,比如一个游戏里,有几个传送门,这样同一个点如果经过传送门的话,路径会大大缩短,这样就需要检查O和C表来更新f值,如果是一个不包含捷径(传送门)的图,那样就可以用个数组来标记已访问过的节点,这样就可以不用C表,也不用检查O表来更新f值。

对于没找到路径的结果,访问的节点有可能差不多是所有节点,这样的效率和Dijkstra一样低,我们可以使用同时从两端用A算法来找路径,这样当其中一个没找到路径的话,寻找结束。这样用的时间将是2 * min(S,E)的时间,S是从起点开始寻路径的时间,E是从终点开始寻路径的时间。这样的一个典型的例子是

     终点是个孤立的点,没有任何点能到达他,而其他点都是链接的,那么如果光从起点开始找的话,要到访问完所有除终点之外的点后才知道找不到终点。这样的效率非常差。 如果同时从两端开始找,马上就能知道终点没有任何路径相邻,寻找结束。

    当然从终点反找起点的算法有限制,比如有向图就无法适用。

两端同时查找的算法需要有些改动:

在第3步时,如果是S端的查找过程,则检查x是否存在E端查找过程的C表里,如果存在,则查找到路径。将两个过程已访问的路径合并则是结果。反过来E端的查找过程也一样比较处理。

我用Qt写了一个例子来检验A算法,这里不好附上程序,就附上几张图

Dijkstra搜索的节点图

同样一张图,A Star算法搜索的节点图

原创粉丝点击