Floyd算法求解最短路径

  • 1、算法概述
  • 2、算法实例
  • 3、算法实战
    • 3.1 算法描述
    • 3.2 解题思路
    • 3.3 代码实现

1、算法概述

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

  核心思路:通过一个图的权值矩阵求出它的每两点间的最短路径矩阵。

  算法过程:

  • 从任意一条单边路径开始。左右两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。

  • 对于每一对顶点u和v,看是否存在一个顶点w使得从u到w再到v比已知的路径更短,如果更短,则更新它。

    上述概念来源于百度百科

2、算法实例

  如下图所示,我们看怎么来求解两点之间的最短路径。

  如果要让任意两点之间(假设是a到b)的路程变短,智能引入第三个点(假设为k),并通过这个点k进行中转即a->k->b,才可能缩短为原来从顶点a到顶点b的路程。有时候可能不止一个中转点,而是经过两个或者更多的点进行中转会更短。比如上图中的4号和3号之间的路程本来是a[4][3]=12,如果通过1号中转4->1->3,路程将缩短为e[4][1]+e[1][3]=5+6=11。如果同时通过1号和2号中转的话,从4号到3号的路程会进一步缩短为e[4]+e[1][2]+e[2][3]=5+2+3=10。通过以上分析,我们发现每个顶点都有可能使得另外两个顶点之间的路程变短。下面我们模拟该过程。

  我们使用邻接矩阵(二维数组)存储这个图,我们约定自己到自己的路程为0,1号和2号城市的路程为2,则设e[1][2]=2。2号城市无法到达4号城市,设e[2][4]=无穷大我们根据图中的权值得出如下矩阵:

  假设我们现在只允许经过1号顶点中转,求任意两点之间的最短路径。

//经过1号顶点中转
for (int i = 1; i <=N ; i++) {for (int j = 1; j <=N; j++) {if(e[i][j]>e[i][1]+e[1][j]){e[i][j]=e[i][1]+e[1][j];}}
}

  此时我们只需要判断e[i][1]+e[1][j]是否比e[i][j]小就行,若小于,更新矩阵。

  由于e[3][1]+e[1][2]=7+2=9<e[3][2]=∞e[3][1]+e[1][2]=7+2=9<e[3][2]=\inftye[3][1]+e[1][2]=7+2=9<e[3][2]=∞,所以更新矩阵e[3][2]=9

  由于e[4][1]+e[1][2]=5+2=7<e[4][2]=∞e[4][1]+e[1][2]=5+2=7<e[4][2]=\inftye[4][1]+e[1][2]=5+2=7<e[4][2]=∞,所以更新矩阵e[4][2]=7

  由于e[4][1]+e[1][3]=5+6=11<e[4][3]=12e[4][1]+e[1][3]=5+6=11<e[4][3]=12e[4][1]+e[1][3]=5+6=11<e[4][3]=12,所以更新矩阵e[4][3]=11

  更新后的矩阵如下所示:

  接下来,求只允许经过1号和2号两个顶点的情况下任意两点之间的最短路径。我们需要在只允许经过1号顶点时任意两点的最短路径的结果下,再判断如果经过2号顶点是否可以使得i号顶点到j号顶点之间的路程变得更短,即判断e[i][2]+e[2][j]是否小于e[i][j]

//经过2号顶点中转
for (int i = 1; i <=N ; i++) {for (int j = 1; j <=N; j++) {if(e[i][j]>e[i][2]+e[2][j]){e[i][j]=e[i][1]+e[1][j];}}
}

  由于e[1][2]+e[2][3]=2+3=5<e[1][3]=6e[1][2]+e[2][3]=2+3=5<e[1][3]=6e[1][2]+e[2][3]=2+3=5<e[1][3]=6,所以e[1][3]=5

  由于e[4][1]+e[1][3]=5+6=11<e[4][3]=11e[4][1]+e[1][3]=5+6=11<e[4][3]=11e[4][1]+e[1][3]=5+6=11<e[4][3]=11,所以e[4][3]=10

  以此类推,后面的就不再一个个写了。

  总结:Floyd算法可以算出任意两点的最短路径,可以处理带有负权边的图,但不能处理带有“负环”的图。时间复杂度:O(n3)O(n^3)O(n3)

3、算法实战

