프로그래밍 공방

다익스트라 알고리즘 : Dijkstra Algorithm 본문

개발/알고리즘

다익스트라 알고리즘 : Dijkstra Algorithm

hyosupsong 2021. 3. 7. 23:58

다익스트라 알고리즘 : Dijkstra Algorithm

그래프에서 특정 꼭짓점에서 다른 모든 꼭짓점 간의 최단 경로를 찾는 알고리즘

시간 복잡도

1. 우선순위 큐를 사용하지 않는 경우 : O(V^2)

2. 우선순위 큐를 사용하는 경우 : O(ElogV)

코드

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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;
 
public class Dijkstra {
 
    // 정점의 개수
    public static int V = 9;
    
    // 최소 거리를 갖는 점
    public static int getMinVertex(int[] dist, boolean[] visit) {
        int index = 0;
        int minDist = Integer.MAX_VALUE;
        for(int i=0; i<dist.length; i++) {
            if(!visit[i] && minDist>dist[i]) {
                minDist = dist[i];
                index = i;
            }
        }
        return index;
    }
    
    // 그래프로 이차원 배열로 나타냈을 때의 다익스트라
    public static int[] dijkstra(int[][] graph, int source) {
        int[] dist = new int[V];
        boolean[] visit = new boolean[V];
        
        for(int i=0; i<V; i++) {
            dist[i] = Integer.MAX_VALUE;
            visit[i] = false;
        }
        dist[source] = 0;
        
        for(int i=0; i<V; i++) {
            int u = getMinVertex(dist, visit);
            visit[u] = true;
            
            for(int j=0; j<V; j++) {
                if(graph[u][j]!=0 && !visit[j] && dist[j]>dist[u]+graph[u][j]) {
                    dist[j] = dist[u]+graph[u][j];
                }
            }
        }
        return dist;
    }
    
    // 연결리스트와 우선순위 큐를 사용한 다익스트라
    public static int[] dijkstraWithPQ(List<int[]>[] adj, int source) {
        int[] dist = new int[V];
        for(int i=0; i<dist.length; i++) dist[i] = Integer.MAX_VALUE;
        PriorityQueue<int[]> pq = new PriorityQueue<int[]>(new Comparator<int[]>() {
            @Override
            public int compare(int[] arg0, int[] arg1) {
                return Integer.compare(arg0[1], arg1[1]);
            }
        });
        
        // {다음 정점, 다음 정점까지의 거리}
        pq.add(new int[] {source, 0});
        dist[source] = 0;
        while(!pq.isEmpty()) {
            int[] cur = pq.poll();
            
            if(dist[cur[0]]<cur[1]) continue;
            
            for(int i=0; i<adj[cur[0]].size(); i++) {
                int[] next = adj[cur[0]].get(i);
                if(dist[next[0]]>cur[1]+next[1]) {
                    dist[next[0]]=cur[1]+next[1];
                    pq.add(new int[] {next[0], cur[1]+next[1]});
                }
            }
        }
        
        
        return dist;
    }
    
    public static void main(String[] args) {
        List<int[]>[] adj = new List[V];
        int[][] graph = new int[][] {
            { 040000080 },
            { 4080000110 }, 
            { 080704002 }, 
            { 0070914000 }, 
            { 0009010000 }, 
            { 00414100200 }, 
            { 000002016 }, 
            { 8110000107 }, 
            { 002000670 }            
        };
        for(int i=0; i<graph.length; i++) {
            adj[i] = new ArrayList<int[]>();
            for(int j=0; j<graph[i].length; j++) {
                if(i!=&& graph[i][j]!=0)
                    adj[i].add(new int[] {j, graph[i][j]});
            }
        }
        int[] dist = dijkstra(graph, 0);
        System.out.println(Arrays.toString(dist));
        dist = dijkstraWithPQ(adj, 0);
        System.out.println(Arrays.toString(dist));
    }
}
cs