【图】:常用图搜索(图遍历)算法

目录

  • 概念
  • 图遍历
    • 深度优先搜索 (DFS)
      • DFS 适用场景
      • DFS 优缺点
    • 广度优先搜索 (BFS)
      • BFS 适用场景
      • BFS 优缺点
    • DFS & BFS 异同点
  • 图搜索
    • Dijkstra算法
    • A*算法
    • Floyd算法
    • Bellman-Ford算法
    • SPFA算法

概念

图遍历和图搜索是解决图论问题时常用的两种基本操作。

  • 图遍历是指从图中的某一个节点出发,访问图中所有的节点,确保每个节点都被访问到且不会重复访问。图遍历有两种主要方式:深度优先搜索(DFS)广度优先搜索(BFS)
  • 图搜索是指在图中寻找特定目标的过程。搜索可能是无目标的(即只是为了遍历整个图),也可能是有目标的,希望找到特定的节点或路径。最常用的有目标图搜索算法是Dijkstra算法(用于找到单源最短路径)和A*算法(结合了BFS和启发式搜索,用于找到最优路径)。

图遍历

深度优先搜索 (DFS)

深度优先搜索(Depth First Search,DFS)是一种用于遍历或搜索树或图的算法。它从起始顶点开始,沿着一条路径直到不能继续为止,然后返回到最近的一个未访问过的节点,继续相同的过程,直到所有节点都被访问过。

在这里插入图片描述

function DFS(node):if node is not visited:mark node as visitedfor each neighbor of node:DFS(neighbor)

DFS 适用场景

  • 寻找路径:DFS 在寻找路径方面非常强大,可以用于解决迷宫问题、寻找图中两个节点之间的路径等。
  • 拓扑排序:DFS 可以用于在有向图中进行拓扑排序,例如在编译器优化、任务调度等领域中应用广泛。
  • 检测环路:DFS 可以用于检测图中是否存在环路,对于拓扑排序来说,有向无环图 (DAG) 才有拓扑排序的结果。
  • 生成最小生成树:DFS 可以用于生成最小生成树,例如在 Prim 算法中。

DFS 优缺点

优点:

  1. 节省空间:相比较于 BFS,DFS 使用递归实现时,不需要额外的数据结构来保存访问状态,因此可能会更节省空间。
  2. 发现深层次的节点:DFS 会尽可能深地探索某一条分支,因此在找到目标节点或解之前,会一直沿着一条路径向下探索。

缺点:

  1. 可能陷入死循环:如果图中包含循环,且没有合适的终止条件,DFS 可能会陷入无限循环。可能

  2. 找到的不是最短路径:由于 DFS 是尽可能深地探索某一条分支,所以找到的路径不一定是最短路径。


广度优先搜索 (BFS)

广度优先搜索(Breadth First Search,BFS)也是一种用于遍历或搜索树或图的算法。它从起始顶点开始,首先访问所有与起始顶点相邻的节点,然后逐层向下访问。

在这里插入图片描述

function BFS(start):create a queue Qenqueue start into Qmark start as visitedwhile Q is not empty:current = dequeue from Qfor each neighbor of current:if neighbor is not visited:mark neighbor as visitedenqueue neighbor into Q

BFS 适用场景

  • 寻找最短路径:BFS 可以用于寻找图中两个节点之间的最短路径,因为它会逐层扩展,所以找到的路径一定是最短的。
  • 最小生成树 (Prim 算法):BFS 也可以用于 Prim 算法中生成最小生成树的过程。

BFS 优缺点

优势:

  1. 找到最短路径:BFS 适用于需要找到最短路径的情况,因为它会优先访问距离起点更近的节点。
  2. 避免陷入死循环:BFS 通常不容易陷入死循环,因为它会逐层扩展,不会无限制地向下探索。

缺点:

  1. 可能占用更多内存:BFS 通常需要一个队列来保存待访问节点,可能会占用比DFS更多的内存。
  2. 不一定能找到最深层次的节点:BFS 在发现目标节点时,不一定会沿着一条深度较大的路径找到它。

DFS & BFS 异同点

相同点:

DFS 和 BFS 都是图遍历算法,用于访问图中的所有节点,确保每个节点都被访问到。

不同点:

  1. 搜索方式:
    - DFS:尽可能深地探索某一条分支,直到不能继续为止,然后回溯。
    - BFS:先访问与起始节点直接相邻的所有节点,然后逐层向下访问。

  2. 适用场景:
    - DFS 适用于寻找路径、拓扑排序、检测环路等问题。
    - BFS 适用于寻找最短路径、最小生成树等问题。

  3. 找到的路径:
    - DFS 找到的路径不一定是最短路径。
    - BFS 一定能找到最短路径。

  4. 空间复杂度:
    - DFS 可能会节省一些空间,特别是使用递归实现时。
    - BFS 通常会占用更多的内存,因为需要一个队列来保存待访问节点。

