Disjoint-Set을 구현할 때 사용하는 알고리즘.
크루스칼 알고리즘에서 그래프의 최소 신장 트리(MST)를 찾는데 활용된다. (정점 연결 및 사이클 형성 여부 확인)
초기에 {0}, {1}, {2}, … {n} 이 각각 n+1개의 집합을 이루고 있다. 여기에 합집합 연산과, 두 원소가 같은 집합에 포함되어 있는지를 확인하는 연산을 수행하려는 경우. 집합의 표현-백준1717번
어떤 사이트의 친구 관계가 생긴 순서대로 주어졌을 때, 가입한 두 사람의 친구 네트워크에 몇 명이 있는지 구하는 프로그램을 작성하는 경우. 친구 네트워크-백준4195번
서로소 집합 자료구조
라고 부른다.
상호 배타적
인 부분 집합들로 나눠진 원소들에 대한 자료구조이다.상호 배타적
을 확실히 이해해야한다. --> A, B 사건이 존재한다면, A, B는 동시에 일어나지 않고 둘 중 하나만 일어나야 한다. (P(A) + P(B)
)독립
은 사건 A, B가 동시에 일어나도 상관없음.먼저 union() 함수와 find() 함수의 기능을 간단히 정리한 후 Python 코드를 살펴보겠다.
x가 속한 집합
과 y가 속한 집합
을 합친다. 즉, x
와 y
가 속한 두 집합을 합치는 연산.x가 속한 집합
의 대표값(루트 노드 값)
을 반환한다. 즉, x
가 어떤 집합에 속해 있는지 찾는 연산.사진 출처 : 링크
parents = [i for i in range(MAX_SIZE)]
# 재귀 함수
def find(parent, x):
# 루트 노드의 부모 노드 번호는 자기 자신이다.
if parent[x] == x:
return x
# 각 노드의 부모 노드를 찾아 올라간다.
else:
return find(parent, parent[x])
def union(parent, x, y):
# 각 원소가 속한 트리의 루트 노드를 찾는다.
rootX = find(parent, x)
rootY = find(parent, y)
parent[rootY] = rootX
위 코드는 기본적인 union-find 구현 방법이다. 하지만, 트리의 모든 높이를 탐색해야하는 최악의 경우에는 비효율적인 성능을 보여준다.
O(N)
이 된다.따라서 우리는 좀 더 효율적인 union-find 알고리즘을 구현해야 한다. 그 코드는 아래에서 설명하겠다.
parents = [i for i in range(MAX_SIZE)]
def find(parent, x):
if parent[x] == x:
return x
# 경로 압축(Path Compression)
# find 하면서 만나는 모든 값의 부모 노드를 root로 만듦.
parent[x] = find(parent, parent[x])
return parent[x]
O(logN)
의 시간복잡도로 효율이 좋다.
(Ex) 아래 예제를 통해 직접 손코딩해서 이해해보자!
parents = [i for i in range(MAX_SIZE)]
rank = [0 for _ in range(MAX_SIZE)]
# find()는 위와 동일
def union(parent, x, y, rank):
rootX = find(parent, x)
rootY = find(parent, y)
# 두 값의 root가 같으면(이미 같은 트리) 연결 X(합치지 않음)
if rootX == rootY:
return
# union-by-rank 최적화
# 항상 높이가 더 낮은 트리를 높이가 높은 트리 밑에 넣음.
# --> 높이가 더 높은 쪽을 root로 함.
if rank[rootX] < rank[rootY]:
parent[rootX] = rootY
else:
parent[rootY] = rootX
if rank[rootX] == rank[rootY]:
rank[rootX] += 1 # 만약 높이가 같다면 합친 후 -> x 높이 + 1
참고 : https://ko.wikipedia.org/wiki/%EC%84%9C%EB%A1%9C%EC%86%8C_%EC%A7%91%ED%95%A9_%EC%9E%90%EB%A3%8C_%EA%B5%AC%EC%A1%B0#cite_note-4
https://mygumi.tistory.com/246
https://gmlwjd9405.github.io/2018/08/31/algorithm-union-find.html
https://www.weeklyps.com/entry/%EC%9C%A0%EB%8B%88%EC%98%A8-%ED%8C%8C%EC%9D%B8%EB%93%9C-Unionfind
https://bowbowbow.tistory.com/26