码迷,mamicode.com
首页 > 编程语言 > 详细

最短路径——Floyd算法

时间:2020-06-30 14:43:06      阅读:79      评论:0      收藏:0      [点我收藏+]

标签:info   mic   练习   lan   顶点   不能   pre   src   多个   

最短路径——Floyd算法

可以用来求带权图和无权图

Floyd算法:求出每一对顶点之间的最短路径

使用动态规划思想,将问题的求解分为多个阶段

技术图片

第一个矩阵就是图的邻接矩阵

第二个矩阵表示两个顶点之间的中转点

技术图片

技术图片

遍历上一个阶段留下来的矩阵A,对于上一个矩阵A当中的每一个具体的元素我们都进行:

若 A^(k-1)[i] [j]>A^(k-1)[i] [k]+A^(k-1)[k] [j]

则 A^(k)[i] [j] = A^(k-1)[i] [k] + A^(k-1)[k] [j];

? path^(k)[i] [j] = k

否则A^(k) 和 path^(k)保持原值

\[A^{(-1)}[2] [1]>A^{(-1)}[2] [0]+A^{(-1)}[0] [1]=11 \]

\[A^{(0)}[2] [1] = 11; \]

\[path^{(0)}[2] [1] = 0; \]

技术图片

\[A^{(0)}[0] [2]>A^{(0)}[0] [1]+A^{(0)}[1] [2]=10 \]

\[A^{(1)}[0] [2] = 10; \]

\[path^{(1)}[0] [2] = 1; \]

技术图片

\[A^{(1)}[1] [0]>A^{(1)}[1] [2]+A^{(1)}[2] [0]=9 \]

\[A^{(2)}[1] [0] = 9; \]

\[path^{(2)}[1] [0] = 2; \]

技术图片

技术图片

Floyd算法核心代码

技术图片

//。。。。准备工作,初始化矩阵A和path
for(int k=0;k<n;k++){	//考虑以vk作为中转点
    for(int i=0;i<n;i++){	//遍历整个矩阵,i为行号,j为列号
        for(int j=0;j<n;j++){
            if(A[i][j]>A[i][k]+A[k][j]){	//以vk作为中转点的路径更短
                A[i][j] = A[i][k]+A[k][j];	//更新最短路径长度
                path[i][j] = k;	//中转点
            }
        }
    }
}

技术图片

Floyd算法实例

技术图片

技术图片

技术图片

技术图片

技术图片

技术图片

技术图片

技术图片

技术图片

技术图片

技术图片

练习:floyd算法用于负权图

技术图片

//。。。。准备工作,初始化矩阵A和path
for(int k=0;k<n;k++){	//考虑以vk作为中转点
    for(int i=0;i<n;i++){	//遍历整个矩阵,i为行号,j为列号
        for(int j=0;j<n;j++){
            if(A[i][j]>A[i][k]+A[k][j]){	//以vk作为中转点的路径更短
                A[i][j] = A[i][k]+A[k][j];	//更新最短路径长度
                path[i][j] = k;	//中转点
            }
        }
    }
}

不能解决的问题

带有“负权值回路”的图

这种图可能没有最短路径

技术图片

知识回顾

技术图片

最短路径——Floyd算法

标签:info   mic   练习   lan   顶点   不能   pre   src   多个   

原文地址:https://www.cnblogs.com/jev-0987/p/13213497.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!