상호배타적 집합의 처리 (Disjoint Sets Algorithm)

상호배타적 집합의 처리 (Disjoint Sets Algorithm)
응용



인터넷 상의 웹페이지 관계
alias 처리
컴퓨터 네트워크
- u와 v가 같은 component
에 있는가?
https://www.cs.princeton.edu/~rs/AlgsDS07/01UnionFind.pdf
1
linked list 사용 방법
2. array 사용 방법
3. tree(forest) 사용 방법
a.
단순 방법
b.
무게(weight)고려 방법
c.
path compression 방법
1.
문제:




노드 1은 어느 component에 있나?
노드 1과 3은 연결되어 있나?
노드 1과 3이 속해 있는 component
를 하나의 component로 만들어라
4
1
2
3
5
6
{1,2}, {3},
{4,5,6}
component가 3개인 그래프 G
해결방법:
 find(1)
 find(1) = find(3)?
 union(1,3)
상호배타적(disjoint): 집합간에 교집합은 f
2

Operations


make_set(v): make a set with an element v
find(v): returns a name of the set containing v

union(u,v): 원소 u와 원소 v를 갖고 있는 집합을 하나로 합친다. 이
미 같은 집합에 속해 있을 수 있다.

문제

find, union의 명령어가 다수 있을 때 효율적인 처리가 가능한 자료구
조와 알고리즘을 개발한다.
3
1. linked list를 사용하는 방법
b
o
a
e
w
t
-
-
set의 이름은 최초 원소값
각 원소는 set이름으로 가는 포인터와 next 포인터를 갖는다.
make_set(v): O(1)
find(v): O(1)
union(u,v): u가 속해 있는 리스트의 set이름으로 가는 포인터를 v가 속해있
는 set의 이름으로 바꾸어 준다.(반대도 가능)

(예) union(a,e)
w
4회의 포인터 변경필요
e
b
o
a
t
4
업데이트되는
포인터의 개수
command
make_set(x1)
make_set(x2)
…….
make_set(xn)
union(x1,x2)
union(x2,x3)
…..
union(xn-1,xn)
1
2
…
1
1
2
…
n-1
k 크기의 리스트가 1개의 리스트에 연결되는 현상

n개의 데이터에 m번의 union은 O(mn)소요
O(n2)
개선점:
리스트의 크기를 별도로 저장하고, 크기가 작은 리스트를 큰 리
스트에 연결한다. …. weighting-union heuristic
(예) union(a,e)
2회의 포인터 변경필요
b
o
a
t
w
e
-
5
n개의 원소가 있을 때, 개선된 방법으로 n-1번의 union을 수행하는데
O(n log n) step 소요

(proof)




step
union(1,2)
union(1,3)
union(1,5)
A가 B가 합쳐져 B가 되었을 때, 새로 만들어진 B에 대해 |B| ≥ 2|A|, 여기서 |A|는 리
스트 A의 크기
따라서 어떠한 원소도 log n 번 보다 더 많이 이동할 수 없다.
한 원소에 대해 O(log n)
따라서 총 O(n log n)
1
1
2
3
4
5
6
7
8
2
1
2
3
4
5
6
7
8
3
1
2
3
4
5
6
7
8
4
1
2
3
4
5
6
7
8
1번 원소는 최대 3회 포인터가 바뀐다.
6
2. array를 사용하는 방법
i
1
2
3
4
5
6
set_id[i]
1
2
3
1
2
2
{1,4}, {3},{2,5,6}
find(x) : set_id[x]만 확인하면 됨
 union(x, y): set_id[x]를 갖고 있는 원소들의 set_id를 set_id[y]로 변경

- union(1,2)


i
1
2
3
4
5
6
set_id[i]
1
1
3
1
1
1
{1,4, 2,5,6}, {3}
리스트를 사용할 때와 마찬가지로 weighting-union heuristic을 사용
하면 시간 단축
리스트와 같은 시간 소요
7
2. tree를 사용하는 방법
(a) 단순한 방법
1
5
3
4
2
{1,4}, {3},{2,5,6}
6
 하나의
component는 하나의 트리로 표현
 전체 그래프가 전체 집합을 나타냄
 roor원소가 집합의 이름을 나타냄
 각 원소는 parent로 향하는 포인터를 갖는다.
 find(x): x에서 출발하여 parent로 향하는 포인터를 따라
root로 이동하여, root값을 반환
 union(x,y): find(x) 원소를 find(y)의 child node로 만든다.
b
a
b
a
y
x
y
union(x,y)
x
8
command
make_set(x1)
make_set(x2)
…….
make_set(xn)
union(x1,x2)
union(x1,x3)
…..
union(x1,xn)
xn
xn-1
…

O(n2)시간 필요
x2
x1
9
(b) 트리의 무게를 고려한 방법
 개선점

트리가 갖고 있는 원소의 수(weight)를 저장한다.

트리의 weight가 작은 것을 weight가 큰 트리에 연결한다.
트리의 높이(heightr)를 이용하여 트리의 rank 정의. rank를 활용해도 같은 효과

