알고리즘

최단 경로 - 다익스트라 알고리즘

leeeehhjj 2022. 6. 27. 15:38

다익스트라 알고리즘

: 특정 노드에서 다른 노드로 가는 각각의 최단 경로를 구해주는 알고리즘(음의 간선이 없을 때 제대로 동작)

1. 출발 노드를 설정한다

2. 최단 거리 테이블을 초기화 한다

3. 방문하지 않은 노드 중 거리가 가장 짧은 노드를 선택한다

4. 해당 노드를 거쳐 다른 노드로 가는 비용을 계산해 최단 거리 테이블을 갱신한다

5. 3과 4번을 반복한다

 

 

-출발 노드는 1일 때

노드 번호 1 2 3 4 5 6
거리 0 무한 무한 무한 무한 무한

-1번 노드에서 갈 수 있는 노드는 2,3,4이므로 이 노드들의 최단 거리 테이블을 갱신

노드 번호 1 2 3 4 5 6
거리 0 2 5 1 무한 무한

-4번 노드가 가장 가까우므로 4번 노드를 거쳐 가는 거리 확인 -> 3번, 5번으로 가는 거리의 최단 거리 갱신

노드 번호 1 2 3 4 5 6
거리 0 2 1+3 1 1+1 무한

-2번과 5번 노드로 가는 거리가 가장 짧으므로 숫자가 작은 2번 노드로 가는 길을 선택 후 2번 노드를 거쳐 가는 거리 확인

-> 현재 거리보다 더 짧게 가는 방법 없으므로 갱신x

 

5번 노드를 거쳐가는 거리 확인

-> 3번과 6번으로 가는 최단 거리 갱신

노드 번호 1 2 3 4 5 6
거리 0 2 1+1+1 1 2 1+1+2

- 3번 노드를 선택한 뒤 테이블 갱신

- 6번 노드 선택 후 갱신

 

간단한 다익스트라 알고리즘(O(V^2)) - v는 노드 개수

: 방문하지 않은 노드 중 최단 거리가 가장 짧은 노드 선택위해 1차원 리스트의 모든 원소를 탐색

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

class Node {
    private int index;
    private int distance;

    public Node(int index, int distance) {
        this.index = index;
        this.distance = distance;
    }

    public int getIndex() {
        return this.index;
    }

    public int getDistance() {
        return distance;
    }
}
public class Main {
    static final int INF = (int)1e9;  //무한 의미하는 10억
    static int n,m,start;
    static ArrayList<ArrayList<Node>> graph = new ArrayList<ArrayList<Node>>();
    static boolean[] visited = new boolean[100001];
    static int[] table = new int[100001];

    // 방문하지 않은 노드 중에서, 가장 최단 거리가 짧은 노드의 번호를 반환
    public static int getSmallestNode() {
        int min = INF;
        int index = 0;
        for (int i = 1; i <= n; i++) {
            if (table[i] < min && !visited[i]) {
                min = table[i];
                index = i;
            }
        }
        return index;
    }

    static void dijkstra(int start) {
        table[start] = 0;
        visited[start] = true;
        for (int i = 0; i < graph.get(start).size(); i++) {
            table[graph.get(start).get(i).getIndex()] = graph.get(start).get(i).getDistance();
        }
        for (int i = 0; i < n-1; i++) {
            int now = getSmallestNode();
            visited[now] = true;
            for (int j = 0; j < graph.get(now).size(); j++) {
                int cost = table[now] + graph.get(now).get(j).getDistance();
                if (cost < table[graph.get(now).get(j).getIndex()])
                    table[graph.get(now).get(j).getIndex()] = cost;
            }
        }
    }
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        n= sc.nextInt();
        m = sc.nextInt();
        start = sc.nextInt();

        //그래프 초기화
        for (int i = 0; i <= n; i++) {
            graph.add(new ArrayList<Node>());
        }

        // 모든 간선 정보를 입력받기
        for (int i = 0; i < m; i++) {
            int a = sc.nextInt();
            int b = sc.nextInt();
            int c = sc.nextInt();
            // a번 노드에서 b번 노드로 가는 비용이 c라는 의미
            graph.get(a).add(new Node(b, c));
        }

        // 최단 거리 테이블을 모두 무한으로 초기화
        Arrays.fill(table, INF);

        // 다익스트라 알고리즘을 수행
        dijkstra(start);

        // 모든 노드로 가기 위한 최단 거리를 출력
        for (int i = 1; i <= n; i++) {
            // 도달할 수 없는 경우, 무한(INFINITY)이라고 출력
            if (table[i] == INF) {
                System.out.println("INFINITY");
            }
            // 도달할 수 있는 경우 거리를 출력
            else {
                System.out.println(table[i]);
            }
        }
    }
}

 

 

참고 

이것이 취업을 위한 코딩 테스트다 with 파이썬