算法介绍

和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]
⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡​000000000​111111111​222222222​333333333​444444444​555555555​666666666​777777777​888888888​⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤​

程序循环第一次,即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]
⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡​001110000​111111111​122122222​131333333​144444444​555555555​666666666​777777777​888888888​⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤​

接下来就是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)算法浅析的更多相关文章

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

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

  2. [Python] 弗洛伊德(Floyd)算法求图的直径并记录路径

    相关概念 对于一个图G=(V, E),求图中两点u, v间最短路径长度,称为图的最短路径问题.最短路径中最长的称为图的直径. 其中,求图中确定的某两点的最短路径算法,称为单源最短路径算法.求图中任意两 ...

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

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

  4. 数据结构与算法--最短路径之Floyd算法

    数据结构与算法--最短路径之Floyd算法 我们知道Dijkstra算法只能解决单源最短路径问题,且要求边上的权重都是非负的.有没有办法解决任意起点到任意顶点的最短路径问题呢?如果用Dijkstra算 ...

  5. C# 弗洛伊德(Floyd)算法

    弗洛伊德(Floyd)算法 主要是用于计算图中所有顶点对之间的最短距离长度的算法,如果是要求某一个特定点到图中所有顶点之间的最短距离可以用;        ;    ;    ;            ...

  6. 最短路径之Floyd算法

    Floyd算法又称弗洛伊德算法,也叫做Floyd's algorithm,Roy–Warshall algorithm,Roy–Floyd algorithm, WFI algorithm. Floy ...

  7. 最短路径问题-Floyd算法

    概念 最短路径也是图的一个应用,即寻找图中某两个顶点的最短路径长度. 实际应用:例如确定某两个城市间的坐火车最短行车路线长度等. Floyd algorithm 中文名就是弗洛伊德算法. 算法思路:用 ...

  8. 最短路径---Dijkstra/Floyd算法

    1.Dijkstra算法基础: 算法过程比prim算法稍微多一点步骤,但思想确实巧妙也是贪心,目的是求某个源点到目的点的最短距离,总的来说dijkstra也就是求某个源点到目的点的最短路,求解的过程也 ...

  9. 26最短路径之Floyd算法

    Floyd算法 思想:将n个顶点的图G“分成”很多子图 每对顶点vi和vj对应子图Gij(i=0,1,…,n-1和j=0,1,…,n-1) 每对顶点vi和vj都保留一条顶点限于子图Gij中的最短路径P ...

随机推荐

  1. ICG游戏:证明,先手不是必胜就是必败。

    简介: ICG游戏:Impartial Combinatorial Games,公平的组合游戏. 以下是定义,来自网络,可能不够严谨: 1.两名选手:2.两名选手轮流行动,每一次行动可以在有限合法操作 ...

  2. 转)GPL、BSD、MIT、Mozilla、Apache和LGPL的区别

    开源许可证GPL.BSD.MIT.Mozilla.Apache和LGPL的区别 以下是上述协议的简单介绍: BSD开源协议 BSD开源协议是一个给于使用者很大自由的协议.基本上使用者可以”为所欲为”, ...

  3. JAVA定时关机小程序

    大一刚学java时候做的小程序.由于当时迅雷还没有下载完成关机,晚上要下很多学习资料.只有自己算时间然后通过shutdown命令设置时间关机. 当时通过shutwodn命令,想到能否通过java做一个 ...

  4. jquery的理解

    1.jquery的好处 简化js的复杂操作 不再需要关心兼容性 提供大量使用方法 2.jquery的设计思想 选择网页元素 -模拟css选择元素 -独有的表达式选择 -多种筛选方法 写法 -方法函数化 ...

  5. [转]如何创建一个自签名的SSL证书(X509)

    原文出自:http://www.joyios.com/?p=47 引言 使用HTTP(超文本传输)协议访问互联网上的数据是没有经过加密的.也就是说,任何人都可以通过适当的工具拦截或者监听到在网络上传输 ...

  6. CocoaPods:library not found for -lPods

    This is my first shot to write a blog in English. Enjoy! ;) CocoaPods is a popular way to control iO ...

  7. .NET基础 (12)时间的操作System.DateTime

    时间的操作System.DateTime1 DateTime如何存储时间2 如何在DateTime对象和字符串对象之间进行转换3 什么是UTC时间,如何转换到UTC时间 时间的操作System.Dat ...

  8. Java学习总结——常见问题及解决方法

    CYTX项目开发中遇到的问题及解决方法 Android开发各类常见错误解决方案: 使用Android Studio遇到的问题及解决过程 登录注册部分问题及解决: 1.问题:"No targe ...

  9. MFC DestroyWindow[转]

    考虑单窗口情况: 假设自己通过new创建了一个窗口对象pWnd,然后pWnd->Create.则销毁窗口的调用次序: 1. 手工调用pWnd->DestroyWindow(): 2. De ...

  10. Cacti部署

    1>监控概述   通常运维人员在一个企业当中所需要管理一台或者多台服务器,或者甚至更多,特别是BAT公司或者门户级别的公司,一个人管理的服务器可能上百甚至上千台                  ...