57 lines
2.4 KiB
Markdown
57 lines
2.4 KiB
Markdown
deck:: Logseq/coding tip
|
|
|
|
- ## 1. 개념(Concept)
|
|
- 최소 스패닝 트리(MST)를 구하는 알고리즘.
|
|
- “임의의 시작 정점에서 출발하여, 현재 트리에 연결된 간선 중 가장 싼 것을 추가하며 확장한다.” 라는 전략을 사용
|
|
- 이를 위해 {{cloze 우선순위 큐}}가 사용됨.
|
|
id:: 69511108-8006-4c0a-9452-d248f8c58ca5
|
|
- [[다익스트라 알고리즘 (Dijkstra Algorithm)]]과 비슷함.
|
|
- ## 2. 동작 원리 (Algorithm Flow)
|
|
- 1) 임의의 정점(vertex)을 하나 선택해서 트리에 포함시킨다.
|
|
- 2) 현재 트리에 포함된 정점들과 포함되지 않은 정점들을 연결하는 간선 중, 가중치가 가장 작은 간선을 찾는다.
|
|
- 3) 해당 간선과 연결된 새로운 정점을 트리에 추가한다.
|
|
- 4) 위의 과정을 반복하여 최종적으로 모든 정점이 트리에 포함될 때 까지 반복한다.
|
|
- ## 3. 코드(python)
|
|
- 입력이 V(정점의 갯수), 인접리스트(graph)와 시작노드(start_node)를 매개변수로 하여
|
|
id:: 695111c8-84a0-4220-a7f4-b9f654761cec
|
|
프림 알고리즘으로 최소 스패닝 트리를 구현하고,
|
|
이때 총 가중치를 반환하는 함수를 구현하면?
|
|
```python
|
|
# graph: (노드: [(비용, 인접노드)]...)
|
|
# ex) graph = [[],[(3,2),(4,5)],[(1,3)]...]
|
|
```
|
|
#card
|
|
- ```python
|
|
import heapq
|
|
|
|
# graph: 인접 리스트 (노드: [(비용, 인접노드), ...])
|
|
def prim(start_node, v, graph):
|
|
visited = [False] * (v + 1)
|
|
min_heap = [(0, start_node)] # (비용, 정점)
|
|
total_cost = 0
|
|
count = 0
|
|
|
|
while min_heap:
|
|
cost, node = heapq.heappop(min_heap)
|
|
|
|
if visited[node]:
|
|
continue
|
|
|
|
visited[node] = True
|
|
total_cost += cost
|
|
count += 1
|
|
|
|
if count == v: # 모든 정점 방문 완료
|
|
break
|
|
|
|
# 인접 정점 중 방문 안 한 곳을 큐에 넣기
|
|
for next_cost, next_node in graph[node]:
|
|
if not visited[next_node]:
|
|
heapq.heappush(min_heap, (next_cost, next_node))
|
|
|
|
return total_cost
|
|
```
|
|
- ## 4. 시간복잡도
|
|
- 우선순위큐 연산이 주된 연산이므로 우선순위 큐 연산 속도에 영향을 많이 받음.
|
|
- 시간복잡도는 {{cloze $O(E\log V)$}}
|
|
id:: 69511407-a9bc-40f2-b57c-f76060ea75f1 |