최소비용신장트리-02
Updated:
강의 사이트
- http://www.kocw.net/home/search/kemView.do?kemId=1148815
Kruskal의 알고리즘
1. Kruskal의 알고리즘
- 에지들을 가중치의 오름차순으로 정렬한다.
- 에지들을 그 순서대로 하나씩 선택해간다.
- 단, 이미 선택된 에지들과 사이 클(cycle)을 형성하면 선택하지 않는다.
- n-1개의 에지가 선택되면 종료한다.
2. 왜 MST가 찾아지는가?
- Kruskal의 알고리즘의 임의의 한 단계를 생각해보자.
- A를 현재까지 알고리즘이 선택한 에지의 집합이라고 하고, A를 포함하는 MST가 존재한다고 가정하자.
3. 사이클 검사
- 초기 상태: 선택된 에지 없음
- 각각의 연결요소를 하나의 집합으로 표현
4. Pseudo Code
4.1 서로소인 집합들의 표현
- 각 집합을 하나의 트리로 표현
- 보통의 트리는 자식 노드의 주소를 가지는 하향식 트리임. 그러나 여기선 상향식 트리
- 누가 부모여도 상관 없음. 집합 {a, b}에서 a든 b든 아무나 부모 노드가 되어서 트리 형태이면 됨
- 각 노드의 부모 노드를 각 노드의 순서대로 배열로 표현
- 모든 트리를 하나의 배열로 표현 가능하다.
4.2 Find-Set(v)
- 자신이 속한 트리의 루트를 찾음
4.3 Union(u, v)
- 한 트리의 루트를 다른 트리의 루트의 자식 노드로 만듬
- 위에서는 C가 F의 자식 노드로 가는데 반대로 해도 상관 없음.
5. Weighted Union
- 지금 까지의 시간 복잡도는 O(m * n)이다.
- m은 노드의 개수. n은 각 노드들이 find-set하는 걸리는 시간
-
위에 알고리즘을 조금 바꾸면 시간복잡도를 향상시킬 수 있다. 그게 weighted Union
- 두 집합을 union할 때 작은 트리의 루트를 큰 트리의 루트의 자식으로 만듬 (여기서 크기란 노드의 개수)
- 각 트리의 크기(노드의 개수)를 카운트하고 있어야 한다.
- 즉, 노드 개수가 적은 트리가 노드 개수가 많은 트리의 자식이 되야 한다는 이야기
WEIGHTED-UNION(u,v){
x <- FIND-SET(u);
y <- FIND-SET(v);
if(size[x] > size[y]) then
p[y] = x;
size[x] <- size[x] + size[y];
else
p[x] = y;
size[y] <- size[y] + size[x];
}
5.1 Worst vs Weighted Union
- Union할 때 사용
5.2 Path Compression(압축)
- Find할 때 사용
- Find하면서 지나가는 노드들을 모두 최상의 부모노드의 자식으로 만든다.
- 실제 그렇게 하는게 아니라 일단 최상의 부모 노드를 찾아놓고 원래 노드로 돌아와서 찾아놓은 부모노드에 연결한다.
- 아래 코드는 위에 말한 내용은 아님. 단순히 왼쪽그림에서 반정도 줄여주는 느낌.
- 위에서 말한 내용을 구현하려면 2번줄을 삭제하고 밑에 다시 while문 하나를 더 넣어야 함. 그렇게 하면 오른쪽 그림처럼 됨.
- 시간 복잡도 측면에서는 while 문 2개 쓰는게 나음
5.3 Weighted Union with Path Compression
- M번의 union-find 연산의 총 시간복잡도는 O(N+Mlog*N).
- 여기서 N은 원소의 개수
- log*N은 (여기서 log는 log2N을 말함) 몇 번 log를 해야 1이 되는지 말함.
- 아래 표를 보면 N이 2일 때 log를 하면 1이다. 따라서 log*N은 1이다. (log를 한 번 사용 했기 때문)
- N이 16일 때는 log를 3번 사용한다. log16은 4이고 다시 log하면 2이고 다시 2에 log하면 1이다.
- 따라서 log를 3번 사용했기 때문.
- 거의 선형시간 알고리즘, 즉 한 번의 Find혹은 Union이 거의 O(1)시간
6. 시간복잡도
- 각 노드들의 부모노드를 자신으로 만드는데 걸리는 loop
- 모든 에지들을 가중치 순으로 정렬 시간 (MlogM)
- 두 번의 Find-Set은 O(1)이고 Union은 O(m)이므로 두 번째 loop는 대략 O(m)이다.
- 즉, 크루스칼 알고리즘에서 시간복잡도에 영향을 미치는 것은 엣지들을 정렬하는 부분
-
그래서 O( E log2 E )이라고 하는데 바꿔서 O(mlogm)이라고 함 - m는 n*(n-1) /2이다.
- 그래서 O(m log m)을 O(m log n^2)라고 할 수 있기 때문에 최종적으로 O( m log n)이다.