์ตœ์†Œ ์‹ ์žฅ ํŠธ๋ฆฌ(MST)์™€ Kruskal ์•Œ๊ณ ๋ฆฌ์ฆ˜, Prim ์•Œ๊ณ ๋ฆฌ์ฆ˜

์ตœ์†Œ ์‹ ์žฅ ํŠธ๋ฆฌ(Mimimum Spanning Tree)

  • ์‹ ์žฅ ํŠธ๋ฆฌ : n๊ฐœ์˜ ์ •์ ์œผ๋กœ ์ด๋ฃจ์–ด์ง„ ๋ฌดํ–ฅ ๊ทธ๋ž˜ํ”„์—์„œ n๊ฐœ์˜ ์ •์ ๊ณผ n-1๊ฐœ์˜ ๊ฐ„์„ ์œผ๋กœ ์ด๋ฃจ์–ด์ง„ ํŠธ๋ฆฌ
  • ์ตœ์†Œ ์‹ ์žฅ ํŠธ๋ฆฌ : ๋ฌดํ–ฅ ๊ฐ€์ค‘์น˜ ๊ทธ๋ž˜ํ”„์—์„œ ์‹ ์žฅ ํŠธ๋ฆฌ๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๊ฐ„์„ ๋“ค์˜ ๊ฐ€์ค‘์น˜ ํ•ฉ์ด ์ตœ์†Œ์ธ ์‹ ์žฅ ํŠธ๋ฆฌ

Kruskal ์•Œ๊ณ ๋ฆฌ์ฆ˜

๊ฐ„์„ ์„ ๊ธฐ์ค€์œผ๋กœ ๊ฐ€์ค‘์น˜๊ฐ€ ์ž‘์€ ๊ฐ„์„ ์„ ์šฐ์„ ์ ์œผ๋กœ ์„ ํƒํ•˜๋ฉฐ MST๋ฅผ ์ฐพ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜

๋กœ์ง ๐Ÿ‘‡

  1. ์ตœ์ดˆ์— ๋ชจ๋“  ๊ฐ„์„ ์„ ๊ฐ€์ค‘์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌํ•œ๋‹ค.
  2. ๊ฐ€์ค‘์น˜๊ฐ€ ๊ฐ€์žฅ ๋‚ฎ์€ ๊ฐ„์„ ๋ถ€ํ„ฐ ์„ ํƒํ•ด๊ฐ€๋ฉฐ ํŠธ๋ฆฌ๋ฅผ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค.(์ด๋•Œ, ์‚ฌ์ดํด์ด ์กด์žฌํ•˜๋ฉด ๋‹ค์Œ์œผ๋กœ ๊ฐ€์ค‘์น˜๊ฐ€ ๋‚ฎ์€ ๊ฐ„์„ ์„ ์„ ํƒํ•œ๋‹ค.)
  3. n-1๊ฐœ์˜ ๊ฐ„์„ ์ด ์„ ํƒ๋  ๋•Œ๊นŒ์ง€ ์œ„ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•œ๋‹ค.
  • ๊ทธ๋ฆฌ๋””ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ํ•ด๊ฒฐ
  • union-find ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Œ
Java
class MSTKruskal {
    static int V, E;             // ์ •์ , ๊ฐ„์„  ๊ฐœ์ˆ˜
    static Edge[] edgeList;      // ๊ฐ„์„  ๋ฆฌ์ŠคํŠธ
    static int[] parents;        // ์„œ๋กœ์†Œ ์ง‘ํ•ฉ์„ ์œ„ํ•œ parents ๋ฐฐ์—ด

    // ๊ฐ„์„ ์„ ํ‘œํ˜„ํ•  ํด๋ž˜์Šค
    static class Edge implements Comparable<Edge> {
        int from, to, weight;      // ์ถœ๋ฐœ ๋…ธ๋“œ, ๋„์ฐฉ ๋…ธ๋“œ, ๊ฐ€์ค‘์น˜

