一、算法介绍

  Floyd-Warshall算法(英语:Floyd-Warshall algorithm),中文亦称弗洛伊德算法,是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权(但不可存在负权回路)的最短路径问题,同时也被用于计算有向图的传递闭包。Floyd-Warshall算法的时间复杂度为 O(N3),空间复杂度为 O(N2),因时间复杂度比较高,不适合计算大量数据。

二、算法原理

Floyd-Warshall算法的原理是动态规划,Floyd算法适用于APSP(All Pairs Shortest Paths,多源最短路径)。

设 Di,j,k 为从 i 到 j 的只以 (1..k) 集合中的节点为中间节点的最短路径的长度。

  1. 若最短路径经过点 k,则 Di,j,k = Di,k,k-1 + Dk,j,k-1
  2. 若最短路径不经过点 k,则 Di,j,k =Di,j,k-1

因此,Di,j,k = min (Di,j,k-1, Di,k,k-1 + Dk,j,k-1)。

1         for (k = 0; k < V; k++) {
2 for (i = 0; i < V; i++) {
3 for (j = 0; j < V; j++) {
4 if (dist[i][j] > dist[i][k] + dist[k][j]) {
5 dist[i][j] = dist[i][k] + dist[k][j];
6 }
7 }
8 }
9 }

输入矩阵:

1     int[][] graph = {
2 {0, 5, INF, 10},
3 {INF, 0, 3, INF},
4 {INF, INF, 0, 1},
5 {INF, INF, INF, 0}
6 };

输出结果:

1   Shortest distance matrix :
2 0 5 8 9
3 INF 0 3 4
4 INF INF 0 1
5 INF INF INF 0

  初始化与输入图矩阵相同的求解矩阵。然后,我们通过将所有顶点视为中间顶点来更新解矩阵。这个思想是一个接一个地选取所有顶点并更新所有最短路径,其中包括所选取的顶点作为最短路径中的中间顶点。

源代码:

 1 package algorithm.shortestpath;
2
3 public class AllPairShortestPath {
4 final static int INF = 99999, V = 4;
5
6 public void floydWarshall(int[][] graph) {
7 int[][] dist = new int[V][V];
8 int i, j ,k;
9 for (i = 0; i < V; i++) {
10 for (j = 0; j < V; j++) {
11 dist[i][j] = graph[i][j];
12 }
13 }
14 for (k = 0; k < V; k++) {
15 for (i = 0; i < V; i++) {
16 for (j = 0; j < V; j++) {
17 if (dist[i][j] > dist[i][k] + dist[k][j]) {
18 dist[i][j] = dist[i][k] + dist[k][j];
19 }
20 }
21 }
22 }
23 printSoultion(dist);
24 }
25
26 private void printSoultion(int[][] dist) {
27 System.out.println("The following matrix shows the shortest "+
28 "distances between every pair of vertices");
29 for (int i = 0; i < V; ++i) {
30 for (int j = 0; j < V; ++j) {
31 if (dist[i][j] == INF) {
32 System.out.print("INF ");
33 } else {
34 System.out.print(dist[i][j] + " ");
35 }
36 }
37 System.out.println();
38 }
39 }
40
41 public static void main(String[] args) {
42 /* 输入带权重矩阵
43 10
44 (0)------->(3)
45 | /|\
46 5 | |
47 | | 1
48 \|/ |
49 (1)------->(2)
50 3 */
51 int[][] graph = {
52 {0, 5, INF, 10},
53 {INF, 0, 3, INF},
54 {INF, INF, 0, 1},
55 {INF, INF, INF, 0}
56 };
57
58 AllPairShortestPath a = new AllPairShortestPath();
59
60 a.floydWarshall(graph);
61 }
62 }

