0x26 广搜变形

0x26 广搜变形

1.双端队列BFS

在最基本的广度优先搜索中,每次沿着分支的扩展都记为“一步”,我们通过逐层搜索,解决了求从起始状态到每个状态的最少步数的问题。这其实等价于在一张边权均为1的图上执行广度优先遍历,求出每个点相对于起点的最短距离(层次)。在第0x21节中我们曾讨论过这个问题,并得到了“队列中的状态的层数满足两段性和单调性”的结论。从而我们可以知道,每个状态在第一次被访问并入队时,计算出的步数即为所求。

然而,如果图上的边权不全为1呢?换句话说,如果每次扩展都有不同的“代价”,我们想求出起始状态到每个状态的最小代价,应该怎么办呢?我们不妨先来讨论图上的边权要么是1、要么是0的情况。

在这样的图上,我们可以通过双端队列广搜来计算。算法框架与一般的广搜类似,只是在每个节点上沿着分支拓展时稍作改变。如果这条分支是边权为0的边,就把沿该分支到达的新节点从队头入队;如果这条分支是边权为1的边,就像一半的广搜一样从队尾入队。这样一来,我们就仍然能保证,任意时刻广搜队列中的节点对应的距离值都具有“两段性”和“单调性”。

2.优先队列BFS

对于更加具有普适性的情况,也就是每次扩展都有各自不同的“代价”时,求出起始状态到每个状态的最小代价,就相当于在一张带权图求出从起点到每个节点的最短路。此时,我们有两个解决方案:

方法一

仍然使用一般的广搜,采用一般的队列。

这时我们不能保证每个状态第一次入队时就能得到最小代价,所以只能允许一个状态被多次更新、多次进出队列。我们不断执行搜索,直到队列为空。

整个广搜算法对搜索树进行了重复遍历与更新,直到“收敛”到最优解,其实也就是“迭代”的思想。最坏情况下,该算法的时间复杂度会从一般广搜的 O ( N ) O(N) O(N)增长到 O ( N 2 ) O(N^2) O(N2)。对应在最短路问题中,就是我们将在0x61节介绍的 S P F A SPFA SPFA算法。

方法二

改用优先队列进行广搜。

这里的“优先队列”就相当于一个二叉堆。我们每次可以从队列中取出当前代价最小的状态进行扩展(该状态一定是最优的,因为队列中其他状态的当前代价都不小于它,所以以后就更不可能在更新它了),沿着各条分支把到达的新状态加入优先队列。不断执行搜索,直到队列为空。

在优先队列BFS中,每个状态也会被多次更新、多次进出队列,一个状态也可能以不同的代价在队列中同时存在。不过当每个状态第一次从队列中被取出时,就得到了从起始状态到该状态的最小代价。之后若再被取出,则可以直接忽略,不进行拓展。所以,优先队列BFS中的每个状态只拓展一次,时间复杂度只多了维护二叉堆的代价。若一般广搜的复杂度为 O ( N ) O(N) O(N),则优先队列BFS的复杂度为 O ( N l o g N ) O(NlogN) O(NlogN)。对应在最短路问题中,就是我们将在0x61节中介绍的堆优化 D i j k s t r a Dijkstra Dijkstra算法。

下图就展示了优先队列BFS的详细过程,每条边的数值标明了每个状态向下扩展所需的代价,节点中的数值标明了每个状态上求出的“当前代价”,灰色节点标明了每个时刻在堆中出现至少一次的节点。

在这里插入图片描述

在这里插入图片描述

建议不熟悉最短路相关算法的读者,简要对0x61节的两个单源最短路径算法进行阅读,这对于理解并写出正确的优先队列BFS有很大的帮助。

至此,我们就可以对BFS的形式,按照对应在图上的边权情况进行分类总结:

1.问题只计最少步数,等价于在边权都为1的图上求最短路。

使用普通的BFS,时间复杂度 O ( N ) O(N) O(N)

每个状态只访问(入队)一次,第一次入队时即为该状态的最少步数。

2.问题每次扩展的代价可能是0或1,等价于在边权只有0和1的图上求最短路。

使用双端队列BFS,时间复杂度 O ( N ) O(N) O(N)

每个状态被更新(入队)多次,只扩展一次,每一次出队时即为该状态的最小代价。

3.问题每次扩展的代价是任意数值,等价于一般的最短路问题。

(1)使用优先队列BFS,时间复杂度 O ( N l o g N ) O(NlogN) O(NlogN)

每个状态被更新(入队)多次,只扩展一次,第一次出队时即为该状态的最小代价。

(2)使用迭代思想+普通的BFS,时间复杂度 O ( N 2 ) O(N^2) O(N2)

每个状态被更新(入队)、扩展(出队)多次,最终完成搜索后,记录数组中保存了最小代价。

