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

article/2025/11/10 11:37:40

前言

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

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

树的几种常见搜索方式

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

  1. 布尔表达式,给一组布尔变量和一个用这些变量组成的布尔表达式,需要寻找一种赋值方式使表达式为真在这里插入图片描述

  2. 8-puzzle问题,给一个九宫格,需要进行排序在这里插入图片描述

  3. 有n个结点的连通图G=(V,E),V为点集,E为边集,寻找哈密顿环。
    哈密顿环是沿着边遍历每一个结点有且仅有一次最后回到起点的环

上述的三个问题,很明显都是能将问题转换成一棵树结构的,第二个就是每次移动一格来形成树;第三个哈密顿环就不用说了,很明显的每一次选择一个顶点,标准树结构。
而且上述问题都是遍历树寻找正确答案的那种,所以我们先解决这几个问题。

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

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

这几个其实都不常用,嗯就是这样,尤其第一个。
这里提到的原因主要是后面的其实还是会用到这些基本解决办法

深度优先
说白了就是在搜索的时候,我们先从一条线走到叶子节点,然后回到上一个分支处,从另一条分支走,不断重复直到最后我们找到目标节点或者遍历完整棵树
在这里插入图片描述
比如这样的一棵树,我们深度优先的方式就是ABD(回溯到A)CG(回溯到C)EF

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

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

广度优先
首先,广度优先和深度优先相似,但是我们这次采取的方法是先遍历行
从顶点开始,先遍历所有的子节点,然后遍历第一个孩子结点的孩子结点,然后是第二个孩子的……
在这里插入图片描述
还是这棵树,这次我们广度优先的结果是:ABCD(找到第二个孩子C)GEF

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

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

爬山法

在深度优先和广度优先中,我们每一个根节点都会遇到很多个可拓展对象,那么哪一个先进行就是一个问题,
但我们还学过贪心啊(点击查看博客),我们能否将两者合并?

爬山法就是这样的产物,是由贪心算法深度优先算法相结合的产物。
同深度优先,爬山法也需要使用

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

就是将我们深度优先的压栈方式改了一下么,那么这一定的顺序是什么呢?
比如在8-puzzle问题中,我们需要将8个方块归位,那么我们就可以定义一个测度,这里的测度是放置错误的方块的个数,毕竟当前正确的方块越多,按理来说就应该更接近问题的正确答案。
在这里插入图片描述
然后,我们来看一下贪心部分,很明显,他不能保证每一次都是最好的……
接下来,就需要进一步优化了。
(虽然不能保证最好,但是在有些情况下用着也还行,kmp还牛皮了,但是我们暴力匹配一下也没啥,工程上也总是直接贪心,不怎么考虑正确性)

best-first

有没有一种方法,既能快速又能产生最短结果的方法?
之前是深度优先的同时,就直接选取了贪心出来的当前最优解,那么我们可以效仿广度优先,将当前所有的可能比较一下,而不是将目光限定在当前的一条分支的选择上。

比如上面的8-puzz问题截图,在爬山法选定最左边的3之后,我们的目光就停在2和4上了,
而我们的bf算法,则是将2、4和上一步留下的344都一起考虑了。

这次我们的存储结构再次更换,使用的是
(如果对堆不够清楚,这是之前关于堆的博客)

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

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

总结

我们在这篇博客中讲解了深度优先、广度优先,虽然只是简单提了一下,
然后延申出了基于深度优先和贪心的爬山法,
还有深度优先、广度优先和贪心的best-first算法。
这些方法不但在上述问题中会遇到,而且在我们的下一篇博客也会提到关于最值问题的解决办法。
(提示一下,这篇博客主要是讲从树结构中选择正确的答案,但在最值问题中我们不知道最佳答案,这时就需要其他的算法了。)


http://chatgpt.dhexx.cn/article/bIZ0onOF.shtml

相关文章

TSP问题解决:模拟退火、贪心法、爬山法,Python实现

