十五个经典算法研究与总结学习笔记之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*就是将估值函数分成两个部分,一个是路径价值,另一个就是一般启发性价值。
在最短路径搜寻效率上,一般有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*就是将估值函数分成两个部分,一个是路径价值,另一个就是一般启发性价值。
相关文章推荐
- 十五个经典算法研究与总结学习笔记之A*搜索算法1
- July《十五个经典算法研究与总结》目录+索引
- 十五个经典算法研究与总结、目录+索引
- 十三个经典算法研究与总结、目录+索引「后续更新为十五个」
- 算法入门经典 第1,2章学习笔记
- 程序员面试、算法研究、编程艺术、红黑树、数据挖掘5大经典原创系列集锦与总结
- mini-web学习笔记之经典CRUD显示页面总结
- 十三个经典算法研究与总结、目录+索引
- 算法竞赛入门经典 第三章 学习笔记
- 程序员面试、算法研究、编程艺术、红黑树、数据挖掘5大经典原创系列集锦与总结
- 【算法学习笔记】60.经典动态规划 SJTU OJ 1370 赫萝的桃子
- 程序员面试、算法研究、编程艺术、红黑树、数据挖掘5大经典原创系列集锦与总结
- 十三个经典算法研究与总结、目录+索引
- 程序员面试、算法研究、编程艺术、红黑树、数据挖掘5大经典原创系列集锦与总结
- [转贴]经典算法研究系列:一、A*搜索算法
- 十三个经典算法研究与总结、目录+索引
- 程序员面试、算法研究、编程艺术、红黑树、数据挖掘5大经典原创系列集锦与总结
- 经典算法研究系列:四、教你通透彻底理解:BFS和DFS优先搜索算法
- 黑马程序员之c#程序学习笔记:c#程序经典例子学习总结
- 十三个经典算法研究与总结