Prim(最小生成樹)

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章