최단 경로

Updated:

강의 사이트
  • http://www.kocw.net/home/search/kemView.do?kemId=1148815

Dijkstra의 알고리즘

1. Dijkstra의 알고리즘

  • bellman ford 알고리즘의 단점을 해결하기 위해 나온 알고리즘
  • 불필요한 relax를 줄이기 위함

1.1 예시 그림

  • 처음 시작 하는 노드를 S라고 하자

  • S를 제외한 위의 그림에서 왼쪽 상단 노드를 A 기준으로 시계방향으로 A, B, C, D라고 하겠다.

  • 각 노드들의 값들을 null처리

  • 맨처음 S의 값은 0이다. 그리고 S를 TRUE(그림에서는 빨간색 칠하기) 처리 한다.

  • S에서 시작하는 모든 엣지들에 대해서 연결된 노드들의 값을 relax한다.

  • 그러면 A는 10이 되고 D는 5가 된다.

  • 이때 TRUE가 된 S를 제외하고 나머지 노드들에 대해서 가장 작은 값인 D 노드를 기준으로 간다.

  • D를 TRUE로 바꾸고 D에 연결된 노드들에 대해서 relax한다.

  • 그러면 A는 8, B는 14, C는 7이 된다.

  • 다시 TRUE를 제외한 A, B, C 중에서 가장 작은 값인 C를 기준으로 한다.

  • C를 TRUE로 바꾸고 C에 연결된 노드들에 대해서 relax한다.

  • 그러면 C는 13이 된다.

  • 다시 TRUE를 제외한 A, B중 가장 작은 값인 A를 기준으로 한다.

  • A를 TRUE로 바꾸고 relax한다.

  • 그러면 B는 9가 된다.

1.2 Dijkstra 알고리즘 정리

  • 음수 가중치가 없다고 가정
  • s로부터의 최단경로의 길이를 이미 알아낸 노드들의 집합 S를 유지. 맨 처음엔 S={공집합}.
  • Loop invariant:
    • u∉S인 각 노드 u에 대해서 d(u)는 이미 S에 속한 노드들만 거쳐서 s로부터 u까지 가는 최단경로의 길이

  • 솔직히 이건 이해가 존나 안감. 알고리즘은 이해가 가는데 정의하는게 이해가 안가네 시발…

  • u가 S에 속해졌으면 {u, v}에 대해서 relaxt해야 한다.
  • 그러면 loop invariant가 유지된다.

1.3 Pseudo Code

  • 5번 째 줄 S는 S가 있는게 아니라 공집합으로 되어야 한다.
  • 1번 째 줄. 초기화 for 반복
  • 집합 S가 총 노드의 개수보다 작으면 반복. S란 relax가 끝난 노드들의 집합
  • 8번 째 줄. 집합 S에 속하지 않는 노드들에서 가장 작은 노드를 찾음
  • 10번 째 줄. 그 노드에 대해서 relax
  • 따라서 전체 노드들을 한번씩 도는 n-1번 반복 * 각 노드에 대해서 relax N번
  • 시간복잡도는 O(N^2)이다.

1.4 시간복잡도

  • Prim의 알고리즘과 동일함
  • d 최솟값을 찾을 때 우선순위 큐를 사용하지 않고 단순하게 구현할 경우 O(n^2)
  • 이진힙을 우선순위 큐로 사용할 경우 O(nlog2n + mlog2n)
  • Fibonacci Heap을 사용하면 O(nlog2n+m)에 구현가능