总的来说,选择使用DFS还是BFS取决于具体的问题和需求。如果需要寻找最短路径或最优解,通常选择BFS。如果问题需要深度搜索或者对内存消耗有限制,可能会选择DFS


图搜索

图搜索根据目标可以分为,目标节点搜索目标路径搜索。

Dijkstra算法

给定一个带权有向图 G=(V,E) ,其中每条边的权是一个非负实数。另外,还给定 V 中的一个顶点,称为源。现在我们要计算从源到所有其他各顶点的最短路径长度。这里的长度是指路上各边权之和。这个问题通常称为单源最短路径问题,如下图所示。

算法思想:将图G中所有的顶点V分成两个顶点集合S和T。以v为源点已经确定了最短路径的终点并入S集合中,S初始时只含顶点v,T则是尚未确定到源点v最短路径的顶点集合。然后每次从T集合中选择S集合点中到T路径最短的那个点,并加入到集合S中,并把这个点从集合T删除。直到T集合为空为止。

在这里插入图片描述

function Dijkstra(Graph, source):create empty set Screate a set Q containing all nodescreate a map distance and set distance[source] = 0while Q is not empty:u = node in Q with smallest distance[u]remove u from Qadd u to Sfor each neighbor v of u:if distance[u] + weight(u, v) < distance[v]:distance[v] = distance[u] + weight(u, v)return distance

算法复杂度:

  • 设带权有向图的边数为m,顶点数为n。
    • 用数组存储顶点方式实现复杂度为: O ( n 2 ) O(n^2) O(n2)
    • 用邻接表存储 + 二叉堆实现复杂度为: O ( ( m + n ) l o g n ) O((m+n)logn) O((m+n)logn)
    • 用邻接表存储 + 斐波那契堆实现复杂度为: O ( m + n l o g n ) O(m+nlogn) O(m+nlogn)

A*算法

A*算法结合了启发式搜索和Dijkstra算法的思想,用于在加权图中找到起点到目标节点的最短路径。它使用一个启发式函数来估计从当前节点到目标节点的距离,并根据这个估计值选择下一个要扩展的节点。

适用于带有启发式函数的加权图,找到起点到目标节点的最短路径。

function AStar(Graph, source, target):create empty set openSet and add source to itcreate empty set closedSetcreate a map gScore and set gScore[source] = 0create a map fScore and set fScore[source] = heuristic(source, target)while openSet is not empty:current = node in openSet with lowest fScoreif current == target:return reconstructPath(cameFrom, current)remove current from openSetadd current to closedSetfor each neighbor of current:if neighbor is in closedSet:continuetentative_gScore = gScore[current] + distance(current, neighbor)if neighbor is not in openSet or tentative_gScore < gScore[neighbor]:cameFrom[neighbor] = currentgScore[neighbor] = tentative_gScorefScore[neighbor] = gScore[neighbor] + heuristic(neighbor, target)if neighbor is not in openSet:add neighbor to openSetreturn failure

Floyd算法

Floyd算法用于解决所有节点对之间的最短路径问题。它采用动态规划的思想,通过中间节点的遍历来更新任意两个节点之间的最短路径。

通过Floyd计算图G=(V,E)中各个顶点的最短路径时,需要引入一个矩阵S,矩阵S中的元素a[i][j]表示顶点i(第i个顶点)到顶点j(第j个顶点)的距离。

假设图G中顶点个数为N,则需要对矩阵S进行N次更新。初始时,矩阵S中顶点a[i][j]的距离为顶点 i 到顶点 j 的权值;如果 i 和 j 不相邻,则a[i][j]=∞。 接下来开始,对矩阵 S 进行N次更新

第1次更新时,如果"a[i][j]的距离" > “a[i][0]+a[0][j]”(a[i][0]+a[0][j]表示" i 与 j 之间经过第1个顶点的距离"),则更新a[i][j]为"a[i][0]+a[0][j]“。 同理,第k次更新时,如果"a[i][j]的距离” > “a[i][k]+a[k][j]”,则更新a[i][j]为"a[i][k]+a[k][j]"。更新N次之后,操作完成!

在这里插入图片描述

function FloydWarshall(Graph):let dist be a matrix of size VxV, initialized with infinityfor each edge (u, v) in Graph:dist[u][v] = weight(u, v)for k from 1 to V:for i from 1 to V:for j from 1 to V:if dist[i][k] + dist[k][j] < dist[i][j]:dist[i][j] = dist[i][k] + dist[k][j]return dist

Bellman-Ford算法

