最小生成树、最短路径树

一、最小生成树与最短路径树的区别

最小生成树能够保证整个拓扑图的所有路径之和最小,但不能保证任意两点之间是最短路径。

应用如网络部线,把所有的电脑(服务器?)都连起来用的网线(光纤?)最少,即用最小的代价让全村人都能上网

最短路径是从一点出发,到达目的地的路径最小。

应用如导航,两个地方怎么走距离最短。可以存在到不了的情况。

二、最小生成树

在图论中,无向图 G 的生成树(英语:Spanning Tree)是具有 G 的全部顶点,但边数最少的连通子图。[1]

一个图的生成树可能有多个。

带权图的生成树中,总权重最小的称为最小生成树。

它在实际中有什么应用呢?比如说有N个城市需要建立互联的通信网路,如何使得需要铺设的通信电缆的总长度最小呢?这就需要用到最小生成树的思想了。

求取最小生成树的算法:

2.1 Prim算法原理:

1)以某一个点开始,寻找当前该点可以访问的所有的边;
2)在已经寻找的边中发现最小边,这个边必须有一个点还没有访问过,将还没有访问的点加入我们的集合,记录添加的边;
3)寻找当前集合可以访问的所有边,重复2的过程,直到没有新的点可以加入;
4)此时由所有边构成的树即为最小生成树。

参考链接:https://wiki.jikexueyuan.com/project/step-by-step-learning-algorithm/prim-algorithm1.html

2.2 Kruskal算法原理:

现在我们假设一个图有m个节点,n条边。首先,我们需要把m个节点看成m个独立的生成树,并且把n条边按照从小到大的数据进行排列。在n条边中,我们依次取出其中的每一条边,如果发现边的两个节点分别位于两棵树上,那么把两棵树合并成为一颗树;如果树的两个节点位于同一棵树上,那么忽略这条边,继续运行。等到所有的边都遍历结束之后,如果所有的生成树可以合并成一条生成树,那么它就是我们需要寻找的最小生成树,反之则没有最小生成树。

参考链接:https://wiki.jikexueyuan.com/project/step-by-step-learning-algorithm/kruskal-algorithm.html

2.3 两算法对比

总的来说,Prim算法是以点为对象,挑选与点相连的最短边来构成最小生成树。而Kruskal算法是以边为对象,不断地加入新的不构成环路的最短边来构成最小生成树。
在这里插入图片描述

三、最短路径树

最短路径就是从一个指定的顶点出发,计算从该顶点出发到其他所有顶点的最短路径。
最短路径树SPT(Short Path Tree)是网络的源点到所有结点的最短路径构成的树。
常见的最短路径算法有三种:dijkstra,floyd,Bellman-Ford和SPFA。

Dijkstra:适用于权值为非负的图的单源最短路径,用斐波那契堆的复杂度O(E+VlgV)
Floyd:每对节点之间的最短路径,时间复杂度O(V^3)
BellmanFord:适用于权值有负值的图的单源最短路径,并且能够检测负圈,复杂度O(VE)
SPFA:适用于权值有负值,且没有负圈的图的单源最短路径,论文中的复杂度O(kE),k为每个节点进入Queue的次数,且k一般<=2,但此处的复杂度证明是有问题的,其实SPFA的最坏情况应该是O(VE).

如果说边权中有负数怎么定义呢?如果有负边,就要分两种情况了。
第一种情况:如果从某点出发,可以到达一个权值和为负数的环,那么这个点到其它点的最短距离就是负无穷了,很明显,如果有负环,且从某点可以到达这个负环,那么我可以无限得走这个负环,每走一次,距离就小一些,这种情况下,我们可以定义这个点到达其它点的最短距离为负无穷。
第二种情况:如果说不存在一个这样的负环,那么就和没有负权边一样了,但是还不是完全一样,接下来我们介绍的四种算法中,有的是可以处理负权边不能处理负环的,有的是可以处理负环的,有的是既不能处理负权边也不能处理负环的。

3.1 Dijkstra

  • 不能适用于负权图
  • 只适用于单源最短路问题
    如果权重是负数,那就直接pass这个算法,在这里原因不表。

单源最短路径就是指只有一个出发点,到其它点的最短路径问题。

在这里插入图片描述
在这里插入图片描述
以上图G4为例,来对迪杰斯特拉进行算法演示(以第4个顶点D为起点)。以下B节点中23应为13。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

