A*路径搜寻算法
2015-09-18 16:10
288 查看
原文链接: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
plaincopy
function A*(start,goal)
closedset := the empty set
openset := {start}
came_from := the empty map
g_score[start] := 0
h_score[start] := heuristic_cost_estimate(start, goal)
f_score[start] := g_score[start] + h_score[start]
while openset is not empty
x := the node in openset having the lowest f_score[] value
if x = goal
return reconstruct_path(came_from, came_from[goal])
remove x from openset
add x to closedset
foreach y in neighbor_nodes(x)
if y in closedset
continue
tentative_g_score := g_score[x] + dist_between(x,y)
if y not in openset
add y to openset
tentative_is_better := true
else if tentative_g_score < g_score[y]
tentative_is_better := true
else
tentative_is_better := false
if tentative_is_better = true
came_from[y] := x
g_score[y] :=tentative_g_score
h_score[y] :=heuristic_cost_estimate(y, goal)
f_score[y] := g_score[y] +h_score[y]
return failure
function reconstruct_path(came_from,current_node)
if came_from[current_node] is set
p := reconstruct_path(came_from, came_from[current_node])
return (p + current_node)
else
return current_node
下面给出一个A*(曼哈顿距离)的例子:
■代表起点,■代表终点,■代表障碍,■代表属于OPENSET,■代表属于CLOSEDSET, ——
黄色线段代表最终得出的路径。
方格内左上角代表f(n)即启发函数值,左下角代表g(n),即起点到该点的距离,右下角代表h(n),即该点到终点距离的估值,使用曼哈顿距离,方格上下左右相邻距离为10,对角线相邻为14,曼哈顿距离以10为单位。
(gif动画文件)
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
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
plaincopy
function A*(start,goal)
closedset := the empty set
openset := {start}
came_from := the empty map
g_score[start] := 0
h_score[start] := heuristic_cost_estimate(start, goal)
f_score[start] := g_score[start] + h_score[start]
while openset is not empty
x := the node in openset having the lowest f_score[] value
if x = goal
return reconstruct_path(came_from, came_from[goal])
remove x from openset
add x to closedset
foreach y in neighbor_nodes(x)
if y in closedset
continue
tentative_g_score := g_score[x] + dist_between(x,y)
if y not in openset
add y to openset
tentative_is_better := true
else if tentative_g_score < g_score[y]
tentative_is_better := true
else
tentative_is_better := false
if tentative_is_better = true
came_from[y] := x
g_score[y] :=tentative_g_score
h_score[y] :=heuristic_cost_estimate(y, goal)
f_score[y] := g_score[y] +h_score[y]
return failure
function reconstruct_path(came_from,current_node)
if came_from[current_node] is set
p := reconstruct_path(came_from, came_from[current_node])
return (p + current_node)
else
return current_node
下面给出一个A*(曼哈顿距离)的例子:
■代表起点,■代表终点,■代表障碍,■代表属于OPENSET,■代表属于CLOSEDSET, ——
黄色线段代表最终得出的路径。
方格内左上角代表f(n)即启发函数值,左下角代表g(n),即起点到该点的距离,右下角代表h(n),即该点到终点距离的估值,使用曼哈顿距离,方格上下左右相邻距离为10,对角线相邻为14,曼哈顿距离以10为单位。
(gif动画文件)
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
相关文章推荐
- JAVA基础学习(十二)--多线程一线程之间的通信
- Android学习笔记:实现图片选择器功能(下)
- 第二课:HTML和CSS
- IOC依赖注入的原理
- python标准日志模块logging的使用方法
- Oracle 分页
- FreeBSD手册——配置FreeBSD内核
- StringUtils方法全集
- Log4j实用手册
- Mongo-connector集成MongoDB到Solr实现增量索引
- Mongo-connector集成MongoDB到Solr实现增量索引
- Hibernate4之二级缓存配置
- 我不能这样活下去
- STL中的map容器的一点总结
- 操作系统笔试题
- ASP.NET实现带有分页信息的列表集合IPagedList
- iOS开发利用系统推送Notifaction和轮询实现简单聊天系统
- githubRepository -- 使用
- 枚举
- tornado开发学习之2.输入输出,数据库操作,内置模板,综合示例