失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 树的搜索问题1(深度优先 广度优先 爬山法和best-first)

树的搜索问题1(深度优先 广度优先 爬山法和best-first)

时间:2022-11-15 23:05:47

相关推荐

树的搜索问题1(深度优先 广度优先 爬山法和best-first)

前言

我们在解决问题中经常使用到的数据结构一定少不了树,在数据结构这一大块中,我们对每一个结构都会讲各种形形色色的操作,比如栈的压栈出栈,树的各种遍历,但其实数据结构最重要的操作其实是搜索。如果我们不知道链表的搜索,如何插入删除?不知道图的搜索,如何寻找最小生成树?

虽然我们讲的是树的搜索,但是本篇文章探讨的问题并非是树,而是将问题转化为树结构来处理。

树的几种常见搜索方式

我们先给出几种常用的例子吧。

布尔表达式,给一组布尔变量和一个用这些变量组成的布尔表达式,需要寻找一种赋值方式使表达式为真

8-puzzle问题,给一个九宫格,需要进行排序

有n个结点的连通图G=(V,E),V为点集,E为边集,寻找哈密顿环。

哈密顿环是沿着边遍历每一个结点有且仅有一次最后回到起点的环

上述的三个问题,很明显都是能将问题转换成一棵树结构的,第二个就是每次移动一格来形成树;第三个哈密顿环就不用说了,很明显的每一次选择一个顶点,标准树结构。

而且上述问题都是遍历树寻找正确答案的那种,所以我们先解决这几个问题。

接下来给出几个常用的树搜索策略:

暴力搜索深度优先广度优先

这几个其实都不常用,嗯就是这样,尤其第一个。

这里提到的原因主要是后面的其实还是会用到这些基本解决办法

深度优先

说白了就是在搜索的时候,我们先从一条线走到叶子节点,然后回到上一个分支处,从另一条分支走,不断重复直到最后我们找到目标节点或者遍历完整棵树

比如这样的一棵树,我们深度优先的方式就是ABD(回溯到A)CG(回溯到C)EF

因为需要回溯,所以我们采取的数据结构为

首先将根节点压栈,判断栈顶元素是否为目标结点,不是继就续将栈顶弹出,将被弹出元素的所有孩子结点压栈(按照从右到左的顺序,因为我们要保证先走左子树)当S为空,说明没找到,否则继续操作2

广度优先

首先,广度优先和深度优先相似,但是我们这次采取的方法是先遍历行

从顶点开始,先遍历所有的子节点,然后遍历第一个孩子结点的孩子结点,然后是第二个孩子的……

还是这棵树,这次我们广度优先的结果是:ABCD(找到第二个孩子C)GEF

因为也需要回溯,我们还是找一个结构存起来,这次我们采取的是队列

首先将根节点入队列如果队列首元素是目标节点,结束程序否则将队首元素出队,将其所有孩子结点入队如果队列为空,说明没有找到,否则重复操作2

爬山法

在深度优先和广度优先中,我们每一个根节点都会遇到很多个可拓展对象,那么哪一个先进行就是一个问题,

但我们还学过贪心啊(点击查看博客),我们能否将两者合并?

爬山法就是这样的产物,是由贪心算法深度优先算法相结合的产物。

同深度优先,爬山法也需要使用

将根节点压栈如果栈顶元素就是我们的目标节点,结束将栈顶元素出栈,同时将出栈的元素按照一定的顺序压栈如果栈空,说明没找到;否则继续操作2

就是将我们深度优先的压栈方式改了一下么,那么这一定的顺序是什么呢?

比如在8-puzzle问题中,我们需要将8个方块归位,那么我们就可以定义一个测度,这里的测度是放置错误的方块的个数,毕竟当前正确的方块越多,按理来说就应该更接近问题的正确答案。

然后,我们来看一下贪心部分,很明显,他不能保证每一次都是最好的……

接下来,就需要进一步优化了。

(虽然不能保证最好,但是在有些情况下用着也还行,kmp还牛皮了,但是我们暴力匹配一下也没啥,工程上也总是直接贪心,不怎么考虑正确性)

best-first

有没有一种方法,既能快速又能产生最短结果的方法?

之前是深度优先的同时,就直接选取了贪心出来的当前最优解,那么我们可以效仿广度优先,将当前所有的可能比较一下,而不是将目光限定在当前的一条分支的选择上。

比如上面的8-puzz问题截图,在爬山法选定最左边的3之后,我们的目光就停在2和4上了,

而我们的bf算法,则是将2、4和上一步留下的344都一起考虑了。

这次我们的存储结构再次更换,使用的是

(如果对堆不够清楚,这是之前关于堆的博客)

将根节点存入堆中如果堆的根节点是目标节点,结束程序否则将根节点删除,将根节点的孩子节点加入堆中如果堆为空,说明没找到,否则就继续操作2

在这种方法中,我们的贪心策略就是成立的,因为是全局选择。

总结

我们在这篇博客中讲解了深度优先、广度优先,虽然只是简单提了一下,

然后延申出了基于深度优先和贪心的爬山法,

还有深度优先、广度优先和贪心的best-first算法。

这些方法不但在上述问题中会遇到,而且在我们的下一篇博客也会提到关于最值问题的解决办法。

(提示一下,这篇博客主要是讲从树结构中选择正确的答案,但在最值问题中我们不知道最佳答案,这时就需要其他的算法了。)

如果觉得《树的搜索问题1(深度优先 广度优先 爬山法和best-first)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。