        public Edge(int from, int to, int weight) {
            super();
            this.from = from;
            this.to = to;
            this.weight = weight;
        }

        // ๊ฐ€์ค‘์น˜ ๊ธฐ์ค€ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ
        @Override
        public int CompareTo(Edge e) {
            return Integer.compare(this.weight, e.weight);     // ์Œ์ˆ˜ ๊ฐ€์ค‘์น˜ ์–ธ๋”ํ”Œ๋กœ์šฐ ์ฃผ์˜
        }
    }

    // union-find์˜ make-set
    private static void makeSet() {
        parents = new int[V];
        for (int i=0; i<V; i++) parents[i] = i;
    }

    // union-find์˜ find-set
    private static int findSet(int a) {
        if (parnets[a] == a) return a;
        return parents[a] = findSet(parents[a]);
    }

    // union-find์˜ union
    private static boolean union(int a, int b) {
        int aRoot = findSet(a);
        int bRoot = findSet(b);

        if (aRoot == bRoot) return false;

        parents[bRoot] = aRoot;
        return true;
    }

    public static void main(String[] args) {
        edgeList = new Edge[E];
        for (int i=0; i<E; i++) edgeList[i] = new Edge(from, to, weight);   // ๊ฐ„์„ ์ •๋ณด๋ฅผ ๊ฐ„์„  ๋ฆฌ์ŠคํŠธ์— ์ €์žฅ

        Arrays.sort(edgeList);       // ๊ทธ๋ฆฌ๋””ํ•˜๊ฒŒ ์ตœ์†Œ ๋น„์šฉ ๊ฐ„์„ ์„ ๋จผ์ € ์„ ํƒํ•  ๊ฒƒ์ด๋ฏ€๋กœ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ

        makeSet();                   // ๋ชจ๋“  ๊ฐ„์„ ์„ ํ•˜๋‚˜์”ฉ ์„ ํƒํ•ด๋ณด๊ธฐ์œ„ํ•ด ๊ฐ ๋…ธ๋“œ๋ฅผ ์„œ๋กœ์†Œ ์ง‘ํ•ฉ์œผ๋กœ ํ‘œํ˜„

        int accumEdge = 0;                         // ์„ ํƒ๋œ ๋ˆ„์  ๊ฐ„์„  ์ˆ˜
        int totalWeight = 0;                       // ์ด ๊ฐ€์ค‘์น˜
        for (Edge edge : edgeList) {               // ๊ฐ€์ค‘์น˜๊ฐ€ ์ž‘์€ ๊ฐ„์„ ๋ถ€ํ„ฐ ์„ ํƒํ•˜๋ฉฐ
            if (union(edge.from, edge.to)) {       // ๋‘ ์ •์ ๊ฐ„ ์‚ฌ์ดํด์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด
                totalWeight += edge.weight;        // ํ•ด๋‹น ๊ฐ„์„ ์„ ์„ ํƒ
                if (++accumEdge >= V-1) break;      // ๋ชจ๋“  ์ •์ ์ด ์—ฐ๊ฒฐ๋˜๋ฉด ์ข…๋ฃŒ
            }
        }
    }

}

Prim ์•Œ๊ณ ๋ฆฌ์ฆ˜

์ •์ ์„ ๊ธฐ์ค€์œผ๋กœ ํ•ด๋‹น ์ •์ ์— ์—ฐ๊ฒฐ๋œ ๊ฐ„์„ ๋“ค ์ค‘ ๊ฐ€์ค‘์น˜๊ฐ€ ์ž‘์€ ๊ฐ„์„ ์„ ์šฐ์„ ์ ์œผ๋กœ ์„ ํƒํ•˜๋ฉฐ MST๋ฅผ ์ฐพ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜

Prim Simulation

Prim Simulation

