Skip to content

Latest commit

ย 

History

History
312 lines (241 loc) ยท 6.5 KB

MST.md

File metadata and controls

312 lines (241 loc) ยท 6.5 KB

์ตœ์†Œ๋น„์šฉ ์‹ ์žฅํŠธ๋ฆฌ(MST)



์‹ ์žฅ ํŠธ๋ฆฌ(Spanning Tree)

์‹ ์žฅ ํŠธ๋ฆฌ๋ž€ ๊ทธ๋ž˜ํ”„๋‚ด์˜ ๋ชจ๋“  ์ •์ ์„ ํฌํ•จํ•˜๋Š” ํŠธ๋ฆฌ

  • n๊ฐœ์˜ ์ •์ ์„ ๊ฐ€์ง€๋Š” ๊ทธ๋ž˜ํ”„์˜ ์‹ ์žฅํŠธ๋ฆฌ๋Š” n-1๊ฐœ์˜ ๊ฐ„์„ ์„ ๊ฐ€์ง„๋‹ค
  • ํ•˜๋‚˜์˜ ๊ทธ๋ž˜ํ”„์—๋Š” ๋งŽ์€ ์‹ ์žฅ ํŠธ๋ฆฌ๊ฐ€ ์กด์žฌํ•  ์ˆ˜ ์žˆ๋‹ค
  • ๋ชจ๋“  ์ •์ ๋“ค์ด ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์–ด์•ผ ํ•˜๊ณ  ์‚ฌ์ดํด์ด ํ˜•์„ฑ๋˜์„œ๋Š” ์•ˆ๋œ๋‹ค

DFS, BFS๋ฅผ ์ด์šฉํ•˜์—ฌ ์‹ ์žฅํŠธ๋ฆฌ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค.

MST(Minimum Spanning Tree)

๋„คํŠธ์›Œํฌ์— ์žˆ๋Š” ๋ชจ๋“  ์ •์ ๋“ค์„ ๊ฐ€์žฅ ์ ์€ ์ˆ˜์˜ ๊ฐ„์„ ๊ณผ ๋น„์šฉ์œผ๋กœ ์—ฐ๊ฒฐํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜

MST์˜ ํŠน์ง•

  1. ๊ฐ„์„ ์˜ ๊ฐ€์ค‘์น˜์˜ ํ•ฉ์ด ์ตœ์†Œ์—ฌ์•ผ ํ•œ๋‹ค
  2. n๊ฐœ์˜ ์ •์ ์„ ๊ฐ€์ง€๋Š” ๊ทธ๋ž˜ํ”„์— ๋Œ€ํ•ด ๋ฐ˜๋“œ์‹œ n-1๊ฐœ์˜ ๊ฐ„์„ ๋งŒ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค
  3. ์‚ฌ์ดํด์ด ํฌํ•จ๋˜์–ด์„œ๋Š” ์•ˆ๋œ๋‹ค.


Kruskal's MST Algorithm

ํƒ์š•์ ์ธ ๋ฐฉ๋ฒ•(greedy method) ์‚ฌ์šฉ

  • ๊ฐ ๋‹จ๊ณ„์—์„œ ์ตœ์„ ์˜ ๋‹ต์„ ์„ ํƒํ•˜๋Š” ๊ณผ์ •์„ ๋ฐ˜๋ณต
  • ํ•ญ์ƒ ์ตœ์ ์˜ ํ•ด๋ฅผ ๊ฐ–๋Š”๋‹ค


Kruskal's MST

union-find Algorithm

์›์†Œ๊ฐ€ ์–ด๋–ค ์ง‘ํ•ฉ์— ์†ํ•˜๋Š”์ง€ ์•Œ์•„๋‚ด๊ธฐ ์œ„ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜

  • Kruskal's MST ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ ์‚ฌ์ดํด ๊ฒ€์‚ฌ์— ์‚ฌ์šฉ

union-find

int parent[MAX_VERTICES];         // ๋ถ€๋ชจ ๋…ธ๋“œ

void set_init(int n)
{
    for(int i=0; i<n; i++>)
        parent[i] = -1;
}

int set_find(int curr)
{
    if(parent[curr] == -1)
        return curr; 
    while(parent[curr] != -1)
        curr=parrent[curr];
    return curr;
}

