基本概念:

图论〔Graph Theory〕是数学的一个分支。它以图为研究对象。图论中的图是由若干给定的点及连接两点的线所构成的图形,这种图形通常用来描述某些事物之间的某种特定关系,用点代表事物,用连接两点的线表示相应两个事物间具有这种关系。

图论是一种表示 "多对多" 的关系

图是由顶点和边组成的:(可以无边,但至少包含一个顶点)

  • 一组顶点:通常用 V(vertex) 表示顶点集合
  • 一组边:通常用 E(edge) 表示边的集合

图可以分为有向图和无向图,在图中:

  • (v, w) 表示无向边,即 v 和 w 是互通的
  • <v, w> 表示有向边,该边始于 v,终于 w

图可以分为有权图和无权图:

  • 有权图:每条边具有一定的权重(weight),通常是一个数字
  • 无权图:每条边均没有权重,也可以理解为权为 1

图又可以分为连通图和非连通图:

  • 连通图:所有的点都有路径相连
  • 非连通图:存在某两个点没有路径相连

图中的顶点有度的概念:

  • 度(Degree):所有与它连接点的个数之和
  • 入度(Indegree):存在于有向图中,所有接入该点的边数之和
  • 出度(Outdegree):存在于有向图中,所有接出该点的边数之和

图的表示:

图在程序中的表示一般有两种方式:

1. 邻接矩阵:

  • 在 n 个顶点的图需要有一个 n × n 大小的矩阵
  • 在一个无权图中,矩阵坐标中每个位置值为 1 代表两个点是相连的,0 表示两点是不相连的
  • 在一个有权图中,矩阵坐标中每个位置值代表该两点之间的权重,0 表示该两点不相连
  • 在无向图中,邻接矩阵关于对角线相等

2. 邻接链表:

  • 对于每个点,存储着一个链表,用来指向所有与该点直接相连的点
  • 对于有权图来说,链表中元素值对应着权重

例如在无向无权图中:

在无向有权图中

可以看出在无向图中,邻接矩阵关于对角线对称,而邻接链表总有两条对称的边

而在有向无权图中:

邻接矩阵和链表对比:

  1. 邻接矩阵由于没有相连的边也占有空间,因此存在浪费空间的问题,而邻接链表则比较合理地利用空间
  2. 邻接链表比较耗时,牺牲很大的时间来查找,因此比较耗时,而邻接矩阵法相比邻接链表法来说,时间复杂度低。

最短路径算法 (Shortest Path Algorithm)

1. 无权图:

问题:在图中找到某一个顶点到其它所有点的距离

对于初始点 v 来说,某个点的 d 代表该点到初始点的距离。

基本步骤:

  1. 将所有点的距离 d 设为无穷大
  2. 挑选初始点 s,将 ds 设为 0,将 shortest 设为 0
  3. 找到所有距离为 d 为 shortest 的点,查找他们的邻接链表的下一个顶点 w,如果 dw 的值为无穷大,则将 dw 设为 shortest + 1
  4. 增加 shortest 的值,重复步骤 3,直到没有顶点的距离值为无穷大

2. 有权图:

在有权图中,常见的最短路径算法有 Dijkstra 算法 Floyd 算法

迪杰斯特拉 Dijkstra 算法:Dijkstra 算法适用于权值为正的的图

Dijkstra 算法属于单源算法,即只能求出某点到其它点最短距离,并不能得出任意两点之间的最短距离。

算法步骤:

  1. 将所有边初始化为无穷大
  2. 选择一个开始的顶点,添加到优先队列中
  3. 对于该点的所有邻接顶点进行判断,如果到该点的距离小于原先的值,则将该值进行更新
  4. 将该点所有邻接顶点添加到优先队列中
  5. 从优先队列中挑选出一个路径值最小的顶点,将其弹出,作为新的顶点,重复步骤 3,4,5
  6. 直到所有点都被处理过一次

例如:

首先选取 v0 作为起始点,添加到优先队列中,将v0弹出,然后对 v0 邻接点进行判断,由于一开始所有边都为无穷大,那么 <v0, v1> 和 <v0, v3> 都更新,值为 2 和 1,按路径大小升序将v3、v1添加到优先队列。

之后将 v3 弹出,对所有 v3 邻接点进行值的更新,并将所有邻接点按路径大小升序添加到优先队列中,若遇到值相同,则无所谓其先后顺序

重复这样的过程,直到所有的点都被处理过,则算法终止,这样最后可以得出从 v0 到其它 v1~v6 节点的距离。

Dijkstra 算法适合于权值为正的情况下,若权值为负则不能使用,因为出现死循环。这时候我们需要计算每个顶点被处理的次数,当某个顶点已经处理过的话,就跳出该循环。

佛洛伊德 Floyd 算法:可以求出任意两点的最短距离