๋กœ์ง ๐Ÿ‘‡

  1. ์ž„์˜์˜ ์ •์ ์„ ํ•˜๋‚˜ ์„ ํƒํ•˜์—ฌ ์‹œ์ž‘ํ•œ๋‹ค.
  2. ์„ ํƒํ•œ ์ •์ ๊ณผ ์ธ์ ‘ํ•˜๋Š” ์ •์ ๋“ค ์ค‘ ์ตœ์†Œ ๋น„์šฉ์˜ ๊ฐ„์„ ์ด ์กด์žฌํ•˜๋Š” ์ •์ ์„ ์„ ํƒํ•œ๋‹ค.
  3. ๋ชจ๋“  ์ •์ ์ด ์„ ํƒ๋  ๋•Œ๊นŒ์ง€ ์œ„์˜ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•œ๋‹ค.
  • ๊ทธ๋ฆฌ๋””ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ํ•ด๊ฒฐ
  • ์ตœ์†Œ ํž™(์šฐ์„  ์ˆœ์œ„ ํ)์„ ์ด์šฉํ•˜์—ฌ ์ตœ์ ํ™” ๊ฐ€๋Šฅ
Java
class MSTPrim {
    public static void main(String[] args) { 
        int N;                                  // ์ •์  ๊ฐœ์ˆ˜
        int[][] adjLMatrix = new int[N][N];     // ๋ชจ๋“  ์ธ์ ‘ ์ •์  ๊ฐ„ ๊ฐ€์ค‘์น˜ ์ •๋ณด ์ €์žฅ
        boolean visited = new boolean[N];       // ์ •์  ๋ฐฉ๋ฌธ ์—ฌ๋ถ€
        int[] minEdge = new int[N];             // ๊ฐ ๋…ธ๋“œ ๋ณ„ ๊ฐ„์„  ๊ฐ€์ค‘์น˜ ์ตœ์†Ÿ๊ฐ’ ์ €์žฅ

        for (int i=0; i<N; i++) {
            for (int j=0; j<N; j++) adjMatrix[i][j] = w;     // ์ธ์ ‘ ์ •์  ๊ฐ„ ๊ฐ€์ค‘์น˜ ์ €์žฅ
            minEdge[i] = Integer.MAX_VALUE;                  // ์ตœ์†Ÿ๊ฐ’์„ ์œ„ํ•ด ์ตœ๋Œ“๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™”
        }

        int totalWeight = 0;          // ์ตœ์ข… ์ตœ์†Œ ์‹ ์žฅ ํŠธ๋ฆฌ ๋น„์šฉ
        minEdge[0] = 0;               // 0๋ฒˆ ์ธ๋ฑ์Šค ๋…ธ๋“œ๋ถ€ํ„ฐ ์‹œ์ž‘ ์„ค์ •(์ž„์˜์˜ ๋…ธ๋“œ)

        for (int i=0; i<N; i++) {
            // 1) ์‹ ์žฅํŠธ๋ฆฌ์— ํฌํ•จ๋˜์ง€ ์•Š์€ ์ •์  ์ค‘ ์ตœ์†Œ ๊ฐ„์„  ๋น„์šฉ์˜ ์ •์ ์„ ์ฐพ๊ธฐ
            int minWeight = Integer.MAX_VALUE;                 // ์ตœ์†Œ ๊ฐ„์„  ๋น„์šฉ
            int minVertex = -1;                                // ์ตœ์†Œ ๊ฐ„์„  ๋น„์šฉ ๋…ธ๋“œ

            for (int j=0; j<N; j++) {
                if (!visited[j] && minEdge[j]<minWeight) {     // ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์•˜๊ณ , ์ตœ์†Œ ๊ฐ„์„  ๋น„์šฉ์ด๋ฉด ์ €์žฅ
                    minWeight = minEdge[j];
                    minVertex = j;
                }
            }

            visited[minVertex] = true;                         // ํ•ด๋‹น ์ •์  ์ตœ์†Œ ๋น„์šฉ ์‹ ์žฅ ํŠธ๋ฆฌ์— ์ถ”๊ฐ€ํ•˜๊ณ 
            totalWeight += minWeight;                          // ์ตœ์ข… ์ตœ์†Œ ๊ฐ„์„  ๋น„์šฉ ํ•ฉ์‚ฐ

            // 2) ์„ ํƒ๋œ ์ •์  ๊ธฐ์ค€์œผ๋กœ ์‹ ์žฅ ํŠธ๋ฆฌ์— ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์€ ํƒ€ ์ •์ ๊ณผ์˜ ๊ฐ„์„  ๋น„์šฉ์„ ์ตœ์†Ÿ๊ฐ’์œผ๋กœ ์—…๋ฐ์ดํŠธ
            for (int j=0; j<N; j++) {
                if (!visited && adjMatrix[minVertex][j] && adjMatrix[minVertex][j]<minEdge[j]) {                                 // ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์•˜๊ณ , minVertex์™€ ์ธ์ ‘ํ•˜๋ฉฐ, minVertex์™€์˜ ๊ฐ„์„  ๋น„์šฉ์ด ๊ธฐ์กด ์ตœ์†Œ ๊ฐ„์„  ๋น„์šฉ๋ณด๋‹ค ์ž‘์œผ๋ฉด
                    minEdge[j] = adjMatrix[minVertex][j];      // minVertex์™€์˜ ๊ฐ„์„  ๋น„์šฉ์œผ๋กœ ์—…๋ฐ์ดํŠธ(์ตœ์†Ÿ๊ฐ’ ๊ฐฑ์‹ )
                }
            }

        }
    }
}

