2024. 2. 5. 15:13ใCS - Roadmap.sh/3. Common Algorithms
CS - 3. Common Algorithms - 3.6 Greedy Algorithms - 3.6.2 Kruskal's algorithm
Kruskal’s algorithm
๐กKruskal’s algorithm is a greedy algorithm that finds a minimum spanning tree for a connected weighted graph. It is a minimum spanning tree algorithm that takes a graph as input and finds the subset of the edges of that graph which form a tree that includes every vertex, where the total weight of all the edges in the tree is minimized. If the graph is not connected, then it finds a minimum spanning forest (a minimum spanning tree for each connected component).
ํฌ๋ฃจ์ค์นผ์ ์๊ณ ๋ฆฌ์ฆ์ ์ฐ๊ฒฐ๋ ๊ฐ์ค ๊ทธ๋ํ์ ๋ํ ์ต์ ์คํจ๋ ํธ๋ฆฌ๋ฅผ ์ฐพ๋ ํ์์ค๋ฌ์ด ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค. ์ต์ ์คํจ๋ ํธ๋ฆฌ ์๊ณ ๋ฆฌ์ฆ์ ๊ทธ๋ํ๋ฅผ ์ ๋ ฅ์ผ๋ก ๋ฐ์ ๋ชจ๋ ์ ์ ์ ํฌํจํ๋ ํธ๋ฆฌ๋ฅผ ํ์ฑํ๋ ๊ทธ๋ํ์ ๊ฐ์ฅ์๋ฆฌ ๋ถ๋ถ ์งํฉ์ ์ฐพ๋ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก, ํธ๋ฆฌ์ ์๋ ๋ชจ๋ ๊ฐ์ฅ์๋ฆฌ์ ์ด ๊ฐ์ค์น๊ฐ ์ต์ํ๋๋ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค. ๊ทธ๋ํ๊ฐ ์ฐ๊ฒฐ๋์ง ์์ ๊ฒฝ์ฐ ์ต์ ์คํจ๋ ํฌ๋ฆฌ์คํธ(์ฐ๊ฒฐ๋ ๊ฐ ์ปดํฌ๋ํธ์ ๋ํ ์ต์ ์คํจ๋ ํธ๋ฆฌ)๋ฅผ ์ฐพ์ต๋๋ค.
ํฌ๋ฃจ์ค์นผ ์๊ณ ๋ฆฌ์ฆ(Kruskal's algorithm)์
https://parkpakrsu.tistory.com/329
์์ ํ๋ฒ ๋ค๋ค์ต๋๋ค.
์ฐ๊ฒฐ๋ ๊ฐ์ค๊ทธ๋ํ์์ ์ต์ ์คํจ๋ ํธ๋ฆฌ(์ต์ ์ ์ฅํธ๋ฆฌ, MST, Minimum Spanning Tree)๋ฅผ ์ฐพ๋ ํ์์๊ณ ๋ฆฌ์ฆ์ ๋๋ค.
ํ๋ฒ๋ ๋ค๋ฃจ๊ณ ๋์ด๊ฐ์๋ฉด,
MST๋ ๊ทธ๋ํ ๋ด์ ๋ชจ๋ ๋ ธ๋๋ฅผ ํฌํจํ๋ ํธ๋ฆฌ์ ๋๋ค.
์ฆ, ๊ทธ๋ํ์ ์ต์ ์ฐ๊ฒฐ ๋ถ๋ถ ๊ทธ๋ํ์ ๋๋ค.
๋ํ, ์ฌ์ดํด์ด ํฌํจ๋์ด์๋ ์๋ฉ๋๋ค.
์ฃผ๋ก ํต์ ๋คํธ์ํฌ, ๋๋ก ๋คํธ์ํฌ๋ฑ ์์ ์ฌ์ฉํฉ๋๋ค.
์๊ณ ๋ฆฌ์ฆ ์๋ฆฌ
๊ฐ์ ์ ๊ฐ์ค์น์ ์ค๋ฆ์ฐจ์ ์ผ๋ก ์ ๋ ฌํฉ๋๋ค.
๊ฐ์ฅ ๊ฐ์ค์น๊ฐ๋ฎ์ ๊ฐ์ ๋ถํฐ ์ฐจ๋ก๋๋ก ์ ํํ๋, ์ฌ์ดํด์ ํ์ฑํ๋ ๊ฐ์ ์ ์ ์ธ
์ด๋ฅผ ์ํด ์ ๋์จ-ํ์ธ๋ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํฉ๋๋ค.
(์ ๋์จ-ํ์ธ๋ Union-Find ๋ ๊ทธ๋ํ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ๋ ๋ ธ๋๊ฐ ๊ฐ์ ๊ทธ๋ํ์ ์ํ๋์ง ํ๋ณํ๋ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค.)
In Python
class Graph:
def __init__(self, vertices):
self.V = vertices
self.graph = []
# ๊ทธ๋ํ๋ฅผ ์ด๊ธฐํํ๋ค.
# vertices๋ ๊ทธ๋ํ์ ์ ์ ์ ์
# self.graph ๊ทธ๋ํ์ ๊ฐ์ ์ ์ ์ฅํ๋ ๋ฆฌ์คํธ
def add_edge(self, u, v, w):
self.graph.append([u, v, w])
# u, v ๋ ๊ฐ์ ์ ์ ๋ ์ ์
# w๋ ๊ฐ์ ์ ๊ฐ์ค์น
def find(self, parent, i):
if parent[i] == i:
return i
return self.find(parent, parent[i])
#fine(self, parent, i)์ด ๋ฉ์๋์์ ๋ถ๋ชจ๋ฐฐ์ด์ i ๋ฒ์งธ ์ ์ ์ ๋ฃจํฌ๋ฅผ ์ฐพ๋๋ค.
def union(self, parent, rank, x, y):
xroot = self.find(parent, x)
yroot = self.find(parent, y)
if rank[xroot] < rank[yroot]:
parent[xroot] = yroot
elif rank[xroot] > rank[yroot]:
parent[yroot] = xroot
else :
parent[yroot] = xroot
rank[xroot] += 1
# union ๋ฉ์๋๋ ๋ ๊ฐ์ ์๋ก ๋ค๋ฅธ ์งํฉ์ ํฉ์น๋ค.
# x, y๋ ๊ฐ๊ฐ ์งํฉ์ ๋ํํ๋ ๋ฃจํธ ์ ์
# ์ด ๋ฉ์๋์์ ๋ ์งํฉ์ rank๋ฅผ ๋น๊ตํด ๋ญํฌ๊ฐ ๋ ๋ฎ์ ์งํฉ์ ๋ญํฌ๊ฐ ๋ ๋์ ์งํฉ์ ํฉ์น๋ค.
# ๋ญํฌ๊ฐ ๊ฐ์ ๊ฒฝ์ฐ์๋ ํ ์งํฉ์ ๋ค๋ฅธ ์งํฉ์ ํฉ์น๊ณ ๋ญํฌ๋ฅผ 1 ์ฆ๊ฐ์ํจ๋ค.
def kruskal(self):
result = []
i = 0
e = 0
self.graph = sorted(self.graph, key=lambda item: item[2])
parent = []
rank = []
for node in range(self.V):
parent.append(node)
rank.append(0)
while e < self.V - 1:
u, v, w = self.graph[i]
i += 1
x = self.find(parent, u)
y = self.find(parent, v)
if x != y:
e += 1
result.append([u, v, w])
self.union(parent, rank, x, y)
return result
ํฌ๋ฃจ์ค์นผ ์๊ณ ๋ฆฌ์ฆ์ ์๊ฐ ๋ณต์ก๋๋ O(E log E) ์ ๋๋ค.
E ๋ edge๋ก ๊ทธ๋ํ ๊ฐ์ ์ ๊ฐ์์ ๋๋ค.
์ O(E log E)์ผ๊น์?
ํฌ๋ฃจ์ค์นผ ์๊ณ ๋ฆฌ์ฆ์ ์์ํ ๋ ๋ชจ๋ ๊ฐ์ ์ ๊ฐ์ค์น์ ๋ฐ๋ผ ์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ ฌํด์ผ ํฉ๋๋ค.
์ด ์ ๋ ฌ ๊ณผ์ ์ด ๊ฐ์ฅ ์๊ฐ์ด ๋ง์ด ๊ฑธ๋ฆฌ๋ ๋ถ๋ถ์ ๋๋ค. ์ด๋ถ๋ถ์ด ๋ฐ๋ก O(E log E) ์๊ฐ ์ด ์์๋ฉ๋๋ค.
๊ทธ ๋ค์ ๋จ๊ณ์์ ๊ฐ ๊ฐ์ ์ ์ํํ๋ฉฐ ์ฌ์ดํด์ ํ์ฑํ๋์ง ํ์ธํฉ๋๋ค.
์ด๋ ๊ฐ ๊ฐ์ ๋ง๋ค 'Find', 'Union' ์ฐ์ฐ์ ์ํํ๋ ๊ฒ์ ํฌํจํ๋๋ฐ, ์ด ๋ ์ฐ์ฐ์ ๊ฑฐ์ ์์ ์๊ฐ์ ์ํ๋ฉ๋๋ค.
๋ฐ๋ผ์ O(E) ์๊ฐ์ด ์์๋ฉ๋๋ค.
์ด O(E log E)์ด๋ฏ๋ก ๊ฐ์ ์ด ๋ง์ ๋ฐ์ง ๊ทธ๋ํ์์๋ ํจ์จ์ ์ผ๋ก ์๋ํฉ๋๋ค.
๋ฌธ์
์ต์ ์คํจ๋ ํธ๋ฆฌ - ๋ฐฑ์ค 1197
๋คํธ์ํฌ ์ฐ๊ฒฐ - ๋ฐฑ์ค 1922
'CS - Roadmap.sh > 3. Common Algorithms' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
3.6.4 Primโs Algorithm (ํ๋ฆผ ์๊ณ ๋ฆฌ์ฆ) (0) | 2024.02.07 |
---|---|
3.6.3 Ford Fulkerson algorithm(ํด๋ํ์ปค์จ ์๊ณ ๋ฆฌ์ฆ) (1) | 2024.02.06 |
3.6 Greedy Algorithms - 3.6.1 Huffman Coding (0) | 2024.02.03 |
3.6 Greedy Algorithms (0) | 2024.02.02 |
3.5 Graph - 3.5.5 A* Algorithm (0) | 2024.01.31 |