【图论】——理论基础总结

图论这一章尤其需要图例进行说明,方便理解,对于作者来说很费时间,本文主要为自己复习方便,所以并不会写的非常详细,见谅。

图论

图的基本概念

基本要素:

  • 节点

两点连成线,多个点连成的线称为图。当然也可以就一个节点,或者啥也没有(空图)。

图的种类

方向的概念
根据边有无方向划分为:

  • 无向图
  • 有向图

权重的概念
边可以有权重,根据有无权重和方向:

  • 加权有向图
  • 加权无向图

度的概念

  • 针对无向图,对于某节点,有几条边连着该节点,就称该节点的度为多少
  • 对于有向图,每个节点有出度和入度
    • 出度:从该节点出发的边的个数
    • 入度:进入该节点的边的个数

连通性的概念

无向图中,根据任意两个节点之间能否到达:

  • 连通图:如果任意两个节点都是可以到达的,可以称之为连通图。
  • 非连通图:反之,如果有任意两个节点不能到达,就是非连通图。

有向图中,注意,是任意两个节点都能互相到达,单向的到达不是强连通图!

  • 强连通图:在有向图中,任何两个节点是可以相互到达的,我们称之为 强连通图。

连通分量的概念
在无向图中,极大连通子图称为该图的一个连通分量。这里最重要的概念是 “ 极大 ” ,只有极大的连通子图才是连通分量!

强连通分量
在有向图中,极大强连通图称为该图的强连通分量。
这里,既是“ 极大 ” , 又是“ 强(任意节点双向可到达) ”,才是强连通分量。

图的构造

基本概念搞清楚了,那么如何用代码表示图?
一般包括:邻接表、邻接矩阵或者类

  1. 邻接矩阵(Adjacency Matrix)
    • 对于一个有 n n n 个顶点的图 G = ( V , E ) G=(V,E) G=(V,E),其邻接矩阵是一个 n × n n×n n×n 的矩阵 A A A。如果图是无向图,当顶点 i i i 和顶点 j j j 之间有边相连时, A i j = A j i = 1 A_{ij}=A_{ji}=1 Aij=Aji=1(若为加权图,则为边的权重值),否则为 0;
    • 如果图是有向图,当存在从顶点 i i i 到顶点 j j j 的边时, A i j = 1 A_{ij}=1 Aij=1(或边的权重), A j i A_{ji} Aji 则根据是否有从 j j j i i i 的边来确定。
    • 这种表示方法的优点是判断两个顶点是否相邻很方便,时间复杂度为 O ( 1 ) O(1) O(1)。缺点是对于稀疏图,会浪费大量的存储空间,因为大量的元素为 0。
    • 例如,一个有 1000 个顶点但只有 100 条边的图,邻接矩阵需要存储 1000 × 1000 = 1000000 1000×1000 = 1000000 1000×1000=1000000 个元素,但实际有用的信息很少。

上面的描述有点抽象

  • 简单说,邻接矩阵就是一个二维矩阵(计算机中叫二维数组)来表示图结构,以节点为主体来描述图
  • 有多少节点就申请多大的二维数组
  • 例如: g r i d [ 2 ] [ 5 ] = 6 grid[2][5] = 6 grid[2][5]=6,表示 节点 2 节点 2 节点2 连接 节点 5 节点5 节点5 为有向图,节点2 指向 节点5,边的权值为 6 6 6
  • 如何用邻接矩阵表示无向图呢? g r i d [ 2 ] [ 5 ] = 6 grid[2][5] = 6 grid[2][5]=6 g r i d [ 5 ] [ 2 ] = 6 grid[5][2] = 6 grid[5][2]=6,表示节点2 与 节点5 相互连通,权值为6。

