가중치 그래프(Weighted Graph)에서 간선(Edge)의 가중치 합이 최소가 되도록 하는 경로를 찾는 것이 목적
최단 경로 문제 종류
1. 단일 출발 및 단일 도착(single-source and single-destination shortest path problem)최단 경로 문제
- 그래프 내의 특정 노드 u에서 출발, 또다른 특정 노드 v에 도착하는 가장 짧은 경로를 찾는 문제
2. 단일 출발(single-source shortest path problem) 최단 경로 문제
- 그래프 내의 특정 노드 u와 그래프 내 다른 모든 노드 각각의 가장 짧은 경로를 찾는 문제
3. 전체 쌍(all-pair)최단경로 : 그래프 내의 모든 노드 쌍(u, v)에 대한 최단 경로를 찾는 문제
최단 경로 알고리즘 - 다익스트라 알고리즘
다익스트라 알고리즘은 단일 출발에 해당 - 하나의 정점에서 다른 모든 정점 간의 각각 가장 짧은 거리를 구함
다익스트라 알고리즘 로직
- 첫 정점을 기준으로 연결되어 있는 정점들을 추가해 가며 최단 거리를 갱신하는 기법 - 다익스트라 알고리즘은 너비우선탐색(BFS)와 유사함 - 첫 정점부터 각 노드간의 거리를 저장하는 배열을 만든 후 첫 정점의 인접 노드 간의 거리부터 먼저 계산하면서 첫 정점부터 해당 노드간의 가장 짧은 거리를 해당 배열에 업데이트
- 우선순위 큐를 활용한 다익스트라 알고리즘 - 우선순위 큐는 MinHeap방식을 활용해서 현재 가장 짧은 거리를 가진 노드 정보를 먼저 꺼내게 됨
1) 첫 정점을 기준으로 배열을 선언하여 첫 정점에서 각 정점까지의 거리를 저장 - 초기에는 첫 정점의 거리는 0 나머지는 무한대로 저장함(inf 라고 표현함) - 우선순위 큐에 (첫 정점, 거리 0)만 먼저 넣음
2) 우선순위 큐에서 노드를 꺼냄 - 처음에는 첫 정점만 저장되어 있으므로 첫 정점이 꺼내짐 - 첫 정점에 인접한 노드를 각각에 대해 첫 정점에서 각 노드로 가는 거리와 현재 배열에 저장되어 있는 첫 정점에서 각 정점까지의 거리를 비교함 - 배열에 저장되어 있는 거리보다 첫 정점에서 해당 노드로 가는 거리가 더 짧을 경우 배열에 해당 노드의 거리를 업데이트함 - 배열에 해당 노드의 거리가 업데이트 된 경우 우선순위 큐에 넣음 - 결과적으로 너비 우선 탐색 방식과 유사하게 첫 정점에 인접한 노드들을 순차적으로 방문하게 됨 - 만약 배열에 기록된 현재까지 발견된 가장 짧은 거리보다 더 긴 거리를 가진 노드의 경우에는 해당 노드와 인접한 노드간의 거리 계산을 하지 않음
3) 2번의 과정을 우선순위 큐에 꺼낼 노드가 없을 때까지 반복한다.
다익스트라 알고리즘(우선순위 큐 활용) 예
1단계 : 초기화
- 첫 정점을 기준으로 배열을 선언하여 첫 정점에서 각 정점까지의 거리 저장 - 초기에는 첫 정점의 거리는 0 나머지는 무한대로 저장(inf라고 표현) - 우선순위 큐에(첫 정점, 거리0)만 먼저 넣음
2단계 : 우선선위 큐에서 추출한 (A, 0) [노드, 첫 노드와의 거리]를 기반으로 인접한 노드와의 거리 계산
- 우선순위 큐에서 노드를 꺼냄 - 처음에는 첫 정점만 저장되어 있으므로 첫 정점이 꺼내짐 - 첫 정점에 인접한 노드를 각각에 대해 첫 정점에서 각 노드로 가는 거리와 현재 배열에 저장되어 있는 첫 정점에서 각 정점까지의 거리를 비교함 - 배열에 저장되어 있는 거리보다 첫 정점에서 해당 노드로 가는 거리가 더 짧을 경우 배열에 해당 노드의 거리를 업데이트함 - 배열에 해당 노드의 거리가 업데이트된 경우 우선순위 큐에 넣음 - 결과적으로 너비 우선 탐색 방식과 유사하게 첫 정점에 인접한 노드들을 순차적으로 방문하게 됨 - 만약 배열에 기록된 현재까지 발견된 가장 짧은 거리보다 더 긴 거리를 가진 노드의 경우에는 해당 노드와 인접한 노드간의 거리 계산을 하지 않음
==>1단계에서 첫 정점이외에 모두 inf였으므로 첫 정점에 인접한 노드들은 모두 우선순위 큐에 들어가고 첫 정점과 인접한 노드간의 거리가 배열에 업데이트됨
3단계 : 우선순위 큐에서(C, 1) [노드, 첫 노드와의 거리]를 기반으로 인접한 노드와의 거리 계산
- 우선순위 큐가 MinHeap(최소합) 방식이므로 2단계에서 넣어진 (C, 1), (D, 2), (B, 8) 중 (C, 1)이 먼저 추출(pop) - 2단계 표에서 보듯이 1단계까지의 A - B 최단 거리는 8임 - A - C까지의 거리는 1, C에 인접한 B, D에서 C - B는 5, 즉 A - C - B는 1 + 5 = 6 이므로 A - B 최단거리 8보다 더 작은 거리를 발견하여 배열에 업데이트 B, 6 값이 우선순위 큐에 넣어짐 - C - D의 거리는 2, 즉 A - C - D는 1 + 2 = 3이므로 A - D의 현재 최단 거리인 2보다 긴 거리, D의 거리는 업데이트 되지 않음
4단계 : 우선순위 큐에서(D, 2) [노드, 첫 노드와의 거리]를 기반으로 인접한 노드와의 거리 계산
- 지금까지 접근하지 못했던 E와 F의 거리가 계산됨 - A - D까지의 거리인 2에 D - E가 3이므로 이를 더해서 E, 5 - A - D까지의 거리인 2에 D - F가 5이므로 이를 더해서 F, 7
5단계 : 우선순위 큐에서(E, 50) [노드, 첫 노드와의 거리]를 기반으로 인접한 노드와의 거리 계산
- A - E거리가 5인 상태에서 E에 인접한 F를 가는 거리는 1, 즉 A - E - F는 5 + 1 = 6 현재 배열에 A - F 최단거리가 7로 기록되어 있으므로 F, 6으로 업데이트 - 우선순위 큐에 F, 6 추가
6단계 : 우선순위 큐에서 (B, 6), (F, 6)를 순차적으로 추출해 각 노드 기바으로 인접한 노드와의 거리 계산
- 예제의 방향 그래프에서 B노드는 다른 노드로 가는 루트가 없음 - F 노드는 A노드로 가는 루트가 있으나 현재 A - A가 0인 반면에 A - F - A는 6 + 5 = 11 즉 더 긴 거리이므로 업데이트되지 않음
6단계 : 우선순위 큐에서 (F, 7), (B, 8)를 순차적으로 추출해 각 노드 기반으로 인접한 노드와의 거리 계산
- A - F로 가는 하나의 루트의 거리가 7인 상황이나 배열에서 이미 A - F로 가는 현재의 최단거리가 6인 루트의 값이 있는 상황이므로 더 긴거리인 F, 7루트 기반 인접 노드까지의 거리는 계산할 필요가 없음 - B, 8도 현재 A - B거리가 6이므로 인접 노드 거리 계산이 필요 없음