【综合算法】A*算法
2016-06-22 15:58
344 查看
A*算法
A*算法;A*(A-Star)算法是一种静态路网中求解最短路径最有效的直接搜索方法,也是许多其他问题的常用启发式算法。注意是最有效的直接搜索算法。之后涌现了很多预处理算法(ALT,CH,HL等等),在线查询效率是A*算法的数千甚至上万倍。在游戏、优化领域,A*算法是很重要的一个算法。例如RTS游戏中控制移动单位到另外一个地点,玩家只需要在指定地点下达指令,移动单位可以自动搜索最好的路径抵达目的地。
在路径搜索方面,A*算法的目标是找到当前已知约束条件下的最优路径。由于A*算法是直接搜索方法,没有全局优化,并且我们并不知道实际情况有多复杂,所以A*算法最后不一定能得出全局最短路径,而是得到当前已知约束条件下的最优路径,甚至可以根据实际情况,在路径搜索速度和路径搜索质量上取得平衡。
A*算法可以看做迪杰斯特拉最短路径算法和最优贪心算法的综合。相比传统的迪杰斯特拉算法,A*算法在每个路径节点的权值计算有所不同。A*算法的权值计算表示为:f(n)=g(n)+h(n),其中f(n)是最终的权值,g(n)是初始点到当前点的代价,类比于迪杰斯特拉算法的节点权值,在游戏中山地区域的权值就比较大,平原区域权值比较小,那么移动单位会倾向于走平原地区;h(n)则是当前节点到目标节点的估计距离。路径搜索速度和路径搜索质量主要是通过h(n)来控制。如果h(n)能非常好的反映当前节点到目标节点的距离度量,那么A*算法得到的搜索路径就等于或逼近于全局最短路径;如果h(n)精准地反映当前节点到目标节点的距离度量,那么实际上我们已经知道当前节点到目标节点的最短路径,也就没A*算法什么事了;如果h(n)接近或者等于0,那么A*算法退化为普通的迪杰斯特拉算法;如果h(n)权重远比h(n)大,那么A*算法退化为普通的路径搜索算法。
h(n)的计算方法有很多种。设当前点为(in,jn),目标点为(id,jd)。比较简单的距离度量有曼哈顿距离,即h(n)=α∗[abs(in−id)+abs(jn−jd)],其中α控制h(n)的作用权重;计算量稍大的有欧式距离,即h(n)=α∗(in−id)2+(jn−jd)2−−−−−−−−−−−−−−−−−√;也可以根据实际情况考量,设置自定义的距离度量。
一般情况下,设上一级搜索的节点为n,其权值为f(n)=g(n)+h(n),下一级搜索到的节点为n+1,则权值为f(n+1)=g(n)+Δg(n)+h(n+1)。这里Δg(n)指代在迪杰斯特拉算法情况下权值的增量,这说明搜索过程中g(n)是累加的,具有记忆效应;而h(n)则需要随时更新,是瞬时的。
另外,格子的走法也需要设置。普通的方格路径,我们需要考量是否可以斜着行进,既可以设置当前点的斜向邻点是否可以移动,也可以只是设置斜向邻点具有稍微大点的权值;在《文明》系列游戏中,单位方格则是六边形方格,角色可以选择移动到周围六个方格。
A*算法的伪代码非常简单,百度百科摘录如下:
创建两个表,OPEN表保存所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。计算算起点的h(s);将起点放入OPEN表;
while(OPEN!=NULL)
{
从OPEN表中取f(n)最小的节点n;
if(n节点==目标节点)
break;
{
计算f(X);
if(X in OPEN)
{
if(新的f(X)小于OPEN中的f(X)){
把n设置为X的父亲;
更新OPEN表中的f(n);
}
if(X in CLOSE)
continue;
if(X为全新节点)
{
把n设置为X的父亲;
求f(X);
并将X插入OPEN表中;//还没有排序
}
}//endfor
将n节点插入CLOSE表中;
按照f(n)将OPEN表中的节点排序;//实际上是比较OPEN表内节点f的大小,从最小路径的节点向下进行。
}//endwhile(OPEN!=NULL)
做完计算之后,如果遇到目标点,那么从目标点开始沿着父节点向上回溯到起始节点,然后对搜索路径执行反向操作,就得到了起始点到目标点的路径。
读懂上述代码就知道A*算法的实现方法,可以说逻辑上比较简单。存在的问题主要在如何给出h(n),如何用数据结构表示,如何同时提升搜索质量和搜索速度。这些就靠编程功力了。
下面给出一部分使用曼哈顿度量计算的结果图和说明,图中包含一个白色C型障碍物,左边的小白点是起始点,右边的小白点是目标点,灰色区域表示搜索范围:
曼哈顿距离权值α=0,算法退化为迪杰斯特拉算法,搜索范围是以起始点为中心的方框。该搜索能获取全局最短路径,但是搜索速度非常慢,因此我终止了搜索。
曼哈顿距离权值α=0.8算法搜索范围极大的缩小了。
曼哈顿距离权值α=1.0搜索范围变大,但是穿过障碍物之后行走一条最短路径。
曼哈顿距离权值α=1.5算法搜索范围更大。路径有些斜扭,但仍然是当前最优路径。
相关文章推荐
- 我是运营,我没有假期
- 搜狗百度360市值齐跌:搜索引擎们陷入集体焦虑?
- MySQL 优化
- 每个 Linux 游戏玩家都绝不想要的恼人体验
- 本人即将筹备败家日志,敬请期待!
- 在 Fedora 上使用 Steam play 和 Proton 来玩 Windows 游戏
- 书评:《算法之美( Algorithms to Live By )》
- Steam 让我们在 Linux 上玩 Windows 的游戏更加容易
- 如何使用 Steam Play 在 Linux 上玩仅限 Windows 的游戏
- 新一代iPad适配应用之游戏篇
- Google排名优化的几个影响因素
- IE:使用搜索助手
- 动易2006序列号破解算法公布
- VB实现的《QQ美女找茬游戏》作弊器实例
- DB2优化(简易版)
- Mysql limit 优化,百万至千万级快速分页 复合索引的引用并应用于轻量级框架
- C#中尾递归的使用、优化及编译器优化
- 对优化Ruby on Rails性能的一些办法的探究
- C#递归算法之分而治之策略
- 优化Ruby脚本效率实例分享