1
5
1
5
5
1
or
union
결과 트리의 높이가 낮은 것이 유리
 find 를 빨리 수행하는 것이 검색하는데 바람직
 이 방법을 사용할 경우 n개의 원소를 갖고 있을 때, forest에 있는 어떠한 트리도
높이가 log n을 넘을 수 없다.
 O(n) union-find operation은 최대 O(n log n) 시간 소요

10
(b) path compression 방법
5
x
5
y
x
y
z
z
find(z)
union with weighting-union and path compression
2
1
5
4
3
6
7
8
7
8
union(7,8)
2
union(1,2)
5
4
3
6
2
1
6
4
1
union(3,4)
1
union(1,4)
2
4
1
3
4
5
4
3
union(5,8)
2
8
1
5
7
7
4
6
8
8
5
7
3
union(3,8)
5
6
8
7
6
3
6
2
1
7
3
2
union(1,6)
8
5
path
compression
2
1
8
6
4
3
5
7
11
n
F(n)
n
G(n)
0
1
1
0
F (0)  1,
1
2
2
1
F (i)  2 F (i 1) , for i  0.
2
4
4
2
3
16
16
3
4
65536
65536
4
5
265536
265536
5
G(n) = min{ k | F(k) ≥ n}
 G(100)=4
 G grows extremely slowly.
 G(n) ≤ 5 for all “practical” value of n, i.e., for all n ≤ 265536 .



n union and find operations take at most O(nG(n))).
superlinear
12
Ch 5. Backtracking
Textbook: Foundations of Algorithms Using C++ Pseudocode by R. Neapolitan and K. Naimipour
This is prepared only for the class.
14
Tree Traversal
1.
1
preorder
2
1
2. inorder
3
4
12345
2
5
4
5
21435
3. postorder
4. level order
1
2
1
3
4
24531
3
2
5
3
4
5
12345
15
Depth-First Search
The root is visited first, and a visit to a node is followed immediately by visits to
all descendants(left to right in general) of the node.
= preorder tree traversal
void depth_first_tree_search (node v) {
node u;
visit v;
for (each child u of v)
depth_first_tree_search(u)
}
16
An Example of Depth-First Search
17
The 4-Queens Problem
to position 4 queens on a 4  4 chessboard so that no two queens threaten each
other – can not be in the same row, column, or diagonal.
18
brute-force algorithm:
4  4  4  4 = 256 candidate solutions.
Q1 Q1
Q1 Q1
Q2 Q2
Q2 Q2
Q3
Q3 Q3
Q3
Q4 Q4 Q4 Q4
Q1 is positioned at
row 1, column 1
(1,1)
ordered tuple
Q2 is positioned at
row 2, column 4:
(2,4)
Fig 5.2 A portion of the state space tree for the instance of the 4-Queens problem.
19
State Space Tree
A path from the root to a leaf is a candidate solution. This tree is called a state
space tree.
A solution can be found by depth-first search of the state space tree among the
candidates.
However, because this method checks all descendants of a node that can not be a
solution, it is very inefficient.
does not need to
visit descendants of
(2,1)
20
Backtracking
promising:

A node is nonpromising if it cannot possibly lead to a solution.

otherwise promising.
backtracking?

the procedure whereby, after determining that a node can lead to nothing but
dead ends, we go back(backtrack) to the node’s parent and proceed with the
search on the next child.

if the node is nonpromising, backtracking to the node’s parent.  pruning
the state space tree.

the subtree consisting of the visited nodes is called the pruned state space
tree.
21
Concept of Backtracking
Backtracking algorithm does depth-first search of a state space tree,

check only children of promising nodes.
procedure
1. doing a depth-first search of a state space tree,
2. checking whether each node is promising,
3. if it is nonpromising, backtracking to the node’s parent.
22
Backtracking Algorithm
a general backtracking algorithm:
void checknode (node v) {
node u;
if (promising(v))
if (there is a solution at v)
write the solution;
else
for (each child u of v)
checknode(u);
}
- A visit to a node consists of first checking whether it is promising.
23
State Space Tree of 4-Queens Problem
(backtracking)
promising
24
25
Depth-First Search vs. Backtracking
Need not actually create a tree. Only needs to keep track of the values in the
current branch being investigated. The state space tree exists implicitly in the
algorithm.
The number of nodes checked until a solution has been found.
 DFS = 155 nodes
1
 Backtracking = 27 nodes
1+3+12+48=64
(nodes appeared in the Fig)
1+1+3=5
1+4+16+64=85
solution
When DFS, all nodes (not appeared in
the Fig) in this area are searched.
26
The 4-Queens Problem: Backtracking
(improved)
void expand (node v) {
node u;
for (each child u of v)
if(promising(u))
if (there is a solution at u)
write the solution;
else
expand(u);
}
check whether a node is promising before passing → decrease the number of
nodes to be checked.
But, the original backtracking approach is easier to understand. The original
one can be transformed to the improved version.
use the original version to describe backtracking approach in the class.
27