dist[]
, s로부터 다른 정점으로의 최단 경로를 만드는 선행 정점들을 담는 배열 prev[]
dist[]
의 요소들을 모두 무한대로 초기화 한다. 단 출발점에 대한 값 dist[s]
는 0으로 초기화 한다.prev[]
의 요소들을 모두 정의되지 않은 값(undefined, null 등)으로 초기화한다.dist[]
가 최소값인 정점 u를 Q에서 제거한다. 위에서 초기화한 결과에 의해 첫 번째 u는 시작 정점 s가 된다.dist[]
와 prev[]
의 요소들이 변경된다.dist[]
와 prev[]
를 반환한다.정점의 개수 - 1
만큼 반복하는 루프를 만든다. 따라서 처음에는 간선 1개만을 사용하는 최단 경로가 계산되고 다음 반복에는 간선 2개, 3개, ... 이런식으로 반복되어 마지막에는 정점의 개수 - 1
만큼의 간선을 사용하는 경로가 계산된다.dist[u] + w < dist[v]
이면 dist[v] = dist[u] + w, prev[v] = u
로 변경한다.dist[u] + w < dist[v]
인 경우가 나오면 그래프에 음의 사이클이 있으며 해가 없다는 의미이므로 오류를 반환한다.dist[]
와 prev[]
를 반환한다.|V| x |V|
크기의 정방행렬(2차원 배열) dist
를 만들고 값은 모두 무한대로 초기화 한다.dist[u][v]
값을 간선 (u, v)의 가중치로 바꾼다.dist[v][v]
값을 0으로 바꾼다.정점의 개수 - 1
까지 똑같이 반복하는 삼중 반복문을 만든다. (k->i->j)j
루프에서 다음과 같이 dist
배열의 값을 바꾸는 작업을 수행한다.dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])
dist
배열을 반환한다.prev
배열을 추가하여 구현하면 된다.포드-풀커슨 알고리즘은 레스터 포드와 델버트 풀커슨이 개발한 그리디 기반 알고리즘으로 네트워크에서 최대 흐름을 구하는 가장 기초적인 알고리즘이다.
이 알고리즘은 단순하게 플로 값을 증가시킬 수 있는 모든 경우의 수를 탐색하는 방식으로 최대값을 찾는다.
관점에 따라 이 알고리즘은 알고리즘의 조건(유한성 등)을 충족하지 못하기 때문에 알고리즘이 아닌 포드-풀커슨 메서드(method)라고 부르기도 한다.
s에서 t까지 플로를 보내기 위한 경로를 증가 경로(augmenting path)라고 하며, 증가 경로 상의 간선은 네트워크 상의 간선의 방향과 반드시 일치하지는 않는다.
증가 경로의 간선이 네트워크의 간선과 방향이 같으면 순방향 간선(forward edge)라고 하며, 방향이 같지 않으면 역방향 간선(backward edge)이라고 한다.
순방향 간선에 대해 간선의 용량에서 실제 사용되는 플로를 뺀 값을 잔여 용량(residual capacity)이라고 한다.
역방향 간선의 잔여 용량은 순방향 간선의 플로와 같은 값이 된다.
순방향 간선의 잔여 용량은 해당 간선에 대해서 플로를 실제로 증가시킬 수 있는 값으로 사용되지만, 역방향 간선의 잔여 용량은 원래 간선에 부여된 플로를 줄일 수 있는 값으로 사용된다.
포드-풀커슨 알고리즘은 모든 경우의 수를 탐색하는 알고리즘이므로 역방향 간선에 대해서도 플로 값을 구해야한다.
이 알고리즘의 수행과정을 요약하면 증가 경로가 더 이상 존재하지 않을 때까지 반복적으로 증가 경로를 찾고, 이 증가 경로의 여유량만큼씩 플로 값을 증가시켜 최대 플로를 구하는 방법이라 할 수 있다.
수행과정을 구체적으로 설명하면 다음과 같다.
네트워크의 모든 용량이 정수인 경우 최대 흐름의 값은 증가 경로를 하나 찾을 때마다 최소 1씩 증가하므로 증가 경로는 항상 최대 흐름 값 이내로 찾게 된다. 하나의 증가 경로를 구하는 시간 복잡도는 이므로 시간 복잡도는 가 된다. 여기서 는 간선의 개수, 는 최대 흐름을 의미한다
포드-풀커슨 알고리즘에선 간선의 용량이 무리수인 경우 알고리즘의 종료가 보장되지 않는다. 또한 다음 그림과 같이 네트워크에서 간선의 용량 차이가 매우 큰 경우 수행시간이 비효율적이라는 문제가 있다.
다음의 네트워크 예시는 간단한 형태임에도 불구하고 경로를 2000번이나 탐색해야 최대 흐름을 구할 수 있다. 가운데에 위치한 1의 흐름에 대해 계산하는 것을 반복해야 하기 때문이다.
이러한 단점을 보완하기 위해 잭 에드먼즈와 리처드 카프에 의해 에드먼즈-카프 알고리즘(Edmonds–Karp algorithm)이 제시되었다.
에드먼즈-카프 알고리즘은 기본적으로 포드-풀커슨 알고리즘과 비슷하지만 증가 경로를 찾을 때 검색 순서가 정해진다는 점이 다르다.
에드먼즈-카프 알고리즘에선 먼저 BFS를 활용하여 s에서 t까지의 최단 경로를 구하고 이를 증가 경로로 사용한다.
이렇게 하면 간선의 용량과 상관없이 시간 복잡도는 이 된다.