3.1 算法描述

  小明喜欢观景,图示今天来到了蓝桥公园。

  已知公园有N个景点,景点和景点之间一共有M条道路,小明有Q个观景计划。每个计划包含一个起点st和一个终点ed,表示他想从st去到ed。但是小明体力有限,对于每个计划他想走最少的路完成,你可以帮帮他吗?

输入描述

  输入第一行包含三个正整数N,M,Q

  第2到M+1行每行包含三个正整数u,v,w,表示u↔vu\leftrightarrow vu↔v之间存在一条距离为w的路。

  第M+2到M+Q-1行每行包含两个正整数st,ed,其含义如题所述。
1≤N≤400,1≤M≤N×(N−1)2,Q≤103,1≤u,v,st,ed≤n,1≤w≤1091\le N\le 400,1\le M\le \frac{N\times (N-1)}{2} ,Q\le 10^3 ,1\le u,v,st,ed\le n,1\le w\le 10^9 1≤N≤400,1≤M≤2N×(N−1)​,Q≤103,1≤u,v,st,ed≤n,1≤w≤109
输出描述

  输出共Q行,对应输入数据中的查询。

  若无法从st到达ed则输出-1。

输入输出样例

输入

3 3 3
1 2 1
1 3 5
2 3 2
1 2
1 3
2 3

输出

1
3
2

3.2 解题思路

  使用Floyd算法求解,由于该算法时间复杂度为O(n3)O(n^3)O(n3),n较大会超时,但是本题的n比较小,所以够用。

  对于图中的任意两个点i和j,我们dist[i][j]表示从i到j的距离。初始时候,对于所有的1≤i,j≤n1\le i,j\le n1≤i,j≤n,有dist[i][j]=∞dist[i][j]=\inftydist[i][j]=∞,如果存在边(i,j),则dist[i][j]=w(i,j)。然后我们用动态规划思想逐步优化dist数组,使得dist[i][j]不断逼近真实的最短路径长度。

  我们主要是维护一个二维数组dist,dist[i][j]表示从i到j的最短路径长度。初始时,如果i和j之间有边,则dist[i][j]为该边(i,j)的权值,否则dist[i][j]=∞dist[i][j]= \inftydist[i][j]=∞。然后从1到n的每个点作为中转点,更新所有可能的最短路径长度。具体的说,对于中转点k,我们遍历所有的i,j,如果dist[i][j]>dist[i][k]+dist[k][j],则执行更新dist[i][j]=dist[i][k]+dist[k][j]。最后得到的dist数组即为任意两点之间的最短路径长度。

  我们对每个点当作中转点都要做双重for循环,所以在外层再加一个循环,只需要使用三重循环依次枚举中转点k和每对起点i和终点j,并更新dist[i][j]的值即可。

3.3 代码实现

