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