首页 > 其他分享 >浅谈 BFS 与 IDDFS

浅谈 BFS 与 IDDFS

时间:2022-11-04 23:56:26浏览次数:54  
标签:浅谈 迭代 text DFS BFS IDDFS 搜索

前记

为什么没有 \(\text{CSDN}\) 和博客园的同步输出了呢?因为博主懒得贴实践代码(实际上 \(6\) 种搜索的效率对比数据本人是有的),认为 \(\text{CSDN}\) 和博客园发博文不会得到什么欢迎,就在洛谷发一发吧。

引入

很多朋友都会在学 \(\text{IDDFS}\)(迭代加深搜索) 的时候问我:

  • \(\text{IDDFS}\) 和 \(\text{BFS}\) 有啥区别?

诚然,它们有一定的相似,不可否认。

本质搜索方式

下面我们来剖析算法的原理。

\(\text{BFS}\) 的原理是把每一层逐层地往下搜。

而 \(\text{IDDFS}\) 也是这样,但它 规定搜的层数

那你会说了:\(\text{IDDFS}\) 可能会重复搜一些状态啊!比方说,它限定层数为 \(d\),从 \(1\) 搜到 \(d\) 会把第 \(1\) 层的状态来回的搜索。这样反而不如 \(\text{BFS}\) 单一地搜啊!

你说的很有道理,你掌握了 \(\text{IDDFS}\) 的精髓,可矛盾的是,为什么它总会比 \(\text{BFS}\) 快呢?

那是因为它还有一个黑科技!

回归各种搜索算法

在讲这个黑科技之前,我们按照一定的顺序捋一捋搜索的算法。

  • 深度优先搜索

  • 宽度优先搜索

  • 双向宽度优先搜索

  • A*

  • IDA*

  • 迭代加深搜索

前两种非常简单,无可厚非;而第三种 只是在第二种搜索的基础上进行双向搜索 而已。

那 \(\text{A*}\) 是啥呢?显然,它引入了一个 估价函数 的概念!即,对当前的状态进行一个估价,如果不如之前的状态就不搜了!

这是非常好的一个剪枝,但如果 估价函数 写错,整个程序可能都错了。\(\text{A*}\) 是建立在 深度优先搜索 基础之上的。

而 \(\text{IDA*}\) 同样用来估价函数,它是建立在 宽度优先搜索 上的。

迭代加深搜索就是今天的 \(\text{IDDFS}\) 了,它会 依次规定层数,并往下进行搜索,是建立在 深度优先搜索\(\text{A*}\) 之上的。

实际上,上面的六种搜索已经按照时间效率从低到高排好序。\(\text{BFS}\) 与 \(\text{IDDFS}\) 的效率为何相差这么大呢?同样都是按层搜索啊!

理论剖析

首先,我们知道 \(\text{BFS} = \text{Breadth-First Search}\),那么 \(\text{IDDFS} = \text{Iterative Deepening Depth-First Search}\),这个单词翻译过来的意思就是 迭代深化深度优先搜索,很长。

它以 \(\text{DFS}\) 为基础,所以是 深度优先搜索,那么“迭代深化”是什么意思呢?通过百度百科可以得到:

迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。

每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。

这说明什么呢?

说明迭代与 \(\text{DFS}\) 是很相似的过程。我们可以认为 \(\text{IDDFS}\) 将 \(\text{DFS}\) 的“迭代过程” 与 \(\text{BFS}\) 的“加深过程”进行了综合。

原理上,\(\text{DFS}\) 会把以 \(u\) 为根的 搜索树的状态全部搜完,才会进行对 \(u\) 的回溯。而 \(\text{BFS}\) 会把以 \(u\) 为根拓展的节点搜出来,一层层的进行状态搜索。实际上又回归到了树的两种核心遍历:\(\text{DFS}\) 和 \(\text{BFS}\).

如何把这两种算法进行糅合?我们考虑按照 \(\text{BFS}\) 的方式,规定当前搜的层数 \(d\),从小到大搜。对于每个 \(d\) 如何验证答案?此时要用 \(\text{DFS}\) 把 层数 \(d\) 以内的搜索树的状态搜完,有解则返回,无解则 \(d \gets d + 1\),继续搜。

但是你会发现,验证答案的过程同样可以换成 \(\text{BFS}\),那样“迭代加深”就失去了它的意义。此时经典的一步来了。我们考虑一个“估价函数”,因为有了 \(d\) 的限制,很多状态会被剪枝。

具体的,假设当前状态用了 \(g(x)\) 步,估价 \(h\) 认为 到达目标状态至少需要 \(h(x)\) 步,总共的搜索步数不能超过 \(f(x)\) 步,此时 \(f(x) = d\),那么应满足 \(g(x) + h(x) \leq f(x)\),否则我们可以剪枝。

这样的话,\(\text{BFS}\) 会把逐层状态搜完,而 \(\text{IDDFS}\) 有了估价函数的黑科技,就可以只搜部分的状态,并且对于当前状态有效的剪枝。

简单比对