算法流程:
  • S1. 设置dis数组,dis[i]表示起点start到i的距离。
  • S2. 从点集V中弹出一个dis值最小且未以该点为起点进行松弛操作的点。
  • S3. 从该点松弛与其领接的各个点更新dis数组,返回S2,循环进行。
  • 通过优先队列的操作可以优化S2,之后详细说明。

举个例子。这个例子也是洛谷的单源最短路径的模板题,请求出1到各点的最短路?
在这里插入图片描述
很显然你用肉眼看,1到本身是0,1到2、3、4的最短路分别为2,4,3。那dijkstra的操作流程是什么呢?

首先我们先开一个dis数组,让数组的值足够大,dis[i]=0x7fffffff,从1开始出发,令dis[1]=0,发现与1相连的有三个点234,那我们一个个进行松弛操作,比较if (dis[1]+w[i]<dis[i]),w表示各边的权重,如果小于,那就让其覆盖本身的dis值,即dis[i]=dis[1]+w[i],这一波更新完后,234的值分别为2,5,4。
然后,我们需要让234全部入队,并选取dis值最小的数即2继续进行松弛操作,发现连接的是3和4,继续更新,这波结束,234的值分别为2,4,3。
接着,是上一轮dis值次小的点4,进行操作,但是4没有出的边,所以不进行操作。
最后就是剩下的一个3了,3和4还有一条权边,但是4最小的dis值依旧是3。

下面我们发现算法到这就截止了,为什么呢,因为S2的一句话,未进行松弛的点,早在第一轮234就已经全部进入过队列并且已经弹出过了,所以之后他们也不会再进入队列,我们可以设置一个bool类型的vis[i]数组代表第i个点是否被访问过了,如果访问过了就结束此循环,或者直接不push进入队列。

这就是整个dijkstra的算法。

总结:

Dijkstra算法是一种优秀的经典的最短路算法,在优先队列的优化下,它的时间复杂度也是可接受的,它在计算机网络等应用中广泛存在,然而它也有它的局限性,它的局限性甚至比Floyd算法都要大,Floyd算法允许有负权边,不允许有负权环,Dijkstra算法连负权边都不允许,因为Dijkstra的正确性基于以下假设:当前未找到最短路的点中,距离源点最短的那个点,无法继续被松弛,这时候他肯定是已经松弛到最短状态了。但是这个假设在有负权边的时候就不成立了,举一个经典例子:一个具有三个点三条边的图,0->1距离为2,0->2距离为3,2->1距离为-2,根据Dijkstra算法,我们第一次肯定会将节点1加入到已经松弛好的点集中,但是这时候是不对的,2并不是0->1最短的路径,而通过点2松弛过的路径:0->2->1才是最短的路径,因为负权边的存在,我们认为的已经被松弛好的点,在未来还有被松弛的可能。这个就是Dijkstra的局限性,然而这并不影响它的伟大,因为在实际应用中,没有负权的图是更为常见的。但是我们仍然需要可以处理负权,甚至负环的算法,这时候Bellman-Ford算法和SPFA算法就派上用场了。

3.2 Floyd

弗洛伊德算法是一种基于动态规划的多源最短路算法。是解决任意两点间的最短路径的一种算法,可以正确处理有向图或有向图或负权(但不可存在负权回路)的最短路径问题,同时也被用于计算有向图的传递闭包。

算法流程:

通过Floyd计算图G=(V,E)中各个顶点的最短路径时,需要引入两个矩阵,矩阵S中的元素a[i][j]表示顶点i(第i个顶点)到顶点j(第j个顶点)的距离。矩阵P中的元素b[i][j],表示顶点i到顶点j经过了b[i][j]记录的值所表示的顶点。
算法描述
a. 从任意一条单边路径开始。所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。
b. 对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比己知的路径更短。如果是更新它。

假设图G中顶点个数为N,则需要对矩阵D和矩阵P进行N次更新。初始时,矩阵D中顶点a[i][j]的距离为顶点i到顶点j的权值;如果i和j不相邻,则a[i][j]=∞,矩阵P的值为顶点b[i][j]的j的值。 接下来开始,对矩阵D进行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]”,更新b[i][j]=b[i][0]。 同理,第k次更新时,如果”a[i][j]的距离” > “a[i][k-1]+a[k-1][j]”,则更新a[i][j]为”a[i][k-1]+a[k-1][j]”,b[i][j]=b[i][k-1]。更新N次之后,操作完成!
举个例子
在这里插入图片描述
第一步,我们先初始化两个矩阵,得到下图两个矩阵:
在这里插入图片描述
在这里插入图片描述
第二步,以v1为中介,更新两个矩阵:
发现,a[1][0]+a[0][6] < a[1][6] 和a[6][0]+a[0][1] < a[6][1],所以我们只需要矩阵D和矩阵P,结果如下:
在这里插入图片描述
在这里插入图片描述
通过矩阵P,我发现v2–v7的最短路径是:v2–v1–v7

