图的最短路径---弗洛伊德(Floyd)算法浅析
算法介绍
和Dijkstra算法一样,Floyd算法也是为了解决寻找给定的加权图中顶点间最短路径的算法。不同的是,Floyd可以用来解决“多源最短路径”的问题。
算法思路
算法需要引入两个二维数组ShortPathTable和Patharc。ShortPathTable表示顶点到顶点的最短路径权值和的矩阵,Patharc表示对应顶点的最小路径的前驱矩阵。在为分析任何顶点之前,ShortPathTable初始化为图的邻接矩阵。
假设图G有N个顶点,那么需要对矩阵ShortPathTable进行N次更新。
第一次更新时如果:
ShortPathTable[v][w] > ShortPathTable[v][0]+ShortPathTable[0][w]
//(ShortPathTable[v][0]+ShortPathTable[0][w]表示"v与w之间经过第1个顶点的距离")
则更新:
ShortPathTable[v][w]为ShortPathTable[v][0]+ShortPathTable[0][w]
同时因为有变化,所以Patharc矩阵对应的Patharc[v][w]和Patharc[w][v]修改为当前中转的顶点的下标0。
同理,第k次更新时:如果"ShortPathTable[v][w]的距离" > “ShortPathTable[v][k]+ShortPathTable[k][w]”,则更新ShortPathTable[v][w]为"ShortPathTable[v][k]+a[k][w]"。
循环更新N次后操作完成。
算法示例

初始化时该网图矩阵(ShortPathTable)如下:
[015∞∞∞∞∞∞10375∞∞∞∞530∞17∞∞∞∞7∞02∞3∞∞∞5120369∞∞∞7∞30∞5∞∞∞∞36∞027∞∞∞∞95204∞∞∞∞∞∞740]
 \left[
 \begin{matrix}
   0 & 1 & 5 & ∞ & ∞ & ∞ & ∞ & ∞ & ∞ \\
   1 & 0 & 3 & 7 & 5 & ∞ & ∞ & ∞ & ∞ \\
   5 & 3 & 0 & ∞ & 1 & 7 & ∞ & ∞ & ∞\\
   ∞ & 7 & ∞ & 0 & 2 & ∞ & 3 & ∞ & ∞\\
   ∞ & 5 & 1 & 2 & 0 & 3 & 6 & 9 & ∞\\
   ∞ & ∞ & 7 & ∞ & 3 & 0 & ∞ & 5 & ∞\\
   ∞ & ∞ & ∞ & 3 & 6 & ∞ & 0 & 2 & 7\\
   ∞ & ∞ & ∞ & ∞ & 9 & 5 & 2 & 0 & 4\\
   ∞ & ∞ & ∞ & ∞ & ∞ & ∞ & 7 & 4 & 0\\
  \end{matrix}
  \right]
⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡015∞∞∞∞∞∞10375∞∞∞∞530∞17∞∞∞∞7∞02∞3∞∞∞5120369∞∞∞7∞30∞5∞∞∞∞36∞027∞∞∞∞95204∞∞∞∞∞∞740⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
Patharc初始化为:
[012345678012345678012345678012345678012345678012345678012345678012345678012345678]
 \left[
 \begin{matrix}
   0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\
  0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\
   0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\
    0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\
    0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\
    0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\
    0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\
    0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\
   0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\
  \end{matrix}
  \right]
⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡000000000111111111222222222333333333444444444555555555666666666777777777888888888⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
程序循环第一次,即k=0时,也就是所有顶点都经过v0v_0v0中转时,没有变化。
当k=1时,也就是说所有顶点都经过v1v_1v1中转,此时,当v=0时,原本ShortPathTable[0][2]=5,现在由于ShortPathTable[0][1]+ShortPathTable[1][2]=4。所以使ShortPathTable[0][2]=4,同理ShortPathTable[0][3]=8,ShortPathTable[0][4]=6.当v=2, 3, 4时也修改了数据。同时在矩阵Patharc上也需要做操作。
此时ShortPathTable:
[01486∞∞∞∞10375∞∞∞∞4301017∞∞∞871002∞3∞∞65120369∞∞∞7∞30∞5∞∞∞∞36∞027∞∞∞∞95204∞∞∞∞∞∞740]
 \left[
 \begin{matrix}
   0 & 1 & 4 & 8 & 6 & ∞ & ∞ & ∞ & ∞ \\
   1 & 0 & 3 & 7 & 5 & ∞ & ∞ & ∞ & ∞ \\
   4 & 3 & 0 & 10 & 1 & 7 & ∞ & ∞ & ∞\\
   8 & 7 & 10 & 0 & 2 & ∞ & 3 & ∞ & ∞\\
   6 & 5 & 1 & 2 & 0 & 3 & 6 & 9 & ∞\\
   ∞ & ∞ & 7 & ∞ & 3 & 0 & ∞ & 5 & ∞\\
   ∞ & ∞ & ∞ & 3 & 6 & ∞ & 0 & 2 & 7\\
   ∞ & ∞ & ∞ & ∞ & 9 & 5 & 2 & 0 & 4\\
   ∞ & ∞ & ∞ & ∞ & ∞ & ∞ & 7 & 4 & 0\\
  \end{matrix}
  \right]
⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡01486∞∞∞∞10375∞∞∞∞4301017∞∞∞871002∞3∞∞65120369∞∞∞7∞30∞5∞∞∞∞36∞027∞∞∞∞95204∞∞∞∞∞∞740⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
此时的Patharc:
[011115678012345678112145678111345678112345678012345678012345678012345678012345678]
 \left[
 \begin{matrix}
   0 & 1 & 1 & 1 & 1 & 5 & 6 & 7 & 8 \\
   0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\
   1 & 1 & 2 & 1 & 4 & 5 & 6 & 7 & 8 \\
    1 & 1 & 1 & 3 & 4 & 5 & 6 & 7 & 8 \\
    1 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\
    0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\
    0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\
    0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\
   0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\
  \end{matrix}
  \right]
⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡001110000111111111122122222131333333144444444555555555666666666777777777888888888⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
接下来就是k=2,一直到k=8,表示针对每个顶点做中转得到的计算结果。
(最终形成的ShortPathTable和Patharc矩阵我就不画了…用markdown来画矩阵好麻烦…)
代码说明
基本定义
	private final int INFINITY = 65535;
	public int MAXVEX;
	public int[][] Patharc;
	public int[][] ShortPathTable;
	//这里直接使用上图的邻接矩阵了,避免了图转矩阵的步骤
	public int[][] maze = {
            {0, 1, 5, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY },
            {1, 0, 3, 7, 5, INFINITY, INFINITY, INFINITY, INFINITY },
            {5, 3, 0, INFINITY, 1, 7, INFINITY, INFINITY, INFINITY },
            {INFINITY, 7, INFINITY, 0, 2, INFINITY, 3, INFINITY, INFINITY },
            {INFINITY, 5, 1, 2, 0, 3, 6, 9, INFINITY},
            {INFINITY, INFINITY, 7, INFINITY, 3, 0, INFINITY, 5, INFINITY},
            {INFINITY, INFINITY, INFINITY, 3, 6, INFINITY, 0, 2, 7},
            {INFINITY, INFINITY,INFINITY, INFINITY, 9, 5, 2, 0, 4},
            {INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, 7, 4,0}
        };
实现代码
	public Floyd() {
		this.MAXVEX = maze.length;
		ShortPathTable = maze;
		Patharc = new int[MAXVEX][MAXVEX];
	}
	public void ShortestPath_Floyd() {
		int v, w, k;
		for (v = 0; v < MAXVEX; v++) {
			for (w = 0; w < MAXVEX; w++) {
				Patharc[v][w] = w;
			}
		}
		//核心代码
		for (k = 0; k < MAXVEX; k++) {
			for (v = 0; v < MAXVEX; v++) {
				for (w = 0; w < MAXVEX; w++) {
					if(ShortPathTable[v][w] > (ShortPathTable[v][k] + ShortPathTable[k][w])) {
						ShortPathTable[v][w] = ShortPathTable[v][k] + ShortPathTable[k][w];
						Patharc[v][w] = Patharc[v][k];
					}
				}
			}
		}
		/**
		 * 最短路径的显示
		 */
		for (v = 0; v < MAXVEX; v++) {
			for (w = 0; w < MAXVEX; w++) {
				System.out.print(v + "-" + "-" + w + " weight:" + ShortPathTable[v][w] + " ");
				k = Patharc[v][w];
				System.out.print("path: " + v);
				while(k != w) {
					System.out.print("->" + k);
					k = Patharc[k][w];
				}
				System.out.print("->" + w + "\n");
			}
			System.out.println();
		}
	}
注意:弗洛伊德(Floyd)算法不能解决带有"负权回路"(又称负权环)。因为带有“负权回路”的图没有最短路。例如下面这个图就不存在1号顶点到3号顶点的最短路径。因为1->2->3->1->2->3->…->1->2->3这样路径中,每绕一次1->-2>3这样的环,最短路就会减少1,永远找不到最短路。其实如果一个图中带有“负权回路”那么这个图则没有最短路。

图的最短路径---弗洛伊德(Floyd)算法浅析的更多相关文章
- 最短路径 - 弗洛伊德(Floyd)算法
		为了能讲明白弗洛伊德(Floyd)算法的主要思想,我们先来看最简单的案例.图7-7-12的左图是一个简单的3个顶点的连通网图. 我们先定义两个二维数组D[3][3]和P[3][3], D代表顶点与顶点 ... 
