Given an undirected weighted graph, a minimum spanning tree (MST) is a subgraph that connects all the vertices with the lowest possible sum of its edge weights.
๋ฐฉํฅ์ฑ์ด ์๊ณ ๊ฐ์ค์น๊ฐ ์๋ ๊ทธ๋ํ์์, ๊ฐ์ฅ ์ต์ํ์ ๊ฐ์ค์น๋ก ๋ชจ๋ ์ ์ ์ ์ฐ๊ฒฐํ ์ ์๋ subgraph๋ฅผ ์๋ฏธ.
Given a weighted graph, the shortest path (or geodesic path) between two vertices is a path with the lowest possible sum of edge weights.
๋ฐฉํฅ์ฑ์ ๋ฌด๊ด. ๊ฐ์ค์น๊ฐ ์๋ ๊ทธ๋ํ์์, ๋ ์ ์ ์ฌ์ด๋ฅผ ์๋ ๊ฐ์ฅ ์ ์ ๊ฐ์ค์น์ ๊ฒฝ๋ก๋ฅผ ์๋ฏธ.
์์ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด, Shortest path๋ ๊ทธ๋ํ์ ๋ชจ๋ ์ ์ ์ ํฌํจํ์ง ์์ ์๋ ์๋ค.
์ธ ๊ฐ์ง ์ ๋์ ์ฐจ์ด์ ์ผ๋ก ์์ฝํ ์ ์๋ค.
- Dijkstraโs algorithm finds the shortest path, but Primโs algorithm finds the MST.
Dijkstra๋ ์ต๋จ๊ฒฝ๋ก๋ฅผ, Prim์ ์ต์ ์ ์ฅ ํธ๋ฆฌ๋ฅผ ์ฐพ์์ค๋ค.
์ด๋ ํ ์ชฝ์ด ๋ค๋ฅธ ํ ์ชฝ์ ๋ณด์ฅํด ์ค ์ ์๋ค.- Dijkstraโs algorithm can work on both directed and undirected graphs, but Primโs algorithm only works on undirected graphs.
Prim์ ๋ฌด๋ฐฉํฅ ๊ทธ๋ํ์์๋ง ๋์ํ๋ค. Dijkstra๋ ์๊ด์๋ค.- Primโs algorithm can handle negative edge weights, but Dijkstraโs algorithm may fail to accurately compute distances if at least one negative edge weight exists.
Prim์ ์์ ๊ฐ์ค์น๋ฅผ ๊ฐ์ง ๊ฐ์ ์์๋ ์ ๋์ํ๋ค. Dijkstra๋ ์ด์ํ ๊ฒฐ๊ณผ๊ฐ ๋์ฌ ์๋ ์๋ค.
๋ค์ ๊ทธ๋ฆผ์ ๋ณด์. Dijkstra ์๊ณ ๋ฆฌ์ฆ์ ์ค๋ช
ํ๋ ๊ทธ๋ฆผ์ด๋ค.
์ง๊ธ Y(์๋ฃ๋ ์ ์ ์งํฉ)์ ์ ์ E ๊น์ง ์ถ๊ฐ๋ ์ํฉ. ๊ทธ ์ดํ์ B ์ ์ ์ ๋ํ distance์ ๊ฐฑ์ ์ ํ๊ณ ์ ํ๋ค.
์ด ์ฐจ์ด์ ๊ทผ๋ณธ์ ์์ธ์ prim์ ๊ทธ์ ์คํจ๋ ํธ๋ฆฌ๋ฅผ ์ต์ํ์ ๊ฑฐ๋ฆฌ ๋งํผ์ฉ๋ง ํ์ฅํ๋ ค๊ณ ํ๋ ๊ฒ์ด๊ณ ,
dijkstra๋ ์ด๋ ํ ์ถ๋ฐ์ (source)์ผ๋ก๋ถํฐ ๊ฐ ์ ์ ์ ๋ํ ์ต์ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ๋ ค๊ณ ํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
์ฐธ๊ณ ๋ก ์์๋ ๊ฒ์, Prim ์ด๋ Dijkstra๋ heap์ ํตํด ์ต์๊ฐ์ ์ป๊ณ ์ ํ ๋๋
heap์ ์ด์ distance์ ๋ํ ์ ๋ณด๋ค์ด ์ฃฝ์ง ์๊ณ ๋จ์์๋ค๋ ์ ์ ์กฐ์ฌํด์ผ ํ๋ค๋ ๊ฒ.
๋ฐฐ์ด๋ก distance ์ ๋ณด๋ฅผ ์ ์ฅํ๊ณ ๊ฐฑ์ ํ๋ค๋ฉด ์ด์ distance๋ค์ด ์๋ก์ด distance๋ก ๋์ฒด๋๊ธฐ ๋๋ฌธ์ ์ด์๋จ์ง ๋ชปํ์ง๋ง, ํ์ ์ต์๊ฐ๋ง ๋ฝ์์ค๋ ์๋ฆฌ๋ผ์ ์ด์ ์ ๋ณด๊ฐ ๋จ์์์ ์ ์๋ค.
์์ ๊ทธ๋ฆผ์์๋ B๋ฅผ Y์ ๋ฃ๊ณ ๋์(Prim)/์ต์๊ฑฐ๋ฆฌ๊ฐ ํ์ ๋๊ณ ๋์(Dijk.),
A์ B๋ฅผ ์ฐ๊ฒฐํ ๊ฐ์ค์น 7์ ๊ฐ์ ์ด heap์ ๊ณ์ ๋จ์์๊ฒ ๋๋ค.
๋ฐ๋ผ์ ์๋์ ์ฝ๋์ ๊ฐ์ด heappop์ ํด์ค ๋ ์กฐ๊ฑด์ ์ฃผ์ด์ผ ํ๋ค.
# Dijkstra
#
# distance ๋ฐฐ์ด์ ํญ์ distance์ ๋ํ ์ต์ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
# heap์ ๋ฐ๋ก ์ฐ๋ ์ด์ ๋ distance ๋ฐฐ์ด์ ์ ํํ์ํด ์ต์๊ฐ์ ์ฐพ๋ ๋ฒ๊ฑฐ๋ฌ์์ ๋๊ธฐ ์ํด.
# ๊ทธ๋์ distance_heap์ distance ๋ฐฐ์ด์ ์ต์ ์ ๋ณด๋ฅผ ๊ฐ์ง๋ฉด์๋, ์ด์ ๋จ๊ณ์ distance์ ๋ณด๋ ๋จ์ ์์ ์ ์๋ค.
# ๊ทธ๋์ a์์ ์ต์ ์ ์ ๋ณด์ธ์ง ํ์ธ์ ํด์ค๋ค. distance๋ ์๊ฐํด๋ณด๋ฉด ์ค์ด๋ค๋ฉด ์ค์ด๋ค์์ง ๋์ง ์๋๋ค. (ํญ์ ์ต์๊ฐ์ผ๋ก ๊ฐฑ์ ํ๋ ค๊ณ ํจ.)
# ๋ฐ๋ผ์ distance_heap์์ ๊บผ๋ธ v์ ๋ํ dist์ ๋ณด๊ฐ, distance๋ฐฐ์ด์ ํด๋น ๊ฐ๋ณด๋ค 'ํฌ๋ค๋ฉด' ์ด๋ฏธ ์ด์ ๋จ๊ณ์ ์ ๋ณด์ธ (visited๋) ๊ฒ์ด๋ค.
# ๊ทธ๋์ continue๋ฅผ ํตํด heap์ ๋ค์ ์ต์๊ฐ์ผ๋ก ๋์ด๊ฐ๋ค.
while distance_heap:
dist, v = heappop(distance_heap)
if distance[v] < dist: # (a) visited check.
continue
# visited check๋ฅผ ํต๊ณผํ ์ ๋ณด์ v๋ ์ต์ ์ distance์ ๋ณด(Y ์์ ๋ค๋ฅธ ์ ์ ์ ๊ฑฐ๋ฆฌ)์์ ์ต์๊ฐ์ ๊ฐ์ง ์ ์ ์ด๋ค.
# ์ด์ v๋ Y์ ๋ค์ด์จ ๊ฒ์ด๋ค.
...
# Prim
while distance:
if (e := heappop(distance))[1] not in Y: # ์ด์ distance์ ๋ณด๋ค์ด heap์ ๊ณ์ ๋จ์์๊ธฐ ๋๋ฌธ์
# Y์งํฉ์ ํฅํ์ง ์๋ ์ฃ์ง๊ฐ ๋์ฌ ๋ ๊น์ง pop ํ๋ค.
# ๋ฐฐ์ด์ ์ด๋ค๋ฉด ๋ฐฐ์ด์ ๋ฐฐ์ด ๊ฐ ์์ฒด๋ฅผ ๊ฐฑ์ ํด์ฃผ๊ธฐ ๋๋ฌธ์ ์ด์ distance์ ๋ณด๊ฐ ๋จ์ ์ ์์ ๊ฒ.
Y.add(e[1]) # vertex
cost += e[0] # weight
next = e
break
...
์์ฐ