import java.util.Arrays;
import java.util.Scanner;public class Floyd {public static void main(String[] args) {Scanner scan = new Scanner(System.in);int N = scan.nextInt();//N个景点int M = scan.nextInt();//经典之间共M条路int Q = scan.nextInt();//Q个观景计划long[][] dist = new long[N + 1][N + 1];for (int i = 1; i <=M ; i++) {  //初始化为最大值Arrays.fill(dist[i],Long.MAX_VALUE);dist[i][i]=0; //对角线赋值0即可(自己到自己)}for (int i = 1; i <=M; i++) {  //初始化两点距离int u = scan.nextInt();int v = scan.nextInt();long w = scan.nextLong();dist[u][v]=Math.min(dist[u][v],w);dist[v][u]=Math.min(dist[v][u],w);}//Floyd算法for (int k = 1; k <=N; k++) {for (int i = 1; i <=N ; i++) {for (int j = 1; j <=N; j++) {if(dist[i][j]>dist[i][k]+dist[k][j]){dist[i][j]=dist[i][k]+dist[k][j];}}}}//查询for (int i = 0; i <Q ; i++) {int start = scan.nextInt();int end = scan.nextInt();if(dist[start][end]>=Long.MAX_VALUE){System.out.println(-1);}else{System.out.println(dist[start][end]);}}}
}

   真正的算法就5~6行,还是比较好理解的。

Floyd算法求解最短路径相关推荐

  1. floyd算法求解地铁路线问题

    题目描述Description 假设有两条地铁线路,1 号线为直线线路,2 号线为环线线路, 假设 1 号线的各个站点名称分别为 "A" "B" "C ...

  2. Floyd算法求解最短距离

    1.问题 用Floyd算法求解下图各个顶点的最短距离.写出Floyd算法的伪代码和给出距离矩阵(顶点之间的最短距离矩阵). 2.解析 Floyd算法又称为插点法,是一种利用动态规划的思想寻找给定的加权 ...

  3. BS1036-基于java+路径规划+CS架构实现的A星算法求解最短路径问题演示程序

    本基于java+路径规划+CS架构实现的A星算法求解最短路径问题演示程序,系统采用多层C/S软件架构,采用java 编程语言开发技术实现A*算法求解地图中的最短路径问题,实时获取计算用户在地图中设置的 ...

  4. 弗洛伊德(Floyd)算法求解图的最短路径

    弗洛伊德(Froyd)算法用于求解所有顶点到所有顶点的的最短路径.时间复杂度为O(n^3). 正如我们所知道的,Floyd算法用于求最短路径.Floyd算法可以说是Warshall算法的扩展,三个fo ...

  5. 动态规划 - Floyd算法求最短路径 - (Matlab建模)

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

  6. floyd算法_最短路径的算法:Floyd算法

    点击箭头处"蓝色字",关注我们哦!! 算法 最短路径的算法-Floyd算法 ● ○ ● Shortest Path Algorithm - Floyd Algorithm ● ○ ...

  7. Floyd算法求最短路径(附代码实例)

    Floyd算法 使用范围: 1)求每对顶点的最短路径; 2)有向图.无向图和混合图; 算法思想: 直接在图的带权邻接矩阵中用插入顶点的方法依次递推地构造出n个矩阵D(1), D(2), -, D(n) ...

  8. 迪杰斯特拉算法---求解最短路径

    迪杰斯特拉算法: 按路径长度递增的次序求解最短路径的方法.从单源点出发查找与单源点连接的最小的边,把该边对应的顶点加入集合V,然后从该顶点开始与原来到其他各顶点的最短路径进行比较,若比原来的路径小,则 ...

  9. Python Floyd算法求最短路径

    Floyd算法简介: Floyd算法 floyd算法(多源最短路径) python实现 例题 求下图各节点最短路径 Floyd算法如下: from math import * import numpy ...

最新文章

  1. 关于在web项目中实现本地打印
  2. mysql日期格式化季度_mysql中常用日期比较与计算函数
  3. Angular应用的部署方式
  4. [html] 说说你对HTML元素的显示优先级的理解
  5. 元组、字典、集合的常用方法
  6. Linux7/Redhat7/Centos7 安装Oracle 12C_监听配置及DBCA安装数据库_05
  7. c#简单记事本应用程序的快捷方式_Windows 10七月更新又翻车,记事本没了
  8. 银河麒麟 安卓nginx_银河麒麟Kydroid 2.0全新发布:原生支持海量安卓APP
  9. Percona XtraBackup
  10. Spring Cloud实战(六)-Spring Cloud Netflix Bus
  11. 创业经验谈(转自:ouravr.com)
  12. 微信小程序--萌系登陆界面
  13. FPGA开平方的实现(三种方法)
  14. 入库出库JAVA技术详情_基于Java_EE的入库出库管理系统
  15. 常见的配置中心:Apollo(二)-接入Apollo
  16. Three.js——天空盒
  17. 大数据与云计算技术---(一)hadoop大数据平台
  18. 为什么要停止过度使用置换重要性来寻找影响特征
  19. Redis集群入门实践教程
  20. 伦敦港竟与这事脱不了干系 | 经济学人全球早报精选

热门文章

  1. word如何合并单元格拆分单元格
  2. FreeRTOS信号量详解第三讲(全网最全)——计数信号量
  3. JAVA 面试题 合辑(二)
  4. pandas给读取到的excel添加表头
  5. 做分页时取整数的计算以及js取整数、取余数的方法
  6. 尚品宫韩式烧烤 无忧致富好项目
  7. 服务器监控系统大概多少钱,服务器监控系统 报价
  8. 小米手环4 你值得拥有(彩屏,支付宝,AI,公交门禁,音乐控制该有的都有了)
  9. 【精品】seata综合示例:订单-库存-扣款
  10. 【exception】java.lang.NoClassDefFoundError Could not initialize class