다익스트라(Dijkstra)
- 가중치 그래프에 대해 최단거리 문제를 해결하기 위한 알고리즘
- 변 경감(edge relaxaxtion) 연산을 바탕으로 한다.
- 그래프의 가중치가 음수가 아니라고 가정한다.
- Extract-Min(Q) 함수를 단순한 선형 탐색으로 구현하면 O(n²)의 복잡도를 가진다.
- 이진 힙 또는 피보나치 힙을 통해 구현하면 O(m+nlogn) 시간까지 개선할 수 있다.
1. 동작 원리
- 각 꼭짓점 v에 대해 시작점(s)에서 끝점까지의 최단 거리 d[v]를 갱신하며 수행한다.
(1) 시작점(s)의 거리를 0으로 하고, 다른 모든 꼭짓점들의 거리는 INF(무한)으로 한다.
(2) Q에 나머지 모든 꼭짓점들을 배정한다.
(3) Q가 비어있으면 수행을 끝낸다.(= 모든 꼭짓점을 방문했다.)
(4) Q에서 꼭짓점 중 최단 거리에 있는 꼭짓점을 꺼낸다.
(5) 꺼내온 꼭짓점을 기준으로, 인접한 점들의 최단거리를 갱신한다.
(6) (2-5) 과정을 반복한다.
[ Fig. 1] 다익스트라 동작원리 - 출저 : Introduction to algorithms 3/E |
Fig. 1을 살펴보면, 회색 꼭짓점은 현재 스택에서 꺼내어져, 인접 꼭짓점들의 거리를 계산하기 위한
기준이된다. 검은색 꼭짓점은 이미 방문이 끝난 지점을 의미한다.
2. 함수 설명
dijkstra() : 다익스트라 알고리즘의 몸통 부분으로, 동작원리 (2) 와 (3)의 기능을 수행한다.
extract_min() : 최단거리에 있는 꼭짓점을 구하는 기능을 수행한다. 기능 (4)에 해당한다.
relax() : 변 경감 연산을 바탕으로 최단거리를 갱신한다. 기능 (5)에 해당한다.
3. 함수 구현
#include <stdio.h> #define UNADJACENCY 0 void malloc_arry( int, int); struct queue{ int **w; // variable for memorizing weights between edges. /* int main( void) scanf("%d%d%d", &nov, &startv, &endv); scanf("%d", &noe); malloc_arry( nov, noe); for( i = 0 ; i < noe ; i ++) w[v-1][n-1] = weight; dijkstra( nov, startv-1); printf("%d에서 %d까지의 최단 거리는 %d입니다.\n경로는", startv, endv, d[endv-1]); print_path( endv-1); printf("%d 입니다.\n", endv); release_arry( nov); return 0; /* // allocate the memory as much as the number of edges. // allocate the memory for the queue. // allocate the memory as much as the row of the array // we have to init elements in the array with 0(zero). /* // Firstly. release the memory that related to the row // release the memory that related to directions. // Lastly, release the memory that related to the column /* /* void print_path( int v) print_path( pre[v]); printf(" %d >", pre[v]+1); /* // search for the vertical in the queue. // remove the element from the queue. /* /* // set the distance of other edges with INF. // it is necessary to do back tracking d[s] = 0; // set the distance of starting point. // insert vertexs into the queue except starting edge. while( !queue_empty()) for( i = 0 ; i < nov ; i ++) |
4. 실행 결과
Fig.1의 그림을 인접 배열로 표현한 결과, 아래와 같은 결과가 출력되는
것을 확인할 수 있다.
'프로그래밍 언어들 > 알고리즘' 카테고리의 다른 글
벨먼-포드 알고리즘(Bellman-Ford algorithm) (1) | 2016.10.18 |
---|---|
A* (A star) 알고리즘 (1) | 2016.10.16 |
너비우선탐색(BFS : Breadth First Search) (0) | 2016.10.13 |
깊이우선탐색(DFS : Depth First Search) (0) | 2016.10.13 |
그래프의 행렬 표현법(Representations of graphs) (0) | 2016.10.13 |