数据结构与算法设计分析——常用搜索算法

目录

  • 一、穷举搜索
  • 二、图的遍历算法
    • (一)深度优先搜索(DFS)
    • (二)广度优先搜索(BFS)
  • 三、回溯法
    • (一)回溯法的定义
    • (二)回溯法的应用
  • 四、分支限界法
    • (一) 上界与下界
    • (二) 分支限界法的定义
    • (三)分支限界法的应用
  • 五、回溯法与分支限界法的对比

一、穷举搜索

穷举搜索法也被称为穷举法,其基本思想是将问题的所有的候选解都枚举出来,然后对候选解按照某种顺序进行逐一枚举和检验,并从中找出符合问题要求的候选解作为问题的解。其优点是实现简单且易于理解,适合规模较小的问题,但当问题的规模较大时,由于需要运行问题所有的候选解消耗大量的时间,从而导致算法的效率大大降低。

二、图的遍历算法

图的遍历算法适合无向图和有向图,有两种方法可分为深度优先搜索(DFS)和广度优先搜索(BFS)。

(一)深度优先搜索(DFS)

深度优先搜索的定义
简单地说,图的深度优先搜索可概括为尽可能深地去搜索一个图,是一个递归的过程(需要用到存储),通过遍历邻接表或邻接矩阵的方式深入搜索一个图,直到访问完所有连通的顶点,若当前分支已经访问过,则会回溯到上一个顶点,继续搜索其他分支顶点,直到所有顶点被访问。

  • 递归这一点就类似树的先序遍历,先访问结点,然后递归向外层结点遍历,尽可能深地搜索一个图,都采用回溯算法。

图的深度优先搜索首先选取图中某一顶点vi,访问后,任意选取一个与vi邻接的顶点,且该顶点未被访问,……,继续重复该过程,直到图中所有与vi连通的顶点都被访问到;若还有顶点未被访问到,则另外选取一个未被访问的顶点再次作为起始点,重复以上步骤,继续直至图中所有结点被访问。

例如,对下面这个图,以顶点a为源点对该图进行深度优先遍历,求其一个遍历序列:
在这里插入图片描述
首先,选择与a邻接的任一顶点,由于与a邻接的顶点有b,c,e,可有以下三种访问序列{a,b,……}或{a,c,……}或{a,e,……},如下:
在这里插入图片描述
然后,选择访问顶点d,也可以选择还未被访问的顶点。由于先前选择访问的序列是{a,d},此时访问与顶点d相邻的顶点f,得到序列{a,d,f};再访问与顶点f相邻的顶点c,得到序列{a,d,f,c};由于此时与c邻接的顶点a和f都被访问过,回退到f,继续检查d,与d邻接的顶点也被访问过,……,最后直到顶点d还未被访问,访问它,可得到一个序列{a,e,d,f,c,b}。【序列不唯一】
在这里插入图片描述

可看出a,e,d,f,c这段部分是该图中尽可能深地去搜索一个图的明显体现。

深度优先搜索的空间复杂度和时间复杂度
对于一个图G=(V,E),由顶点集V和边集E组成。
1、空间复杂度

  • 由于DFS算法是一个递归算法,即递归遍历顶点集V,所以通过DFS遍历的空间复杂度为O(|V|)。

2、时间复杂度

  • 时间复杂度取决于图的存储结构,若通过邻接矩阵表示图,则查找顶点的邻接顶点所需时间为O(|V|),总时间复杂度为O(|V2|)(邻接矩阵为方阵n×n);若通过邻接表表示图,则查找所有顶点的邻接顶点所需时间为O(|E|),访问顶点所需时间为O(|V|),即总时间复杂度为O(|V|+|E|)。

(二)广度优先搜索(BFS)

广度优先搜索的定义
广度优先搜索是通过队列来存储顶点实现遍历(队列用于避免重复访问,存放已经访问过的各邻接顶点),可以采用邻接表或邻接矩阵搜索,首先从起始点开始访问,将其邻接顶点依次入队,直到队列为空,从而访问到所有的顶点,即逐层遍历所有的顶点直到遍历完所有节点

  • 逐层遍历这一点就类似树的层序遍历,一层一层向外遍历。