第三步:以v2作为中介,来更新我们的两个矩阵,使用同样的原理,扫描整个矩阵,得到如下图的结果:
在这里插入图片描述
在这里插入图片描述
OK,到这里我们也就应该明白Floyd算法是如何工作的了,他每次都会选择一个中介点,然后,遍历整个矩阵,查找需要更新的值,下面还剩下五步,就不继续演示下去了,理解了方法,我们就可以写代码了。

总结

Floyd算法只能在不存在负权环的情况下使用,因为其并不能判断负权环,上面也说过,如果有负权环,那么最短路将无意义,因为我们可以不断走负权环,这样最短路径值便成为了负无穷。
但是其可以处理带负权边但是无负权环的情况。
以上就是求多源最短路的Floyd算法,基于动态规划,十分优雅。
但是其复杂度确实是不敢恭维,因为要维护一个路径矩阵,因此空间复杂度达到了O(n^ 2 ) ,时间复杂度达到了O(n^ 3),只有在数据规模很小的时候,才适合使用这个算法。

3.3 Bellman-Ford

Bellman-Ford是最常规下的单源最短路问题,对边的情况没有要求,不仅可以处理负权边,还能处理负环。可谓是来者不拒。

算法描述:

对于一个图G(v,e)(v代表点集,e代表边集),执行|v|-1次边集的松弛操作,所谓松弛操作,就是对于每个边e1(v,w),将源点到w的距离更新为:原来源点到w的距离 和 源点到v的距离加上v到w的距离 中较小的那个。v-1轮松弛操作之后,判断是否有源点能到达的负环,判断的方法就是,再执行一次边集的松弛操作,如果这一轮松弛操作,有松弛成功的边,那么就说明图中有负环。算法复杂度为O(ne),e为图的边数

优化(SPFA)

Bellman-Ford算法虽然可以处理负环,但是时间复杂度为O(ne),在图为稠密图的时候,是不可接受的。复杂度太高。我们分析一下能不能进行优化,Bellman-Ford算法的正确性保证依赖于路径松弛性质,我们只要能够保证最短路径中的边的松弛顺序即可,Bellman-Ford算法属于一种暴力的算法,即,每次将所有的边都松弛一遍,这样肯定能保证顺序,但是仔细分析不难发现,源点s到达其他的点的最短路径中的第一条边,必定是源点s与s的邻接点相连的边,因此,第一次松弛,我们只需要将这些边松弛一下即可。第二条边必定是第一次松弛的时候的邻接点与这些邻接点的邻接点相连的边(这句话是SPFA算法的关键,请读者自行体会),因此我们可以这样进行优化:设置一个队列,初始的时候将源点s放入,然后s出队,松弛s与其邻接点相连的边,将松弛成功的点放入队列中,然后再次取出队列中的点,松弛该点与该点的邻接点相连的边,如果松弛成功,看这个邻接点是否在队列中,没有则进入,有则不管,这里要说明一下,如果发现某点u的邻接点v已经在队列中,那么将点v再次放到队列中是没有意义的。因为即时你不放入队列中,点v的邻接点相连的边也会被松弛,只有松弛成功的边相连的邻接点,且这个点没有在队列中,这时候稍后对其进行松弛才有意义。因为该点已经更新,需要重新松弛。

总结:

Bellman-Ford算法和SPFA算法,都是基于松弛操作,以及路径松弛性质的,不同之处在于,前者是一种很暴力的算法,为了保证顺序,每次把所有的边都松弛一遍,复杂度很高,而后者SPFA,则是在Bellman-Ford算法的基础上进行了剪枝优化,只松弛那些可能是下一条路径的边,但是关于SPFA算法的复杂度,现在还没有个定论,不过达成的共识是:算法的时间复杂度为O(me),其中m为入队的平均次数,其发明者,西安交大的段凡丁大神的论文中,m是一个常数(这个结论是错的),我们“姑且”认为该算法的时间复杂度为O(e)【滑稽】,的确该算法的效率是很高的,博主在oi中经常使用这个算法,除非题目数据特意卡SPFA。或者的确是稠密图,一般情况下不会超时。关于其判断负环,我们可以认为,在某个节点入队次数达到n的时候,就可以说明遇到了负环。SPFA有两个优化策略:SLF:Small Label First 策略,设要加入队列的节点是j,队首元素为i,若d[j]<dist[i],则将j插入队首,否则插入队尾; LLL:Large Label Last 策略,设队首元素为i,队列中所有d值的平均值为x,若d[i]>x则将i插入到队尾,查找下一元素,直到找到某一i使d[i]<=x,则将i出队进行松弛操作。其实,实际应用中,SPFA的时间复杂度是很不稳定的,因此我们能用Dijkstra+优先队列,就用Dijkstra+优先队列为好。