最短路径算法:弗洛伊德(Floyd-Warshall)算法的更多相关文章

  1. 数据结构与算法——弗洛伊德(Floyd)算法

    介绍 和 Dijkstra 算法一样,弗洛伊德(Floyd)算法 也是一种用于寻找给定的加权图中顶点间最短路径的算法.该算法名称以创始人之一.1978 年图灵奖获得者.斯坦福大学计算机科学系教授罗伯特 ...

  2. JS实现最短路径之弗洛伊德(Floyd)算法

    弗洛伊德算法是实现最小生成树的一个很精妙的算法,也是求所有顶点至所有顶点的最短路径问题的不二之选.时间复杂度为O(n3),n为顶点数. 精妙之处在于:一个二重初始化,加一个三重循环权值修正,完成了所有 ...

  3. Floyd—Warshall算法

    我们用DP来求解任意两点间的最短路问题 首先定义状态:d[k][i][k]表示使用顶点1~k,i,j的情况下,i到j的最短路径 (d[0][i][j]表示只使用i和j,因此d[0][i][j] = c ...

  4. 图论之最短路径(1)——Floyd Warshall & Dijkstra算法

    开始图论学习的第二部分:最短路径. 由于知识储备还不充足,暂时不使用邻接表的方法来计算. 最短路径主要分为两部分:多源最短路径和单源最短路径问题 多源最短路径: 介绍最简单的Floyd Warshal ...

  5. 算法:最短路径之弗洛伊德(Floyd)算法

    https://cloud.tencent.com/developer/article/1012420 为了能讲明白弗洛伊德(Floyd)算法的主要思想,我们先来看最简单的案例.图7-7-12的左图是 ...

  6. 最短路径 - 弗洛伊德(Floyd)算法

    为了能讲明白弗洛伊德(Floyd)算法的主要思想,我们先来看最简单的案例.图7-7-12的左图是一个简单的3个顶点的连通网图. 我们先定义两个二维数组D[3][3]和P[3][3], D代表顶点与顶点 ...

  7. 图的最短路径---弗洛伊德(Floyd)算法浅析

    算法介绍 和Dijkstra算法一样,Floyd算法也是为了解决寻找给定的加权图中顶点间最短路径的算法.不同的是,Floyd可以用来解决"多源最短路径"的问题. 算法思路 算法需要 ...

  8. 最短路径问题:弗洛伊德算法(Floyd)

    Floyd算法 1.定义概览 Floyd-Warshall算法(Floyd-Warshall algorithm)是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题,同时也被 ...

  9. 最短路径:Dijkstra & Floyd 算法图解,c++描述

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. 最小生成树(prime算法 & kruskal算法)和 最短路径算法(floyd算法 & dijkstra算法)

    一.主要内容: 介绍图论中两大经典问题:最小生成树问题以及最短路径问题,以及给出解决每个问题的两种不同算法. 其中最小生成树问题可参考以下题目: 题目1012:畅通工程 http://ac.jobdu ...

随机推荐

  1. 【多线程】Android多线程学习笔记——线程池

    Java线程池采用了享元设计模式,在系统中维持一定数量的线程,用于处理异步或并发需求,在平时处理异步或并发任务时被广泛使用.这里基于JDK1.8和Android28来整理一些关于线程池的知识点. 一. ...

  2. 自己实现一个Controller——精简型

    写在最前 controller-manager作为K8S master的其中一个组件,负责众多controller的启动和终止,这些controller负责监控着k8s中各种资源,执行调谐,使他们的实 ...

  3. Spring Boot中如何配置线程池拒绝策略,妥善处理好溢出的任务

    通过之前三篇关于Spring Boot异步任务实现的博文,我们分别学会了用@Async创建异步任务.为异步任务配置线程池.使用多个线程池隔离不同的异步任务.今天这篇,我们继续对上面的知识进行完善和优化 ...

  4. Linux系列(7) - 链接命令

    硬链接 拥有相同的i节点和存储block块,可以看做事同一个文件 可通过i节点识别 不能跨分区 不能针对目录使用,只能针对文件 软链接 类似Windows快捷方式 软链接拥有自己的i节点和block块 ...

  5. Python中“if __name__=='__main__':”

    在Python当中,如果代码写得规范一些,通常会写上一句"if name=='main:"作为程序的入口,但似乎没有这么一句代码,程序也能正常运行.这句代码多余吗?原理又在哪里? ...

  6. CF280D-k-Maximum Subsequence Sum【模拟费用流,线段树】

    正题 题目链接:https://www.luogu.com.cn/problem/CF280D 题目大意 一个长度为\(n\)的序列,\(m\)次操作 修改一个数 询问一个区间中选出\(k\)段不交子 ...

  7. AT4353-[ARC101D]Robots and Exits【LIS】

    正题 题目链接:https://www.luogu.com.cn/problem/AT4353 题目大意 数轴上有\(n\)个球\(m\)个洞,每次可以将所有球左移或者右移,球到洞的位置会掉下去. 求 ...

  8. Appium+Python自动化环境搭建-1

    前言 appium可以说是做app最火的一个自动化框架,它的主要优势是支持android和ios,另外脚本语言也是支持java和Python. 小编擅长Python,所以接下来的教程是appium+p ...

  9. nginx负载均衡部署

    1 系统版本 CentOS Linux release 6.0.1708 (Core) 2 编译安装前所需要的准备: 1.GCC编译器 首先检查GCC是否安装,命令:gcc -v ,如果显示有相关版本 ...

  10. RobotFramework+Selenium如何提高脚本稳定性

     通过RF来跑selenium的脚本,正常运行一遍都没有问题,但如果要多次运行,提高脚本的稳定性,那么应该如何做呢?  当然有时候最简单最简单的方法就是直接通过sleep来等待,虽然简单粗暴,但会带来 ...