void set_union(int a, int b)
{
    int root1 = set_find(a);              // ๋…ธ๋“œ a์˜ root๋ฅผ ์ฐพ๋Š”๋‹ค.
    int root2 = set_find(b);              // ๋…ธ๋“œ b์˜ root๋ฅผ ์ฐพ๋Š”๋‹ค.
    if(root1 != root2)                    // ํ•ฉํ•œ๋‹ค.
        parent[root1] = root2;
}


Kruskal's MST

#include <stdio.h>
#include <stdlib.h>

#define TRUE 1
#define FALSE 0

#define MAX_VERTICES 100
#define INF 1000

int parent[MAX_VERTICES];		// ๋ถ€๋ชจ ๋…ธ๋“œ 

// ์ดˆ๊ธฐํ™”
void set_init(int n)
{
	for (int i = 0; i<n; i++) 
		parent[i] = -1;
}

// curr๊ฐ€ ์†ํ•˜๋Š” ์ง‘ํ•ฉ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
int set_find(int curr)
{
	if (parent[curr] == -1)
		return curr; 			// ๋ฃจํŠธ 
	while (parent[curr] != -1) curr = parent[curr];
	return curr;
}

// ๋‘๊ฐœ์˜ ์›์†Œ๊ฐ€ ์†ํ•œ ์ง‘ํ•ฉ์„ ํ•ฉ์นœ๋‹ค.
void set_union(int a, int b)
{
	int root1 = set_find(a);	// ๋…ธ๋“œ a์˜ ๋ฃจํŠธ๋ฅผ ์ฐพ๋Š”๋‹ค. 
	int root2 = set_find(b);	// ๋…ธ๋“œ b์˜ ๋ฃจํŠธ๋ฅผ ์ฐพ๋Š”๋‹ค. 
	if (root1 != root2) 	// ํ•ฉํ•œ๋‹ค. 
		parent[root1] = root2;
}

struct Edge {			// ๊ฐ„์„ ์„ ๋‚˜ํƒ€๋‚ด๋Š” ๊ตฌ์กฐ์ฒด
	int start, end, weight;
};

typedef struct GraphType {
	int n;	// ๊ฐ„์„ ์˜ ๊ฐœ์ˆ˜
	struct Edge edges[2 * MAX_VERTICES];
} GraphType;

// ๊ทธ๋ž˜ํ”„ ์ดˆ๊ธฐํ™” 
void graph_init(GraphType* g)
{
	g->n = 0;
	for (int i = 0; i < 2 * MAX_VERTICES; i++) {
		g->edges[i].start = 0;
		g->edges[i].end = 0;
		g->edges[i].weight = INF;
	}
}

// ๊ฐ„์„  ์‚ฝ์ž… ์—ฐ์‚ฐ
void insert_edge(GraphType* g, int start, int end, int w)
{
	g->edges[g->n].start = start;
	g->edges[g->n].end = end;
	g->edges[g->n].weight = w;
	g->n++;
}

// qsort()์— ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜
int compare(const void* a, const void* b)
{
	struct Edge* x = (struct Edge*)a;
	struct Edge* y = (struct Edge*)b;
	return (x->weight - y->weight);
}

// kruskal์˜ ์ตœ์†Œ ๋น„์šฉ ์‹ ์žฅ ํŠธ๋ฆฌ ํ”„๋กœ๊ทธ๋žจ
void kruskal(GraphType *g)
{
	int edge_accepted = 0;	// ํ˜„์žฌ๊นŒ์ง€ ์„ ํƒ๋œ ๊ฐ„์„ ์˜ ์ˆ˜	
	int uset, vset;			// ์ •์  u์™€ ์ •์  v์˜ ์ง‘ํ•ฉ ๋ฒˆํ˜ธ
	struct Edge e;

	set_init(g->n);				// ์ง‘ํ•ฉ ์ดˆ๊ธฐํ™”
	qsort(g->edges, g->n, sizeof(struct Edge), compare);

	printf("ํฌ๋ฃจ์Šค์นผ ์ตœ์†Œ ์‹ ์žฅ ํŠธ๋ฆฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜ \n");
	int i = 0;
	while (edge_accepted < (g->n - 1))	// ๊ฐ„์„ ์˜ ์ˆ˜ < (n-1)
	{
		e = g->edges[i];
		uset = set_find(e.start);		// ์ •์  u์˜ ์ง‘ํ•ฉ ๋ฒˆํ˜ธ 
		vset = set_find(e.end);		// ์ •์  v์˜ ์ง‘ํ•ฉ ๋ฒˆํ˜ธ
		if (uset != vset) {			// ์„œ๋กœ ์†ํ•œ ์ง‘ํ•ฉ์ด ๋‹ค๋ฅด๋ฉด
			printf("๊ฐ„์„  (%d,%d) %d ์„ ํƒ\n", e.start, e.end, e.weight);
			edge_accepted++;
			set_union(uset, vset);	// ๋‘๊ฐœ์˜ ์ง‘ํ•ฉ์„ ํ•ฉ์นœ๋‹ค.
		}
		i++;
	}
}

