Floyd算法是啥?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Floyd算法是啥?相关的知识,希望对你有一定的参考价值。

Floyd算法又称为弗洛伊德算法,插点法,是一种用于寻找给定的加权图中顶点间最短路径的算法。
通过一个图的权值矩阵求出它的每两点间的最短路径矩阵。   
从图的带权邻接矩阵A=[a(i,j)] n×n开始,递归地进行n次更新,即由矩阵D(0)=A,按一个公式,构造出矩阵D(1);又用同样地公式由D(1)构造出D(2);……;最后又用同样的公式由D(n-1)构造出矩阵D(n)。矩阵D(n)的i行j列元素便是i号顶点到j号顶点的最短路径长度,称D(n)为图的距离矩阵,同时还可引入一个后继节点矩阵path来记录两点间的最短路径。   
采用的是(松弛技术),对在i和j之间的所有其他点进行一次松弛。所以时间复杂度为O(n^3);   其状态转移方程如下: map[i,j]:=minmap[i,k]+map[k,j],map[i,j]   map[i,j]表示i到j的最短距离   K是穷举i,j的断点   map[n,n]初值应该为0,或者按照题目意思来做。   
当然,如果这条路没有通的话,还必须特殊处理,比如没有map[i,k]这条路
参考技术A Floyd算法 就是求一个有权图中 任意两点的最短路径
有C ,c++,java 等等不同语言算法
参考技术B Floyd算法又称为弗洛伊德算法,插点法,是一种用于寻找给定的加权图中顶点间最短路径的算法。通过一个图的权值矩阵求出它的每两点间的最短路径矩阵。从图的带权邻接矩阵 开始,递归地进行n次更新,即由矩阵D(0)=A,按一个公式,构造出矩阵D(1);又用同样地公式由D(1)构造出D(2);……;最后又用同样的公式由D(n-1)构造出矩阵D(n)。矩阵D(n)的i行j列元素便是i号顶点到j号顶点的最短路径长度,称D(n)为所有点对的最短距离矩阵。

最短路径之Floyd算法

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

Floyd算法是一种在有权图中(有确定的非负的权值,不能存在环路)查找最短路径的算法。该算法的一次简单执行可以找出任意结点之间的最短路径(尽管它没有返回路径的具体信息)。

思想:

Floyd算法通过比较图中任意两点间所有可能存在的路径长度得到最短路径长度。

我们定义一个函数shortestPath(i,j,k)代表从结点i到结点j的最短路径且路径上所有结点的编号均小于k。

两结点间最短路径只有两种情况:1、从结点i经过若干编号小于k的结点到达结点j;2、从结点i经过若干编号小于k+1的结点到达结点j。

其中若最短路径为第二种情况,则此事路径可以分割为两段:从结点i到结点k+1和从结点k+1到结点j,其中从结点i到结点k+1为最短路径,从结点k+1到结点j也为最短路径。

我们定义w(i,j)为结点i到结点j的边的距离,如果两结点之间没有变则w(i,j)为无穷大。

那么以下等式

shortPath(i,j,0)=w(i,j);

shortestPath(i,j,k+1)=min(shortestPaht(i,j,k),shortestPaht(i,k+1,k)+shortestPath(k+1,j,k))

伪代码如下:

let dist be a |V| × |V| array of minimum distances initialized to ∞ (infinity)
 for each vertex v
    dist[v][v] ← 0
 for each edge (u,v)
    dist[u][v] ← w(u,v)  // the weight of the edge (u,v)
 for k from 1 to |V|
    for i from 1 to |V|
       for j from 1 to |V|
          if dist[i][j] > dist[i][k] + dist[k][j] 
             dist[i][j] ← dist[i][k] + dist[k][j]
         end if

 C代码

#include <stdio.h>
#define N 10//定义顶点个数
int arr[N][N];//定义二维数组,其初始值为该图的邻接矩阵
int main(){
    int len;
    while(scanf("%d",&len)!=EOF){
        for(int i=0;i<N;i++){
            for(int j=0;j<N;j++){
                arr[i][j]=-1;//初始化二维数组,因为floyd不存在负数权值,故我们使用-1代替无穷大
            }
        }
        int i,j,c;//定义结点及权值
        while(len--){
            scanf("%d %d %d",&i,&j,&c);//输入边的两个结点及边的距离
            arr[i][j]=arr[j][i]=c;
        }
        //
        for(int k=0;k<len;k++){
            for(int i=0;i<len;i++){
                for(int j=0;j<len;j++){
                    if(arr[i][k]==-1||arr[k][j]==-1)//如果两个之中有一个是无穷大,则必有arr[i][j]不能经过k结点联结
                        continue;
                    if(arr[i][j]==-1||arr[i][k]+arr[k][j]<arr[i][j])//如果经过k结点后路径变短,则更新路径
                        arr[i][j]=arr[j][i]=arr[i][k]+arr[k][j];
                }
            }
        }
    }

    return 0;
}

 

以上是关于Floyd算法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Floyd算法与Dijkstra算法的区别?

最短路径之Floyd算法

Floyd判圈算法 Floyd Cycle Detection Algorithm

最短路(Floyd算法的动态规划本质)- HDU 2544

floyd算法 是动态规划的思想吗

Floyd(弗洛伊德)算法