プリムのアルゴリズム (Java)

1. プリムアルゴリズムの概要

  Prim のアルゴリズムは、最小全域木を構築するアルゴリズムです。プリムのアルゴリズムの時間計算量はO ( ∣ V ∣ 2 ) O(|V|^2)です。O ( V 2 )EEに依存しないEなので、密なエッジを持つグラフの最小全域木を解くのに適しています。

2. プリムアルゴリズムの原理

  (1) 最初に、頂点がグラフからランダムに選択され、最小スパニング ツリー MinTree 頂点セットに追加されます。
  (2) 現在の MinTree に設定されている頂点に最も近い頂点を選択し、その頂点と対応するエッジを MinTree に追加すると、操作のたびに MinTree の頂点の数とエッジの数が 1 ずつ増加します。 。
  (3) すべての頂点が MinTree に追加されるまでステップ (2) を繰り返し、最小スパニング ツリーを取得します。このとき、 MinTree にはn − 1 n-1 個あります。n1面。

3. プリムアルゴリズムの図

ここに画像の説明を挿入
  グラフ(a)の最小全域木を構築する過程は以下の通りである。
  (1) 頂点V 1 V_{1}からV1開始、V 1 V_{1}からV1最も近い 3 つの頂点はV 2 、 V 3 、 V 4 V_{2}、V_{3}、V_{4}です。V2V3V4、最小の重みを持つ頂点V 3 V_{3}を選択します。V3、頂点セットを結合し、エッジを < V 1 、V 3 V_{1}、V_{3}にします。V1V3>最小スパニングツリーに参加します。(図bのように)
  (2) このときの頂点集合は( V 1 , V 3 V_{1}, V_{3}V1V3)、頂点セット内の最も近い頂点はV 2 、 V 4 、 V 5 、 V 6 V_{2}、V_{4}、V_{5}、V_{6}です。V2V4V5V6、重みが最小の頂点V 6 V_{6}を選択します。V6、頂点セットを結合し、エッジを < V 3 、 V 6 V_{3}、V_{6}にします。V3V6>最小スパニングツリーに参加します。(図cのように)
  (3) このときの頂点集合は( V 1 , V 3 , V 6 V_{1}, V_{3}, V_{6}V1V3V6)、頂点セット内の最も近い頂点はV 2 、V 4 、V 5 V_{2}、V_{4}、V_{5}です。V2V4V5、最小の重みを持つ頂点V 4 V_{4}を選択します。V4、頂点セットを結合し、エッジを < V 6 、V 4 V_{6}、V_{4}にします。V6V4>最小スパニングツリーに参加します。(図dに示すように)
  (3) このときの頂点集合は( V 1 , V 3 , V 6 , V 4 V_{1}, V_{3}, V_{6}, V_{4}V1V3V6V4)、頂点セット内の最も近い頂点はV 2 、V 5 V_{2}、V_{5}です。V2V5、最小の重みを持つ頂点V 2 V_{2}を選択します。V2、頂点セットを結合し、エッジを < V 3 、V 2 V_{3}、V_{2}にします。V3V2>最小スパニングツリーに参加します。(図eのように)
  (4) このときの頂点集合は、( V 1 , V 3 , V 6 , V 4 , V 2 V_{1}, V_{3}, V_{6}, V_{ 4}、V_{2}V1V3V6V4V2)、頂点セット内の最も近い頂点はV 5 V_{5}です。V5、最小の重みを持つ頂点V 5 V_{5}を選択します。V5、頂点セットを結合し、エッジを < V 2 、 V 5 V_{2}、V_{5}にします。V2V5>最小スパニングツリーに参加します。(図fのように)
  (5) このときの頂点集合は( V 1 , V 3 , V 6 , V 4 , V 2 , V 5 V_{1}, V_{3}, V_{6} 、V_{ 4}、V_{2}、V_{5}V1V3V6V4V2V5)、すべての頂点がセットに追加されました。最小スパニング ツリーのエッジは < V 1 、V 3 V_{1}、V_{3}です。V1V3>、< V 3 、 V 6 V_{3}、V_{6}V3V6>、< V 6 、 V 4 V_{6}、V_{4}V6V4>、< V 3 、 V 2 V_{3}、V_{2}V3V2>、< V 2 、 V 5 V_{2}、V_{5}V2V5>。

4. Primアルゴリズムコードの実装

package com.haiyang.algorithm.prim;

/**
 * @author haiYang
 * @create 2022-02-01 16:57
 */
public class PrimAlgorithm {
    
    
    public static void main(String[] args) {
    
    
        
        char[] data = new char[]{
    
    'A', 'B', 'C', 'D', 'E', 'F', 'G'};
        int vertexs = data.length;
        //maxValue表示两个顶点之前没有边
        int maxValue = Integer.MAX_VALUE;
        //邻接矩阵的关系使用二维数组表示,maxValue表示两个点不联通
        int[][] weight = new int[][]{
    
    
                {
    
    maxValue, 5, 7, maxValue, maxValue, maxValue, 2},
                {
    
    5, maxValue, maxValue, 9, maxValue, maxValue, 3},
                {
    
    7, maxValue, maxValue, maxValue, 8, maxValue, maxValue},
                {
    
    maxValue, 9, maxValue, maxValue, maxValue, 4, maxValue},
                {
    
    maxValue, maxValue, 8, maxValue, maxValue, 5, 4},
                {
    
    maxValue, maxValue, maxValue, 4, 5, maxValue, 6},
                {
    
    2, 3, maxValue, maxValue, 4, 6, maxValue}};
        Graph graph = new Graph(vertexs, data, weight);
        prim(graph, 0);


    }

    /**
     * @param graph 图
     * @param v     开始顶点
     */
    public static void prim(Graph graph, int v) {
    
    
        //标记已访问顶点
        int[] visited = new int[graph.vertexs];
        //将开始顶点标记已访问
        visited[v] = 1;
        //h1、h2标记最小的权值weight位置
        int h1 = -1;
        int h2 = -1;
        //记录最小权值
        int minWeight = Integer.MAX_VALUE;
        //除开始顶点,将其他graph.verrtexs-1个顶点进行选取
        for (int k = 1; k < graph.vertexs; k++) {
    
    

            //遍历图的所有情况,找到此轮的最小权值连接的顶点
            for (int i = 0; i < graph.vertexs; i++) {
    
    
                for (int j = 0; j < graph.vertexs; j++) {
    
    
                    //选取的顶点要求:i是已经选取的的顶点,j是为选取的顶点,找到满足情况的最小权值,记录位置
                    if (visited[i] == 1 && visited[j] == 0 && graph.weight[i][j] < minWeight) {
    
    
                        minWeight = graph.weight[i][j];
                        h1 = i;
                        h2 = j;
                    }
                }

            }
            //将此轮选取的最小权值连接的顶点信息输出
            System.out.println("边<" + graph.data[h1] + "," + graph.data[h2] + "> 权值=" + minWeight);
            //将此轮选取的顶点标记为已访问
            visited[h2] = 1;
            //重新初始化minWeight值
            minWeight = Integer.MAX_VALUE;

        }


    }
}

/**
 * 图类
 */
class Graph {
    
    
    int vertexs; //表示顶点个数
    char[] data;//存放顶点数据
    int[][] weight; //使用邻接矩阵存放边

    public Graph(int vertexs, char[] data, int[][] weight) {
    
    
        this.vertexs = vertexs;
        this.data = data;
        this.weight = weight;
    }
}

おすすめ

転載: blog.csdn.net/weixin_43698993/article/details/122770231