分析邻接矩阵的优缺点:
缺点:

  • 一个有 N N N 个节点的图,需要申请 N 2 N^2 N2 尺寸的二维数组,需要 N 2 N^2 N2 尺寸的空间,显然邻接矩阵这种表达方式容易造成空间浪费,
  • 并且,在寻找节点连接情况的时候,需要遍历整个矩阵,即时间复杂度也相当高,达到了 O ( l o g N 2 ) O (logN^2) O(logN2)

优点:

  • 表达方式简答,易于理解
  • 检查任意两个顶点之间是否存在边的操作非常快
  • 适合稠密图,在边数接近顶点平方数的图中,邻接矩阵是一种空间效率较高的表示方法
  1. 邻接表(Adjacency List)
    • 对于图中的每个顶点,用一个链表(或其他合适的数据结构,如数组等)来存储与它相邻的顶点。
    • 在有向图中,可以分别存储出边邻接表和入边邻接表。这种表示方法对于稀疏图很节省空间,只存储实际存在的边信息。
    • 其优点是存储效率高,尤其是在边数较少的情况下。
    • 缺点是查询两个顶点是否相邻的时间复杂度比邻接矩阵高,需要遍历链表,平均时间复杂度为 O ( d ) O(d) O(d) d d d 为顶点的度)。
    • 例如,在一个社交网络图中,如果用邻接表表示,每个用户的好友列表就是其邻接表,这样可以高效地存储和查询用户之间的关系。

简单说:

  • 邻接表以边为主体,使用数组+链表来表示边的连接情况,有多少边就申请多少对应大小的链表
  • 优点:
    • 对于稀疏图的存储,只需要存储边,空间利用率高
    • 遍历节点连接情况,相对容易
  • 缺点:
    • 检查任意两个节点之间是否存在边,效率相对较低,需要 O ( V ) O(V) O(V)时间,V表示某节点连接其他节点的数量
    • 实现相对复杂,不直观,不易理解

图的遍历方式

  • 深度优先搜索(DFS)
  • 广度优先搜索(BFS)

注意!

  • 二叉树的递归遍历,是dfs在二叉树上的遍历方式
  • 二叉树的层序遍历,是bfs在二叉树上的遍历方式
  1. 深度优先搜索(DFS - Depth - First - Search)

    • 从图中的某个起始顶点 v v v 开始,首先访问顶点 v v v
    • 然后选择一个与 v v v 相邻且未被访问过的顶点 w w w,递归地对 w w w 进行深度优先搜索,直到遇到一个顶点,其所有相邻顶点都已被访问过,然后回溯到上一个有未访问邻接顶点的顶点,继续搜索。
    • 这个过程可以使用栈(递归调用本身就利用了系统栈)来实现。
    • 例如,在一个迷宫图中,可以想象为沿着一条通道一直走,直到走不通了,再返回上一个岔路口选择另一条路。
    • 在实现中,可以使用一个布尔数组来标记顶点是否已被访问。深度优先搜索可以用来判断图是否连通、寻找图的连通分量、生成图的生成树等。
  2. 广度优先搜索(BFS - Breadth - First - Search)

    • 从起始顶点 v v v 开始,首先访问顶点 v v v,然后依次访问 v v v 的所有未被访问过的邻接顶点,接着再依次访问这些邻接顶点的未被访问过的邻接顶点,以此类推,按照层次进行遍历。这个过程可以使用队列来实现。例如,在一个网络拓扑图中,如果从一个节点开始传播信息,BFS 可以模拟信息按照距离逐步传播的过程。
    • 广度优先搜索可以用于计算图中顶点的最短路径(在无权图中,距离就是边的数目)、判断图的连通性等。在实现时,同样需要一个布尔数组来标记顶点是否已被访问,还需要一个队列来存储待访问的顶点。

