[0326 석재호]상호배타적 집합의 처리

34
상호배타적 집합의 처리 기초 알고리즘 스터디 데브루키 꿜라 석재호

Upload: jaeho-seok

Post on 12-Jul-2015

564 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: [0326 석재호]상호배타적 집합의 처리

상호배타적 집합의 처리

기초 알고리즘 스터디

데브루키 꿜라 석재호

Page 2: [0326 석재호]상호배타적 집합의 처리

상호배타적 집합

분리 집합 (Disjoint Set) 과 같은 표현

의미 : 교집합을 갖지 않는 집합들 .

집합이 단 하나만 존재할 때 공통된 원소의

유무를 따질 수 없으므로

상호배타적이라는 용어는 두 개 이상의 집합에

대해서만 정의가 된다 .

Page 3: [0326 석재호]상호배타적 집합의 처리

집합의 처리

교집합에 대한 연산은 없다

집합 처리 연산 Make-Set(x) : 원소 ( 데이터 ) x 를 가진 집합을 생성

Find-Set(x) : 원소 x 를 가지는 집합을 알아낸다

Union(x,y) : 원소 x 를 가진 집합과 원소 y 를 가진

집합을 합친다 .

Page 4: [0326 석재호]상호배타적 집합의 처리

구현 방식 (1/2)

트 리

데이터와 부모에 대한 포인터를 가진 노드

1

2 3 4

5 6

Page 5: [0326 석재호]상호배타적 집합의 처리

구현 방식 (2/2)

리스트

데이터 , 집합의 루트에 대한 포인터 ,

다음 노드에 대한 포인터를 가진 노드

1 2 3 4

Page 6: [0326 석재호]상호배타적 집합의 처리

트리를 이용한 구현

* 원소 구조

typedef struct _TREEDISJSET

{

struct _TREEDISJSET* parent;

int data; // 설명의 편의를 위해 int 로 ..

_TREEDISJSET(int _data)

{ data = _data; parent = NULL }

} TreeDS;

Page 7: [0326 석재호]상호배타적 집합의 처리

트리를 이용한 구현 – 집합 생성

MakeSet

TreeDS* MakeSet(int _data)

{

TreeDS* node = new TreeDS(_data);

return node;

}

Page 8: [0326 석재호]상호배타적 집합의 처리

트리를 이용한 구현 – 집합 생성

1

3

2

Page 9: [0326 석재호]상호배타적 집합의 처리

트리를 이용한 구현 – 집합 찾기

FindSet

TreeDS* FindSet(TreeDS* node)

{

while(node->parent != NULL)

node = node->parent;

return node;

}

Page 10: [0326 석재호]상호배타적 집합의 처리

트리를 이용한 구현 – 집합 찾기

1

2 3 4

5 6

Page 11: [0326 석재호]상호배타적 집합의 처리

트리를 이용한 구현 – 합집합 연산

UnionSet

void UnionSet(TreeDS* set1, TreeDS* set2)

{

FindSet(set2)->parent = set1;

}

Page 12: [0326 석재호]상호배타적 집합의 처리

트리를 이용한 구현 – 합집합 연산

1

2 3

4

5 6

set1

set2

1

2 3

4

5 6

Page 13: [0326 석재호]상호배타적 집합의 처리

리스트를 이용한 구현

원소 구조

typedef struct _LISTDISJSET

{

struct _LISTDISJSET* root;

struct _LISTDISJSET* next;

int data;

_LISTDISJSET(int _data)

{ root = this; next = NULL; data = _data; }

} ListDS;

Page 14: [0326 석재호]상호배타적 집합의 처리

리스트를 이용한 구현 – 집합 생성

ListDS* MakeSet(int _data)

{

ListDS* node = new ListDS(_data);

return node;

}

Page 15: [0326 석재호]상호배타적 집합의 처리

리스트를 이용한 구현 – 집합 생성

1

2

3

Page 16: [0326 석재호]상호배타적 집합의 처리

리스트를 이용한 구현 – 집합 찾기

ListDS* FindSet(ListDS* node)

{

return node->root;

}

Page 17: [0326 석재호]상호배타적 집합의 처리

리스트를 이용한 구현 – 집합 찾기

1 2 3 4

Page 18: [0326 석재호]상호배타적 집합의 처리

리스트를 이용한 구현 – 합집합 연산

void UnionSet(ListDS* set1, ListDS* set2)

{

ListDS* tail = set1;

while(tail->next != NULL) tail = tail->next;

tail->next = FindSet(set2);

ListDS* root = FindSet(set1);

while(tail->next != NULL)

{

tail = tail->next;

tail->root = root;

}

}

Page 19: [0326 석재호]상호배타적 집합의 처리

리스트를 이용한 구현 – 합집합 연산

1 2 3 4

5 6 7

set1

set2

1 2 3 4

5 6 7

Page 20: [0326 석재호]상호배타적 집합의 처리

최적화 및 응용

Page 21: [0326 석재호]상호배타적 집합의 처리

