十五个经典算法研究与总结学习笔记之A*搜索算法1

1、A*算法常用语游戏中NPC移动计算,或者线上游戏BOT移动计算,找到一条最短路径,进行启发式的搜索。
核心在于估值函数设计:
f(n)=g(n)+h(n)

f(n)是每个可能试探的点的估值,由两部分组成:

g(n)表示从起始搜索点到当前点的代价(通常用某节点在搜索树中的深度来表示);

h(n)表示当前节点到目的节点的估值,h(n)设计的好坏,直接影响算法能否称为A*算法。

成为A*算法的充分条件:

1、搜索树上存在着从起始点到终了点的最优路径。

2、问题域是有限的。

3、所有节点的子节点的搜索代价值>0。

4、h(n)=<h*(n) (h*(n)为实际问题的代价)。

2、算法的实现


求此起始点V0->途径任意顶点->目标顶点V5的最短路径。


A*算法的核心过程,就在每次选择下一个当前搜索点时,从所有已探知但为搜索过点中(可能是不同层,也可能不在同一条支路上),选取f值最小的节点进行展开。

所有“已探知但未搜索点”通过一个按f值升序的队列(优先队列)进行排列。

这样,按照广度优先的算法,从优先队列中弹出队首元素(f值),对其可能子节点计算g,h和f值,知道队列为空(无解)或找到终止点。


3、A*算法流程

首先将起始节点S放入OPEN表,CLOSE表为空:

1、如果OPEN表不为空,从表头取一个节点n,如果为空算法失败;

2、n是目标解吗?是,找到一个解(继续寻找,或终止算法);

3、将n的所有后继节点展开,就是从n可以直接关联的节点(子节点),如果不在CLOSE表中,就将它们放入OPEN表,并把S放入CLOSE表,同时计算每一个后继节点的估价值f(n),将OPEN表按照f(x)排序,最小的放在表头,重复算法,回到1。

closedset :=the empty set //已经被估算的节点集合

openset :=set containing the initial node //将要被估算的节点集合

g_score[start] :=0 //g(n)

h_score[start] :=0 //h(n)

f_score[start] :=0 //f(n)


while openset is not empty //若OPEN 表不为空

    x := the node in openset having the lowest f_score[] value//x为OPEN表中最小的

if x = goal//如果x是一个解

    return reconstruct_path(came_from, goal)

remove x from openset

add x to closedset


CLOSE表

for each y in neighbor_nodes(x)//对于x邻居集中的每个邻居节点y

    if y in closedset//如果y在CLOSE表中

        continue//那么不进行处理

    tentative_g_score := g_score[x] + dist_between(x, y)//y到目的的g(n)估算等于g(x)加上xy之间的代价


    if y not in openset//如果y不在OPEN表中

        add y to openset//将y加入OPEN表

        tentative_is_better := true                 //是否是更佳路径,是

    else if tentative_g_score < g_score[y]//如果估算探索g(n)小于g(y)

        tentative_is_better := true//是否更佳路径,是

    else

        tentative_is_better := false//否则非更佳路径

    if tentative_is_better = true//如果是更佳路径

        came_form[y] := x//将y设置为x的下一目标节点

        g_score[y] := tentative_g_score//g(y)等于估算的探索g(y)

        h_score[y] := heuristic_estimate_of_distance(y, goal)//x-->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 the empty path//直到路径为空停止

 

算法性能:外循环中每次从OPEN表中取一个元素,共取了n此(共n个节点),每次展开一个节点的后续节点时,需要O(n)次,同时再对OPEN做排序,OPEN表大小事O(n)级别的,快排序就是O(nlogn),复杂度是O(n^2*logn)。

A*最短路径算法

目标:从当前位置A到目标位置B找到一条最短的行走路径。

方法:

从A点开始,遍历所有的可走路径,记录到一个结构中,记录内容为(位置点,最小步数)。

当任何第二次走到一个点的时候,判断下最小步数是否小于记录的内容,如果是,则更新掉原最小步数,一直到所有的路径点都不能继续了位置,最终那个点被标注的最小步数既是最短路径。

而反向找跟他相连的步数相继少一个值得点连起来就形成了最短路径,当多个点相同,则任意取一条即可。

总结:

A*算法实际是个穷举算法。



前言: 本人的原创作品经典算法研究系列,自从10年12月末至11年12月,写了近一年。可以这么说,开博头俩个月一直在整理微软等公司的面试题,而后的四个月至今,则断断续续,除了继续微软面试100题系列,和程序员编程艺术系列之外,便在写这经典算法研究系列和相关算法文章。 本经典算法研究系列,涵盖A*.Dijkstra.DP.BFS/DFS.红黑树.KMP.遗传.启发式搜索.图像特征提取SIFT.傅立叶变换.Hash.快速排序.SPFA.快递选择SELECT等15个经典基础算法,共计31篇文章,包括算法理论的研究与阐述,及其编程的具体实现。很多个算法都后续写了续集,如第二个算法:Dijkstra 算法,便写了4篇文章;sift算法包括其编译及实现,写了5篇文章;而红黑树系列,则更是最后写了6篇文章,成为了国内最为经典的红黑树教程。 OK,任何人有任何问题,欢迎随时在blog上留言评论,或来信:zhoulei0907@yahoo.cn批评指正。谢谢。以下是已经写了的15个经典算法集锦,算是一个目录+索引,共计31篇文章: 十五个经典算法研究集锦+目录 一、A*搜索算法 一(续)、A*,Dijkstra,BFS算法性能比较及A*算法的应用 二、Dijkstra 算法初探 二(续)、彻底理解Dijkstra算法 二(再续)、Dijkstra 算法+fibonacci堆的逐步c实现 二(三续)、Dijkstra 算法+Heap堆的完整c实现源码 三、动态规划算法 四、BFS和DFS优先搜索算法 五、教你透彻了解红黑树 (红黑数系列六篇文章之其中两篇) 五(续)、红黑树算法的实现与剖析 六、教你初步了解KMP算法、updated (KMP算法系列三篇文章) 六(续)、从KMP算法一步一步谈到BM算法 六(三续)、KMP算法总结篇(必懂KMP) 七、遗传算法 透析GA本质 八、再谈启发式搜索算法 九、图像特征提取与匹配之SIFT算法 (SIFT算法系列五篇文章) 九(续)、sift算法的编译与实现 九(再续)、教你一步一步用c语言实现sift算法、上 九(再续)、教你一步一步用c语言实现sift算法、下 九(三续):SIFT算法的应用--目标识别之Bag-of-words模型 十、从头到尾彻底理解傅里叶变换算法、上 十、从头到尾彻底理解傅里叶变换算法、下 十一、从头到尾彻底解析Hash表算法 十一(续)、倒排索引关键词Hash不重复编码实践 十二、快速排序算法 (快速排序算法3篇文章) 十二(续)、快速排序算法的深入分析 十二(再续):快速排序算法之所有版本的c/c++实现 十三、通过浙大上机复试试题学SPFA 算法 十四、快速选择SELECT算法的深入分析与实现 十五、多项式乘法与快速傅里叶变换
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ymaym

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值