图的广度优先搜索中首先选取一个起始点顶点vi,访问后将其入队并标记为已访问,当队列不为空时检查出队顶点的所有邻接顶点,访问未被访问的邻接顶点并将其入队,……,继续重复该过程,直到图中所有与vi连通的顶点都被访问到;当队列为空时跳出循环,则此时遍历完成。

例如,如下所示的图,从顶点1开始求一个广度优先搜索遍历序列:
在这里插入图片描述
首先,选择与顶点1邻接的所有顶点进行访问,有2和3,可得序列{1,2,3}或{1,3,2};然后,再访问与2和3邻接的其他顶点,直到所有顶点被访问。例如,访问顶点2和3后,访问其邻接顶点4,然后再依次访问顶点4的邻接顶点5和6,最后访问顶点7,得到{1,2,3,4,5,6,7}。【序列不唯一】
广度优先搜索的空间复杂度和时间复杂度
对于一个图G=(V,E),由顶点集V和边集E组成。
1、BFS算法的空间复杂度

  • 与深度搜索所需空间一样,通过BFS遍历的空间复杂度也为O(|V|)。

2、BFS算法的时间复杂度

  • 时间复杂度取决于图的存储结构,若通过邻接矩阵表示图,则查找顶点的邻接顶点所需时间为O(|V|),总时间复杂度为O(|V2|)(邻接矩阵为方阵n×n),这和DFS算法的时间复杂度是一样的;若通过邻接表表示图,则每个顶点都入队一次,即所需时间为O(|V|),搜索顶点的邻接顶点所需时间为O(|E|),其时间复杂度为O(|V|+|E|)。

三、回溯法

(一)回溯法的定义

回溯法用到了上面的深度优先搜索(DFS)的思想,首先,通过穷举所有可能的解(明确搜索范围),从初始状态出发,以深度优先搜索来搜索问题的解,若当前结点不满足,则会退一步回溯到上一个结点尝试其他选择,直到最后找到包含问题解的结点。同样,若问题规模较大时,由于需要穷举所有可能的解,所以此时回溯法的搜索效率较低。【找出解空间树中满足约束条件的所有解】

注:递归算法与回溯法不是同一种思想,回溯法是穷举解空间树来找到满足条件的解的搜索算法思想,而递归是将大问题划分成小问题,然后通过递归以解决小问题来实现最终问题的解,运用了分治的思想。

回溯法的算法框架可分为三部分:
1、针对所给问题,定义问题的解空间;

2、确定易于搜索的解空间组织结构;

3、以深度优先搜索解空间,并在搜索过程中用剪枝函数(隐约束)避免无效搜索。

隐约束分为两种,一种是约束条件,用于判断是否能得到可行解,二是限界条件,用于判断是否能得到最优解。所以,从算法上来看,回溯法是一种带有约束函数(约束条件)或限界函数(限界条件)的深度优先搜索方法。

(二)回溯法的应用

回溯法常用解决排列问题、组合问题、子集问题、路径问题等等。
1、组合问题(组合树/满m叉树)
一组元素中有若干个元素,若将这些元素组合使其一起满足某种性质,该问题的所有组合(解空间树)是一棵满m叉树组合树。例如一个满二叉树如下(m=2):
在这里插入图片描述
例如,一个满m叉树的实例:
对于一个有4个交通信号灯的道路,每个交通信号灯有3种可能的选择(红、黄、绿),需要找出一种选择,使得该道路满足某活动。该场景可以使用满三叉树来表示每个元素(交通信号灯)的选择情况,在满三叉树的每个节点上,有三个子节点,每个子节点代表一个元素(交通信号灯)的选择。如果选择了其中一个元素(交通信号灯),则可以将其对应的子节点标记为已访问,并将该节点加入到结果集中。当遍历完整个满三叉树后,可以得到所有可能的交通信号灯的组合,其中每个组合都满足某种性质,从而找到目标性质满足该活动。

2、排列问题(排列树)
在若干个元素的排列中,确定满足某种性质的一个排列时,该问题的所有排列(解空间树)是一棵排列树。例如,n个元素的排列数为n!(n的阶乘),若n=3,三个元素为{1,2,3},则其排列树如下:
在这里插入图片描述
其中树的根结点为空,表示初始状态。

