Dijkstra, 최단경로를 탐색하는 알고리즘으로 동적계획법을 활용한다.
특정 노드에서 다른 모든 노드를 향하는 최단 경로를 구할수 있고, 음의간선이 존재하지 않을 경우 활용할 수 있는 알고리즘이다.
정렬을 사용하여 그리디 알고리즘이라고도 일컫는다.
기본적으로 동적계획법을 활용하기 때문에, 이전까지 구한 최단거리 정보를 그대로 활용하는 알고리즘이며 GPS, 인공위성 등에 활용하는 가장 대표적인 알고리즘이기도 하다.
다익스트라 알고리즘의 시작은 출발노드를 설정하는 것이다.
출발노드를 1이라 가정하자.
초기 상태에서의 graph 생성하기
[
[0 3 6 7],[3 0 1 INF],[6, 1, 0, 1],[7, INF, 1, 0]
]
출발노드는 1부터, 그 후 노드 설정은 가중치가 가장 작은 인덱스부터
먼저 1의 인접노드인 2, 3, 4에 대해 위와 같이 최초의 거리를 기재한다.
그 후 출발노드와 인접한 노드들 중 최단거리의 노드를 선택하고 인접노드의 가중치를 계산한다.
거쳐서가는 가중치를 위 배열에 업데이트한다.
현재 이동한 노드의 인접 노드 중 방문하지 않으면서 최소 가중치의 노드를 방문하고, 위 과정을 반복한다.
node = 6
INF = 100000000
#graph 구성하기
graph = [
[0, 2, 5, 1, INF, INF],
[2, 0, 3, 2, INF, INF],
[5, 3, 0, 3, 1, 5],
[1, 2, 3, 0, 1, INF],
[INF, INF, 1, 1, 0, 2],
[INF, INF, 5, INF, 2, 0]
]
#방문여부
visited = [False] * node
#거리
distance = [0] * node
#출발노드를 기준으로 해당 노드까지 최소비용이 구해진 후(배열생성)
#최소거리(비용)에 대한 노드를 반환(방문하지 않은 노드 중)
def getSmallIndex():
min = INF
index = 0
for i in range(node):
if distance[i] < min and visited[i] is not True:
min = distance[i]
index = i
return index
#다익스트라를 수행하는 함수
def dijkstra(start):
visited[start] = True
for i in range(node):
#graph에 적혀진 비용정보를 distance에 입력
#원래 알고있는 최소비용
distance[i] = graph[start][i]
#방문하지않는 노드 중 최소 비용이 발생하였을때(거쳐가는 경우)
#방문하지않는 노드의 우선노드는 distance 상에서 최소비용을 가지는 노드
for i in range(node-2):
#자기자신과 이전 기준점까지는 탐색완료(탐색대상이 node-2)
currentIndex = getSmallIndex()
visited[currentIndex] = True
for j in range(node):
if visited[j] is not True and distance[currentIndex]+graph[currentIndex][j] < distance[j]:
distance[j] = distance[currentIndex] + graph[currentIndex][j]
dijkstra(1)
print((distance))
node = 6
INF = 100000000
#graph 구성하기
graph = {
1: {2: 2, 3: 5, 4: 1},
2: {1: 2, 3: 3, 4: 2},
3: {1: 5, 2: 3, 4: 3, 5: 1, 6: 5},
4: {1: 1, 2: 2, 3: 3, 5: 1},
5: {3: 5, 4: 1, 6: 2},
6: {3: 5, 5: 2}
}
#distance
import heapq
#최소비용인 인접노드를 탐색하는 부분을 heap정렬을 이용해 구하는 경우
#시간복잡도를 기존 알고리즘 대비 개선시킬 수 있는 알고리즘
def dijkstra(start):
distance = {node: INF for node in graph}
distance[start] = 0
queue = []
#min heap
heapq.heappush(queue, [distance[start], start])
while queue:
currentDistance, currentIndex = heapq.heappop(queue)
#시작점이 정해진 상태임을 기억
#현재 선택된 노드에 대해
if distance[currentIndex] < currentDistance:
continue
#인접노드 방문 후 새로운 거리값 계산
for newIndex, newDistance in graph[currentIndex].items():
tempDistance = currentDistance + newDistance
if tempDistance < distance[newIndex]:
distance[newIndex] = tempDistance
heapq.heappush(queue, [tempDistance, newIndex])
return distance
print(dijkstra(1))
heap 구조를 이용할때 graph를 기존 2차원 행렬로 표현하고, 이 상태에서 그대로 익스트라 알고리즘을 구현할 수 있는 경우를 생각해보자.
python list에서 max/min 메소드
https://www.delftstack.com/ko/howto/python/get-index-of-min-and-max-value-from-list-in-python/
익스트라 알고리즘
https://codingcocoon.tistory.com/129
heapq
https://www.daleseo.com/python-heapq/
heapq를 이용한 익스트라 알고리즘
https://justkode.kr/algorithm/python-dijkstra
익스트라 알고리즘 과정
https://techblog-history-younghunjo1.tistory.com/247