int main(void)
{
	GraphType *g;
	g = (GraphType *)malloc(sizeof(GraphType));
	graph_init(g);

	insert_edge(g, 0, 1, 29);
	insert_edge(g, 1, 2, 16);
	insert_edge(g, 2, 3, 12);
	insert_edge(g, 3, 4, 22);
	insert_edge(g, 4, 5, 27);
	insert_edge(g, 5, 0, 10);
	insert_edge(g, 6, 1, 15);
	insert_edge(g, 6, 3, 18);
	insert_edge(g, 6, 4, 25);

	kruskal(g);
	free(g);
	return 0;
}


Prim's MST

์‹œ์ž‘ ์ •์ ์—์„œ๋ถ€ํ„ฐ ์ถœ๋ฐœํ•˜์—ฌ ์‹ ์žฅ ํŠธ๋ฆฌ ์ง‘ํ•ฉ์„ ๋‹จ๊ณ„์ ์œผ๋กœ ํ™•์žฅํ•ด๋‚˜๊ฐ€๋Š” ๋ฐฉ๋ฒ•

  • ์‹ ์žฅ ํŠธ๋ฆฌ ์ง‘ํ•ฉ์—์„œ ์ธ์ ‘ํ•œ ์ •์  ์ค‘์—์„œ ์ตœ์ € ๊ฐ„์„ ์œผ๋กœ ์—ฐ๊ฒฐ๋œ ์ •์ ์„ ์„ ํƒํ•˜์—ฌ ์‹ ์žฅ ํŠธ๋ฆฌ ์ง‘ํ•ฉ์— ์ถ”๊ฐ€



Prim's MST

#include <stdio.h>
#include <stdlib.h>

#define TRUE 1
#define FALSE 0
#define MAX_VERTICES 100
#define INF 1000L

typedef struct GraphType {
	int n;	// ์ •์ ์˜ ๊ฐœ์ˆ˜
	int weight[MAX_VERTICES][MAX_VERTICES];
} GraphType;

int selected[MAX_VERTICES];
int distance[MAX_VERTICES];

// ์ตœ์†Œ dist[v] ๊ฐ’์„ ๊ฐ–๋Š” ์ •์ ์„ ๋ฐ˜ํ™˜
int get_min_vertex(int n)
{
	int v, i;
	for (i = 0; i <n; i++)
		if (!selected[i]) {
			v = i;
			break;
		}
	for (i = 0; i < n; i++)
		if (!selected[i] && (distance[i] < distance[v])) v = i;
	return (v);
}

void prim(GraphType* g, int s)
{
	int i, u, v;

	for (u = 0; u<g->n; u++)
		distance[u] = INF;
	distance[s] = 0;
	for (i = 0; i<g->n; i++) {
		u = get_min_vertex(g->n);
		selected[u] = TRUE;
		if (distance[u] == INF) return;
		printf("์ •์  %d ์ถ”๊ฐ€\n", u);
		for (v = 0; v<g->n; v++)
			if (g->weight[u][v] != INF)
				if (!selected[v] && g->weight[u][v]< distance[v])
					distance[v] = g->weight[u][v];
	}
}

int main(void)
{
	GraphType g = { 7, 
	{{ 0, 29, INF, INF, INF, 10, INF },
	{ 29,  0, 16, INF, INF, INF, 15 },
	{ INF, 16, 0, 12, INF, INF, INF },
	{ INF, INF, 12, 0, 22, INF, 18 },
	{ INF, INF, INF, 22, 0, 27, 25 },
	{ 10, INF, INF, INF, 27, 0, INF },
	{ INF, 15, INF, 18, 25, INF, 0 } }
	};
	prim(&g, 0);
	return 0;
}