Kruskal ์•Œ๊ณ ๋ฆฌ์ฆ˜ Vs Prim ์•Œ๊ณ ๋ฆฌ์ฆ˜

๊ณตํ†ต์ 

  • MST ์•Œ๊ณ ๋ฆฌ์ฆ˜(ํŠธ๋ฆฌ์˜ ๋ชจ๋“  ์ •์ (n๊ฐœ ์ •์ )์ด ์—ฐ๊ฒฐ๋  ์ˆ˜ ์žˆ๋Š” ๊ฐ„์„ ๋“ค(n-1๊ฐœ ๊ฐ„์„ ) ์˜ ๋น„์šฉ์˜ ์ตœ์†Œ ํ•ฉ์„ ๊ตฌํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜)
  • ์ตœ์†Œ ๋น„์šฉ์„ ๋ณด์žฅ
  • ๋‘ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ชจ๋‘ ๊ทธ๋ฆฌ๋””ํ•˜๊ฒŒ ํ˜„์žฌ ์ƒํ™ฉ์—์„œ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ์ตœ์†Œ ๋น„์šฉ์„ ์ตœ์ข… ๋น„์šฉ์— ๋ฐ˜์˜

์ฐจ์ด์ 

  • ํฌ๋ฃจ์Šค์นผ

    • ๊ฐ„์„  ๊ธฐ์ค€ ๋น„์šฉ ๊ณ„์‚ฐ
    • ๋ชจ๋“  ๊ฐ„์„ ์„ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌํ•ด์„œ ํ•ด๋‹น ๊ฐ„์„ ์„ ์ฑ„ํƒํ–ˆ์„ ๋•Œ ๋ชจ๋“  ์ •์ ์ด ์„ ํƒ๋๋‹ค๋ฉด ์ตœ์†Œ ๋น„์šฉ์„ ๊ณ„์‚ฐํ•œ ๊ฒƒ
  • ํ”„๋ฆผ

    • ์ •์  ๊ธฐ์ค€ ๋น„์šฉ ๊ณ„์‚ฐ
    • ์ž„์˜์˜ ์‹œ์ž‘ ์ •์ ์„ ์„ ํƒํ•˜์—ฌ ์ตœ์ข…์œผ๋กœ ์™„์„ฑ๋  ํ•˜๋‚˜์˜ MST์— ๊ฐ ์ •์ ์„ ํ•˜๋‚˜์”ฉ ์ถ”๊ฐ€ํ•ด๊ฐ€๋Š”๋ฐ ๋“œ๋Š” ์ตœ์†Œ ๋น„์šฉ์„ ์„ ํƒ