java实现Prim算法
源代码
图的结构java实现
Prim需要图是连通图,生成的图一定是一棵树,而Kruskal可能生成森林
Prim
public class Prim {
private static final int INF = Integer.MAX_VALUE;
/**
* 初始化距离矩阵
*
* @param graph 图
* @return 距离矩阵
*/
private static int[][] initDistance(GraphMatrix graph) {
int vertexNum = graph.getVertexNum();
int[][] result = new int[vertexNum][vertexNum];
// 初始化距离矩阵
for (int i = 0; i < vertexNum; i++) {
for (int j = 0; j < vertexNum; j++) {
result[i][j] = graph.edges[i][j];
if (i != j && result[i][j] == 0) {
result[i][j] = INF;
}
}
}
return result;
}
private static int prim(GraphMatrix graph) {
int vertexNum = graph.getVertexNum();
//统计最小的权
int sum = 0;
//当前最小生成树所能到达的顶点的最小权数组
int[] costs = new int[vertexNum];
//当前各个顶点对应的起点
int[] startPoint = new int[vertexNum];
int[][] distance = initDistance(graph);
//初始化
for (int i = 1; i < vertexNum; i++) {
//所有点的起点赋值为0
startPoint[i] = 0;
//以0为起点到达各个顶点的权值
costs[i] = distance[0][i];
}
//挑选剩余的vertexNum-1个顶点
for (int i = 1; i < vertexNum; i++) {
System.out.print("cost:");
for (int cost : costs) {
System.out.print(cost + " ");
}
System.out.println();
//记录当前costs里面的最小权值是多少
int min = INF;
//记录当前costs里面的最小权值对应的数组下标,即顶点
//(数组[顶点]=该顶点对应的起点)
int minIndex = 0;
//遍历costs 找出距离当前集合权值最小的点
for (int j = 1; j < vertexNum; j++) {
int temp = costs[j];
//costs[j]==0代表节点j已加入MST
if (temp != 0 && temp < min) {
min = temp;
minIndex = j;
}
}
sum += min;
//将已加入MST的对应的权值赋值为0
costs[minIndex] = 0;
//选定了新的顶点到MST后,树到达各顶点的最小开销和起点将更新
//更新costs和startPoint
for (int k = 0; k < vertexNum; k++) {
//用minIndex顶点到各个顶点的权值比较costs数组的值,若较小则替换,并更新起点为minIndex
int newCost = distance[minIndex][k];
if (newCost != 0 && newCost < costs[k]) {
costs[k] = newCost;
//更新K的起点为minIndex
startPoint[k] = minIndex;
}
}
}
System.out.println("树的边为:");
for (int i = 1; i < vertexNum; i++) {
System.out.println(graph.vertexList.get(i) + "->" + graph.vertexList.get(startPoint[i]));
}
return sum;
}
public static void main(String[] args) {
GraphMatrix<String> graph = new GraphMatrix<>("ABCDEF");
graph.addEdge("A", "B", 6);
graph.addEdge("A", "C", 1);
graph.addEdge("A", "D", 5);
graph.addEdge("B", "C", 5);
graph.addEdge("B", "E", 3);
graph.addEdge("C", "D", 5);
graph.addEdge("C", "E", 6);
graph.addEdge("C", "F", 4);
graph.addEdge("D", "F", 2);
graph.addEdge("E", "F", 6);
graph.information();
System.out.println("最小生成树权重和:" + prim(graph));
}
}
log
顶点信息:
A B C D E F
边表:
A<->B B<->A A<->C C<->A A<->D D<->A B<->C C<->B B<->E E<->B C<->D D<->C C<->E E<->C C<->F F<->C D<->F F<->D E<->F F<->E
边的权重表:
0 6 1 5 0 0
6 0 5 0 3 0
1 5 0 5 6 4
5 0 5 0 0 2
0 3 6 0 0 6
0 0 4 2 6 0
cost:0 6 1 5 2147483647 2147483647
cost:0 5 0 5 6 4
cost:0 5 0 2 6 0
cost:0 5 0 0 6 0
cost:0 0 0 0 3 0
树的边为:
B->C
C->A
D->F
E->B
F->C
最小生成树权重和:15