图-最短路径—Dijkstra算法和Floyd算法

本文详细介绍了Dijkstra算法和Floyd算法,主要用于寻找图中的最短路径。Dijkstra算法适用于单源最短路径问题,而Floyd算法解决任意两点间的最短路径。文中还给出了两种算法的Java代码实现。
摘要由CSDN通过智能技术生成

一、Dijkstra算法

1.定义概览:单源最短路径算法

Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法是很有代表性的最短路径算法,算法使用了广度优先搜索解决赋权有向图或者无向图的单源最短路径问题,算法最终得到一个最短路径树。该算法常用于路由算法或者作为其他图算法的一个子模块。

时间复杂度是O(n2)

注意:该算法要求图中不存在负权边

2.算法思想:

       Dijkstra算法采用的是一种贪心的策略,声明一个数组distance来保存源点到各个顶点的最短距离和一个保存已经找到了最短路径的顶点的集合:T。

      初始化,原点 s 的路径权重被赋为 0 (distance[s] = 0,如果是有向图也可以设置为无穷大,因为有向图需要区别是否有到达自己的路径)。若对于顶点 s 存在能直接到达的边(s,m),则把distance[m]设为weight(s, m),同时把所有其他(s不能直接到达的)顶点的路径长度设为无穷大。同时,把顶点s加入集合T。 
     然后,从distance数组选择最小值,则该值就是源点s到该值对应的顶点的最短路径,并且把该点加入到T中,OK,此时完成一个顶点。 
     接着,我们需要看看新加入的顶点是否可以到达其他顶点,并且看看通过该顶点到达其他点的路径长度是否比源点直接到达短,如果是,那么就替换这些顶点在distance中的值。 
    重复上述动作,直到T中包含了图的所有顶点。

3、Dijkstra算法示例演示
下面我求下图,从任一源点(因为原博主的图是选择v1作为源点,咋们就用它吧,个人比较懒,懒得去自己画图了,只要自己能讲清楚算法实现,部分拿来主义也未尝不可,本人实现的算法是可以自定义源点的)到其他各个顶点的最短路径

è¿éåå¾çæè¿°

首先第一步,我们先声明一个dis数组,该数组初始化的值为: 

è¿éåå¾çæè¿°
我们的顶点集T的初始化为:T={v1}

既然是求 v1顶点到其余各个顶点的最短路程,那就先找一个离 V1 号顶点最近的顶点。通过数组 dis 可知当前离v1顶点最近是 v3顶点,则 v1顶点到 v3顶点的最短路程就是当前 dis[2]值,将V3加入到T中。 

你以为这次循环中已经结束了吗?no,接着,既然确定了一个顶点的最短路径,下面我们就要根据这个新入的顶点V3是否有出度,发现以v3 为起点的有: < v3,v4 >,那么我们看看路径:v1–v3–v4的长度是否比源点v1–v4短,因为dis[3]代表的就是v1–v4的长度为无穷大,而v1–v3–v4的长度为:10+50=60,所以更新dis[3]的值,得到如下结果: 

è¿éåå¾çæè¿°
因此 distance[3]要更新为 60。这个过程有个专业术语叫做“松弛”。即 v1顶点到 v4顶点的路程即 distance[3],通过 < v3,v4> 这条边松弛成功。这便是 Dijkstra 算法的主要思想:通过“边”来松弛v1顶点到其余各个顶点的路程。

然后,我们又从distance中查找除了已经访问的V1和V3外的其他点中的最小值,发现distance[4]的值最小,通过之前是解释的原理,可以知道v1到v5的最短距离就是dis[4]的值,然后,我们把v5加入到集合T中,然后,考虑v5的出度是否会影响我们的数组dis的值,v5有两条出度:< v5,v4>和 < v5,v6>,然后我们发现:v1–v5–v4的长度为:50,而dis[3]的值为60,所以我们要更新dis[3]的值.另外,v1-v5-v6的长度为:90,而distance[5]为100,所以我们需要更新distance[5]的值。更新后的dis数组如下图: 

è¿éåå¾çæè¿°
然后,继续从dis中选择未确定的顶点的值中选择一个最小的值,发现dis[3]的值是最小的,所以把v4加入到集合T中,此时集合T={v1,v3,v5,v4},然后,考虑v4的出度是否会影响我们的数组dis的值,v4有一条出度:< v4,v6>,然后我们发现:v1–v5–v4–v6的长度为:60,而dis[5]的值为90,所以我们要更新dis[5]的值,更新后的dis数组如下图: 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值