Bellman-Ford算法用于在带有负权边的图中找到单源最短路径。它通过对边进行松弛操作来逐步优化到达每个节点的最短距离。解题思路就是假设有一条边 {begin,end,value} ,如果 dis[begin] + value < dis[end] ,我们可以更新 dis[end] 的值为 dis[begin] + value

Bellman-Ford不能计算有负权回路的图,因为在负权回路中,如果一直转圈的话,值就会一直变小。

在这里插入图片描述

function BellmanFord(Graph, source):create a list of size V called distance and set distance[source] = 0for i from 1 to V-1:for each edge (u, v) in Graph:if distance[u] + weight(u, v) < distance[v]:distance[v] = distance[u] + weight(u, v)for each edge (u, v) in Graph:if distance[u] + weight(u, v) < distance[v]:return "Graph contains a negative-weight cycle"return distance

SPFA算法

SPFA算法也用于在带有负权边的图中找到单源最短路径。它采用了队列来优化Bellman-Ford算法,通过动态选择要松弛的节点,减少了不必要的松弛操作,提高了算法的效率。

function SPFA(Graph, source):create a queue Qenqueue source into Qcreate a set visited and add source to itcreate a map distance and set distance[source] = 0while Q is not empty:current = dequeue from Qremove current from visitedfor each neighbor of current:if distance[current] + weight(current, neighbor) < distance[neighbor]:distance[neighbor] = distance[current] + weight(current, neighbor)if neighbor is not in visited:enqueue neighbor into Qadd neighbor to visitedreturn distance

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

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

相关文章

nssm部署nginx

nssm install Nginx8098 --安装nginx nssm start Nginx8098 --启用nginx nginx 选择nginx路径&#xff0c;安装

易云维®工厂能耗管理平台系统方案,保证运营质量,推动广东制造企业节能减排

我国《关于完整准确全面贯彻新发展理念推进碳达峰碳中和工作的实施意见》出台&#xff0c;提出了推进碳达峰碳中和工作的总体目标。到2025年&#xff0c;广东具备条件的地区、行业和企业率先实现碳达峰&#xff0c;为全省实现碳达峰、碳中和奠定坚实基础&#xff1b;2030年前实…

玩具乐器展示预约小程序的内容是什么

玩具乐器产品的受众非常广&#xff0c;随着互联网电商深入&#xff0c;很多传统线下经营的商家开始转变为线上经营&#xff0c;入驻第三方平台或自建线上商城卖货等&#xff0c;当然除了直接卖产品外&#xff0c;还有产品展示预约咨询场景&#xff0c;因此很多商家也会选择制作…

redis主从复制玩法全过程笔记(redis7+版本)

目录标题 环境目的实操一主多仆服务器和本地主机配置环境docker 环境配置 薪火相传反客为主 主从复制的流程主从复制的特性主从复制的缺点本篇结语 环境 我的环境介绍window环境VM虚拟机一台并安装centos7&#xff0c;一台阿里云Linux服务器&#xff0c;另一台Linux系统主机并…

Mybatis-Plus使用Wrapper自定义SQL

文章目录 准备工作Mybatis-Plus使用Wrapper自定义SQL注意事项目录结构如下所示domain层Controller层Service层ServiceImplMapper层UserMapper.xml 结果如下所示&#xff1a;单表查询条件构造器单表查询&#xff0c;Mybatis-Plus使用Wrapper自定义SQL联表查询不用&#xff0c;My…

C# OpenCvSharp 去除字母后面的杂线

