๊ตญ๋ฏผ๋ํ๊ต์์ "์ฝ๊ฒ ๋ฐฐ์ฐ๋ ์๊ณ ๋ฆฌ์ฆ" ๊ต์ฌ๋ฅผ ์ด์ฉํ
๋ฐํ๋ช ๊ต์๋์ ๊ฐ์ ๊ต์์ ์ด์ฉํ์ฌ ์์ ๋ด์ฉ์ ์ ๋ฆฌํ์์ต๋๋ค
Minimum Spanning Trees
Spanning Tree๋ ๊ทธ๋ํ G = (V, E)์์ ๊ฐ์ ์ |V| - 1 ๊ฐ๋ง ๋จ๊ฒจ ํธ๋ฆฌ๊ฐ ๋๋๋ก ๋ง๋ ๊ฒ
Minimm Spanning Tree๋ Spanning Tree ์ค์์ edge weight์ ํฉ์ด ๊ฐ์ฅ ์์ ๊ฒ
=> ํ ๊ทธ๋ํ์ ์ฌ๋ฌ๊ฐ์ MST๊ฐ ์กด์ฌํ ์ ์์
์ด๋ป๊ฒ MST๋ฅผ ๊ตฌํ ๊น..?
Naive Solution์ ์๊ฐํด๋ณด๋ฉด
๋ชจ๋ subgraph๋ฅผ ์ดํด๋ณด๊ณ , ๊ทธ ์ค์์ spanning tree์ด๋ฉด์ weight์ ํฉ์ด ๊ฐ์ฅ ์์ ๊ฒ์ ์ฐพ์ผ๋ฉด๋จ
=> subgraph์ ์๋ ๊ฐ๊ฐ์ edge๊ฐ ์๋ ์๋์ ๋ฐ๋ผ ๊ฒฐ์ ๋๋ฏ๋ก 2^|E| ์
(ํฐ ๊ทธ๋ํ๋ ์ฌ์ค์ ์ฒ๋ฆฌ ๋ถ๊ฐ)
์ด์ ๋ํด ํจ์จ์ ์ธ ํฌ๋ฃจ์ค์นผ, ํ๋ฆผ ์๊ณ ๋ฆฌ์ฆ์ด ์กด์ฌํจ
(๋๋ค Greedy Algorithm)
Kruskal's Algorithm
Cycle์ ๋ง๋ค์ง ์๋ ์ต์ ๊ฐ์ ์ MST์ ๋ฐ๋ณตํ์ฌ ์ถ๊ฐํ๋ ๊ฒ์
์์๋
1. ๊ฐ์ ์ weight๋ฅผ ๊ธฐ์ค์ผ๋ก ์ค๋ฆ์ฐจ์ ์ ๋ ฌ
2. weight๊ฐ ๊ฐ์ฅ ์์ ๊ฐ์ ์ ์ ํํ๊ณ ์ด๋ฏธ MST์ ์ถ๊ฐ๋ ๊ฐ์ ๋ค๊ณผ cycle์ ์ด๋ฃจ๋์ง ํ์ธ
=> cycle์ ์ด๋ฃจ๋ ๊ฒฝ์ฐ ๊ฐ์ ์ ์ ์ธํ๊ณ ์ด๋ฃจ์ง ์๋ ๊ฒฝ์ฐ ๊ฐ์ ์ MST์ ์ถ๊ฐ
3. |V| - 1 ๊ฐ์ ๊ฐ์ ์ด ์ ํ๋ ๋ ๊น์ง Step 2๋ฅผ ๋ฐ๋ณต
Cycle์ ํจ์จ์ ์ผ๋ก ํ์ธํ๊ธฐ ์ํด Disjoint Set์ ํ์ฉ
Disjoint Set์ด ๊ธฐ์ต์ด ์๋๋ฉด
https://hanjungyo.tistory.com/96
L10 - Disjoint Sets
๊ตญ๋ฏผ๋ํ๊ต์์ "์ฝ๊ฒ ๋ฐฐ์ฐ๋ ์๊ณ ๋ฆฌ์ฆ" ๊ต์ฌ๋ฅผ ์ด์ฉํ ๋ฐํ๋ช ๊ต์๋์ ๊ฐ์ ๊ต์์ ์ด์ฉํ์ฌ ์์ ๋ด์ฉ์ ์ ๋ฆฌํ์์ต๋๋ค Disjoint Sets Disjoint Sets๋ ์๋ก ๊ฒน์น์ง ์๋ ์งํฉ๋ค์ ์๋ฏธํจ =>
hanjungyo.tistory.com
๊ทธ๋์ ๊ฒฐ๋ก ์ ์ผ๋ก Disjoint Set์ ํ์ฉํด Cycle์ ํ์ธํ๋ ๋ฐฉ๋ฒ์
- ๊ฐ ์ ์ ์ด ๋
๋ฆฝ๋ ์งํฉ์ ์ด๋ฃจ๋๋ก ์ด๊ธฐํ (make-set)
- ๊ฐ์ (u, v)๊ฐ MST์ ์ถ๊ฐ๋ ๋ union(u, v) ์คํ
- ๊ฐ์ (u, v)๊ฐ cycle์ ์ด๋ฃฌ๋ค๋๊ฑด u์ v๊ฐ ๊ฐ์ ์งํฉ์ ์๋ค๋ ๋ป
=> ์ฆ, find-set(u) = find-set(v)์ธ ๊ฒฝ์ฐ cycle์ ์ด๋ฃธ
Complexity Analysis
pseudo code๋ฅผ ์ดํด๋ณด๋ฉด
mst = [] # edges of MST
for u in range(n + 1) :
make_set(u)
#sort by weight
edges.sort(lambda x: x[2])
for u, v in edges :
if find_set(u) != find_set(v) :
mst.append((u, v))
union(u, v)
Space Complexity
- Edges : O(|E|)
=> edge๋ง ์ ๋ ฅ์ผ๋ก ์ฃผ๋ฉด ๋๋ฏ๋ก
(edge๋ง ์ ๋ ฌ, ์ํํจ) - Disjoint sets : O(|V|)
=> ๊ฐ ๋ ธ๋๊ฐ ๋ถ๋ชจ ์ ๋ณด๋ฅผ ๊ฐ์ง๋ฏ๋ก ๋ ธ๋์ ๊ฐ์์ ๋์ผ - Total : O(|V| + |E|)
Time Complexity
- Sorting : O(|E|log|E|)
=> ์ฌ๊ธฐ์ E๋ ์ต๋ V^2 ์ด๋ฏ๋ก |E|log|V|^2 = 2|E|log|V| = O(|E|log|V|)๋ก ๋ณผ ์ ์์ - Disjoint sets : O(|E|log*|V|)
=> log*์ ์ฌ์ค์ ์์์ด๋ฏ๋ก Sorting์ด ์ฐ์ธํญ์ผ๋ก ์์ฉ - Total : O(|E|log|V|)
Prim's Algorithm
MST์ ๊ฐ์ฅ ๊ฐ๊น์ด ์ ์ ์ ๋ฐ๋ณตํ์ฌ ์ถ๊ฐํ๋ ๊ฒ์
์์๋
1. ์๋ฌด ์ ์ ํ๋๋ฅผ ์ ํํ์ฌ MST์ ์ถ๊ฐ
2. MST์ ์ง์ ์ฐ๊ฒฐ๋ ์ธ๋ถ์ ์ ์ ์ค ๊ฐ์ฅ ๊ฐ๊น์ด ์ ์ ์ MST์ ์ถ๊ฐ
3. ๋ชจ๋ ์ ์ ์ด MST์ ์ถ๊ฐ๋ ๋ ๊น์ง ๋ฐ๋ณต
์ด๋ป๊ฒ ํ๋ณด ๊ฐ์ ๋ค ์ค ๊ฐ์ฅ ์งง์ ์ ๋ฅผ ์ฐพ์ ์ ์์๊น?
min-heap์ ํ์ฉํ๋ฉด ๋จ
pseudo code๋ฅผ ์ดํด๋ณด๋ฉด
mst = []
Q = min_heap()
Q.enqueue((0, 0, None)) # ์์๋๋ก weight, node, MST์์ ๋์ ์ฐ๊ฒฐ๋ node
S = {}
while Q is not empty :
w, u, p = Q.dequeue()
if u in S : continue # ์ด๋ฏธ MST์ ๋ค์ด๊ฐ๋ค๋ ๋ป
S.add(u)
mst.append((p, u))
for v, w_uv in neighbors(u) :
if v not in S :
Q.enqueue((w_uv, v, u))
Complexity Analysis
Space Complexity
- ์ธ์ ๋ฆฌ์คํธ ๊ทธ๋ํ : O(|E| + |V|)
=> neighbors์์ ์ธ์ ๋ฆฌ์คํธ๋ฅผ ์ฐ๋๊ฒ ํจ์จ์ ์ด๊ธฐ ๋๋ฌธ์ ์ธ์ ๋ฆฌ์คํธ ์ฌ์ฉ - min-heap : O(|E|)
=> ๊ฐ์ ๋ค์ ๋ค ๋ฃ์ผ๋ฏ๋ก - S : O(|V|)
=> ์ต๋ ํฌ๊ธฐ๊ฐ ์ ์ ์ ๊ฐ์์ด๋ฏ๋ก - Total : O(|V| + |E|)
Time Complexity
- min-heap : O(|E|log|E|)
=> ์์์ ๋ค๋ฃฌ ๋ด์ฉ๊ณผ ๋์ผํ๊ฒ O(|E|log|V|)๋ก ๋ณผ ์ ์์
(min-heap์ ๊ฐ์ ๋ฃ์ ๋ ์ต๋ log|E|๋ฅผ edge์์ธ |E| ๋งํผ ๋ฐ๋ณต)
Correctness Analysis
Kruskal's, Prim's Algorithm์ ์ ๋น์ฑ?
์ ์ฒด ์ ์ ์งํฉ V๋ฅผ S, V - S๋ก ๋๋ด์ ๋ S์ V - S ์ฌ์ด๋ฅผ ์ฐ๊ฒฐํ๋ ๊ฐ์ฅ ์งง์ ๊ฐ์ ์ e๋ผ ํ๋ฉด, e๋ฅผ ํฌํจํ๋ MST๊ฐ ๋ฐ๋์ ์กด์ฌํจ
e๋ฅผ ํฌํจํ์ง ์๋ MST์ธ T๊ฐ ์กด์ฌํ๋ค๊ณ ๊ฐ์ ํด๋ณด์
e = (u, v) ์ผ ๋, MST์์ u์ v์ฌ์ด์ ๊ฒฝ๋ก P๋ ์ ์ผํจ
=> P์์ S์ V - S ์ฌ์ด๋ฅผ ์ง๋๋ ๊ฐ์ e'์ ์ ์ผ
(2๊ฐ ์์ผ๋ฉด cycle)
e'์ ์ง์ฐ๊ณ e๋ฅผ ์ถ๊ฐํ T'๋ ๋๋ค๋ฅธ Spanning Tree์ธ๋ฐ
1. w(e') > w(e) ์ธ ๊ฒฝ์ฐ T๋ MST๊ฐ ์๋ (๋ชจ์)
2. w(e') = w(e) ์ธ ๊ฒฝ์ฐ T'๋ e๋ฅผ ํฌํจํ MST
'๐ฅ Algorithm' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
L13 - Topological Sorting (0) | 2024.11.29 |
---|---|
L12 - Single Source Shortest Paths (0) | 2024.11.28 |
L10 - Disjoint Sets (0) | 2024.11.22 |
L09 - Greedy Algorithms (1) | 2024.11.03 |
L07 - Selection (4) | 2024.10.13 |