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

转载 2017年01月03日 18:08:55
Floyd算法可以用于构造无向或有向加权图(不包含长度为负的回路)的完全最短路径:




Floyd算法算法的构造过程非常类似于Warshall算法,所以放在一起讲:

Warshall算法是通过每次加入一个顶点,看把这个顶点作为中间顶点是否能改进传递闭包的矩阵(通过这个新加入的顶点作为中间桥梁,使得原来不可达的2个顶点可

达,以此逐步向传递闭包逼近)。

Floyd算法非常类似,通过初试的权重矩阵,每次加入一个顶点,看这个顶点是否能作为中间顶点改变图的权重矩阵(加入这个中间顶点后,每两个点之间的最短距离

是否减小了)。



伪代码:




实现:

复制代码
package Section8;


/*第八章 动态规划 完全最短路径的Floyd算法*/

public class Floyd {

/**
*
@param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int[][] WeightMat = {
{
0,1000,3,1000},
{
2,0,1000,1000},
{
1000,7,0,1},
{
6,1000,1000,0}
};
int[][] Result = Floyd(WeightMat);

System.out.println(
"输出表达完全最短路径的矩阵:\n");
for(int i = 0;i < Result.length;i++)
{
for(int j = 0;j < Result.length;j++)
System.out.print(Result[i][j]
+ " ");
System.out.println();
}

}

public static int[][] Floyd(int[][] WeightMat){
//接受一个图的权重矩阵,返回表达完全最短路径的矩阵
int n = WeightMat.length;
int[][] Result = WeightMat;

for(int k = 0;k < n;k++) //进行n次变换,每次加入第k个点
{
int[][] temp = new int[n][n];
for(int i = 0;i < n;i++)
for(int j = 0;j < n;j++)
temp[i][j]
= min(Result[i][j],Result[i][k]+Result[k][j]);//加入第k个点后路径是否能缩短
Result = temp;
}

return Result;
}

private static int min(int m,int n){
if(m < n)
return m;
return n;
}

}
复制代码


运行结果:


输出表达完全最短路径的矩阵:

0   10   3   4   
2   0   5   6   
7   7   0   1   

6   16   9   0



例如Floyd算法,我们得到了它的最短路径的值,但具体的最短路径又是哪一条呢?

这也是动态规划问题的一个常见的关键点,我们常见的是求出最优的那个代价,但有时候需要去求得到这个代价的具体路径


于是有下面一道很好的思考题:

Q:加强Floyd算法,使得它能得到最短路径本身,而不仅仅是它的长度。


解答:

可以再弄一个矩阵p(大小为n*n),p[i , j] = k,表明从 i 到 j 的最短路径要经过顶点 k (注意不是只经过 k)。这样在原来的Floyd算法里,每次加入顶点 k 来改

变矩阵时,若 k 起到了作用(加入k后对某个最短路径起到了修正作用),那么就把进行把 k 记在 p 矩阵里:



相比原算法,就是多用了一个p矩阵,加了最后一行,每次加入k起到了作用的时候,记下。注意这个伪代码是空间优化了的Floyd算法,直接在原矩阵上填。

这样最终结果就得到了2个矩阵:D矩阵记录了所有 i 到 j 顶点的最短路径。p矩阵间接表达了每条最短路径的具体路径。例如:最终可能得到下列p矩阵:



根据p[i , j] 的定义, p[1][2] = 3,表明从顶点1(即顶点a)到顶点2(即顶点b)的最短路路径至少要经过顶点3(即顶点c)----见最上面那幅图。

即顶点3是顶点1到2最短路径上的一个桥梁,那么从1到3以及从3到2之间还有没有别的桥梁呢?再看p[1][3] = 0,p[3][2] = 0,所以没有了,那么从1到2的最短

路径就是1,3,2。

下列递归算法可以表明上述过程,来从p矩阵中输出任意两个点之间的最短路径:



注意是递归的,每个k都将 i,j 分开了,为什么可以递归?这里又要说到最优子结构,因为从 i 到 j是最短路径,那么从 i 到 k,以及从 k 到 j也是子问题的最短路

径。


这个问题很重要,注意怎么去记录一个动态规划产生的过程,这样我们最终得到的就不仅仅是一个最优化的代价,还可以得到一个表达这个动态规划解是怎么来的矩

阵。
注意这个矩阵只是表达了生成的过程,要输出具体的解,还需要一个算法从这个矩阵中去挖掘出这个答案

最短路径:Dijkstra算法和Floyd算法

最短路径问题是图论研究中的一个经典算法问题,旨在寻找图(由结点和路径组成的)中两结点之间的最短路径。算法具体的形式包括:         1.确定起点的最短路径问题:即已知起始结点,求最短路径的问题...
  • yang1018679
  • yang1018679
  • 2015年05月16日 11:27
  • 4461

floyd算法求解最短路径

转自  http://blog.csdn.net/zhongkeli/article/details/8832946 这个算法主要要弄懂三个循环的顺序关系。 弗洛伊德(...
  • Bocai_Fire
  • Bocai_Fire
  • 2015年05月05日 07:54
  • 8369

结点对最短路径之Floyd算法原理详解及实现

上两篇博客介绍了计算单源最短路径的Bellman-Ford算法和Dijkstra算法。Bellman-Ford算法适用于任何有向图,即使图中包含负环路,它还能报告此问题。Dijkstra算法运行速度比...
  • Ivan_zgj
  • Ivan_zgj
  • 2016年06月02日 14:08
  • 7208

计算完全最短路径的Floyd算法剖析

【转载自http://www.cnblogs.com/chenchuangfeng/archive/2013/03/29/2989825.html】 到两个重要矩阵:         1.d[nu...
  • solarlhh
  • solarlhh
  • 2013年07月23日 00:04
  • 577

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

Floyd算法可以用于构造无向或有向加权图(不包含长度为负的回路)的完全最短路径: Floyd算法算法的构造过程非常类似于Warshall算法,所以放在一起讲: Warshal...
  • fbz123456
  • fbz123456
  • 2016年03月16日 21:17
  • 335

计算完全最短路径的Floyd算法剖析

到两个重要矩阵:         1.d[numVex][numVex]  (numVex图的顶点数):最开始该矩阵就是图的邻接矩阵,经过Floyd算法处理开后,d[numVex][numVex]中...
  • pql925
  • pql925
  • 2017年01月03日 18:15
  • 159

floyd算法,复杂网络最短路径的计算

  • 2013年04月07日 10:55
  • 714B
  • 下载

Floyd算法求最短路径

  • 2009年01月03日 11:14
  • 3KB
  • 下载

Floyd算法求任意两点间的最短路径

  • 2012年12月13日 17:28
  • 5KB
  • 下载

C例子:最短路径(floyd算法)

  • 2015年10月11日 10:18
  • 2KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:计算完全最短路径的Floyd算法
举报原因:
原因补充:

(最多只允许输入30个字)