[Algorithm] Kruskal’s Algorithm
Introduction (including Spanning Tree)
Kruskal 알고리즘이란 최소한의 비용으로 다수의 노드를 연결을 greedy하게 할 때 사용하는 알고리즘이다. 이 알고리즘은 보통 Spanning Tree를 만들 때 사용되는데, Spanning Tree란 graph 구조에서 모든 vertex가 서로 연결이 되는데 최소한의 edge로 연결을 시킨 graph를 말한다. 따라서 Spanning Tree가 되기 위한 조건은 다음과 같다.
총 Vertex의 수 = 총 Edge의 수 + 1
그렇다면 최소한의 비용으로 구성되는 Spanning Tree를 Minimum Spanning Tree (MST)라 부르는데, MST를 만드는 방법을 알아보면 간략하게 다음 과정을 거친다.
Algorithm
- Graph의 edge들을 가중치를 작은 것부터 큰 순서대로 오름차순으로 정렬한다.
- 가장 가중치가 낮은 edge부터 추가하면서 graph를 만든다.
- 만약 edge를 추가하다가 cycle이 발생되면 해당 edge는 제외한다.
- Cycle이 발생되는지 확인 방법은 edge의 source vertex의 그룹과 종료 destination vertex의 그룹이 같으면 cycle이 발생되는 것이라 판단 가능하다.
- Edge의 수가 vertex의 수보다 1개 적으면 종료한다.
Example









Source Code
#include <iostream>
#include <vector>
#include <algorithm>
#define NUM_EDGES 8
#define NUM_VERTEX 5
using namespace std;
class Edge
{
public:
Edge(int _src, int _dst, int _w): src(_src), dst(_dst), w(_w) {}
int src;
int dst;
int w;
};
vector<Edge> edge_list;
int group_table[NUM_VERTEX];
int total_weight;
bool cmp(Edge e1, Edge e2)
{
if (e1.w == e2.w)
return e1.src < e2.src;
else
return e1.w < e2.w;
}
void addEdge(int _s, int _d, int _w, int _bidirection)
{
edge_list.push_back(Edge(_s, _d, _w));
}
void updateGroupTable(int _s, int _d)
{
int s_group = group_table[_s];
int d_group = group_table[_d];
int smaller = (s_group < d_group) ? s_group : d_group;
int bigger = (s_group < d_group) ? d_group : s_group;
for (int i=0; i<NUM_VERTEX; i++) {
if (group_table[i] == bigger)
group_table[i] = smaller;
}
}
void doMST(void)
{
int edge_num = 0;
for (int i=0; i<NUM_EDGES; i++) {
// Compare group number
if (group_table[edge_list[i].src] != group_table[edge_list[i].dst]) {
printf("[%d]---(%d)---[%d]\n", edge_list[i].src, edge_list[i].w, edge_list[i].dst);
edge_num++;
total_weight += edge_list[i].w;
if (edge_num == NUM_VERTEX + 1) {
return;
}
updateGroupTable(edge_list[i].src, edge_list[i].dst);
}
}
}
int main(void)
{
for (int i=0; i<NUM_VERTEX; i++)
group_table[i] = i;
addEdge(0, 1, 1, true);
addEdge(0, 2, 3, true);
addEdge(0, 4, 5, true);
addEdge(1, 2, 2, true);
addEdge(1, 4, 4, true);
addEdge(2, 4, 6, true);
addEdge(2, 3, 7, true);
addEdge(3, 4, 8, true);
sort(edge_list.begin(), edge_list.end(), cmp);
doMST();
printf("Total weight: %d\n", total_weight);
return 0;
}
[0]---(1)---[1] [1]---(2)---[2] [1]---(4)---[4] [2]---(7)---[3] Total weight: 14