前言

图论中,在寻路最短路径中除了Dijkstra算法以外,还有Floyd算法也是非常经典,然而两种算法还是有区别的,Floyd主要计算多源最短路径。

在单源正权值最短路径,我们会用Dijkstra算法来求最短路径,并且算法的思想很简单——贪心算法:每次确定最短路径的一个点然后维护(更新)这个点周围点的距离加入预选队列,等待下一次的抛出确定。但是虽然思想很简单,实现起来是非常复杂的,我们需要邻接矩阵(表)储存长度,需要优先队列(或者每次都比较)维护一个预选点的集合。还要用一个boolean数组标记是否已经确定、还要---------

总之,Dijkstra算法的思想上是很容易接受的,但是实现上其实是非常麻烦的。但是单源最短路径没有更好的办法。复杂度也为O(n2)

而在n节点多源最短路径中,如果从Dijkstra算法的角度上,只需要将Dijkstra封装,然后执行n次Dijkstra算法即可,复杂度为O(n3)。但是这样感觉很臃肿,代码量巨大,占用很多空间内存。有没有啥方法能够稍微变变口味呢?

答案是有的,这就是易写但稍需要理解的Floyd算法。一个求多元最短路径算法。

算法介绍

先看看百度百科的定义吧:

Floyd算法又称为插点法,是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名。

简单的来说,算法的主要思想是动态规划(dp),而求最短路径需要不断松弛(熟悉spfa算法的可能熟悉松弛)。

而算法的具体思想为:

  1. 邻接矩阵dist储存路径,同时最终状态代表点点的最短路径。如果没有直接相连的两点那么默认为一个很大的值(不要溢出)!而自己的长度为0.
  2. 第1个到第n个点依次加入图中。每个点加入进行试探是否有路径长度被更改。
  3. 而上述试探具体方法为遍历图中每一个点(i,j双重循环),判断每一个点对距离是否因为加入的点而发生最小距离变化。如果发生改变,那么两点(i,j)距离就更改。
  4. 重复上述直到最后插点试探完成。

其中第三步的状态转移方程为:

  • dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j])
    其中dp[x][y]的意思可以理解为x到y的最短路径。所以dp[i][k]的意思可以理解为i到k的最短路径dp[k][j]的意思可以理解为k到j的最短路径.

咱们图解一个案例:

默认的最短长度初始为邻接矩阵初始状态

  • 加入第一个节点1,大家可以发现,由于1的加入,使得本来不连通的2,3点对和2,4点对变得联通,并且加入1后距离为当前最小。(可以很直观加入5之后2,4,更短但是还没加入)。为了更好的描述其实此时的直接联通点多了两条。(2,3)和(2,4).我们在dp中不管这个结果是通过前面那些步骤来的,但是在这个状态,这两点的最短距离就算它!
  • 同时你可以发现加入1其中也使得3,1,4这样联通,但是 3,1,4联通的话距离为9远远大于本来的(3,4)为2,所以不进行更新。
  • 咱们继续加入第二个节点。在加入的初始态为:
  • 进行遍历插入看看是否更新节点

    实际上这个时候图中的连线就比较多了。当然这些连线都是代表当前的最短路径。 这也和我们的需求贴合,我们最终要的是所有节点的最短路径。每个节点最终都应该有6条指向不同节点的边! 表示邻接矩阵的最终结果。

至于算法的模拟两部核心已经告诉大家了,大家可以自行模拟剩下的。

程序实现

而对于程序而言,这个插入的过程相当简单。核心代码只有四行!
代码如下

public class floyd {static int max = 66666;// 别Intege.max 两个相加越界为负public static void main(String[] args) {int dist[][] = {{ 0, 2, 3, 6, max, max }, { 2, 0, max, max,4, 6 }, { 3, max, 0, 2, max, max },{ 6, max, 2, 0, 1, 3 }, { max, 4, max, 1, 0, max }, { max, 6, max, 3, max, 0 } };// 地图// 6个for (int k = 0; k < 6; k++)// 加入滴k个节点{for (int i = 0; i < 6; i++)// 松弛I行{for (int j = 0; j < 6; j++)// 松弛i列{dist[i][j] = Math.min(dist[i][j], dist[i][k] + dist[k][j]);}}}// 输出for (int i = 0; i < 6; i++) {System.out.print("节点"+(i+1)+" 的最短路径");for (int j = 0; j < 6; j++) {System.out.print(dist[i][j]+" ");}System.out.println();}}
}

结果为:

可以自行计算,图和上篇的Dijkstra是一致的,大家可以自行比对,结果一致,说明咱么的结果成功的。

当然,在你学习的过程中,可以在每加入一个节点插入完成后,打印邻接矩阵的结果,看看前两部和笔者的是否相同(有助于理解),如果相同,则说明正确!

你可能还会有疑惑,那咱么就用一个局部性来演示一下,看其中AB最短距离变化情况祝你理解:

