Kruskalアルゴリズム&連合検索アルゴリズム


Union-Find algorithm

  • Union-Findは集約ルックアップアルゴリズムと呼ばれている.
  • 要素がどの集合に属するかを判別するために用いられる(図).
  • Kruskalでは、Union−Findアルゴリズムを使用して、選択されたエッジがループを形成するかどうかを検証することができる.
  • 各ノードの親ノードを配列に格納します。 最上位の親ノードに再帰的に移動し、それに基づいてセットを分割します。

    インプリメンテーション

    class UnionFind {
    
        public boolean hasSameParent(int[] parentNodes, int a, int b) {
            return findParent(parentNodes, a) == findParent(parentNodes, b);
        }
    
        public void union(int[] parentNodes, int a, int b) {
            int parentA = findParent(parentNodes, a);
            int parentB = findParent(parentNodes, b);
            if (parentA > parentB) parentNodes[parentA] = parentB;
            else parentNodes[parentB] = parentA;
        }
        
        private int findParent(int[] parentNodes, int node) {
            if (parentNodes[node] == node) return node;
            return findParent(parentNodes, parentNodes[node]);
        }
    }

    Kruskal algorithm

  • に代償的に割り当てられたエッジ接続図が与えられると、最小伸長部分ツリー(MST)のアルゴリズムは、接続エッジによって達成される.
  • の場合、MSTの条件は以下の通りである.
    1.最低料金のedgeのみで構成される.
    2.cycleは含まれません.
  • 最小コストedgeを
  • Greedyで追加し、完全なグラフを得る.
  • Union−Findアルゴリズムを用いてループの形成を調べると、エッジの個数eに対してO(eloge)の時間的複雑さがある.
  • アルゴリズムフローは以下の通りです.
    edgeをコストの昇順に並べ替えます。 ソートedge順にループを形成しないedgeを選択し、MSTに追加します。 すべてのノードが親ノードとして同じノードを持つ場合、MSTは完了し、アルゴリズムは終了する。

    インプリメンテーション

    public int kruskal(int n, int[][] costs) {
        Arrays.sort(costs, (Comparator.comparingInt(o -> o[COST])));
        int[] parentNodes = createCycleTable(n);
        int answer = 0;
        for (int[] edge : costs) {
            if (!hasSameParent(parentNodes, edge[0], edge[1])) {
                union(parentNodes, edge[0], edge[1]);
                answer += edge[COST];
            }
            if (pathCreated(parentNodes)) break;
        }
        return answer;
    }