那么你会问了,\(\text{IDDFS}\) 的验证过程可不可以换成 \(\text{BFS}\) 和估价函数的实现呢?实际上是可以的。但是那样的话,\(\text{IDDFS}\) 和 \(\text{IDA*}\) 将会非常相似,失去了“加深”的意义。实际上“迭代”是 \(\text{BFS}\) 的思想,“加深”是 \(\text{DFS}\) 的思想。这样可以使得 \(\text{IDDFS}\) 在搜索算法中效率到达顶峰。

简单的说吧,就 \(4 \times 4\) 的数独搜索题,前 \(4\) 种搜索都 很难通过,只有用 \(\text{IDA*}\) 和 \(\text{IDDFS}\) 才可以。实际上搜索的优化不是一戳而就的。

搜索历史

首先有了最简单的 \(\text{DFS}\),然后人们逐渐发现有些题目层数是较小的,但是深度很大,加上树的搜索基础,\(\text{BFS}\) 就应运而生。

接着人们发现 \(\text{BFS}\) 也不够快,于是考虑一个“起点和终点同时出发”的算法,并把 \(\text{BFS}\) 的时间复杂度降到了 \(\sqrt{}\) 级别,使得双向搜索被广泛应用。实际上 双向搜索在背包问题中对 \(n \leq 40\),\(v_i , w_i \leq 10^9\) 也有应用

人们在对双向搜索的调试过程中,发现有的时候 程序会明显向更劣的状态进行搜索,于是 估价函数 应运而生,这样出现了 \(\text{A*}\),与双向搜索的效率不相上下,但 \(\text{A*}\) 总体效率较高。

再后,人们又发现在 \(\text{A*}\) 的过程中可以规定深度,这样有了 \(\text{IDA*}\),通过实践和理论证明也证明了 \(\text{IDA*}\) 比 \(\text{A*}\) 要优。

最后,人们把 \(\text{IDA*}\) ,\(\text{DFS}\) 与 \(\text{BFS}\) 结合,出现了 \(\text{IDDFS}\),把搜索的效率推到了顶峰。在数独方面,\(\text{IDDFS}\) 的搜索效率极高。(实际上 \(\text{Dancing Links}\) 的效率应当更高些,它的时间复杂度是稳的)

后记

因此 \(\text{IDDFS}\) 与 \(\text{BFS}\) 大家应该都明白了吧!一切安好。

标签:浅谈,迭代,text,DFS,BFS,IDDFS,搜索
From: https://www.cnblogs.com/bifanwen/p/16859468.html

相关文章

  • 浅谈敏捷设计
    https://www.cnblogs.com/imyalost/p/7689920.html在软件开发过程中,都避免不了进行概要设计、详细设计等过程,这和软件测试过程中进行测试计划测试方案设计很类似。这篇博......
  • 浅谈持续集成
    转载:https://www.cnblogs.com/imyalost/p/9326779.html参考资料:《京东系统质量保障技术实战》其他资料:《jenkins入门指南》、《持续集成:软件质量改进和风险降低之道......
  • 浅谈自定义组件样式覆盖的方式
    简介有时候,基础组件提供的样式不够,需要在不同模块中使用不同的样式,而且差异大到无法通过一两个属性完成。比如组件的颜色,最常见的有三个区域(文字/图标、背景、边框,常用但......
  • 浅谈PHP设计模式的适配器模式
    简介:适配器模式属于结构型设计模式。将一个类的接口转换成可应用的兼容接口。适配器使原本由于接口不兼容而不能一起工作的那些类可以一起工作。适配器模式有两种实现方......
  • 浅谈建筑电气火灾原因分析及防范措施
    陈盼安科瑞电气股份有限公司上海嘉定201801 【摘要】随着经济和科技的快速发展,建筑业以及建筑电气得到了充分的发展。建筑中电气的应用极大地提高了人们的生活质量。但是......
  • 浅谈限流式保护器应用于防范电动自行车火灾的解决方案
    陈盼安科瑞电气股份有限公司上海嘉定201801【摘要】为了进一步研究电动自行车火灾事故发生机理,提升安全防范的针对性,文章分析了低压电气系统发生火灾的原理,解构了电动自行......
  • 浅谈this关键字
    java中的this关键字用法灵活,用途很广,本文谈一下其的基础用法this表示表示当前正在被调用的对象 publicPersonshow(){ returnthis; }}publicclassThisTest{......
  • 从火热的双十一大促浅谈制造业大整合趋势
    一年一次的双十一结束了,一年中最受关注的电商优惠大战让那些主营业务是TOC的企业估计都又要笑得睡不着觉,又要赚得盆满钵满了。国外的企业早就眼馋得不行,苹果和三星也开始加......
  • 浅谈 MySQL 新的身份验证插件 caching_sha2_password
    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。GreatSQL是MySQL的国产分支版本,使用上与MySQL一致。介绍从MySQL8.0.4开始,MySQL默认身份验......
  • 浅谈PHP设计模式的装饰器模式
    简介装饰器模式又叫做装饰者模式,属于结构型的设计模式。指的是在不改变原类文件和使用继承的情况下动态扩展这个对象的功能,从而修饰源数据。组成:抽象构件(Component)角色......