好啦,Floyd算法就介绍到这里,如果对你有帮助,请动动小手点个赞吧!蟹蟹。
希望和各位共同进步!欢迎关注笔者公众号:bigsai!

短小精悍的多源最短路径算法—Floyd算法相关推荐

  1. 图论-全源最短路径-对比Floyd算法与暴力Dijkstra算法

    题目 输入顶点数N,有向边数M,接下来M行输入格式为u,v,w分别代表两个顶点u,v和两点之间边的权值w.输出全源最短路径 输入样例: 6 8 0 1 1 0 3 4 0 4 4 1 3 2 2 5 ...

  2. 最短路径:Dijkstra算法(求单源最短路径)Floyd算法(求各顶点之间最短路径)

    最短路径: 在一个带权图中,顶点V0到图中任意一个顶点Vi的一条路径所经过边上的权值之和,定义为该路径的带权路径长度,把带权路径最短的那条路径称为最短路径. DiskStra算法: 求单源最短路径,即 ...

  3. 图的单源最短路径,Floyd算法(数据结构c++)

    这个算法结构很是简单,但是理解还是有一定的困难,一开始做的时候想不明白,跟着算法自己动手画画就知道这个算法具体是怎么回事了. 时间复杂度是O(N*3) 算法有点动态规划的意思,有两个数组,一个(dis ...

  4. 图的单源最短路径:Dijkstra算法实现

    本文介绍的是图的非负权值的单源最短路径问题.问题的提出是,对于有权图D,t提供源点v,要找到从v到其他所有点的最短路径,即单源最短路径问题,在本文中,解决这一问题,是普遍比较熟悉的Dijkstra算法 ...

  5. dijkstra算法PHP,单源最短路径(dijkstra算法)php实现

    做一个医学项目,其中在病例评分时会用到单源最短路径的算法.单源最短路径的dijkstra算法的思路如下: 如果存在一条从i到j的最短路径(Vi.....Vk,Vj),Vk是Vj前面的一顶点.那么(Vi ...

  6. matlab结束外循环,求单源最短路径的BellmanFord算法的matlab实现及其优化

    function [minD,path] = BellmanFord(w,start,terminal) %求单源最短路径的Bellman-Ford算法(图论) %调用格式:[minD,path] = ...

  7. 计算完全最短路径的Floyd算法

    [计算完全最短路径的Floyd算法] (一).定义** Floyd–Warshall(简称Floyd算法)是一种著名的解决任意两点间的最短路径(All Paris Shortest Paths,APS ...

  8. 【算法设计与分析】 单源最短路径(贪心算法) Dijkstra

    [算法设计与分析] 单源最短路径(贪心算法) Dijkstra [问题描述] Dijkstra算法解决的是带权重的有向图上单源最短路径问题.所有边的权重都为非负值.设置顶点集合S并不断地作贪心选择来扩 ...

  9. 03 最短路 dijkstra算法spfa算法floyd算法(附带实例代码) 图论-1

    文章目录 最短路 邻接表的图如下 邻接矩阵如下图 链表实现邻接表实现代码 单源最短路径 Dijkstra 算法 朴素版本 Dijkstra 实现代码 堆优化的dijkstra算法代码实现 Bellma ...

最新文章

  1. UVA - 1594 Ducci Sequence
  2. SAP QM 如何在SAP系统里审批挂在Quality Notification里的document?
  3. 推荐系统中使用ctr排序的f(x)的设计-传统模型篇
  4. 实现一个正则表达式引擎in Python(一)
  5. 用Rocker制作模板
  6. centos安装python3.8
  7. Linux之fgrep命令
  8. 五轮面试,阿里offer到手!!
  9. php隐藏json数据,PHP调用出json后出来的数目字 想隐藏掉 50份求高手帮忙下
  10. 【论文笔记】Neural Machine Translation by Jointly Learning to Align and Translate
  11. Windows AD域功能介绍、Windows AD域方案介绍
  12. AE 二次开发。请考虑更改其中一个程序集的“嵌入互操作类型”属性。
  13. 萧伯纳:劳动和运动(转)
  14. SurfaceView在线视频播放
  15. 机器学习笔记day01
  16. Pr——2020版本对导入视频如何编辑的操作
  17. 如何提取谷歌地球的高程点为XYZ文本
  18. IPMI之ipmitool工具命令详解
  19. 批处理实例:图片批量重命名
  20. 吹爆这份HTTP顶级教程,从基础到核心实战,技术总监都拍手叫好

热门文章

  1. optee中添加一个中断以及底层代码的相关解读
  2. [reference]-ARM core timeline
  3. Android Security视频学习合集
  4. 文件与目录管理——笔记
  5. MFC控件的绘制与响应顺序——ZOrder
  6. 使用vs2019编写dll
  7. QT连接Postgresql数据库
  8. Windows x64内核学习笔记(五)—— KPTI(未完待续)
  9. Android之Xposed框架完全使用指南
  10. 9.任务段(TSS)