Floyd算法

Floyd算法

核心思路:

通过一个图的权值求出它每两点之间的最短路,也可求解多源最短路

从带权的图a中,递归地进行n次更新,构造出距离矩阵。

采用松弛操作,对在ij之间的点做一次松弛。

时间复杂度为On^3

 

动态转移方程:

Map[i][j]=min{

               Map[i][j]+Map[k][j],

               Map[i][j]

           }

 

 

Map[i][j]表示ij的最短距离,k是穷举ij的断点。

 

 最短距离有三种情况:

1、两点的直达距离最短。
2、两点间只通过一个中间点而距离最短。
3、两点间用通过两各以上的顶点而距离最短。

 

算法过程:

  

1.    从一条边开始,两点之间的距离是边的权,如果两点之间没有边,就可以默认权无穷大。从任意节点i到任意节点j的最短路径不外乎2种可能,1是直接从ij2是从i经过若干个节点kj。所以,我们假设Dis(i,j)为节点u到节点v的最短路径的距离,对于每一个节点k,我们检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,证明从ik再到j的路径比i直接到j的路径短,我们便设置Dis(i,j) = Dis(i,k) + Dis(k,j),这样一来,当我们遍历完所有节点kDis(i,j)中记录的便是ij的最短路径的距离。

 

2.    对于每一对顶点uv,看看是否存在一个顶点w使得uv之间中转更短,如果是则更新它。

 

例如有图如下:

这就是一个多源最短路,也就是求任意两点的距离。

那矩阵e为:

0

2

6

4

无穷

0

3

无穷

7

无穷

0

1

5

无穷

12

0

 

 

 

 

 

Floyd算法过程矩阵的计算----十字交叉法

方法:两条线,从左上角开始计算一直到右下角

这个算法过程虽说麻烦,但核心代码只有5行:

1 void Floyd()

{
2     int i,j,k;


3     for(k=1;k<=n;k++)


4         for(i=1;i<=n;i++)


5             for(j=1;j<=n;j++)


6                 if(dist[i][k]+dist[k][j]<dist[i][j])


7                     dist[i][j]=dist[i][k]+dist[k][j];


8 }

复杂度:

 

由于代码:

 

16     for(k=1;k<=n;k++)

 

17         for(i=1;i<=n;i++)

 

18             for(j=1;j<=n;j++)

 

19                 if(e[i][j]>e[i][k]+e[k][j])

 

20                     e[i][j]=e[i][k]+e[k][j];

 

所以显而易见,此算法需要On^3)的时间复杂度

 

空间复杂度有二维数组,所以为On^2

 

    Floyd算法属于一种动态规划思想的算法,简单有效,效率高于执行NDijkstra算法,也高于执行Nspfa算法,但是此算法时间复杂度较高,所以不适合计算大数据。

 

整体核心代码:

for(int k=1;k<=n;k++)
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
posted @ 2016-06-23 11:13  wxjor  阅读(506)  评论(0编辑  收藏  举报