- [Python] 弗洛伊德(Floyd)算法求图的直径并记录路径
		相关概念 对于一个图G=(V, E),求图中两点u, v间最短路径长度,称为图的最短路径问题.最短路径中最长的称为图的直径. 其中,求图中确定的某两点的最短路径算法,称为单源最短路径算法.求图中任意两 ... 
- 数据结构与算法——弗洛伊德(Floyd)算法
		介绍 和 Dijkstra 算法一样,弗洛伊德(Floyd)算法 也是一种用于寻找给定的加权图中顶点间最短路径的算法.该算法名称以创始人之一.1978 年图灵奖获得者.斯坦福大学计算机科学系教授罗伯特 ... 
- 数据结构与算法--最短路径之Floyd算法
		数据结构与算法--最短路径之Floyd算法 我们知道Dijkstra算法只能解决单源最短路径问题,且要求边上的权重都是非负的.有没有办法解决任意起点到任意顶点的最短路径问题呢?如果用Dijkstra算 ... 
- C# 弗洛伊德(Floyd)算法
		弗洛伊德(Floyd)算法 主要是用于计算图中所有顶点对之间的最短距离长度的算法,如果是要求某一个特定点到图中所有顶点之间的最短距离可以用; ; ; ; ... 
- 最短路径之Floyd算法
		Floyd算法又称弗洛伊德算法,也叫做Floyd's algorithm,Roy–Warshall algorithm,Roy–Floyd algorithm, WFI algorithm. Floy ... 
- 最短路径问题-Floyd算法
		概念 最短路径也是图的一个应用,即寻找图中某两个顶点的最短路径长度. 实际应用:例如确定某两个城市间的坐火车最短行车路线长度等. Floyd algorithm 中文名就是弗洛伊德算法. 算法思路:用 ... 
- 最短路径---Dijkstra/Floyd算法
		1.Dijkstra算法基础: 算法过程比prim算法稍微多一点步骤,但思想确实巧妙也是贪心,目的是求某个源点到目的点的最短距离,总的来说dijkstra也就是求某个源点到目的点的最短路,求解的过程也 ... 
- 26最短路径之Floyd算法
		Floyd算法 思想:将n个顶点的图G“分成”很多子图 每对顶点vi和vj对应子图Gij(i=0,1,…,n-1和j=0,1,…,n-1) 每对顶点vi和vj都保留一条顶点限于子图Gij中的最短路径P ... 
随机推荐
- Window Application has "update" key words
			Error Qt Creater:console error:Failed to start program. Path or permissions wrong? Description 在使用Qt ... 
- 3D 点云特征
			博客参考: https://blog.csdn.net/shaozhenghan/article/details/81346585 和 https://www.cnblogs.com/li-yao77 ... 
- 解决 Laravel try catch 不工作的问题
			最近再用laravel框架发现,try catch用了没有效果,不能捕获异常, 然后在think框架里也试了一下,发现竟然也不可以! [php] view plain copy try{ $i = ... 
- Composer安装和使用 - Windows
			记录windows下安装和使用Composer的方法 1,使用安装程序 这是将 Composer 安装在你机器上的最简单的方法. 下载并且运行 Composer-Setup.exe,它将安装最新版本的 ... 
- ajax 测试
			在学习SpringMVC的过程中,接触到ajax,顺便复习一下前面学习到的知识! 这篇博客中讲的比较详细 http://www.cnblogs.com/lsnproj/archive/2012/02/ ... 
- 关于wcf配置未启动net.tcp监控导致无法访问wcf
			在服务里面启动NetTcpActivator和NetTcpPortSharing服务 
- js 根本没有“JSON对象”这回事!   JSON对象——转
			前言 写这篇文章的目的是经常看到开发人员说:把字符串转化为JSON对象,把JSON对象转化成字符串等类似的话题,所以把之前收藏的一篇老外的文章整理翻译了一下,供大家讨论,如有错误,请大家指出,多谢. ... 
- leetcode-8-String to Integer (atoi) (已总结)
			8. String to Integer (atoi) Total Accepted: 93917 Total Submissions: 699588 Difficulty: Easy Impleme ... 
- 在github创建用户
			在Github注册账户 第一个是创建用户名,第二个是填写邮箱,第三个是设置密码 进入给github会让你选择账户类型 第二步完成后会让你完成邮箱的验证 验证完邮箱以后此时就验证成功了点击绿色的 let ... 
- 我的"gethup"(GitHub)注册之旅
			大家好,我叫张琪琪,来自网络工程143(学号1413042062),.平时喜欢运动,也喜欢看电视尤其是动漫.其实对于自己的编程能力没有多大自信,如果看着题目回忆课本内容写下的程序也算的话,那是敲过不少 ... 