https://zhuanlan.zhihu.com/p/34922624
https://zhuanlan.zhihu.com/p/150434472
https://zhuanlan.zhihu.com/p/33162490
https://zhuanlan.zhihu.com/p/40338107

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

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

相关文章

卫星链路

卫星通信系统中&#xff0c;信息传输中&#xff0c;一条传输链路包括发端地球站、上行链路、卫星转发器、下行链路、收端地球站。按照空间分布可以分为星地链路和星间链路。影响其通信性能的因素主要有&#xff1a;发射端的发射功率与天线增益、传输过程中的损耗、传输过程中所…

计算机网络组成包括哪些内容,计算机网络系统的组成

互联网时代已经到来了&#xff0c;小编为你科普一下网络相关基础知识《计算机网络系统的组成》&#xff0c;让你更快融入互联网时代。计算机网络系统是通信子网和资源子网组成的。而网络软件系统和网络硬件系统是网络系统赖以存在的基础。在网络系统中&#xff0c;硬件对网络的…

正定和半正定

在众多的机器学习模型中&#xff0c;线性代数的身影无处不在&#xff0c;当然&#xff0c;我们也会时常碰到线性代数中的正定矩阵和半正定矩阵。例如&#xff0c;多元正态分布的协方差矩阵要求是半正定的。 ------------------------------------------ 1. 基本的定义 正定和…

HTML中button怎么填充GIF,css3给按钮添加背景渐变动画

