Skip to content

Latest commit

ย 

History

History
312 lines (241 loc) ยท 6.5 KB

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;
}