携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第22天,点击查看活动详情
Floyd算法介绍
Floyd算法是经典的动态规划算法,基本思想是递推产生一个矩阵序列A1,A2,.....,Ak,...,An(图有n个节点),Ak=(ak(i,j))nxn。其中矩阵Ak第i行第j列表示从顶点vi到顶点vj的路径上经过的顶点序号不大于k的最短路径长度。
算法的原理
算法实现无外乎就是三个循环嵌套,i,j的循环是任意两个点,而k则是两个点之间所经过的第三个点,我们就是在循环之中不断比较从i到j的距离与从i到k距离加上从k到j距离的大小,如果经过这个点,路径变短了,我们就接受这个点,认为可以经过这个点;否则就不经过这个点,就是从i到j最短。
算法实现
- 先生成图的邻接距阵与路径距阵
- 用d[i,j]表示i点到j点的最短距离,但i到j可能会经过K个顶点才能找到最短路径: d[i][j]=d[i][k]+d[k][j],其中的k可能为多个点
- 遍历全部顶点,如果出现d[i][j]>d[i][k]+d[k][j],我们就用短的路径替换长的路径,如图中v1->v2直接走为4,用v1->v0->v2==3
- 为了找到全部结点对之间的最短路径,可以在路径计算过程中,取数组p[i][j]=p[i][k]用于记录每次的替换过程;
代码实现
public static final int I = 100;
//邻接距阵
public static int[][] d = new int[][]{
{0, 2, 1, 5},
{2, 0, 4, I},
{1, 4, 0, 3},
{5, I, 3, 0}
};
public static int[][] p=new int[][]{
{0,1,2,3},
{0,1,2,3},
{0,1,2,3},
{0,1,2,3}
};
public static void floyd(){
for (int k = 0; k < d.length; k++) {
for(int i=0;i<d.length;i++){
for (int j = 0; j < d.length; j++) {
if(d[i][j]>d[i][k]+d[k][j]){
d[i][j]=d[i][k]+d[k][j];
//记录下路径
p[i][j]=p[i][k];
}
}
}
}
}