Floyd 算法是一个经典的动态规划算法。用通俗的语言来描述的话,首先我们的目标是寻找从点 i 到点 j 的最短路径。

从任意节点 i 到任意节点 j 的最短路径不外乎 2 种可能:

  1. 是直接从 i 到 j
  2. 是从 i 经过若干个节点 k 到 j

所以,我们假设 Dis(i,j) 为节点 u 到节点 v 的最短路径的距离,对于每一个节点 k,我们检查Dis(i,k) + Dis(k,j) < Dis(i,j) 是否成立,如果成立,证明从 i 到 k 再到 j 的路径比 i 直接到 j 的路径短,我们便设置 Dis(i,j) = Dis(i,k) + Dis(k,j),这样一来,当我们遍历完所有节点 k,Dis(i,j) 中记录的便是 i 到 j 的最短路径的距离。

Dis(i,k) + Dis(k,j) < Dis(i,j),这里的Dis(i,j)来自上一次Dis(i,j)= Dis(i,k) + Dis(k,j),满足了前面式子的小于号之后重新赋值,实现不断更小,最终遍历全图,找到最小值

不断迭代 重新赋值

for(int k=0; k<n; k++) {
for(i=0; i<n; i++) {
for(j=0; j<n; j++)
if(A[i][j]>(A[i][k]+A[k][j])) {
A[i][j]=A[i][k]+A[k][j];
path[i][j]=k;
}
}
}

最小生成树 (Minimum Spanning Trees MST)

例如:要在 n 个城市之间铺设光缆,主要目标是要使这 n 个城市的任意两个之间都可以通信,但铺设光缆的费用很高,且各个城市之间铺设光缆的费用不同,因此另一个目标是要使铺设光缆的总费用最低。这就需要找到带权的最小生成树。

特点:

  1. 该树是连通的
  2. 权值之和最小
  3. 边数比顶点个数少 1

存在个数:最小生成树在一些情况下可能会有多个

  1. 当图的每一条边的权值都相同时,该图的所有生成树都是最小生成树
  2. 如果图的每一条边的权值都互不相同,那么最小生成树将只有一个

比如:

生成最小生成树的算法一般有两种,分别是 Prim 算法和 Kruskal 算法

1. 普里姆算法 (Prim 算法):

算法步骤:

  1. 输入:一个加权连通图,其中顶点集合为 V,边集合为 E
  2. 初始化:Vnew = {x},其中 x 为集合 V 中的任一节点(起始点),Enew = {} 为空
  3. 在集合 E 中选取权值最小的边 <u, v>,其中 u 为集合 Vnew 中的元素,而 v 不在 Vnew 集合当中,并且 v∈V (如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一)
  4. 将 v 加入集合 Vnew 中,将 <u, v> 边加入集合 Enew 中
  5. 重复步骤 3、4 直到 Vnew = V

更详细的解释 参考 维基百科

时间复杂度:O(V^2)

2. Kruskal 算法:需要一个集合用来升序存储所有边

算法步骤:

  1. 先构造一个只含有 n 个顶点,而边集为空的子图
  2. 从边集 E 中选取一条权值最小的边,若该条边的两个顶点分属不同的树,则将其加入子图。(也就是说,将这两个顶点分别所在的两棵树合成一棵树) 反之,若该条边的两个顶点已落在同一棵树上,则不可取,而应该取下一条权值最小的边再试之
  3. 重复步骤 2,直到所有点连通

时间复杂度:O( ElogV )

例如:

在对所有边进行排序之后,我们得到一个边集合,从边集合中取出最小权的边 AD

剩下的边中寻找。我们找到了 CE。这里边的权重也是 5,依次类推我们找到了 6,7,7

尽管现在长度为 8 的边是最小的未选择的边。但是他们已经连通了

最后就剩下 EG 和 FG 了。当然我们选择了 EG

转载自数据结构与算法系列 目录

prim算法

prim是在当前的最小生成树基础上,选择一条最短边作为新的最小生成树。将新加入的点看做一个最小生成树即可。用堆来加速的话,时间复杂度是O(mlogn)O(mlogn)。缺点是空间占用大(因为堆)。由于prim算法需要知道当前点周围的边是什么,一般配合邻接表。

kruskal算法

kruskal算法和prim在思路上的唯一区别就是kruskal每次合并的是一整棵树,而不是一个点。如果用并查集,时间复杂度是O(mlogm)O(mlogm),优点是代码简单,不过基本上跑不过prim。如果是稠密图时间相差两倍左右,稀疏图则能差到五倍以上。kruskal并不需要每个点周围的边,并且用邻接表做反而麻烦,所以一般选用前向星。

