广度优先搜索技巧.ppt

  1. 1、本文档共67页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
双向广度优先搜索(DBFS) DBFS算法是对BFS算法的一种扩展。 BFS算法从起始节点以广度优先的顺序不断扩展,直到遇到目的节点 DBFS算法从两个方向以广度优先的顺序同时扩展,一个是从起始节点开始扩展,另一个是从目的节点扩展,直到一个扩展队列中出现另外一个队列中已经扩展的节点,也就相当于两个扩展方向出现了交点,那么可以认为我们找到了一条路径。 比较 DBFS算法相对于BFS算法来说,由于采用了从两个跟开始扩展的方式,搜索树的深度得到了明显的减少,所以在算法的时间复杂度和空间复杂度上都有较大的优势! DBFS的框架(1) 一、主控函数: void solve() { 1. 将起始节点放入队列q1,将目的节点放入队列q2; 2. 当 两个队列都未空时,作如下循环: ????????? 1) 如果队列q1里的未处理节点比q2中的少(即tail[0]-head[0] tail[1]-head[1]),则扩展(expand())队列q1; ????????? 2) 否则扩展(expand())队列q2 (即tail[0]-head[0] = tail[1]-head[1]时); 3. 如果队列q1未空,循环扩展(expand())q1直到为空; 4. 如果队列q2未空,循环扩展(expand())q2直到为空; } DBFS的框架(2) 二、扩展函数 int expand(i) //其中i为队列的编号(表示q0或者q1) { ??????????取队列qi的头结点H; ????????? 对头节点H的每一个相邻节点adj,作如下循环: ??????????????? 1 如果adj已经在队列qi之前的某个位置出现,则 抛弃节点adj; ??????????????? 2 如果adj在队列qi中不存在[函数 isduplicate(i)] ????????????????????? 1) 将adj放入队列qi; ????????????????????? 2)????如果adj 在队列(q(1-i)),也就是另外一个 队列中出现[函数 isintersect()]; ????????????输出 找到路径?; } DBFS的框架(3) 三、判断当前扩展出的节点是否在另外一个队列出现,也就是判断相交的函数: int isintersect(i,j) //i为队列编号,j为当前节点在队列中的指针 { ??????????遍历队列,判断是否存在 } //【线性遍历的时间复杂度为O(N),如果用HashTable优化,时间复杂度可以降到O(1)】 DBFS参考代码 见附件 进一步提高查找效率,采用hash函数优化线性查找 见附件 A*算法 针对八数码问题,提出了人工智能史上很有名的A*算法(启发式搜索算法) 广度优先算法:当目标的深度较深时,产生很多冗余节点,空间消耗很大 有限深度优先算法:在时间或空间复杂度上均没有明显的优势,但如果目标深度较深而且路径选择得当的话,可以较快地得到解答;当问题复杂时时间消耗很多 A*算法:可以消耗较少的空间解决问题,但是由于每次选择均需要寻找估价函数最小的节点,因此当深度增加相应的节点数目增加时,A*算法在时间上并不占优势。然而,A*算法总可以在有限的时间内得到问题的解。 * A*算法的基本思想 A*算法基本上与BFS算法相同,但是在扩展出一结点后,要根据估价函数对待扩展的结点排序,从而保证每次扩展的结点都是估价函数最小的结点。 估价函数: f(n) = g(n) + h(n) 这里f(n)是估价函数,g(n)是起点到终点的最短路径值(也称为最小耗费或最小代价),h(n)是n到目标的最短路经的启发值。 由于这个f‘(n)其实是无法预先知道的,所以实际上使用“不在位”数和当前层数之和 A*算法的基本步骤 建立一个队列,计算初始结点的估价函数f,并将初始结点入队,设置队列头和尾指针。 取出队列头(队列头指针所指)的结点,如果该结点是目标结点,则输出路径,程序结束。否则对结点进行扩展。 检查扩展的新结点是否与队列中的结点重复 若与不能再扩展的结点重复(位于队列头指针之前),则将它抛弃; 若新结点与待扩展的结点重复(位于队列头指针之后),则比较两个结点的估价函数中g的大小,保留较小g值的结点。跳至第五步。 如果扩展出的新结点与队列中的结点不重复,则按照它的估价函数f大小将它插入队列中的头结点后待扩展结点的适当位置,使它们按从小到大的顺序排列,最后更新队列尾指针 如果队列头的结点还可以扩展,直接返回第二步。否则将队列头指针指向下一结点,再返回第二步。 #include iostream using

文档评论(0)

希望之星 + 关注
实名认证
内容提供者

我是一名原创力文库的爱好者!从事自由职业!

1亿VIP精品文档

相关文档