하나의 정점으로 부터 모든 다른 정점까지의 최단 경로를 찾는 최단 경로 알고리즘인 다익스트라 알고리즘에 대해 공부해보고자 한다.
최단 경로 알고리즘의 아이디어
1. 출발 노드와 도착 노드 설정
2. 알고 있는 모든 거리 값 부여
3. 출발 노드부터 시작해 방문하지 않은 인접 노드 방문, 거리 계산하고 현재 알고있는 거리보다 짧으면 값 갱신
4. 현재 노드에 인접한 모든 미방문 노드까지 거리 계산했으면, 현재 노드를 미방문 집합에서 제거 5. 도착 노드가 미방문 노드 집합에서 벗어나면, 알고리즘 종료
사전 배경 지식
heapq 모듈 자료구조
heapq 모듈은 이진 트리 기반의 최소 힙 자료구조를 제공한다.
최소 힙을 사용하면 원소들이 항상 정렬된 상태로 추가되고 삭제되며, 최소 힙에서 가장 작은 값은 언제나 인덱스 0, 즉, 이진 트리의 루트에 위치한다.
내부적으로 최소 힙 내의 모든 원소는 항상 자식 원소들 (2k+1, 2k+2)보다 크기가 작거나 같도록 원소가 추가되고 삭제된다.
(min heap 자료구조 예시)
1 ---> root
/ \
3 5
/ \ /
4 8 7
# 모듈 임포트
from heapq import heappush, heappop
# 최소 힙 생성
# 파이썬에서는 heapq 모듈을 통해서 원소를 추가하거나 삭제한 리스트가 그냥 최소 힙이다.
heap = []
# 힙에 원소 추가
from heapq import heappush
heappush(heap, 4)
heappush(heap, 1)
heappush(heap, 7)
heappush(heap, 3)
print(heap)
>>> [1, 3, 7, 4]
# 힙에서 원소 삭제
from heapq import heqppop
print(heappop(heap))
print(heap)
>>> 1
>>> [3, 4, 7]
# 기본 리스트를 힙으로 변환
from heapq import heapify
heap = [4, 1, 7, 3, 8, 5]
heapify(heap)
print(heap)
>>> [1, 3, 5, 4, 8, 7]
코드 구현
import heapq
def dijkstra(graph, start):
distances = {node: float('inf') for node in graph}
distances[start] = 0 # 시작 값은 0
queue = []
heapq.heappush(queue, [distances[start], start]) # 시작 노드부터 탐색 시작
while queue:
current_distance, current_destination = heapq.heappop(queue) # 탐색 할 노드, 거리를 가져온다.
if distances[current_destination] < current_distance: # 기존에 있는 거리보다 길다면, 넘어감
continue
for new_destination, new_distance in graph[current_destination].items():
distance = current_distance + new_distance # 해당 노드를 거쳐 갈 때 거리
if distance < distances[new_destination]: # 알고 있는 거리보다 작으면 갱신
distances[new_destination] = distance
heapq.heappush(queue, [distance, new_destination]) # 다음 인접 거리를 계산 하기 위해 큐에 삽입
return distances
in
print(dijkstra(graph, 'A'))
out
{'A': 0, 'B': 6, 'C': 1, 'D': 2, 'E': 5, 'F': 6}
'알고리즘 > 코딩테스트공부' 카테고리의 다른 글
[Programmers] SQL 문제들 (0) | 2023.10.17 |
---|---|
기타 필기 모음 (0) | 2023.02.09 |
[프로그래머스 SQL]GROUP BY_카테고리 별 도서 판매량 집계하기 (0) | 2023.02.07 |
[프로그래머스 SQL]GROUP BY_대여 횟수가 많은 자동차들의 월별 대여 횟수 구하기 (0) | 2023.02.07 |
[프로그래머스 SQL]String, Date_자동차 대여 기록 별 대여 금액 구하기 (0) | 2023.02.06 |