css3给按钮添加背景渐变动画button {color:#FFF;font-size:16px;outline:none;width:300px;height:48px;background:#26A1D9;border:none;-webkit-border-radius:5px;border-radius:5px;}button:active{outline:none;background:#208FC1;/*执行动画*/-webkit-animation:showBtn…

导数,微分,偏导,全微分,方向导数,梯度

多元函数与一元函数有一个很大的区别在于定义域的不同&#xff1a;一元函数自变量就在x轴上&#xff0c;因此趋近的方向只有某点的左右两侧&#xff0c;因此&#xff0c;考察一元函数极限的时候&#xff0c;仅考虑左邻域和右邻域即可。但是多变量微分变得复杂&#xff0c;趋向方…

牛顿法, Jacobian矩阵 和 Hessian矩阵

牛顿法 主要有两方面的应用&#xff1a; 求方程的根&#xff1b;求解最优化方法&#xff1b; 为什么要用牛顿法求方程的根&#xff1f; 问题很多&#xff0c;牛顿法 是什么&#xff1f;目前还没有讲清楚&#xff0c;没关系&#xff0c;先直观理解为 牛顿法是一种迭代求解方法…

奇异矩阵,非奇异矩阵,伪逆矩阵

奇异矩阵就是Singular Matrix 的中文翻译。 Singular 就是唯一的&#xff0c;可以想成是单身狗&#xff0c;所以他没有对象 逆矩阵。 Non-singular的非奇异矩阵就是Couple 有逆矩阵。 奇异矩阵 奇异矩阵是线性代数的概念&#xff0c;就是对应的行列式等于0的矩阵。 奇异矩阵…

ActiveMQ性能测试

我们使用ActiveMQ作为消息传递层–发送大量需要低延迟的消息。 通常它可以正常工作&#xff0c;但是在某些情况下我们遇到了性能问题。 在花了太多时间测试我们的基础架构之后&#xff0c;我想我已经学到了有关ActiveMQ的一些有趣的东西&#xff1a;它可能真的很慢。 尽管一般…

计算机网络严楠,安徽工程大学

安徽工程大学是一所以工为主的省属多科性高等院校&#xff0c;是安徽省高校综合改革首批试点院校、安徽省系统推进全面创新改革试验高校创新自主权改革试点单位&#xff0c;入选教育部新工科研究与实践项目。 学校办学历史始于1935年创设的安徽私立内思高级工校&#xff0c;历经…

垃圾收集算法,垃圾收集器_垃圾收集器准则和提示

垃圾收集算法,垃圾收集器这些是我需要调整GC时通常会看到的一些准则和技巧。 主要由以下两本书组成&#xff0c;而根据我的经验却很少&#xff1a; Java性能 JBoss AS 5性能调优 希望它们对在那里的其他人有用&#xff01; 垃圾收集器 XX:AggressiveOpts将HotSpot内部布尔变…

3SAT问题

3-Satisfiability (3Sat) https://samjjx.github.io/2019/03/14/3sat2ds/

Java,JavaFX的流利设计风格文本字段和密码字段

我刚刚发布了Java版本4.5 &#xff0c;JavaFX主题JMetro 。 此版本为“文本字段”和“密码字段”添加了新样式。 和往常一样&#xff0c;受到Fluent Design的启发。 在这篇文章中&#xff0c;我将详细介绍这个新版本。 JMetro版本4.5 就像我在简介中所说的那样&#xff0c;JM…

零空间,Markov‘s inequality, Chebyshev Chernoff Bound, Union Bound

0. 零空间 零空间是在线性映射&#xff08;即矩阵&#xff09;的背景下出现的&#xff0c;指&#xff1a;像为零的原像空间&#xff0c;即{x| Ax0}。 在数学中&#xff0c;一个算子 A 的零空间是方程 Av 0 的所有解 v 的集合。它也叫做 A 的核&#xff0c;核空间。如果算子是…

prd展示html文件,prd目的.html

PRD目的$axure.utils.getTransparentGifPath function() { return resources/images/transparent.gif; };$axure.utils.getOtherPath function() { return resources/Other.html; };$axure.utils.getReloadPath function() { return resources/reload.html; };业务优先于需求…

连续、偏导数、可微

1 连续的含义 通俗来说&#xff0c;用笔作画&#xff0c;不提笔画出来的曲线就是连续的&#xff1a; 1.1 没有缝隙 我们对连续的函数曲线的直观感受是没有缝隙&#xff1a; 1.2 另一层含义 2 可微的含义 可微可导的几何意义 对于一元函数,可微的几何意义是该点处存在切…

齐次(Homogeneous)、单项式、多项式

齐次 所谓的「齐」&#xff0c;必然是有两个或者以上的对象&#xff0c;那么就以两个对象x,yx,yx,y为例。 齐次&#xff0c;是指所列的式子只和Xn,ynX^n, y^nXn,yn相关&#xff0c;不存在Xm,yl(m≠n,l≠n)X^m, y^l (m \neq n, l \neq n)Xm,yl(m​n,l​n)的项&#xff0c;包…

spring mail 发送html simple,SpringBoot整合Mail邮件发送

Spring提供了非常好用的JavaMailSender接口实现邮件发送。在Spring Boot的Starter模块中也为此提供了自动化配置。添加依赖org.springframework.bootspring-boot-starter-mail配置application.yml文件spring:mail:host: smtp.qq.com# 你的邮箱授权码password:nickname: # 该参数…

二次型、特征值/向量、奇异值、特征值、奇异值分解、奇异值分解(SVD)原理与在降维中的应用

一、二次型 通过矩阵来研究二次函数&#xff08;方程&#xff09;&#xff0c;这就是线性代数中二次型的重点。 1 二次函数&#xff08;方程&#xff09;的特点 1.1 二次函数 最简单的一元二次函数就是&#xff1a; 给它增加一次项不会改变形状&#xff1a; 增加常数项就…

2021年最受欢迎的微信公众号推广方式

时下&#xff0c;微信公众平台已成为热门的营销推广平台&#xff0c;大家都对微信非常重视&#xff0c;有的礼品企业甚至推出N个公共号&#xff0c;抽调专门人手系统运营。每天&#xff0c;都有大量礼品企业使用公众账号通过移动端和粉丝互动&#xff0c;不仅可以群发文字、图片…

计算机应用与软件是csci吗,计算机与信息技术学院

鲁凌云职 称&#xff1a; 副教授学 位&#xff1a;博士邮 箱&#xff1a;lylubjtu.edu.cn办公电话&#xff1a;个人主页&#xff1a;个人履历鲁凌云 (副教授、博士生导师)毕业院校&#xff1a; 北京交通大学最后学位&#xff1a; 工学博士研究方向&#xff1a;无线跨层资源管理…