最短路径算法

  1. 迪杰斯特拉算法(Dijkstra’s Algorithm)

    • 用于计算加权有向图(或加权无向图)中一个顶点到其他所有顶点的最短路径。算法维护一个集合 S S S,表示已经找到最短路径的顶点集合,初始时只包含起始顶点。对于每个顶点 v v v,记录从起始顶点到 v v v 的当前最短距离 d [ v ] d[v] d[v]。在每次迭代中,选择不在 S S S 中且 d [ v ] d[v] d[v] 最小的顶点 u u u,将其加入 S S S,然后更新与 u u u 相邻的顶点的最短距离估计。例如,在一个交通网络中,要找到从一个城市到其他所有城市的最短距离,迪杰斯特拉算法可以通过逐步扩展已确定最短路径的城市集合来计算。
    • 算法的时间复杂度一般为 O ( ∣ V ∣ 2 ) O(|V|^2) O(V2) ∣ V ∣ |V| V 是顶点数),使用合适的数据结构(如优先队列)可以优化到 O ( ∣ E ∣ + ∣ V ∣ l o g ∣ V ∣ ) O(|E| + |V|log|V|) O(E+VlogV) ∣ E ∣ |E| E 是边数)。
  2. 贝尔曼 - 福特算法(Bellman - Ford Algorithm)

    • 可以处理有负权重边的图(但不能有负权重环),用于计算单源最短路径。算法通过对所有边进行多次松弛操作来逐步逼近最短路径。每次迭代,遍历图中的所有边,尝试更新通过该边连接的两个顶点的最短距离。例如,在一些经济模型中,可能会出现负权重的情况,贝尔曼 - 福特算法可以用于分析成本等相关问题。
    • 算法的时间复杂度为 O ( ∣ V ∣ ∣ E ∣ ) O(|V||E|) O(V∣∣E)
  3. 弗洛伊德算法(Floyd - Warshall Algorithm)

    • 用于计算加权图(有向或无向)中所有顶点对之间的最短路径。算法使用动态规划的思想,通过一个二维数组来存储顶点之间的最短距离,逐步更新数组的值。例如,在分析一个大型通信网络中任意两个节点之间的最短通信路径时,弗洛伊德算法可以一次性计算出所有的最短路径信息。
    • 算法的时间复杂度为 O ( ∣ V ∣ 3 ) O(|V|^3) O(V3)

