티스토리 뷰

1. 개요


[그림 1] 가중치배열 ( Weight Array )



다익스트라 알고리즘 ( Dijstra Algorithm ) 은 가중치가 부여된 그래프에서 두 정점 사이의 최단 경로를 찾을 때 사용하는 알고리즘이다. 이 알고리즘에서는 어떤 시작점 S가 주어졌을 때, 그 정점에서 시작하여 다른 모든 정점으로 가는 최단 경로를 찾을 수 있기 때문에 결과적으로 어떤 최종 목적지 T로 가는 최단 경로를 구할 수 있다.


다익스트라 알고리즘에서 가장 중요하고 핵심이 되는 "가중치 배열 (Weight Array)"은 시작점 S를 기준으로 각 정점의 최단거리를 가리키는 배열이다. 






2. 다익스트라 알고리즘 (Dijstra Algorithm) 코드 구현 및 설명





우선 메인함수에서 가중치배열과 부모정점저장 배열을 선언하고 이것들을 다익스트라 함수 전달인자로 넘겨준다.


변수로는 1) minIndex , 2) target , 3) check배열 , 4) dist , 5) tmpWeight 다섯가지가 있다. 1번 변수 "minIndex"의 역할은 정점들 중 가장 작은 가중치를 저장하는 정점의 인덱스를 저장할 변수이다. 2번 변수 "target"은 가중치 계산시 대상이 되는 정점의 인덱스를 저장한다. 그리고 3번 변수 체크배열은 정점이 검사한곳인지 안 한곳인지 판별해주는 아주 중요한 배열이다. 4번 "dist"변수는 우회가중치를 저장하는 변수이고 마지막 5번 tmpWeight는 minIndex를 찾기위해 비교되는 임시 변수이다.


예시로 기준 정점을 "A"라고 하자. A번방 인덱스를 기준으로 전달인자로 받은 가중치배열에 기준 정점으로부터 각 정점의 가중치를 넣어주고, 부모정점배열의 모든 방을 기준정점의 인덱스로 초기화, 마지막으로 체크배열도 모두 0으로 (방문X)로 초기화시켜준다.


이제 기준 정점 "A"를 기준으로 가중치배열을 하나씩 계산하자.


Check배열에 기준정점을 체크시키고 큰 For문 하나를 모든 정점에 대해 반복하도록 설정해준다. 일단 minIndex를 0으로 초기화시키고 tmpWeight도 초기화 해준다.

다음 과정은 가장 가중치가 작은 인덱스를 찾는 과정이다. 이중 for문을 통해 정점갯수만큼 반복시키게 두고 조건을 체크되지 않은 정점 중 가장 작은 정점의 인덱스를  찾는 조건으로 설정한다.


[그림 1]의 경우 가장 작은 정점의 인덱스는 "B"가 될 것이고 "B"를 체크배열에 방문처리해준다.


다음은 가중치배열을 타겟정점이 포함된 가중치로 계산하는 작업을 한다. 정점 "A"부터 시작하여 끝 정점까지 업데이트 해줄것이다. 

[그림 1]의 경우로 A,B정점은 체크되었으니 건너뛰고 C정점도 간선연결이 되어있지않으므로 건너뛴다. (코드에서는 이 판별조건이 주석처리되었다. C도 계산을 할 테지만 가중치가 무한대라 갱신이 되지않을것) 

B정점을 기준으로 한 인접정점들끼리의 가중치를 계산한다. 그림에서는 E정점과 F정점이 있는데 E정점을 계산하면 " dist = 2 ( 시작점 "A"에서 현재 minIndex 정점 "B" 가중치 ) + 5 ( "B"에서 "E" 의 가중치 ) => 7 " 이다.

이 dist값이 직접경로 가중치 weightArray[E] 보다 작으면 갱신 한다. 당연히 시작점 "A"에서 "E" 가중치는 무한대이므로 우회로가 더 빠르다 따라서 갱신한다. dist값으로 갱신하고 부모정점배열도 바꿔준다.


이 과정을 정점 갯수만큼 반복하면 가중치배열이 그때그때 바뀔것이고 마지막에 갱신되는 배열이 최종 최단거리를 나타내게 된다.




3. 시작정점기준 각 정점으로의 최단거리 출력



시작정점을 기준으로 하여 각 정점으로의 최단거리를 출력해주는 함수이다.

가중치배열을 만들때 같이 만들었던 부모정점배열을 이용한다. 



4. main()




'프로그래밍 > 알고리즘' 카테고리의 다른 글

깊이 우선 탐색 (DFS)  (0) 2016.08.26
탐욕법 ( Greedy )  (0) 2016.08.26
백 트래킹 ( Backtracking )  (0) 2016.08.24
분할 정복 ( Divide and conquer Algorithm )  (1) 2016.08.24
재귀 호출 ( Recursive call )  (0) 2016.08.24
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함