3、子集问题(子集树)
在若干个元素组成的集合S,确定满足某种性质的一个子集时,该问题的所有子集(解空间树)对应一个子集树。例如,0-1背包问题中,所要找到满足性质的子集为该子集中物品的重量不超过背包容量,且背包内总价值是最大的,该问题的解空间树是一棵子集树。子集树通常有2n个叶结点,其结点总个数为2(n+1)-1,是一棵完全二叉树。

在回溯法中,解向量<x1,x2,…,xn>可以表示为分量取值为{0,1}的比特串,解空间可以组成一颗完全二叉树,这棵搜索树被称为子集树。

四、分支限界法

(一) 上界与下界

对于一个待求解的问题,上界和下界是对问题的可能解进行限制和估计的方法,从而用于解决问题。上界相当于当前最高要求,指问题中的最优解不会超过某个已知值,下界相当于当前最低要求,指问题中的最优解不会低于某个已知值。

利用这一点,可以用于剪枝搜索树的分支,避免对不可能得到最优解的分支进行搜索,从而缩小了搜索空间,达到提高算法效率的目的。

(二) 分支限界法的定义

  • 分支限界法也是一种搜索算法,简单的来说,分支限界法的限界就是利用上界和下界来提高搜索效率。搜索解空间树中利用上界和下界的信息来剪枝搜索树的分支,舍弃导致不可行解或导致非最优解的分支。【找出解空间树中满足约束条件的一个解】

分支限界法中通常采用广度优先搜索(BFS),是以最大收益(最小耗费)的方式来搜索解空间树,其步骤如下:
①首先,将根结点加入活结点表,然后从其中取出,使其成为扩展结点;
②依次生成扩展结点的所有分支,即其孩子结点;
③判断每个孩子结点。通过计算孩子结点的上界和下界,并根据这些界限来决定是否继续搜索该分支,若某个分支的界限满足上界小于或等于下界,则可以剪掉该分支;否则,继续搜索该分支,直到找到满足要求的解或搜索完所有分支(继续通过扩展结点)。

(三)分支限界法的应用

分支限界法的应用场景有:
1、0-1背包问题
2、旅行商问题
旅行商问题指的是在一组给定的城市之间找到最短的路径,使得每个城市恰好被访问一次,最终回到起点。
3、集装箱装载问题
旅行商问题是一个经典的组合优化问题,可以使用分支限界法进行求解。通过搜索所有可能的路径组合,找到总距离最短的一条路径。
4、电路设计中的布线问题
电路设计中的布线问题可以使用分支限界法求解,通过搜索所有可能的布线方式,找到最优解。例如,在M×N的方格中,指定一个方格的中点为a,另一个方格的中点为b,找到a到b的最短路径(布线时只能走直线或直角边)。通过可以把布线的情况剪掉,将能布线的方格加入活结点表,扩展直到找到目标点或活结点表空为止。

五、回溯法与分支限界法的对比

  • 回溯法的优点在于它能够找出所有可能的解,而不仅仅是最优解。而若对于大型问题,回溯法的效率可能较低,因为它需要穷举所有可能的解;分支限界法的优点在于它能够在问题规模较大时,通过剪枝有效地减少搜索空间,从而快速找到最优解,但不能保证找到所有的可能解。
搜索算法名称回溯法分支限界法
搜索解空间树方式深度优先搜索(DFS)广度优先搜索(BFS)
求解解空间树目的找出满足约束条件的所有解找出满足约束条件的一个解
活结点成为扩展结点一次或多次一次

回溯法的适用场景有:n皇后问题、子集树(0-1背包问题、最大团问题)、排列树(旅行商问题、批处理作业调度问题)、组合树(图的m着色问题)等等;

分支限界法的适用场景有:0-1背包问题、旅行商问题、集装箱装载问题、电路设计中的布线问题等等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/190851.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot 2.x 实战仿B站高性能后端项目

SpringBoot 2.x 实战仿B站高性能后端项目 下栽の地止&#xff1a;请看文章末尾 通常SpringBoot新建项目&#xff0c;默认是集成了Maven&#xff0c;然后所有内容都在一个主模块中。 如果项目架构稍微复杂一点&#xff0c;就需要用到Maven多模块。 本文简单概述一下&#xff0c…

【论文阅读】(CTGAN)Modeling Tabular data using Conditional GAN