生成树

  1. 生成树的定义

    • 对于一个连通图 G = ( V , E ) G=(V,E) G=(V,E),生成树是 G G G 的一个子图 T = ( V , E ′ ) T=(V,E') T=(V,E),其中 E ′ ⊆ E E'\subseteq E EE,且 T T T 是一棵树(即无环且连通),包含图 G G G 的所有顶点。例如,在一个电网图中,生成树可以表示一种最小的电线连接方式,使得所有节点都能有电且没有多余的回路。
  2. 最小生成树(MST - Minimum Spanning Tree)

    • 在加权连通图中,所有生成树中边的权重之和最小的生成树称为最小生成树。常见的计算最小生成树的算法有:
    • 普里姆算法(Prim’s Algorithm):从任意一个顶点开始,每次选择一个与当前生成树相连且边权重最小的顶点,将其加入生成树,直到所有顶点都被包含。算法时间复杂度一般为 O ( ∣ V ∣ 2 ) O(|V|^2) O(V2),使用合适的数据结构可以优化到 O ( ∣ E ∣ + ∣ V ∣ l o g ∣ V ∣ ) O(|E| + |V|log|V|) O(E+VlogV)
    • 克鲁斯卡尔算法(Kruskal’s Algorithm):将图中的所有边按照权重从小到大排序,然后依次选择边,如果选择的边不会形成环,则将其加入生成树,直到生成树包含 n − 1 n - 1 n1 条边( n n n 是顶点数)。算法时间复杂度主要取决于边的排序,一般为 O ( ∣ E ∣ l o g ∣ E ∣ ) O(|E|log|E|) O(ElogE)。最小生成树在网络设计、电路布线等领域有广泛应用。

拓扑排序

  1. 拓扑排序的定义

    • 对于一个有向无环图(DAG - Directed Acyclic Graph),拓扑排序是将图中所有顶点排成一个线性序列,使得对于图中的任意一条有向边 ( u , v ) (u,v) (u,v),顶点 u u u 在序列中都排在顶点 v v v 的前面。例如,在一个课程学习的先后顺序图中,拓扑排序可以表示课程的学习顺序,先修课程排在前面,后修课程排在后面。
  2. 拓扑排序算法

    • 一种常见的方法是使用深度优先搜索。在 DFS 遍历过程中,当一个顶点的所有后继顶点都被访问完后,将该顶点加入拓扑排序序列。也可以使用入度表的方法,不断删除入度为 0 的顶点,并更新其邻接顶点的入度,直到所有顶点都被处理。拓扑排序在任务调度、项目规划等领域有重要应用,用于确定任务的执行顺序。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

C++类与对象(中)

类的默认成员函数 1. 默认成员函数,就是用户没有去显式实现,而编译器会自动生成的成员函数。 2. 对于⼀个类,一般情况下,编译器会默认生成6个默认成员函数。我们主要学习前面4个默认成员函数,对于后面两个默认成员函数…

HFSS 3D Layout中Design setting各个选项的解释

从HFSS 3D LAYOUT菜单中,选择Design Settings打开窗口,会有六个选项:DC Extrapolation, Nexxim Options, Export S Parameters, Lossy Dielectrics, HFSS Meshing Method, and HFSS Adaptive Mesh. DC Extrapolation 直流外推 直流外推分为标…

Python绘制爱心

文章目录 系列目录写在前面技术需求完整代码代码分析写在后面 系列目录 序号直达链接爱心系列1Python制作一个无法拒绝的表白界面2Python满屏飘字表白代码3Python无限弹窗满屏表白代码4Python李峋同款可写字版跳动的爱心5Python流星雨代码6Python漂浮爱心代码7Python爱心光波代…

C++ | Leetcode C++题解之第538题把二叉搜索树转换为累加树

题目: 题解: class Solution { public:TreeNode* getSuccessor(TreeNode* node) {TreeNode* succ node->right;while (succ->left ! nullptr && succ->left ! node) {succ succ->left;}return succ;}TreeNode* convertBST(TreeNo…

Linux基础命令(十)之 压缩命令 zip,gzip,bzip2,xz,tar

目录 一,zip和unzip 常见用法 二,gzip和ungzip命令 常见用法 三,bzip2和bunzip2命令 常见用法 四,xz和unxz命令 常见用法 五,归档命令tar 参数及其作用 常见用法 一,zip和unzip 语法:…

已解决,部署GPTSoVITS报错‘AsyncRequest‘ object has no attribute ‘_json_response_data‘

部署GPTSoVITS过程中,开启一键三连进程发生,报错AsyncRequest object has no attribute _json_response_data 具体报错内容为 (GPTSoVITS) PS D:\Code\GPT-SoVITS-beta0706> python webui.py Running on local URL: http://0.0.0.0:9874 IMPORTANT:…

ISUP协议视频平台EasyCVR视频融合平台接入各类摄像机的方法

安防视频监控ISUP协议视频平台EasyCVR兼容性强、支持灵活拓展,平台可提供视频远程监控、录像、存储与回放、视频转码、视频快照、告警、云台控制、语音对讲、平台级联等视频能力。 想要将摄像机顺利接入EasyCVR平台,实现视频监控的集中管理和分发&#x…

to_sql报错not all arguments converted during string formatting

报错: DatabaseError: Execution failed on sql SELECT name FROM sqlite_master WHERE typetable AND name?;: not all arguments converted during string formattingb 报错的代码如下: import pymysql import pandas as pd con pymysql.connect(…

7.机器学习--K-means算法(聚类)

聚类分析是在没有给定划分类别的情况下,根据数据相似度进行样本分组的一种方法。与分类模型需要使用有类标记样本构成的训练数据不同,聚类模型可以建立在无类标记的数据上,是一种非监督的学习算法。 聚类的输入是一组未被标记的样本&#xff…

GPIO子系统层次与数据结构详解

往期内容 本专栏往期内容: Pinctrl子系统和其主要结构体引入Pinctrl子系统pinctrl_desc结构体进一步介绍Pinctrl子系统中client端设备树相关数据结构介绍和解析inctrl子系统中Pincontroller构造过程驱动分析:imx_pinctrl_soc_info结构体Pinctrl子系统中c…

干货丨通信网络与大模型的融合与协同

本文首发《中兴通讯技术》,2024年4月,第30卷第2期,作者:浙江大学在读本科生任天骐,浙江大学信息与电子工程学院副教授李荣鹏,浙江大学兼任教授、博士生导师张宏纲。边缘计算社区经过授权发布,以…

[ vulnhub靶机通关篇 ] 渗透测试综合靶场 DarkHole:1 通关详解 (附靶机搭建教程)

🍬 博主介绍 👨‍🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~ ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 🎉点赞➕评论➕收藏 养成习…

对于一个STM32外设的应用有哪一些?可以列举一个实际的设计案例吗?

STM32 具有丰富的外设,以下是一些常见的应用: 1. **GPIO(通用输入输出)**: - 控制 LED 灯的亮灭。 - 读取按键状态。 - 与外部数字设备进行通信,如驱动数码管。 2. **USART(通用同步异步收发器…

iDP3——改进3D扩散策略以赋能人形机器人的训练:不再依赖相机校准和点云分割(含DP3、Diff-Control、ControlNet详解)

前言 今天10.23日,明天1024则将作为长沙程序员代表,在CSDN和长沙相关部门举办的1024程序员节开幕式上发言,欢迎广大开发者来长工作 生活 考察 创业,​包括我司七月也一直在招聘大模型与机器人开发人员 后天,则将和相关…

前端 react 面试题(二)

文章目录 hooks的使用规则为什么hooks要确保在函数组件的最顶层,而不能放置在循环或者条件语句中。react的事件模型react的合成事件是如何实现的react事件传参,可以使用箭头函数或bind方法,这两种哪一种更好使用箭头函数:使用`bind`方法:react的事件模型和vue的区别React …

【P2-10】ESP8266 WIFI模块连接原子云服务器与原子云APP通信

前言:本节实现ESP8266 WIFI模块连接原子云服务器与原子云APP通信。 演示视频: 【物联网】ESP8266 WIFI模块连接原子云服务器与原子云APP通信 目录 1.WIFI模块连接原子云服务器互相通信 2.WIFI模块与原子云APP通信 1.WIFI模块连接原子云服务器互相通信 原子云服务器登陆入…

2024-11-4 学习人工智能的Day21 openCV(3)

图像滤波 所为图像滤波通过滤波器得到另一个图像 什么是滤波器 在深度学习中,滤波器又称为卷积核,滤波的过程成为卷积 卷积核概念 卷积核大小,一般为奇数,如 3*35*57*7 为什么卷积核大小是奇数? 原因是&…

CSS基础知识六(浮动的高度塌陷问题及解决方案)

目录 1.浮动高度塌陷概念 2.下面是几种解决高度塌陷的几种方案: 解决方案一: 解决方案二: 解决方案三: 1.浮动高度塌陷概念 在CSS中,高度塌陷问题指的是父元素没有正确地根据其内部的浮动元素或绝对定位元素来计…

8、raid磁盘阵列

raid级别及概念 不同分区组成的逻辑硬盘,可以实现高可用,即阵列当中有一个分区的硬盘损坏,不影响整个阵列的使用,可以满足企业级的读写性能的要求。 raid磁盘阵列——raid级别: raid0,raid1,…

hivt实战

argoverse数据集和API forcasting包含tracking的结果,然后结合argo-api去获取hdmap数据 重要的api 数据结构 lane segment argoverse-api/argoverse/map_representation/lane_segment.py at master argoverse/argoverse-api GitHub 练习 get started with th…