效果 项目 代码 using OpenCvSharp; using System; using System.Drawing; using System.Windows.Forms;namespace OpenCvSharp_Demo {public partial class frmMain : Form{public frmMain(){InitializeComponent();}string image_path "";private void Form1_Loa…

最近的总结(2023.11.8)

菜鸟本来是不打算写文章的&#xff0c;奈何1500的曝光券让我心痒难耐 菜鸟主要是想把这篇博客&#xff08;平凡人的一生的意义是什么&#xff1f;&#xff09;推出去&#xff0c;看看大家的看法&#xff01; 不过既然写&#xff0c;菜鸟自然要好好写&#xff0c;就来聊聊最近…

如何选择SVM中最佳的【核函数】

参数“kernel"在sklearn中可选以下几种 选项&#xff1a; 接下来我们 就通过一个例子&#xff0c;来探索一下不同数据集上核函数的表现。我们现在有一系列线性或非线性可分的数据&#xff0c;我们希望通过绘制SVC在不同核函数下的决策边界并计算SVC在不同核函数下分类准确…

NeRF神经辐射场渲染过程详解,三维重建渲染过程基本原理_光线采样sample_pdf()和光线渲染render_rays ()代码详解

目录 1 神经辐射场 1.1 基本原理 1.2 基本流程 1.3 数学解释 2 三维场景图像渲染详解 2.1射线采样 2.2 NeRF 模型预测 2.3 体积渲染 3 采样与渲染代码详解 &#xff08;rending.py&#xff09; 3.1 神经体积渲染代码解析 3.2 sample_pdf 函数 3.3 render_rays 函数 …

持续集成交付CICD:Jenkins Pipeline与远程构建触发器

目录 一、实验 1.Jenkins Pipeline本地构建触发器 2.Jenkins Pipeline与远程构建触发器&#xff08;第一种方式&#xff09; 3.Jenkins Pipeline与远程构建触发器&#xff08;第二种方式&#xff09; 4.Jenkins Pipeline与远程构建触发器&#xff08;第三种方式&#xff0…

3.JMeter高级使用-让你与众不同

目录 概述插件下载与安装插件下载配置插件 服务器硬件资源监控(精简版)配置服务端代理JMeter配置监控CPU监控网络 JMeter下载结束 概述 今日目标&#xff1a; 插件下载与安装Basic Graphs 主要点 Average Response Time 平均响应时间Active Threads 活动线程数Successful/Fai…

windows11使用docker部署安装minio

时间 2023-11-08 windows11使用docker部署安装minio 目录 1.docker 下载镜像2.docker安装镜像3.访问控制台4.安装问题解决5.使用教程 1.docker 下载镜像 调整镜像源到国内&#xff0c;否则会很慢 docker pull minio/minio2.docker安装镜像 设置用户名和密码时需要注意&…

闪客网盘系统源码,已测试对接腾讯COS及本地和支付(支持限速+按时收费+文件分享+可对接易支付)- 修复版

正文概述 资源入口 支持对文件下载限速 对接易支付 推广赚钱啥的功能 源码非常的好 支持腾讯cos 阿里云cos 本地储存 远程存储 源码仅支持服务器搭建 php7.2 伪静态thinkphp 运行目录public 导入数据库 修改config目录下的database.php数据库信息 后台地址&#xff1a; 域名/ad…

大型企业是否有必要进行数字化转型?_数据治理平台_光点科技

数字化转型是大型企业在现代商业环境中保持竞争力的关键。一开始我们要明确数字化转型指的是利用数字技术来改变企业的业务模式和企业文化&#xff0c;以提高效率和效益。对于大型企业而言&#xff0c;进行数字化转型有着多重必要性。 1.数字化转型可以帮助企业优化内部流程&am…

P02项目诊断报警组件(学习操作日志记录、单元测试开发)

★ P02项目诊断报警组件 诊断报警组件的主要功能有&#xff1a; 接收、记录硬件设备上报的报警信息。从预先设定的错误码对照表中找到对应的声光报警和蜂鸣器报警策略&#xff0c;结合当前的报警情况对设备下发报警指示。将报警消息发送到消息队列&#xff0c;由其它组件发送…

【delphi】中 TNetHTTPClient 注意事项

一、TNetHTTPClient 是什么&#xff1f; 用于管理 HTTP 客户端的组件。相当于indy中的TidHTTP控件&#xff0c;是实现HTTP请求的客户端控件。 二、TNetHTTPClient 需要注意什么&#xff1f; 需要注意的是几个Timeout&#xff0c;因为我们使用TNetHTTPClient控件的时候&#x…

JavaScript使用正则表达式

正则表达式(RegExp)也称规则表达式(regular expression)&#xff0c;是非常强大的字符串操作工具&#xff0c;语法格式为一组特殊字符构成的匹配模式&#xff0c;用来匹配字符串。ECMAScript 3以Perl为基础规范JavaScript正则表达式&#xff0c;实现Perl 5正则表达式的子集。Ja…

2023年云计算发展趋势:生活的智能未来

目录 引言1 智能家居的崭新时代2 无人驾驶的崭新时代3 虚拟现实的扩展与改进4 人工智能的综合应用5 云计算的可持续性结语 引言 时光荏苒&#xff0c;科技的飞速发展已经成为当今社会的标志之一。在这个数字化时代&#xff0c;云计算已经成为推动技术革新和生活方式改变的关键…

uniapp subNvue 写的视频播放

文件下载地址(没会员的留下邮箱&#xff0c;有空就发过去) https://download.csdn.net/download/weixin_47517731/88500016https://download.csdn.net/download/weixin_47517731/88500016 1:在pages.json中配置视频播放页面 {/* 视频详情页面 */"path": "pag…

力扣每日一题 ---- 2918. 数组的最小相等和

贪心题(吐槽一下&#xff0c;最烦贪心题了&#xff0c;每次遇到没见过的就只能连蒙带骗) 好在本题比较容易发现 数组1 &#xff1a;3 2 0 1 0 数组2 &#xff1a;6 5 0 我们遇到这种题&#xff0c;先将小的凑成相同的&#xff0c;(我们预处理出来两个数组的分别的元素和和0的个…