[matlab] 18.图与网络 (转载)的更多相关文章

  1. [matlab] 20.图与网络 matlab自带函数使用

    matlab自带的biography(产生一个句柄) 可以用于画图 R=[1 1 2 4 1 2 3 3 5 7 3 4 5 6 7 8]; % 起始节点编号 C=[2 3 3 3 4 5 5 6 6 ...

  2. matlab学习——04图与网络(最短路,最小生成树,最大流)

    04图与网络 1.最短路 (1) 自己写的dijstra算法 format compact; clc,clear all a=zeros(6); a(1,2)=50;a(1,4)=40;a(1,5)= ...

  3. MATLAB实例:聚类网络连接图

    MATLAB实例:聚类网络连接图 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 本文给出一个简单实例,先生成2维高斯数据,得到数据之后,用模糊C均值( ...

  4. 建模算法(五)——图与网络

    (一)图与网络的基本概念 一.无向图 含有的元素为顶点,弧和权重,但是没有方向 二.有向图 含有的元素为顶点,弧和权重,弧具有方向. 三.有限图.无限图 顶点和边有限就是有限图,否则就是无限图. 四. ...

  5. iOS最笨的办法实现无限轮播图(网络加载)

    iOS最笨的办法实现无限轮播图(网络加载) 简单的做了一下: 使用方法: 把 请求返回的 图片地址(字符串类型)放进数组中就行 可以使用SDWebImage(我就是用的这个)等..需要自己导入并引用, ...

  6. 【GCN】图卷积网络初探——基于图(Graph)的傅里叶变换和卷积

    [GCN]图卷积网络初探——基于图(Graph)的傅里叶变换和卷积 2018年11月29日 11:50:38 夏至夏至520 阅读数 5980更多 分类专栏: # MachineLearning   ...

  7. [Linux] Ubuntu 18 LTS netplan 网络配置

    Ubuntu 18 LTS netplan 网络配置 今天装完 Ubuntu 18 LTS,配置网络时发现Ubuntu 18LTS ifupdown has been replaced by netp ...

  8. 最全面的图卷积网络GCN的理解和详细推导,都在这里了!

    目录 目录 1. 为什么会出现图卷积神经网络? 2. 图卷积网络的两种理解方式 2.1 vertex domain(spatial domain):顶点域(空间域) 2.2 spectral doma ...

  9. Matlab 矩阵卷积理解(转载)

    转载自:http://blog.csdn.net/andrewseu/article/details/51783181 在图像处理的过程中,经常会看到矩阵卷积的概念,比如说用一个模板去和一张图片进行卷 ...

随机推荐

  1. 4.3 explain 之 type

    一.explain 的type类型 二.类型的排序 从最好到最差依次是: system > const > eq_ref > ref > range > index &g ...

  2. jquery中each中使用break和continue

    在jquery中each中直接使用break或者continue会提示:必须在循环中使用.会报错不能直接使用. 但是,是不是就不能用呢,答案是的,但是换种方法可以达到相同的效果: 可以只用return ...

  3. VMWAR-workstatuon

    https://blog.csdn.net/felix__h/article/details/82853501 链接中的秘钥可用~感谢原文作者 下载安装: 官网下载地址:https://www.vmw ...

  4. jQuery 练习:tab 切换

    实现内容随菜单切换 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  5. Spring的原理性总结

    一.Bean的生命过程 Bean的生命过程可以借鉴Servlet的生命过程,了解其生命过程对于不管是思想还是以后的使用都很有帮助: Bean可以通过两种方式进行加载,分别是使用BeanFactory ...

  6. input range样式优化

    首先HTML代码: <input id="snrPollInterval" type="range" min="1" max=&quo ...

  7. Flutter 布局详解

    本文主要介绍了Flutter布局相关的内容,对相关知识点进行了梳理,并从实际例子触发,进一步讲解该如何去进行布局. 1. 简介 在介绍Flutter布局之前,我们得先了解Flutter中的一些布局相关 ...

  8. PyCharm 使用Github管理Django项目

    不管是对于教程代码免费分享的需要,还是项目开发过程中的版本管理,Github都是我们首选的开源代码仓库,如果你没有私有仓库,并且不用保护代码,那么将项目上传到Github上是最佳的选择. 关于如何使用 ...

  9. 有效运维的 on-call 机制

    [编者按]本文作者为云告警平台OneAlert负责人,著<云计算与OpenStack>,在IT运营管理.云计算方面从业10多年. 正文 互联网技术的发展,离不开运维支撑工作,没有零bug的 ...

  10. 关于商米D1S,USB默认权限在关机后丢失的FAQ

    1.机器型号:商米D1S 2.机器系统版本:7.1.2 3.情况描述:双屏的机器不管是银盒子收银还是银盒子智能收银,勾选默认后重启机器还是会提示, 4.解决方案:商米厂商大约会在1月份进行系统更新,到 ...