弗洛伊德(Floyd)算法
-
介绍
- 弗洛伊德算法计算各个顶点之间的最短路径
- 迪杰斯特拉算法用于计算某一个顶点到其它顶点的最短路径
-
过程
- 对于n个顶点的图G,求任意一对顶点vi->vj之间的最短路径可以分为以下几个阶段
-
初始:不允许在其它顶点中转,最短路径是?
-
若允许在V0中转,最短路径是?
-
若允许在V0、V1中转,最短路径是?
-
若允许在V0、V1...Vn-1中转,最短路径是?
若A[i][j] > A[i][k] + A[k][j]
则A[i][j] = A[i][k] + A[k][j]
path[i][j] = k;
否则A和path保持原值
注意:其中k为中转结点
-
- 对于n个顶点的图G,求任意一对顶点vi->vj之间的最短路径可以分为以下几个阶段
-
代码
java
import java.util.Arrays;
public class FloydDemo {
private static final int INF = Integer.MAX_VALUE;
public static void main(String[] args) {
char[] vertexes = {'A','B','C','D','E','F','G'};
int[][] matrix = {
{0,5,7,INF,INF,INF,2},
{5,0,INF,9,INF,INF,3},
{7,INF,0,INF,8,INF,INF},
{INF,9,INF,0,INF,4,INF},
{INF,INF,8,INF,0,5,4},
{INF,INF,INF,4,5,0,6},
{2,3,INF,INF,4,6,0}
};
G g = new G(vertexes, matrix);
Floyd floyd = new Floyd(vertexes.length,matrix);
floyd.floyd();
floyd.show(vertexes);
}
}
class Floyd {
private int[][] path;
private int[][] distance;
private static final int INF = Integer.MAX_VALUE;
public Floyd(int n,int[][] matrix) {
path = new int[n][n];
// -1表示没有前驱,直连
for (int i = 0; i < n;i++) {
for (int j = 0; j < n;j++) {
path[i][j] = -1;
}
}
// 没有中转情况下的最短路径
distance = new int[n][n];
for(int i = 0; i < n;i++) {
for(int j = 0; j < n;j++) {
distance[i][j] = matrix[i][j];
}
}
}
/**
* 弗洛伊德算法
*/
public void floyd() {
int length = distance.length;
// 没有中转情况下的距离
// 以各个顶点为中转,计算最小路径
for(int i = 0; i < length; i++) {
// 遍历整个邻接矩阵
for(int m = 0; m < length;m++) {
for(int n = 0; n < length; n++) {
// 判断以i为中转,最短路径会不会缩短
if(m != i && distance[m][i] != INF && distance[i][n] != INF && distance[m][i] + distance[i][n] < distance[m][n]) {
distance[m][n] = distance[m][i] + distance[i][n];
path[m][n] = i;
}
}
}
}
}
/**
* 显示最短路径矩阵
*/
public void show(char[] vertexes) {
for(int[] link:distance) {
System.out.println(Arrays.toString(link));
}
System.out.println("------------最短路径前缀为------------------");
for (int[] link:path) {
for (int num:link) {
if (num == -1) {
System.out.print("-1" + "\t");
}else {
System.out.print(vertexes[num] + "\t");
}
}
System.out.println();
}
}
}
class G {
// 顶点集
private char[] vertexes;
// 邻接矩阵
private int[][] edges;
public G(char[] vertexes, int[][] edges) {
int length = vertexes.length;
this.vertexes = new char[length];
this.edges = new int[length][length];
// 初始化顶点集和邻接矩阵
for (int i = 0; i < length; i++) {
this.vertexes[i] = vertexes[i];
}
for (int i = 0; i < length; i++) {
for (int j = 0; j < length; j++) {
this.edges[i][j] = edges[i][j];
}
}
}
public char[] getVertexes() {
return vertexes;
}
public int[][] getEdges() {
return edges;
}
}