TSP问题解决:模拟退火、贪心法、爬山法,Python实现这里写目录标题 一、TSP问题二、简单介绍:贪心法、爬山法、模拟退火三、python代码实现四、分别用这三种方法得出结果,进行比较 一、TSP问题 1、TSP问题描述 简单来说&#xff0…

爬山法实现 八皇后问题 (Python 实现)

本文主要简单阐述爬山法的基本算法思想,并给出用此算法实现八皇后问题详细过程 最基本的爬上搜索算法表示:(节选自《人工智能》第二版): function HILL-CLIMBING(problem) return a state thate is a locak maximum inputs: problem …

爬山法求解八皇后问题的全部解法

爬山法求解八皇后问题的全部解法 程序的概要设计思想初始状态冲突函数寻找邻居状态寻找全部解集 程序主要函数的作用运行结果截图Python源代码 程序的概要设计思想 爬山算法是一种局部贪婪算法,每次更新一次状态,都对相邻状态的冲突状态进行排序&#x…

Python启发式算法中爬山法的讲解及解方程问题实战(超详细 附源码)

一、启发式算法 还有一类重要的迭代法,它的迭代关系式不依赖问题的数学性能,而是受某种自然现象的启发而得到,称为启发式算法(Heuristic Algorithm),如爬山法、遗传算法、模拟退火算法、蚁群算法等。 启发…

人工智能:爬山法、随机重启爬山法、模拟退火算法、遗传算法、启发式搜索方法解决八数码和八皇后问题

摘要 本文主要分为两个部分,分别采用实验对比对不同的方法进行分析。第一,以八数码问题和八皇后问题为例,对比爬山法,随机重启爬山法,模拟退火算法,遗传算法的搜索性能。第二,以八数码问题为例…

进化优化算法--第二章:爬山法

算法2.1&#xff1a; 最快上升爬山法 x0 <- 随机生成的个体 while not ( 终止准则)计算x0的适应度f(x0)For 每一个解的特征 q1,2,,...nxq <- x0 用一个随机变异替换xq的第q个特征计算xq的适应度f(xq)获取下一个更优的解:寻找使f(xq)最大的xq, 令其等于x, x <- argma…

Python:爬山法/随机重启爬山法/允许侧移的爬山法解决八皇后问题

文章目录 1 八皇后问题2 程序代码2.1 程序12.2 程序22.3 程序32.3.1 爬山法2.3.2 随机重启爬山法2.3.3 允许皇后侧移的爬山法 3 评价 1 八皇后问题 有一个8乘8的棋盘&#xff0c;现在要将八个皇后放到棋盘上&#xff0c;满足&#xff1a;对于每一个皇后&#xff0c;在自己所在…

爬山法和模拟退火

文章目录 前言一、爬山法1.算法步骤2.算法局限性 二、模拟退火1.算法步骤2.注意点3.例题求费马点保龄球均分数据 总结 前言 爬山法和模拟退火都为随机化算法&#xff0c;考场想不到正解时可用来骗分&#xff0c;通常效果较好。模拟退火是基于爬山法的优化。 一、爬山法 爬山法是…

搜索算法——爬山法

不断更新中...... 一、 爬山算法&#xff1a;爬山算法是一种简单的贪心搜索算法&#xff0c;该算法每次从当前位置的临近空间中选择一个最优解作为当前解&#xff0c;直到达到一个局部最优解。爬山算法可以类比成一个有失忆的人在浓雾中爬山。这里就揭示了爬山算法的两个问题…

搜索 —— 启发式搜索 —— 爬山法

【概述】 爬山法&#xff08;Hill Climbing&#xff0c;HC&#xff09;是一种局部择优的贪心搜索算法&#xff0c;其本质上是梯度下降法。 该算法每次从当前的节点开始&#xff0c;与周围的邻接点进行比较&#xff1a; 若当前节点是最大的&#xff0c;那么返回当前节点&…

Linux:快速查看IP地址及修改IP地址

