package com.guigu.algorithm.floydAlgorithm;
import java.util.Arrays;
/**
* @author: guorui fu
* @versiion: 1.0
* 弗洛伊德算法 本质就是将邻接矩阵中N值填满 时间复杂度3^n
* 每一种两顶点线路都有遍历到
*/
public class FloydAlgorithm {
public static void main(String[] args) {
char[] vertex = {'A','B','C','D','E','F','G'};
//创建邻接矩阵
int[][] matrix = new int[vertex.length][vertex.length];
final int N = 65535;
matrix[0] = new int[]{0, 5, 7, N, N, N, 2};
matrix[1] = new int[]{5, 0, N, 9, N, N, 3};
matrix[2] = new int[]{7, N, 0, N, 8, N, N};
matrix[3] = new int[]{N, 9, N, 0, N, 4, N};
matrix[4] = new int[]{N, N, 8, N, 0, 5, 4};
matrix[5] = new int[]{N, N, N, 4, 5, 0, 6};
matrix[6] = new int[]{2, 3, N, N, 4, 6, 0};
Graph graph = new Graph(vertex.length, matrix, vertex);
graph.show();
graph.floyd();
graph.show();
}
}
class Graph{
private char[] vertex;//存放顶点的数组
private int[][] dis;//保存 各个顶点到其他顶点的距离
private int[][] pre;//保存到达目标顶点的前驱顶点
//传入长度,邻接矩阵,顶点数组
public Graph(int length,int[][] matrix,char[] vertex) {
this.vertex = vertex;
this.dis = matrix;
this.pre = new int[length][length];
for (int i = 0; i < length; i++) {
Arrays.fill(pre[i],i);//按行填入下标
}
}
//显示pre 和 dis 数组
public void show(){
System.out.println("=======前驱节点========");
for (int[] p : pre) {
System.out.println(Arrays.toString(p));
}
System.out.println("=======最短距离========");
for (int[] d : dis) {
System.out.println(Arrays.toString(d));
}
}
//弗洛伊德算法
public void floyd(){
int len = 0;
for (int k = 0; k < dis.length; k++) {//从中间顶点遍历 k为中间顶点的下标
//从i顶点开始出发
for (int i = 0; i < dis.length; i++) {
for (int j = 0; j < dis[i].length; j++) {
len = dis[i][k] + dis[k][j];//求出从i顶点出发,经过k中间节点,到达j顶点
if (len < dis[i][j]){//更新dis[i][j] 的距离 找出最短路径 长的会被短的遍历覆盖
dis[i][j] = len;
//更新前驱节点 保存i到j最短路径时 终点j的前驱节点
//由于len < dis[i][j] 所以最短路径到j必然经过中间节点k
// 所以pre[k][j]保存的节点就是pre[i][j]最短路径的前节点
//i->k->j ij的终点前节点就是中间节点的前节点
//加入A-B-C-D 中间节点B的终点的前节点依赖已保存的B-C-D中C为中间节点的终点前驱节点 也就是C
//而初始pre中C行所有都为C 也就是任意两点之间的前驱节点取决于pre的行坐标
pre[i][j] = pre[k][j];
}
}
}
}
}
}
[算法] 弗洛伊德算法 找出所有顶点之间最短距离
最新推荐文章于 2023-04-29 14:30:00 发布