작은 것을 큰 것에 붙인다

무게 ( 총 개수 ) 고려한 Union ( 리스트 ) 리스트의 Union 시 붙는 쪽의 집합은

그 원소 개수만큼 root 를 갱신한다

리스트 길이에 대한 정보를 저장한다면

Union 시 긴 쪽에 짧은 쪽을 합침으로써

root 갱신 비용을 줄일 수 있다

Page 22: [0326 석재호]상호배타적 집합의 처리

작은 것을 큰 것에 붙인다

랭크를 이용한 Union ( 트리 ) 트리의 각 노드에 자신의 서브트리의

높이 값을 저장 (int rank)

Union 시에 두 개의 집합 중 루트의

랭크 값이 높은 쪽 루트에 낮은 쪽을 합친다

-> 구현 간결성이나 효율에 있어서 이점

Page 23: [0326 석재호]상호배타적 집합의 처리

작은 것을 큰 것에 붙인다

뭐가 되어도 서로 랭크만 다르면

랭크 변화는 어디에도 없다

Page 24: [0326 석재호]상호배타적 집합의 처리

작은 것을 큰 것에 붙인다

유일하게 랭크가 변화하는 경우 양쪽 루트의 랭크가 같을 경우

Page 25: [0326 석재호]상호배타적 집합의 처리

작은 것을 큰 것에 붙인다

구현상의 변화 MakeSet : rank 를 0 으로 초기화 O(1)

FindSet : 변화 없음 . O(depth)

UnionSet : 두 집합 루트 랭크 비교 >>

랭크 동일한 경우만 랭크 갱신

랭크는 갈수록 증가하고 , 비용 역시 증가

Page 26: [0326 석재호]상호배타적 집합의 처리

트리 깊이 줄이기

경로 압축 FindSet 실행 시 , 타고 올라가며 만나는 모든

노드의 parent 를 루트 노드로 갱신

-> 루트 노드에 대한 포인터를 얻을 때까진

갱신이 유예된다

재귀호출이나 스택 푸싱으로 구현

점근적으로는 FindSet 의 복잡도 차이가 없다

Page 27: [0326 석재호]상호배타적 집합의 처리

트리 깊이 줄이기

Page 28: [0326 석재호]상호배타적 집합의 처리

최적화 성능의 수학적 증명

랭크 알고리즘을 이용한 트리가n 개 원소를 가질 때의 최대 깊이 : lo g

2n + 1

랭크 알고리즘 특성상 노드 당 1 개의 자식으로 트리를 이어나갈 수 없고 , 자식이 2 개를 넘어가

면 최대 깊이의 경우가 되지 않으므로 밑수는 2 가 됨

깊이에 대한 증명은 다음장에

Page 29: [0326 석재호]상호배타적 집합의 처리

최적화 성능의 수학적 증명

N-1 회의 Union 연산이 이루어졌다고 할 때

N 번째의 Union 연산을 보면 .. 트리 T1, T2 의 노드 수 = m 개와 N-m 개

1≤m≤N/2 라는 가정이 가능

T2 의 노드 수가 m 개라고 할 때 양 트리의 높이 :

T1 의 높이는 T2 와 동일하거나 T2 보다 1 크다

Page 30: [0326 석재호]상호배타적 집합의 처리

최적화 성능의 수학적 증명

T1 의 높이 :

T2 의 높이 :

1nlog1m)(nlog 22 +≤+−

1nlog22

nlog2mlog 222 +≤+

≤+

T1 T2

Page 31: [0326 석재호]상호배타적 집합의 처리

최적화 성능의 수학적 증명

N 개의 노드 가진 트리에서 FindSet 실행 복잡도

O(lo g2N)

단일 노드를 가진 집합들에 대한 N 회의 U n io n

시 시간 복잡도 U n io n 내부에서 Find S e t호출 - > O (lo g

2N)

O (Nlo g2N)

Page 32: [0326 석재호]상호배타적 집합의 처리

이해하지 못한 정리

트리에서 랭크 알고리즘과 경로압축을

모두 사용할 때 m 회의 MakeSet, FindSet,

UnionSet 을 실행하고 그 중 MakeSet 이

n 회 호출되었다면 시간 복잡도는

O(m log*n) 이다

여기서 log*n = min {k : log log … logn ≤ 1}

즉 , n 에 k 회 거듭 log 를 씌워 1 이하가 나오는

k 의 최소값 -> 어떠한 n 에 대해서도 매우 작은 값

Page 33: [0326 석재호]상호배타적 집합의 처리

제 한

실용적인 면의 제한 집합 내 순회 불가

리스트의 경우 루트에서부터 순회가 가능하나

트리는 부모로부터 자식으로 순회가 불가한 구조

-> 자식에 대한 참조 배열이나 리스트가 필요

집합 분리에 대해 다루지 않음 집합 일부를 분리하고 합치는 것이 자유로워야

분리집합의 실질적인 활용도가 있을 것으로 보임

Page 34: [0326 석재호]상호배타적 집합의 처리

감사합니다