导读Linux下如何快速查看IP地址及修改IP地址&#xff0c;有一个方法供参考 查ip 方法/步骤1: 打开linux操作系统在进入到界面 方法/步骤2: 在桌面右击打开终端。 方法/步骤3: 终端里输入ifconfig -a命令在回车键 方法/步骤4: 如下图可以看到了ip地址。 修改ip 方法/…

Linux Ubuntu查看IP信息的两种方式Ubuntu中检查你的 IP 地址

论使用什么系统&#xff0c;都有用到ip地址的时候&#xff0c;习惯了windows系统的人很容易就能查找出系统的ip&#xff0c;但是在linux系统如何查看ip呢&#xff1f;作为Linux新手&#xff0c;以Ubuntu的使用经验&#xff0c;我知道Ubuntu查看IP有两种方式。 第一种是在终端中…

Linux查询出口IP

查询的方式是通过Linux的curl访问查询ip的网站进行查询 具体步骤&#xff1a; 1.查询查询ip网站的ip 2.配置Linux的hosts文件 在/etc中的hosts文件增加上面的域名和ip&#xff08;注意&#xff1a;是ifconfig&#xff0c;不是ipconfig&#xff09; 3.在ssh命令下执行 curl ifc…

Linux 查看本地ip

Linux 查看本地ip 终端中输入指令ifconfig -a终端中输入指令hostname -I通过图形界面查看IP地址&#xff08;还未试通&#xff09; 终端中输入指令ifconfig -a 弹出的IP地址有点多 。 终端中输入指令hostname -I 会直接显示本机在局域网内的IP地址&#xff0c;但可能会显示多…

Linux服务器查看Ip地址

在服务器的网络配置中&#xff0c;需要同时配置这两种网络&#xff0c;才能使服务器正常使用。使用内网是为了保证我们的服务器处在一个安全的网络环境中&#xff0c;可以减少外部病毒的影响&#xff0c;而访问外网是为了方便我们配置服务器一些资源&#xff0c;如驱动程序&…

Linux 查看IP

UBuntu 系统下 按CtrlAltT 唤出终端 在终端输入: ifconfig 命令 点击回车 就可以看到自己电脑在局域网的IP地址了 图中第二行 inet 地址&#xff1a;192.168.1.101 就是你的电脑在局域网的IP地址了 如果输入 ifconfig 提示 找不到命令 那就在终端输入&#xff1a;sudo apt-get …

linux查看本机ip地址

linux中哪个命令可以查看自己的IP地址 50 我的主机是通过宽带联网的&#xff0c;主机的IP通过那个本地连接可以看到&#xff0c;但在虚拟机Debian linux5.0终端下输入route -n显示的是destination的IP&#xff0c;怎么查看属于虚拟机linux的IP呢&#xff1f;&#xff08;linux通…

Linux系统下怎么查询自己的ip和port

Linux系统下如何查询自己的ip和port 前言&#xff1a;在Linux系统中&#xff0c;学习网络协议之后&#xff0c;就需要经常查看自己系统的ip和port是否正常开启,那么怎么快速查找它们呢&#xff1f; 我现在就把它们列出来&#xff0c;以解我的心头之恨&#xff01;&#xff01;…

Linux查看IP地址命令

Linux查看公有&#xff08;运营商&#xff09;IP地址&#xff1a;下面两个命令都可以查 curl http://ifconfig.io curl ident.me Linux查看私有IP地址&#xff1a;可以使用以下四个命令中的任一一个 ip addr hostname -I | awk {print $1} ip route get 1.2.3.4 | awk {print…

linux怎么查看ip地址

linux怎么查看IP地址&#xff0c;怎么使用命令来查看IP地址&#xff1f;如下图教您怎么操作。 演示环境&#xff1a;centos7 方法一&#xff1a; 首先打开linux操作系统在进入到界面。 桌面右键打开终端 在终端里输入命令后按下回车键 ifconfig -a我们将看到ens33 位置处的…