3.双向BFS

0x24节中我们介绍了双向搜索的思想,双向BFS与双向DFS的思想完全相同。因为BFS本身就是逐层搜索的算法,所以双向BFS的实现更加自然、简便。以普通的求最少步数的双向BFS为例,我们只需从起始状态、目标状态分别开始,两边轮流进行,每次各扩展一整层。当两边各自有一个状态在记录数组中发生重复时,就说明这两个搜索相遇了,可以合并得出起点到终点的最少步数。

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

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

相关文章

idea 如何使用 JaCoCo 跑覆盖率

背景介绍 什么代码覆盖? 代码覆盖(Code coverage)是软件测试中的一种度量,描述程序中源代码被测试的比例和程度,所得比例称为代码覆盖率。简单来理解,就是单元测试中代码执行量与代码总量之间的比率。 Java常用的单元测试覆盖率…

为什么要用云渲染?3d Max云渲染怎么使用?

云计算技术的兴起让渲染任务的执行更加灵活和高效。借助于云计算服务,影视和动画制作公司能够将大型和资源密集型的渲染任务外包至远程服务器。这些任务在云渲染服务器上按块处理,而更小规模的渲染作业则可在本地工作站上完成。这种作业分配方法大幅优化…

MyBatis的配置文件!!!(properties标签 , typeAliases标签,Mappers标签)

一.将数据库配置信息定义在一个独立的配置文件里。 mybatis-config.xml: <?xml version"1.0" encoding"UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-co…

【ICCV 2023】MPI-Flow:什么,只需要单张图片就能训练光流估计模型了?

ICCV 2023 | MPI-Flow&#xff1a;从单视角构建的多平面图像中学习光流 引言&#xff1a;主要贡献&#xff1a;Motivation&#xff1a;算法细节&#xff1a;Optical Flow Data GenerationIndependent Object MotionsDepth-Aware Inpainting 实验结果&#xff1a; 来源&#xff…

海外代理IP如何选择?如何避开误区?

近年来&#xff0c;我国互联网商业保持持续发展的状态大环境的优化&#xff0c;大大小小的企业都想乘胜追击&#xff0c;大展宏图&#xff0c;积极推动各项数据业务的进程。 而对于跨境业务来说&#xff0c;代理IP是不可或缺的重要工具之一&#xff0c;市面上代理IP类型众多&a…

由于CUDA OOM,对XLA(HLO)内存分配过程的一点总结

单卡&#xff08;A800, 80GB&#xff09;测试llama7B时出现CUDA OOM&#xff0c;从日志看&#xff0c;是分配preallocated temp allocation时&#xff0c;出现了OOM。从结果上看&#xff0c;XLA module需要的临时内存&#xff0c;需要一次性分配出来&#xff0c;这导致图还未真…

《opencv实用探索·二十一》人脸识别

Haar级联分类器 在OpenCV中主要使用了两种特征&#xff08;即两种方法&#xff09;进行人脸检测&#xff0c;Haar特征和LBP特征。用的最多的是Haar特征人脸检测。 Haar级联分类器是一种用于目标检测的机器学习方法&#xff0c;它是一种基于机器学习的特征选择方法&#xff0c;…

一款双极锁存型霍尔位置传感器

一、产品特点 双极锁存型霍尔效应传感器 宽的工作电压范围: 3.8V~30V 集电极开路输出 最大输出灌电流&#xff1a;50mA 电源反极性保护 工作温度&#xff1a;-40℃~125℃ 封装形式: SOT23-3 TX412是一款集成霍尔效应传感器&#xff0c;主要应用于直流无刷电机的电子信号…

【JAVA】仓库、货架、货物

当前只有添加、查询&#xff0c;没有删除和修改部分&#xff1a; import java.util.LinkedList;class Goods {String id;String name;int price;public Goods(String id, String name, int price) {this.id id;this.name name;this.price price;}Overridepublic String toS…

Kafka为什么能高效读写数据

1&#xff09;Kafka 本身是分布式集群&#xff0c;可以采用分区技术&#xff0c;并行度高&#xff08;生产消费方并行度高&#xff09;&#xff1b; 2&#xff09;读数据采用稀疏索引&#xff0c;可以快速定位要消费的数据&#xff1b; 3&#xff09;顺序写磁盘&#xff1b; …

Redis数据结构及使用

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理、分布式技术原理、数据库技术&#x1f525;如果感觉博主的文章还不错的…

网易面试:亿级用户,如何做微服务底层架构?

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业网易、美团、字节、如阿里、滴滴、极兔、有赞、希音、百度、美团的面试资格&#xff0c;遇到很多很重要的面试题&#xff1a; 微服务改造&#xff0c;你是怎么做的&#xff1…