다익스트라 알고리즘(dijkstra's algorithm)
두 정점 사이간 최소 거리를 구하는 알고리즘의 일종.
간단히 이론적인 것을 설명하자면..
N개의 정점을 모두 돌아다니는데 N과 연결된 정점을 찾아 거리를 계산해주는 것이다.
Start(시작점), End(도착점)이 존재하는데 각 점과 Start의 거리의 초기 값은 inf(무한대)이고
정점을 찾아다니며 최소 거리를 갱신하는 것이다.
-실제로는 inf 값을 넣지않고 큰 값, 혹은 일정한 값을 넣는다.(음수도 가능?할지도)
예를 들어
정점 5개가 존재하고 각 정점을 0~4로 이름을 매긴다.
각 정점 간 관계는 아래와 같다.
또한 각 정점 간 거리는 아래와 같다.
Start가 0, End가 3이라 놓는다면
0은 1과 2밖에 연결이 안 되어 있으니, 탐색은 0->1, 0->2로 시작된다.
이때 0->1, 0->2는 0으로부터 각 정점간 최단 거리이므로 3, 2가 최단거리가 될 것이다.
또한 1은 2와 3이랑 연결이 되어있다.
이때 탐색 루트는 0->1->2 , 0->1->3이 되는 것인데
0->1->2 루트의 거리는 5이고 이전에 0->2는 2이므로 최단거리 갱신이 안된다.
0->1->3 루트는 첫 탐색이므로 7이 최단거리가 된다.
0->2->3, 0->2->4 탐색을 해보자.
0->2->3 루트는 이미 0->1->3으로 0->3간 최단 거리가 설정되있다.
하지만 0->2->3 루트는 거리가 3이므로 기존에 7보다 작으므로 최단거리 갱신이 된다.
0->3까지 최단거리는 이로써 3이 된다.
원래는 C++, C는 우선순위 큐를 이용하여 작성해야만 변수가 사라진다.
지금은 C# 코드만 ..
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | //Rextester.Program.Main is the entry point for your code. Don't change it. //Compiler version 4.0.30319.17929 for Microsoft (R) .NET Framework 4.5 using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; namespace Rextester { public class Program { //빈공간이라는 것을 의미하는 변수 private static int BigSize = 50000; //n개의 정점간 관계를 나타내는 이차원 배열 private static int[,] map=new int[,]{{BigSize,3,2,BigSize,BigSize}, {BigSize,BigSize,2,4,BigSize}, {BigSize,BigSize,BigSize,1,3}, {BigSize,BigSize,BigSize,BigSize,4}, {BigSize,BigSize,BigSize,BigSize,BigSize}}; //각 정점과 start와의 최소 거리 private static int[] dist=new int[]{BigSize,BigSize,BigSize,BigSize,BigSize}; //트래커, 이전에 어떤 정점을 거쳐온건지 체크 private static int[] prev=new int[]{-1,-1,-1,-1,-1}; public static void Main(string[] args) { serch(0,4); } private static void serch(int start, int end){ if(start>5 || end>5) // 일단은 정점이 5개므로 초과로 입력되는 것을 막는다. Console.WriteLine("error"); dist[start]=0; // start initialization // 시작 정점은 최소거리가 0이므로 초기화를 시켜준다. for(int i=0; i<5; i++){ for(int j=0; j<5; j++){ if(map[i,j]!=BigSize){ // 정점 간 간선이 존재한다면 if(dist[j]==BigSize){ // 그리고 첫번째 방문이라면 dist[j]=dist[i]+map[i,j]; // 바로 최소거리가 된다. prev[j]=i; //그리고 이전 정점을 넣어준다. } else if(dist[j] > dist[i]+map[i,j]){ // 첫 방문이 아니고 이전에 설정된 최소거리가 지금 최소거리보다 크다면 dist[j]=dist[i]+map[i,j]; prev[j]=i; } } } } Console.WriteLine("length:"+dist[end]); trck(start,end); } private static int trck(int start,int tmp){ // 최소거리가 되는 정점을 찾는다. if(tmp==start){ Console.Write(start); }else{ Console.Write(tmp+"->"); return trck(start,prev[tmp]); } return 0; } } } | cs |
'Algorithm' 카테고리의 다른 글
자료구조. 순회(전위 중위 후위) (0) | 2018.03.19 |
---|---|
자료구조 트리. Tree (0) | 2018.02.21 |
자료구조. 스택(stack)과 큐(queue) (0) | 2018.02.20 |
자료구조. Linked List (0) | 2018.02.18 |
Horner's role (0) | 2017.03.15 |