论文地址&#xff1a;[1907.00503] Modeling Tabular data using Conditional GAN (arxiv.org) 摘要 对表格数据中行的概率分布进行建模并生成真实的合成数据是一项非常重要的任务&#xff0c;有着许多挑战。本文设计了CTGAN&#xff0c;使用条件生成器解决挑战。为了帮助进行公…

如何去掉图片上的水印?这三种去水印的方法帮你解决!

当我们从网上看到喜欢的图片&#xff0c;想要保存下来作为头像或者插入到工作汇报中时&#xff0c;却发现下载的图片带有水印。这不仅影响了图片的美观&#xff0c;还可能对图片的可用性造成影响。那么&#xff0c;如何去掉图片上的水印呢? 实际上&#xff0c;现在市面上的很多…

【每日一题】数位和相等数对的最大和

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;哈希表 写在最后 Tag 【哈希表】【数组】【2023-11-18】 题目来源 2342. 数位和相等数对的最大和 题目解读 在数组中找出数位和相等数对的和的最大值。 解题思路 方法一&#xff1a;哈希表 维护一个不同的数位和表…

【Spring篇】使用注解进行开发

&#x1f38a;专栏【Spring】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【如愿】 &#x1f970;欢迎并且感谢大家指出小吉的问题 文章目录 &#x1f33a;原代码&#xff08;无注解&#xff09;&#x1f384;加上注解⭐两个注…

软磁交流测试仪系统磁参量指标

1. 主要应用 2. 软磁交流测试仪磁参量指标 被测参数 最佳测量不确定度 ( k 2 ) 1 kHz 最佳测量重复性 主要动态磁特性参数 Ps 2.0% 1.0% μa 3.0% 1.0% Bm 1.0% 0.5% Hm 1.0% 0.5% δ 5.0% 1.5% 其他磁特性参数供参考 Br 2.0% 1.0% Hc 3.0% 1.0% μ…

es 算法函数 有点不太懂了没有大神给指点一下

我先说一下我对算法分析的理解 算法函数&#xff0c;我们使用算法函数给指定的数据提高对应的值的方式 比如我现在要给一家酒店排名提高排名&#xff0c;我们可以利用算法函数&#xff0c;提高酒店排名&#xff0c;因为酒店的名称 相关算法的使用场景 在使用的时候出现了这…

代码示例:基于JAX-WS和JAXB,其中http请求和响应的报文体都是xml数据

说明 基于JAX-WS编写了RESTful的web服务端点。 http请求和响应的报文体都是xml数据&#xff0c;服务端分别对应了用JAXB注解的请求和响应类。 只实现了服务端的代码示例 客户端使用了Postman 示例 要实现的目标&#xff1a;http请求和响应报文体的xml数据 http请求报文体的…

快速提高编码生产力——中国用户如何使用Jetbrains内置的AI助手

文章目录 安装AI助手插件怎么在国内使用特殊工具先安排上系统设置代理IDE设置代理 使用案例 安装AI助手插件 此功能依赖于AI Assistant插件&#xff0c;您需要安装并启用该插件。 按打开 IDE 设置&#xff0c;然后选择插件。CtrlAltS打开Marketplace选项卡&#xff0c;找到AI…

Spring 如何自己创建一个IOC 容器

IOC(Inversion of Control),意思是控制反转&#xff0c;不是什么技术&#xff0c;而是一种设计思想&#xff0c;IOC意味着将你设计好的对象交给容器控制&#xff0c;而不是传统的在你的对象内部直接控制。 在传统的程序设计中&#xff0c;我们直接在对象内部通过new进行对象创建…

Swift 如何打造兼容新老系统的字符串分割(split)方法

0. 概览 在 Swift 的开发中&#xff0c;我们经常要与字符串打交道。其中一个常见的操作就是用特定的“分隔符”来分割字符串&#xff0c;这里分隔符可能不仅仅是字符&#xff0c;而是多字符组成的字符串。 从 iOS 16 开始&#xff0c; 新增了对应的方法来专注此事。不过&am…

zabbix的安装配置,邮件告警,钉钉告警

zabbix监控架构 zabbix优点 开源&#xff0c;无软件成本投入server对设备性能要求低支持设备多&#xff0c;自带多种监控模板支持分布式集中管理&#xff0c;有自动发现功能&#xff0c;可以实现自动化监控开放式接口&#xff0c;扩展性强&#xff0c;插件编写容易当监控的item…