您的位置:首页 > 其它

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

2014-04-11 14:02 246 查看
A*搜寻算法的高效之处

在最短路径搜寻效率上,一般有A*>Dijkstra、双向BFS。

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

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

OPEN表表示已经展开但还没有访问的节点集,另一个CLOSE表表示那些已经访问过的节点集。

蛮力搜索(BFS,DFS)

BFS(宽度优先搜索,Breadth-First-Search)

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

1、如果OPEN不为空,从中取节点S,为空算法失败;

2、S是目标解吗?是,找到一个解(继续或终止);不是转3;

3、将所有S的所有后继节点展开,就是从S可以直接关联的节点,若不在CLOSE中,就将其放入OPEN表尾,S放入CLOSE表,重复1。

DFS(深度优先搜索,Depth-First-Search)

1、如果OPEn不空,从中取S,空,算法失败;

2、S是目标解码?是,找到一个解(继续或终止);不是转3;

3、将S的所有后继展开,就是从S可以直接关联的节点,若不在CLOSE中,就将其放入OPEN开始,S放入CLOSE表,重复1。

观察OPEN表中的访问节点组织形式,BFS是从表头取节点,从表尾添加节点,也就是说OPEN是一个队列;

DFS从OPEN表头取节点,也从表头添加节点,OPEN为一个栈。

注意:DFS用到了栈,可以使用递归实现,好处是在系统中只需要存节点最大深度那么大的空间。

利用系统栈实现DFS

函数dfs(节点 s)

{

s超过最大深度了吗?是:相应处理,返回;

s是目标节点吗?是:相应处理;否则;

{

s放入CLOSE表;

for(c=s.第一个节点;c不为空;c=c.下一个节点())

if(c不在CLOSE表中)

dfs(c):递归

}

}

在象棋等棋类程序中,就是用DFS基本模式搜索棋局局面树的。

启发式搜索:

为了改善上面的算法,我们需要对展开后续节点时对子节点有所了解,需要估值函数,用来评价子节点的好坏。

排序可能是对OPEN表整体进行排序,也可以是对后续展开的子节点排序,排序的目的就是要使程序有启发性,更快搜出目标解。

如果估值函数只考虑节点的某种性能上的价值,而不考虑深度,有序搜索(Ordered-Search),着重看好能否找出解,而不看解离起始节点的距离(深度)。

如果估值函数考虑了深度,或者是带权距离(从起始点到目标节点的距离加权和),就是A*。

A*就是将估值函数分成两个部分,一个是路径价值,另一个就是一般启发性价值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: