[アルゴリズム概念]最小成長木(MST)−Kruskal


[アルゴリズム概念]最小成長木(MST)−Kruskal


コンセプト
  • 貪欲な方法は最小の身長の木を求めます
  • シーケンス
  • 幹線の重みは昇順に
  • 並べられている.
  • に配列する幹線リストでは、周期を形成しない幹線が見つけ出され、現在の最小費用増加ツリーのセットに
  • が追加する.
  • サイクルを本当に理解するには、接続する幹線の両端点が同じ集合にあるかどうかを確認する必要があります.このためunion-findアルゴリズム
  • を用いる
    インプリメンテーション
       import java.util.Arrays;
       
       public class algorithm_kruskal {
       
       	static int parent[];
       	public static void main(String[] args) {
            // =================== 값 세팅 =======================
       		int V = 5; // 정점 수
       		int E = 7; // 간선 수
       
       		parent = new int[V];
       		makeSet();
       				
       		// 7개 간선의 각 정점과 가중치(시작 정점, 끝 정점, 가중치)
       		int graph[][] = new int[E][3];
       		
       		// 임의의 간선과 가중치 부여 (무방향 그래프)
       		// 0 -> 1 -> 2 -> 3 -> 4 로 이어지도록 가중치를 일부러 적게 부여
       		graph[0] = new int[] {0,1,1};
       		graph[2] = new int[] {1,2,1};
       		graph[1] = new int[] {1,3,6};
       		graph[3] = new int[] {1,4,5};
       		graph[4] = new int[] {2,3,1};
       		graph[5] = new int[] {3,4,1};
       		graph[6] = new int[] {3,1,7};
       		
       		//====================== 구현 =========================
               
            // 1. 비용이 낮은 순으로 간선을 정렬
       		Arrays.sort(graph,(o1,o2) -> Integer.compare(o1[2], o2[2]));
       		
       		int cost = 0;
               
       		// 2. 사이클을 만들지 않으면서 최소 비용의 간선 찾기
       		for(int i=0;i<E;i++) {
       			if(union(graph[i][0], graph[i][1])) {
       				cost += graph[i][2];
       			}
       		}
       		
            // ======================= 출력 =========================
       		System.out.println("cost : " + cost);
       		// cost : 4
       		System.out.println("각 정점이 가리키는 부모 : " + Arrays.toString(parent));
       		// 각 정점이 기리키는 부모 : [1, 2, 3, 4, 4]
       	}
       	
           
        // ================= 유니온파인드 =====================
        
       	public static void makeSet() {
       		for(int i=0;i<parent.length;i++) {
       			parent[i] = i;
       		}
       	}
       	
       	public static boolean union(int a, int b) {
       		a = find(a);
       		b = find(b);
       		
       		if(a < b) {
       			parent[a] = b;
       			return true;
       		}
       		else if(a > b) {
       			parent[b] = a;
       			return true;
       		}
       		return false;
       	}
       	
       	public static int find(int a) {
       		if(a == parent[a]) return a;
       		
       		return find(parent[a]);
       		// 경로 압축 
       		// return parent[a] = find(parent[a]);
       	}
       
       }
       
       ```