Skip to content

Latest commit

 

History

History
190 lines (152 loc) · 7.25 KB

어정윤.md

File metadata and controls

190 lines (152 loc) · 7.25 KB

[Algorithm] Dijkstra

Dijkstra

다익스트라(Dijkstra) 알고리즘은 그래프 상에서 시작 정점부터 나머지 각 정점까지의 최단거리를 계산하는 알고리즘이다. 다익스트라 알고리즘은 그래프의 어느 간선의 가중치라도 음수가 있으면 안된다. (가중치에 음수가 포함될 수 있으면 벨만-포드 알고리즘)

다익스트라 알고리즘을 구현하기 위해서는 다음과 같은 과정을 반복하면 된다.

  1. 방문하지 않은 정점 중 가장 가중치 값이 작은 정점을 방문한다. (처음엔 시작 정점 방문)
  2. 해당 정점을 거쳐서 갈 수 있는 정점의 거리가 이전에 기록한 값보다 작다면 그 거리를 갱신한다.

Dijkstra 구현

public class Dijkstra {

    public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        int v = Integer.parseInt(bufferedReader.readLine());

        int[][] adjMatrix = new int[v][v];
        int start = 0;

        StringTokenizer stringTokenizer = null;
        for (int i = 0; i < v; i++) {
            stringTokenizer = new StringTokenizer(bufferedReader.readLine());
            for (int j = 0; j < v; j++) {
                adjMatrix[i][j] = Integer.parseInt(stringTokenizer.nextToken());
            }
        }

        int[] distance = new int[v];    // 출발지에서 자신으로 오는 최소비용
        boolean[] visited = new boolean[v]; // 최소비용 확정여부

        Arrays.fill(distance, Integer.MAX_VALUE);
        distance[start] = 0;    // 시작점 0으로

        for (int i = 0; i < v; i++) {
            // step 01. 최소비용이 확정되지 않은 정점 중 최소비용의 정점 선택
            int min = Integer.MAX_VALUE;
            int current = 0;
            for (int j = 0; j < v; j++) {
                if (!visited[j] && min > distance[j]) {
                    min = distance[j];
                    current = j;
                }
            }
            visited[current] = true;

            // step 02. 선택된 정점을 경유지로 하여 아직 최소비용이 확정되지 않은 다른 정점의 최소비용을 고려
            for (int j = 0; j < v; j++) {
                if (!visited[j] && adjMatrix[current][j] != 0 && distance[j] > distance[current]+adjMatrix[current][j]) {
                    distance[j] = distance[current] + adjMatrix[current][j];
                }
            }
        }
        System.out.println(Arrays.toString(distance));
    }
}

Dijkstra 구현 with 우선순위큐

public class DijkstraWithPQ {

    static class Vertex implements Comparable<Vertex> {

        int no; // 정점 번호
        int minDistance;    // 출발지에서 자신으로의 최소비용

        public Vertex(int no, int minDistance) {
            this.no = no;
            this.minDistance = minDistance;
        }

        @Override
        public int compareTo(Vertex o) {
            return this.minDistance - o.minDistance;
        }
    }

    public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        int v = Integer.parseInt(bufferedReader.readLine());

        int[][] adjMatrix = new int[v][v];
        int start = 0;

        StringTokenizer stringTokenizer = null;
        for (int i = 0; i < v; i++) {
            stringTokenizer = new StringTokenizer(bufferedReader.readLine());
            for (int j = 0; j < v; j++) {
                adjMatrix[i][j] = Integer.parseInt(stringTokenizer.nextToken());
            }
        }

        int[] distance = new int[v];    // 출발지에서 자신으로 오는 최소비용
        boolean[] visited = new boolean[v]; // 최소비용 확정여부
        PriorityQueue<Vertex> priorityQueue = new PriorityQueue<>();

        Arrays.fill(distance, Integer.MAX_VALUE);
        distance[start] = 0;    // 시작점 0으로
        priorityQueue.offer(new Vertex(start, distance[start]));

        for (int i = 0; i < v; i++) {
            // step 01. 최소비용이 확정되지 않은 정점 중 최소비용의 정점 선택
            Vertex current = priorityQueue.poll();
            if (visited[current.no]) {
                continue;
            }
            visited[current.no] = true;

            // step 02. 선택된 정점을 경유지로 하여 아직 최소비용이 확정되지 않은 다른 정점의 최소비용을 고려
            for (int j = 0; j < v; j++) {
                if (!visited[j] && adjMatrix[current.no][j] != 0 && distance[j] > distance[current.no]+adjMatrix[current.no][j]) {
                    distance[j] = distance[current.no] + adjMatrix[current.no][j];
                    priorityQueue.offer(new Vertex(j, distance[j]));
                }
            }
        }
        System.out.println(Arrays.toString(distance));
    }
}

Dijkstra 구현 with 우선순위큐

public class DijkstraWithPQ {

    static class Vertex implements Comparable<Vertex> {

        int no; // 정점 번호
        int minDistance;    // 출발지에서 자신으로의 최소비용

        public Vertex(int no, int minDistance) {
            this.no = no;
            this.minDistance = minDistance;
        }

        @Override
        public int compareTo(Vertex o) {
            return this.minDistance - o.minDistance;
        }
    }

    public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        int v = Integer.parseInt(bufferedReader.readLine());

        int[][] adjMatrix = new int[v][v];
        int start = 0;

        StringTokenizer stringTokenizer = null;
        for (int i = 0; i < v; i++) {
            stringTokenizer = new StringTokenizer(bufferedReader.readLine());
            for (int j = 0; j < v; j++) {
                adjMatrix[i][j] = Integer.parseInt(stringTokenizer.nextToken());
            }
        }

        int[] distance = new int[v];    // 출발지에서 자신으로 오는 최소비용
        boolean[] visited = new boolean[v]; // 최소비용 확정여부
        PriorityQueue<Vertex> priorityQueue = new PriorityQueue<>();

        Arrays.fill(distance, Integer.MAX_VALUE);
        distance[start] = 0;    // 시작점 0으로
        priorityQueue.offer(new Vertex(start, distance[start]));

        for (int i = 0; i < v; i++) {
            // step 01. 최소비용이 확정되지 않은 정점 중 최소비용의 정점 선택
            Vertex current = priorityQueue.poll();
            if (visited[current.no]) {
                continue;
            }
            visited[current.no] = true;

            // step 02. 선택된 정점을 경유지로 하여 아직 최소비용이 확정되지 않은 다른 정점의 최소비용을 고려
            for (int j = 0; j < v; j++) {
                if (!visited[j] && adjMatrix[current.no][j] != 0 && distance[j] > distance[current.no]+adjMatrix[current.no][j]) {
                    distance[j] = distance[current.no] + adjMatrix[current.no][j];
                    priorityQueue.offer(new Vertex(j, distance[j]));
                }
            }
        }
        System.out.println(Arrays.toString(distance));
    }
}