Kruskal & Prim Algorithm을 Python으로 구현해보고 해당 알고리즘에 대해 분석해보자
Kruskal Algorithm
그래프 이론에서 사용되는 그래프 최소 신장 트리 (Minimum Spanning Tree,MST)를 찾는 알고리즘 중 하나
그래프의 모든 정점을 연결하면서 가중치가 작은 간선들로 이루어진 트리를 구성
- 간선의 가중치 기반 선택
- 사이클 방지
- 그리디 알고리즘
그래프의 모든 간선을 가중치 순으로 정렬
정렬된 간선 목록을 처음부터 순회하면서 사이클을 형성하지 않는 간선 선택
선택한 간선을 트리에 추가
> 해당 알고리즘을 통해 MST를 리턴
G = {
'vertices' : [],
'edges': []
}
parent = dict()
rank = dict()
def initial(node):
parent[node] = node
rank[node] = 0
def find(node):
if parent[node] != node:
parent[node] = find(parent[node])
return parent[node]
def union(node_a, node_b):
root_a = find(node_a)
root_b = find(node_b)
if rank[root_a]>rank[root_b]:
parent[root_b] = root_a
else:
parent[root_a] = root_b
if rank[root_a] == rank[root_b]:
rank[root_b]+=1
def KruskalMST(G):
mst = []
for node in G['vertices']:
initial(node)
e = G['edges']
e.sort(key=lambda x : x[2])
for edge in e:
node_a, node_b, weight = edge
if find(node_a) != find(node_b):
union(node_a,node_b)
mst.append(edge)
return mst
v, e = map(int,input().split())
for i in range(v):
G['vertices'].append(i)
for i in range(e):
u, v, weight = map(int, input().split())
G['edges'].append((u,v,weight))
KruskalMST(G)
크루스칼 알고리즘의 시간 복잡도는 (E log E) - 간선의 수 E에 따라 변화함
Prim Algorithm
그래프 이론에서 사용되는 그래프 최소 신장 트리 (Minimum Spanning Tree,MST)를 찾는 알고리즘 중 하나
시작 정점을 통해 해당 정점에 연결된 간선의 가중치가 작은 것을 선택해가는 알고리즘
- 시작 정점 선택
- 그리디 알고리즘
- 사이클 방지
import heapq
v, e = map(int,input().split()) # 노드 수, 간선 수
visited = [0] * (v+1) # 노드의 방문 정보 초기화
graph = [[] for _ in range(v+1)] # 그래프 초기화
# 무방향 그래프 생성
for i in range(e): # 간성 정보 입력 받기
u, v, weight = map(int,input().split())
graph[u].append([weight, u, v])
graph[v].append([weight, v, u])
# 프림 알고리즘
def PrimMST(start):
visited[start] = 1 # 방문 갱신
candidate = graph[start] # 인접 간선 추출
heapq.heapify(candidate) # 우선순위 큐 생성
mst = [] # mst
while candidate:
weight, u, v = heapq.heappop(candidate) # 가중치가 가장 적은 간선 추출
if visited[v] == 0: # 방문하지 않았다면
visited[v] = 1 # 방문 갱신
mst.append((u,v,weight)) # mst 삽입
for edge in graph[v]: # 다음 인접 간선 탐색
if visited[edge[2]] == 0: # 방문한 노드가 아니라면, (순환 방지)
heapq.heappush(candidate, edge) # 우선순위 큐에 edge 삽입
return mst
start_node = int(input())
print(PrimMST(start_node))
일반적인 프림 알고리즘은 O(E log V)의 시간 복잡도를 가집니다
대규모 그래프에서 효율적으로 동작할 수 있습니다
최소 신장 트리를 만드는 kruskal과 prim 알고리즘에 대해 알아보았습니다
'Computer Science > Data Structure & Algorithm' 카테고리의 다른 글
[알고리즘] 모든 쌍에 대한 최단 경로 구하기 (78) | 2023.10.31 |
---|---|
[알고리즘] Merge Sort(합병 정렬) (292) | 2023.10.15 |
[알고리즘] 벨만-포드 알고리즘 vs 존슨 알고리즘 (21) | 2023.09.21 |
존슨 알고리즘 (1) | 2023.08.17 |
다이나믹 프로그래밍 (2) - P/NP,플로이드-워셜 알고리즘 (0) | 2023.07.06 |