플로이드-워셜 알고리즘 (Floyd-Warshall algorithm)

벨만-포드 알고리즘과 다익스트라 알고리즘과 달리 모든 최단 경로를 구하는 알고리즘 (All pairs shortest path algorithm) (물론 두 알고리즘도 모든 정점에대해 수행하면 모든 최단 경로를 구할 수 있다.)

특징

  • 음의 가중치 허용

  • optimal substructure 개념 이용

  • 배열을 이용하여 구현

  • 밀집그래프에서 모든 edge간 경로 구할때 적합

Pesudo Code

 let dist be a |V| × |V| array of minimum distances initialized to ∞
 let p be a |V| × |V| array of previous node initialized to null
 for each edge (u,v)
    dist[u][v] ← w(u,v)  // edge (u,v)의 가중치
    next[u][v] ← u      // 연결된 edge는 시작값으로 초기화

 for each vertex v
    dist[v][v] ← 0      //사이클을 허용하지 않으니 자기자신은 0

 for i from 1 to |V|
    for j from 1 to |V|
       for k from 1 to |V|
          if (dist[i][j] > dist[i][k] + dist[k][j])
             dist[i][j] ← dist[i][k] + dist[k][j]
             next[i][j] ← next[k][j]

구현 방법

  1. 그래프 edge가 주어졌을때, edge들의 정보를 이용하여 각 edge간 거리 정보를 저장할 distance 2차원 행렬과 경로를 구하기 위해 이전 노드를 저장할 previous 2차원 행렬생성한다.

  2. distance 행렬은 Infinity로 previous 행렬은 NIL(-1)로 초기화한다.

  3. 그래프 G의 edge들의 가중치의 정보를 이용해 distance행렬을 초기화하고 자기의 거리는 0으로 초기화

  4. 3중 반복문을 이용하여, 현재까지 계산된 i - j까지의 경로 값보다 사이에 k를 경유하는 경로 값이 더 작다면 값을 바꿔준다.

시간복잡도

매번 모든 노드들의 조합에 대해서 현재까지의 최단 경로를 구하고 총 |V-1|번 반복하기 때문에 O(|V|^3)의 시간복잡도를 갖는다.

i-j까지의 경로 중 k를 경유하는 값이 더작다면 값을 교환하는 방식으로 k는 V-1번 이 올 수 있으며 목적지 노드인 j도 V-1번, i도 V-1번으로 총 O(|V|^3)의 시간을 갖는다.

구현 코드

아래 코드는 사이클이없는 방향의 그래프이고, 양의 가중치를 무작위로 생성한 그래프이다.

소스코드 c++ ( 접기 / 펼치기 )

Last updated