A*路径搜寻算法

原文链接:http://blog.csdn.net/luckyxiaoqiang/article/details/6996963


A*搜寻算法,俗称A星算法。这是一种在图形平面上,有多个节点的路径,求出最低通过成本的算法。常用于游戏中的NPC(Non-Player-ControlledCharacter)的移动计算,或线上游戏的BOT(ROBOT)的移动计算上。该算法像Dijkstra算法一样,可以找到一条最短路径;也像BFS一样,进行启发式的搜索。

A*算法是一种启发式搜索算法,启发式搜索就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标。这样可以省略大量无谓的搜索路径,提高了效率。在启发式搜索中,对位置的估价是十分重要的。采用了不同的估价可以有不同的效果。

A*算法的公式为:f(n)=g(n)+h(n),g(n)表示从起点到任意顶点n的实际距离,h(n)表示任意顶点n到目标顶点的估算距离。 这个公式遵循以下特性:

  • 如果h(n)为0,只需求出g(n),即求出起点到任意顶点n的最短路径,则转化为单源最短路径问题,即Dijkstra算法
  • 如果h(n)<=“n到目标的实际距离”,则一定可以求出最优解。而且h(n)越小,需要计算的节点越多,算法效率越低。

对于函数h(n),估算距离常用的方法有:

  • 曼哈顿距离:定义曼哈顿距离的正式意义为L1-距离或城市区块距离,也就是在欧几里德空间的固定直角坐标系上两点所形成的线段对轴产生的投影的距离总和。例如在平面上,坐标(x1,y1)的点P1与坐标(x2, y2)的点P2的曼哈顿距离为:|x1 - x2| + |y1 - y2|。
  • 欧氏距离:是一个通常采用的距离定义,它是在m维空间中两个点之间的真实距离。在二维和三维空间中的欧氏距离的就是两点之间的距离。例如在平面上,坐标(x1,y1)的点P1与坐标(x2, y2)的点P2的欧氏距离为: sqrt((x1-x2)^2+(y1-y2)^2 )。
  • 切比雪夫距离:是两个向量之间各分量差值的最大值。例如在平面上,坐标(x1, y1)的点P1与坐标(x2, y2)的点P2的切比雪夫距离为:max(|x1 - x2| , |y1 - y2|)。

A*算法实现伪代码:

[cpp]  view plain copy
  1. function A*(start,goal)  
  2.     closedset := the empty set  
  3.     openset := {start}   
  4.     came_from := the empty map  
  5.    
  6.     g_score[start] := 0  
  7.     h_score[start] := heuristic_cost_estimate(start, goal)  
  8.     f_score[start] := g_score[start] + h_score[start]  
  9.    
  10.     while openset is not empty  
  11.         x := the node in openset having the lowest f_score[] value  
  12.         if x = goal  
  13.             return reconstruct_path(came_from, came_from[goal])  
  14.    
  15.         remove x from openset  
  16.         add x to closedset  
  17.         foreach y in neighbor_nodes(x)  
  18.             if y in closedset  
  19.                  continue  
  20.             tentative_g_score := g_score[x] + dist_between(x,y)  
  21.    
  22.             if y not in openset  
  23.                  add y to openset  
  24.                  tentative_is_better := true  
  25.             else if tentative_g_score < g_score[y]  
  26.                  tentative_is_better := true  
  27.             else  
  28.                  tentative_is_better := false  
  29.    
  30.             if tentative_is_better = true  
  31.                  came_from[y] := x  
  32.                  g_score[y] :=tentative_g_score  
  33.                  h_score[y] :=heuristic_cost_estimate(y, goal)  
  34.                  f_score[y] := g_score[y] +h_score[y]  
  35.    
  36.     return failure  
  37.    
  38.  function reconstruct_path(came_from,current_node)  
  39.     if came_from[current_node] is set  
  40.         p := reconstruct_path(came_from, came_from[current_node])  
  41.         return (p + current_node)  
  42.     else  
  43.         return current_node  

下面给出一个A*(曼哈顿距离)的例子:

代表起点,代表终点,代表障碍,代表属于OPENSET,代表属于CLOSEDSET, ——  黄色线段代表最终得出的路径。
方格内左上角代表f(n)即启发函数值,左下角代表g(n),即起点到该点的距离,右下角代表h(n),即该点到终点距离的估值,使用曼哈顿距离,方格上下左右相邻距离为10,对角线相邻为14,曼哈顿距离以10为单位。
(gif动画文件)

demo

A*与Dijkstra,DFS,BFS:

  • A*算法,每次从OPENSET中选择 f(n) 最小的节点将其加入CLOESEDSET中,同时扩展相邻节点,可把OPENSET看成一个优先队列,key值为 f(n),优先级最高的先出。
  • Dijkstra算法,每次从OPENSET中选择 g(n) 最小的节点将其加入CLOSEDSET中,同时扩展相邻节点,可把OPENSET看成一个优先队列,key值为 g(n),优先级最高的先出。
  • DFS算法,每次从OPENSET中选择最晚被加入的节点将其加入CLOSEDSET中,同时扩展相邻节点,可把OPENSET看成一个栈,后进先出。
  • BFS算法,每次从OPENGSET中选择最早被加入的节点将其加入CLOSEDSET中,同时扩展相邻节点,可把OPENSET看成一个队列,先进先出。

下面通过几个例子对比一下5种算法,A*(曼哈顿距离),A*(欧氏距离),A*(切比雪夫距离),Dijkstra,Bi-Directional Breadth-First-Search ,以显示A*算法的优越性。
例一:
1.1 A*(曼哈顿距离)

1.2 A*(欧氏距离)

1.3 A*(切比雪夫距离)

1.4 Dijkstra 

1.5 Bi-Directional Breadth-First-Search


例二:
2.1 A*(曼哈顿距离)

2.2 A*(欧氏距离)

2.3 A*(切比雪夫距离)

2.4 Dijkstra

2.5 Bi-Directional Breadth-First-Search

例三:
3.1 A*(曼哈顿距离)

3.2 A*(欧氏距离)

3.3 A*(切比雪夫距离)

3.4 Dijkstra

3.5 Bi-Directional Breadth-First-Search

例四:

4.1 A*(曼哈顿距离)

4.2 A*(欧氏距离)

4.3 A*(切比雪夫距离)

4.4 Dijkstra

4.5 Bi-Directional Breadth-First-Search

附:
我从网上找到的比较好的一个算法演示程序,下载地址
http://download.csdn.net/detail/walkinginthewind/3822153


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值