Disjoint Set & Path Compression
2020-1νκΈ°, λνμμ βμκ³ λ¦¬μ¦β μμ μ λ£κ³ 곡λΆν λ°λ₯Ό μ 리ν κΈμ λλ€. μ§μ μ μΈμ λ νμμ λλ€ :)
Kruskalβs Algorithm & Primβs Algorithmμμ μ΄μ΄μ§λ ν¬μ€νΈμ λλ€.
Disjoint Set
μ΄λ² ν¬μ€νΈμμλ <Disjoint Set>μ΄λΌλ μλ£κ΅¬μ‘°μ λν΄ μ΄ν΄λ³Έλ€. μνμ Setμ μλ£κ΅¬μ‘°λ‘ ꡬνν κ²μ΄λΌκ³ μκ°νλ©΄ λλ€.
λ¨Όμ <disjoint set>μ ꡬ체μ μ΄ κ΅¬ν μμ΄ κΈ°λ³Έ μ°μ°λ€μ μ΄ν΄λ³΄μ.
- $\text{makeset}(x)$: create a new set containing $x$.
- $\text{find}(x)$: return the root node of the set containing $x$.
- $\text{union}(x, y)$: form a union of two sets containing $x$ and $y$.
νν μ§ν©μ κΈ°λ³Έ μ°μ°μ΄λΌκ³ νλ©΄ μ§ν© μ¬μ΄μ Intersection, Union, Differenceλ₯Ό μκ°νκΈ° λ§λ ¨μΈλ°, μ μλ κΈ°λ³Έ μ°μ°λ€μ λͺ¨λ λ Έλ $x$λ₯Ό μΈμλ‘ λ°λ κ²μ λ³Ό μ μλ€.
κ·Έλ¦¬κ³ λ Έλ $x$μ λν΄μλ
- $\pi(x)$: pointer to its parent
- $\text{rank}(x)$: height of the subtree hanging from $x$ ($x$λ₯Ό 루νΈλ‘ κ°λ subtreeμ λμ΄)
μ¬μ€ $\pi(x)$μ $\text{rank}(x)$λ <disjoint set>μ΄ Tree ννλ‘ κ΅¬νλμ΄ μλ€λ κ²μ μμμΌ μ λλ‘ μ΄ν΄ν μ μλ€.
<disjoint set>μ κΈ°λ³Έ μ°μ°μΌλ‘ μ΄λ»κ² Tree ννμ <disjoin set>μ΄ λ§λ€μ΄μ§λμ§ μ΄ν΄λ³΄μ. π
λ¨Όμ $\text{makeset}(x)$λ λ£¨νΈ λ Έλλ§ μλ νΈλ¦¬λ₯Ό μμ±νλ€. κ·Έλ¦¬κ³ $\text{union}(x, y)$ μ°μ°μ κ° λ Έλκ° ν¬ν¨λ λ κ°μ νΈλ¦¬λ₯Ό νλμ νΈλ¦¬λ‘ λ³ν©νλ€. μ΄λ νλμ νΈλ¦¬λ₯Ό λ€λ₯Έ νΈλ¦¬μ subtreeλ‘ λ³ν©λλ€. ꡬ체μ μΌλ‘ μ΄λ»κ² $\text{union}(x, y)$λ‘ νΈλ¦¬λ₯Ό λ³ν©νλμ§λ μ½λλ₯Ό 보며 μ΄ν΄ν΄λ³΄μ.
Algorithm $\text{makeset}(x)$
$\pi(x) \leftarrow x$
$\text{rank}(x) \leftarrow 0$
λ¨Όμ $\text{makeset}(x)$μ λ£¨νΈ λ Έλλ§ μλ νΈλ¦¬λ₯Ό λ§λ λ€. λ£¨νΈ λ Έλλ λΆλͺ¨κ° μκΈ° μμ μ κ°λ¦¬ν€κΈ° λλ¬Έμ $\pi(x)$λ μκΈ°μμ μΈ $x$μ΄λ€.
Algorithm $\text{find}(x)$
while $x \ne \pi(x)$
Β Β do $x \leftarrow \pi(x)$
return x
λ Έλ $x$μ λ£¨νΈ λ Έλλ₯Ό λ°ννλ $\text{find}(x)$λ $\pi(x)$λ₯Ό μννλ©° μ½κ² ꡬν μ μλ€.
Algorithm $\text{union}(x, y)$
$r_x \leftarrow \text{find}(x)$
$r_y \leftarrow \text{find}(y)$
if $r_x = r_y$ // already in same set
Β Β them return
if $\text{rank}(r_x) > \text{rank}(r_y)$
Β Β then $\pi(r_y) \leftarrow r_x$ // attach $r_y$ to $r_x$
else if $\text{rank}(r_x) < \text{rank}(r_y)$
Β Β $\pi(r_y) \leftarrow r_x$ // attach $r_x$ to $r_y$
else
Β Β $\pi(r_y) \leftarrow r_x$
Β Β $\text{rank}(r_y) \leftarrow \text{rank}(r_y) + 1$
μ¦, λ λ Έλ $x$, $y$μ λ£¨νΈ λ Έλλ₯Ό $\text{find}()$λ‘ μ°Ύμ ν, λ setμ ν¬κΈ°λ₯Ό $\text{rank}(r_x)$, $\text{rank}(r_y)$λ‘ μ»μ΄ $\text{rank}$κ° ν° μ§ν©μ μμ μ§ν©μ λΆμ΄λ λ°©μμΌλ‘ $\text{union}()$μ μννλ€.
<disjoint set>μ μ£Όμν μ°μ°μΈ $\text{union}$κ³Ό $\text{find}$μμ λ°κ²¬λλ μ±μ§μ λμ΄νλ©΄ μλμ κ°λ€.
- For any $x$, $\text{rank}(x) \le \text{rank}(\pi(x))$
- If $x$ is not a root, $\text{rank}(x)$ will nenver change again.
- Rank changes only for roots. A non-root node never becomes a root.
- Any root node of rank $k$ has at least $2^k$ nodes in its tree.
- If there are $n$ elements overall, there can be at most $n/2^k$ nodes of rank $k$.
- The maximum rank is $\log n$, so the tree height $\le \log n$.
μ΄ μ€μμ 3λ²μ§Έ λ¬Έμ₯μ μ¦λͺ ν΄λ³΄μ.
[Proof by Induction]
- (Base) It holds for $k=0$
- Assume that the claim holds for $k-1$.
- A node $x$ of rank $k$ is created only by mergining two roots of rank $k-1$, each subtree consisting of $\ge 2^{k-1}$ nodes. Thus, $x$ has $\ge 2^k$ nodes in its subtree.
$\blacksquare$
λ§μ§λ§ 4λ²μ§Έ λ¬Έμ₯μ λ λ Έλκ° λμΌ μ§ν©μ μνλμ§λ₯Ό νλ¨νλλ° $O(\log n)$μ λΉμ©μ΄ νμν¨μ μλ―Ένλ€. κ·Έλμ Kruskal Algorithmμμλ MSTλ₯Ό λ§λ€κΈ° μν΄ union-findλ‘ λμΌ μ§ν©μ μνλμ§ κ³μ 체ν¬νκ² λλλ°, μ΄ μμ μ $O(E \log V)$ λ§νΌμ λΉμ©μ΄ λ°μνλ€.
Path Compression
λλκ²λ <disjoint set>μ Path Compressionμ΄λΌλ μμ μ λ³νν΄μ£Όλ©΄ ν¨μ¬ μ μ λΉμ©μΌλ‘ union-find μμ μ μνν μ μλ€! π² Path Compressionμ <disjoint set>μ νΈλ¦¬μ λμ΄λ₯Ό μ§§κ² μ μ§ν΄μ£Όλ λ°©λ²μ΄λ€.
Path Compressionμ $\text{find}(x)$ μ°μ°μ μννκΈ°λ§ νλ©΄ λλ€!
Algorithm $\text{find}(x)$
if $x \ne \pi(x)$
Β Β then $\pi(x) \leftarrow \text{find}(\pi(x))$
return $\pi(x)$
$\text{find}(x)$ ν¨μκ° μ¬κ·ν¨μμ κΌ΄μ΄ λμ΄μ ν·κ°λ¦΄ μλ μμ§λ§, ν΅μ¬μ λ Έλ $x$κ° λ£¨νΈ λ Έλλλ‘ λ§λ λ€λ κ²μ΄λ€. $\text{find}(x)$κ° νμ λ£¨νΈ λ Έλλ₯Ό λ°ννλ€λ μ¬μ€μ μ ν΄μνλ©΄ λλ€.
κ·Έλ¦ΌμΌλ‘ 보면 μλμ κ°λ€.
Time Complexity
Path Compressionμ λμ νλ©΄μ λμ΄μ $\text{find}$μ λΉμ©μ $O(\log n)$λ³΄λ€ μμμ§κ² λμλ€. κ·Έλ λ΄ μκ° λ³΅μ‘λλ₯Ό μ΄λ»κ² ꡬν΄μΌ ν κΉ?
μ κΉ! π μκ° λ³΅μ‘λλ₯Ό μ λνκΈ° μ μ <interval>μ΄λΌλ κ°λ μ λν΄ μ΄ν΄λ³΄κ³ κ°μ. interval $I_k$λ μλμ κ°μ΄ μ μνλ€.
\[I_k = \left\{ k+1, k+2, ..., 2^k \right\}\]κ·Έλμ κ°μ λμ΄ν΄λ³΄λ©΄,
\[\begin{aligned} I_0 &= \left\{ 1 \right\} \\ I_1 &= \left\{ 2 \right\} \\ I_2 &= \left\{ 3, 4 \right\} \\ I_4 &= \left\{ 5, 6, ..., 15, 16 \right\} \\ I_{16} &= \left\{ 17, 18, ..., 2^{16} \right\} \\ &... \\ I_i &= \left\{i+1, ..., 2^i\right\}\\ I_{2^i} &= \left\{ ... \right\} \end{aligned}\]μ! λ€μ disjoint setμ treeλ‘ λμμ보μ. $n$κ° λ Έλλ₯Ό κ°λ disjoint setμ treeμ $\text{rank}$λ μλμ λ²μλ₯Ό κ°λλ€.
\[0 \le \text{rank}(x) \le \log n\]μ°λ¦¬λ $\text{rank}(x)$λ₯Ό μμμ ꡬν <interval>λ‘ λΆλ°°ν κ²μ΄λ€. μ΄λ $\text{rank}(x)$κ° μ΄λ <interval>μ μνλμ§λ μλμ ν¨μλ‘ μ½κ² μ μ μλ€.
\[\log^{*} n\]μ΄ $\log^{*}$ ν¨μλ βnumber of successive $\log$ operationβμ κ³μ°νλ ν¨μλ‘ μ μ $n$μ $\log$μ λͺλ² μ·¨ν΄μΌ $\le 1$μ΄ λλμ§λ₯Ό κ³μ°νλ ν¨μλ€. μ νμμΌλ‘ νννλ©΄ μλμ κ°λ€.
\[\log^{*} n = \begin{cases} 0 & \text{for} \; n \le 1 \\ 1 + \log^{*}(\log_2 n) & \text{for} \; n > 1 \end{cases}\]$16 = 2^{2^{2}}$λ₯Ό μλ‘ λ€μλ©΄,
\[\log^{*} 2^{2^{2}} = 1 + \log^{*} 2^{2} = 2 + \log^{*} 2 = 3\]μ΄ λλ€. μ΄κ²μ 곧 $16$μ΄ 3λ²μ§Έ <interval>μΈ $I_4$μ μνλ€λ κ²μ λ§νλ€.
<interval>μ΄λ $\log^{*}$ ν¨μλ μλΏμ§ μμ μ μλ€. μ΄ λ¬Έλ¨μμ μ»μ κ²μ $\log^{*}$ ν¨μλ‘ $\text{rank}(x)$κ° λͺ λ²μ§Έ <interval>μ μνλμ§ μ μ μλ€λ κ²κ³Ό μ΄λ₯Ό νμ©νλ©΄ λ λ Έλ $x$, $y$μ $\text{rank}$ κ°μ΄ μλ‘ κ°μ <interval>μ μνλμ§ μλμ§λ₯Ό $\log^{*}$ ν¨μλ‘ μ½κ² μ μ μλ€λ κ²λ§ μ μ΄ν΄νλ©΄ λλ€ π
μ°λ¦¬λ $\text{find}$ μ°μ°κ³Ό $\text{union}$ μ°μ°μ΄ μμ¬μλ μΌλ ¨μ μ°μ°μ μ΄ν΄λ³Έλ€κ³ νμ. μΌλ¨ μ²μμλ empty treeμμλΆν° μμνλ€. μΌλ ¨μ μ°μ°μλ $\text{find}$ μ°μ°κ³Ό $\text{union}$ μ°μ°μ΄ μμ¬μμ§λ§ μ°λ¦¬λ $\text{find}$ μ°μ°μ $m$λ² μ€ννλ€κ³ μκ°ν κ²μ΄λ€. μλλ©΄ $\text{union}$ μ°μ°λ κ²°κ΅μ $\text{find}$λ₯Ό μ°κΈ° λλ¬Έμ΄λ€.
μ΄λ€ λ Έλ $u$μμ $\text{find}$λ₯Ό ν΅ν΄ λ£¨νΈ λ ΈλκΉμ§ λλ¬νλ κ³Όμ μ μκ°ν΄λ³΄μ. λΆλͺ¨ λ Έλλ₯Ό κ±°μ¬λ¬ μ¬λΌκ° λλ§λ€ μ°λ¦¬λ λ€μμ λ κ°μ§ κ²½μ°λ₯Ό λ§μ£Όνλ€.
- $x$ and $\pi(x)$ belong to the different interval.
- $x$ and $\pi(x)$ belong to the same interval.
μ°λ¦¬λ κ° κ²½μ°μ λν΄ κ±Έλ¦¬λ λΉμ©μ $T_1$, $T_2$λ‘ μ κ³ , $\text{find}$λ‘ λ£¨νΈ λ Έλμ λλ¬νλ κ³Όμ μ μ΄ λΉμ© $T$λ₯Ό μ λν κ²μ΄λ€.
\[T = T_1 + T_2 = \sum (1) + \sum (2)\]1. $x$ and $\pi(x)$ belong to the different interval
$n$μ λ Έλλ₯Ό κ°μ§ Treeκ° μλ€κ³ μκ°ν΄λ³΄μ. μ΅λ $\text{rank}$κ° $\log n$μ΄κΈ° λλ¬Έμ intervalμ κ°―μλ $\log^{*} n$μ΄λ€. κ·Έλμ νλ²μ $\text{find}$μμ intervalμ΄ λ°λλ νμλ μ΅λ $\log^{*} n$λ² λ§νΌ μΌμ΄λλ€. μ²μμ $\text{find}$ μ°μ°μ $m$λ² μ€ννλ€κ³ νμΌλ―λ‘ λΉμ© $T_1$μ
\[T_1 = O(m \cdot \log^{*} n)\]μ΄λ€.
2. $x$ and $\pi(x)$ belong to the same interval
κ°μ intervalμ μνλ $\text{rank}$λ λͺ¨λ κ°μ $\log^{*}$ κ°μ κ°μ§λ€. κ·ΈλΌ $n$κ° λ Έλλ₯Ό κ°μ§ treeμμ κ°μ intervalμ μνκ² λλ λ Έλμ κ°―μλ μ΄ λͺ κ°λ λ κΉ?
<disjoint set>μ μλ£νμ μ±μ§ μ€ λ§μ§λ§ 4λ²μ¬ μ±μ§μμ $\text{rank}$κ° $k$μΈ λ Έλκ° μ΅λ $n/2^{k}$κ° λ§νΌ μ‘΄μ¬νλ€λ κ²μ μλ€. κ·Έλμ ν interval μμ μνλ λ Έλμ μ΄ κ°―μλ
\[\frac{n}{2^{k+1}} + \frac{n}{2^{k+2}} + \cdots\]λ§νΌ μ‘΄μ¬ν κ²μ΄λ€. κ·Έλ¦¬κ³ μ΄κ²μ
\[\begin{aligned} &\frac{n}{2^{k+1}} + \frac{n}{2^{k+2}} + \cdots \\ &= n \cdot \left( \frac{1}{2^{k+1}} + \frac{1}{2^{k+2}} + \cdots \right) \\ &= \frac{n}{2^{k+1}} \cdot \left( 1 + \frac{1}{2} + \frac{1}{2^2} + \cdots\right) \\ &= \frac{n}{2^{k+1}} \cdot 2 = \frac{n}{2^k} \end{aligned}\]κ° λλ€. μ¦, interval $I_k$μ λν΄ $\left| I_k \right| = n/2^k$λΌλ λ§μ΄λ€.
κ·ΈλΌ μ΄λ€ λ Έλ $u$μμ $\text{find}$λ₯Ό μμν΄μ λ€λ₯Έ intervalμ μνκ² λ λκΉμ§ μ΄ λͺ λ²μ $\text{find}$ ν¨μ νΈμΆμ΄ νμν κΉ? $\text{find}$ νΈμΆ 1νλΉ νλμ© $\text{rank}$κ° νλμ© μ€μ΄κ°λ€κ³ μκ°νλ©΄ $\le 2^{k}$λ²μ $\text{find}$ νΈμΆλ‘ λ€λ₯Έ intervalμ μνλ λ Έλλ₯Ό λ§λκ² λλ€.
κ·Έλμ interval $I_k$μ μνλ λͺ¨λ λ Έλλ€μ λν΄ μ΄κ²λ€μ λ€λ₯Έ intervalμ μνκ² νλ €λ©΄ μ΄ $(\le 2^{k}) \times n/2^k = (\le n)$λ² λ§νΌμ $\text{find}$ νΈμΆμ΄ νμνλ€.
μ΄κ²μ νλμ intervalμ λν΄ νμ ν $\text{find}$ νΈμΆμ μ΄ νμμ΄λ€. Treeμ $\log^{*} n$ λ§νΌμ intervalμ΄ μμΌλ―λ‘ $(\le n) \times \log^{*} n$ λ§νΌμ $\text{find}$ νΈμΆμ΄ νμνλ€.
\[T_2 = O(n \cdot \log^{*} n)\]μ΄μ $T_1$, $T_2$μ λΉμ©μ λν΄μ μΌλ ¨μ $\text{find}$, $\text{union}$ μ°μ°μ λλ λΉμ©μ ꡬν΄λ³΄μ. μ 체 μ°μ°μ νμν μ΄ λΉμ©μ
\[O(m \cdot \log^{*} n) + O(n \cdot \log^{*} n) = O(m \cdot \log^{*} n)\]μ΄λ€. μ¬κΈ°μ μ°λ¦¬λ μ°μ°μ μ΄ λΉμ©μ μ°μ°μ νμ $m$μ λλμ΄ amortized costλ₯Ό μ λν κ²μ΄λ€. λ°λΌμ $\text{find}$ μ°μ°μ amortize costλ
\[O(m \cdot \log^{*} n) / m = O(\log^{*} n)\]μ΄λ€!
μ΅μ’ μ μΌλ‘ ꡬν΄μ§ $\text{find}(x)$μ λΉμ©μΈ $O(\log^{*} n)$λ μ λ§ μμ λΉμ©μ΄λ€. $n = 2^{16}$μΌ λλ 4λ°μ μ λκΈ° λλ¬Έμ μ¬μ€μ μμ λΉμ©μ΄λΌκ³ 보면 λλ€.
μ΄κ²μΌλ‘ <disjoint set> μλ£κ΅¬μ‘°μ λν΄ μ΄ν΄λ³΄μλ€. disjoint setμ ν΅ν΄ κ·Έλνμμ μ¬μ΄ν΄μ΄ μ‘΄μ¬νλμ§ νμΈν μ μκΈ° λλ¬Έμ MST μΈμλ μΆ©λΆν νμ©ν μ μλ€.
λ€λ₯Έ ν¬μ€νΈμμ <Heap> μλ£κ΅¬μ‘°μ ꡬνμ λν΄ κΈ°μ ν Implementations of Heap ν¬μ€νΈλ μμΌλ μκ³ λ¦¬μ¦ λ¬Έμ ν΄κ²°μ μ°λ μλ£κ΅¬μ‘°κ° λ κΆκΈνλ€λ©΄ μΆμ²νλ€.