[Algo] 유량 네트워크 (2) 포드-풀커슨 방법 분석

0

Algorithm

목록 보기
13/13
post-thumbnail

Introduction to Algorithm 4th edition을 번역 및 정리한 글입니다.

1. 포드-풀커슨 방법 분석

이전 글에서 다뤘던 최대 유량 최소 컷 정리와 포드-풀커슨 방법의 pseudo-code를 다시 보자.

최대 유량 최소 컷 정리

f가 소스 s, 싱크 t를 가지는 유량 네트워크 G=(V,E)의 흐름이라 하자. 다음의 세 조건은 서로 동치다.
1. ff가 GG의 최대 유량이다.
2. 잔여 네트워크에 GfG_f​ 증가 경로가 존재하지 않는다.
3. GG의 어떤 컷 (S,T)(S,T)에 대해, f=c(S,T)|f∣=c(S,T) 다.

포드-풀커슨 방법의 pseudo-code

FORD-FULKERSON(G, s, t)
for each edge (u,v)G.E(u, v) \in G.E
    (u,v).f=0(u, v).f = 0
while there exists a path pp from ss to tt in the residual network GfG_f
    cf(p)=min{cf(u,v):(u,v) is in p}c_f(p) = min\{c_f(u, v) : (u, v) \text{ is in } p\}
    for each edge (u,v)(u, v) in pp
      if (u,v)G.E(u, v) \in G.E
        (u,v).f=(u,v).f+cf(p)(u,v).f = (u, v).f + c_f(p)
      else (v,u).f=(v.u).fcf(p)(v, u).f = (v.u).f - c_f(p)
return ff

이 pseudo-code는 최대 유량 최소 컷 정리에 따라, while문이 종료하는 경우, 다시 말해 더 이상 ss에서 tt로의 증가 경로를 찾을 수 없는 경우 최대 유량을 반환한다.

문제는 어떤 경우 while 문이 끝나지 않는 경우가 발생할 수 있다는 것, 즉 계속해서 증가 경로를 찾는 데 성공하는 경우가 있을 수 있다는 점, 게다가 이때 흘려보내는 유량이 구하고자 하는 최대 유량에 수렴조차 하지 않는 경우가 있을 수 있다는 점이다.

2.무리수 용량 간선이 포함된 경우의 무한 루프 사례 (링크)

다음을 만족하는 수열 {an}\{a_n\}을 생각해보자.

an+2=anan+1, an=rn(n0)a_{n+ 2} = a_n - a_{n + 1},\ a_n = r^n(n \geq 0)

r=(51)/2r = (\sqrt{5} - 1)/2는 위를 만족하니 이 값을 쓰도록 하자.

이제 아래와 같은 네트워크를 보자.

이때 e1,e2,e3e_1, e_2, e_3의 용량은 각각 a0=1,a1=r,1a_0 = 1, a_1 = r, 1이고, 나머지 간선의 용량은 모두 어떤 큰 정수 M4M \geq 4라 하자. 위 네트워크의 최대 유량은 2M+12M + 1이 된다.

여기서 잠깐 간선 e1,e2,e3e_1, e_2, e_3의 잔여 용량이 각각 an,an+1,0a_n, a_{n + 1}, 0인 경우를 생각해보자.

만약 네트워크의 증가 경로에 e1,e2,e3e_1, e_2, e_3'(e3e_3'e3e_3의 역방향 잔여 간선이라고 하자)가 있고, e2e_2핵심 간선(critical edge), 즉 경로 상에서 잔여 용량이 가장 작은 간선이라면, 이 경로를 따르는 흐름은 cf(e2)=an+1c_f(e2) = a_{n + 1}이 될 것이다.

이 흐름은 e1,e2e_1, e_2an+1a_{n+1}만큼의 흐름을 더하고, e3e_3에서는 an+1a_{n + 1}만큼의 흐름을 덜어내기에, e1,e2,e3e_1, e_2, e_3의 잔여 용량은 각각 anan+1=an+2,0,an+1a_n - a_{n + 1} = a_{n + 2}, 0, a_{n+1}로 바뀐다.

이제 다음과 같은 세 경로 p1,p2,p3p_1, p_2, p_3를 생각해보자. p1p_1은 앞서 설명한 경우와 같다.

여기서 다음의 경로를 따라 1의 유량이 흘렀다고 해보자.

이제 e1,e2,e3e_1, e_2, e_3의 잔여 용량은 각각 a0,a1,0a_0, a_1, 0이 된다.

간선 e1,e2,e3e_1, e_2, e_3의 잔여 용량이 각각 an,an+1,0a_n, a_{n + 1}, 0이고, 나머지 간선들의 잔여 용량은 적어도 1은 된다고 해보자. 이때 경로 p1p_1의 핵심 간선은 e2e2이고, 이 경로를 따랐을 때 각 간선의 잔여 용량은 an+2,0,an+1a_{n + 2}, 0, a_{n + 1}로 변하고, 흐름의 값은 f|f|에서 f|f| + cf(e2)|c_f(e2)|로 증가했다.

이 상태에서 경로 p2p_2를 골라보자. 이 간선의 핵심 간선을 찾아보면 e3e_3가 되고, 그 잔여 용량은 an+1a_{n+ 1}이다. 이를 따라 흐름을 보냈을 때 간선 e1,e2,e3e_1, e_2, e_3의 잔여 용량은 an+2,an+1,0a_{n + 2}, a_{n + 1}, 0이 된다. 이후로도 e1e1을 핵심 간선으로 가지는 p1p1, e3e3를 핵심 간선으로 하는 p3p_3를 골라 유량을 흘려 보내면, e1,e2,e3e_1, e_2, e_3는 다시 (an,an+1,0)(a_{n}, a_{n + 1}, 0) 꼴의 잔여 용량을 가지게 된다.

(an,an+1,0)p1(an+2,0,an+1)p2(an+2,an+1,0)p1(0,an+3,an+2)p3(an+2,an+3,0)(a_n, a_{n+1}, 0) \xrightarrow{p_1} (a_{n+2}, 0, a_{n+1}) \xrightarrow{p_2} (a_{n + 2}, a_{n+1}, 0) \xrightarrow{p_1} (0, a_{n+3}, a_{n+2}) \xrightarrow{p_3} (a_{n+2}, a_{n+3},0)

위와 같은 네 번의 증가를 통해 유량은 2an+2an+1=2an12a_n + 2a_{n+1} = 2a_{n - 1}만큼 증가한다.

다시 1의 유량을 흘려보내 e1,e2,e3e_1, e_2, e_3의 잔여 용량이 각각 a0,a1,0a_0, a_1, 0이 됐을 때를 보자. 위와 같이 증가 경로를 택해 흐름을 보내면 무한 루프에 빠질 뿐만 아니라, 그 수렴값도 1+2n=2an=31 + 2\sum_{n = 2}^{\infty}a_n = 3 정도로 , 앞서 찾았던 최대 유량 2M+12M + 1에는 한참 못 미치게 된다.

3. 유리수 용량 간선만이 주어진 경우

그래도 보통 최대 유량 문제에서는 정수 용량의 간선들을 사용하고, 그렇게 정수 용량의 간선들만 있는 경우, 포드-풀커슨 방법은 무한 루프 없이 최대 유량을 반환할 수 있음이 보장된다. 간선의 용량이 정수가 아니라 유리수로 주어지는 경우에도, 간선들의 용량에 적절한 정수를 곱해 정수로 만들 수 있으니 포드-풀커슨 방법을 사용해 최대 유량을 구할 수 있다.

이전 글에 나왔던 두 정리를 다시 보자.

Lemma 2

유량 네트워크 G=(V,E)G = (V, E)와 흐름 ff를 생각하자. ppGfG_f의 증가 경로라 할 때, fp:V×VRf_p : V \times V \rightarrow \mathbb{R}를 다음과 같이 정의하면, fpf_pfp=cf(p)>0|f_p| = c_f(p) > 0GfG_f의 흐름이다.

fp(u,v)={cf(p)if (u,v) is on p,0otherwise.f_p(u, v) = \begin {cases} c_f(p) & \text{if } (u,v)\ \text{is on } p, \\ 0 & \text{otherwise.} \end {cases}

Corollary 1

G=(V,E)G = (V, E)가 유량 네트워크고, ffGG의 흐름, ppGfG_f에서의 증가 경로라 하자. fpf_p가 위에 정의된 것과 같고, fffpf_p만큼 증가하는 경우, 함수 ffpf \uparrow f_p는 값 ffp=f+fp>f|f \uparrow f_p| = |f| + |f_p| > |f|을 가지는 GG의 흐름이다.

Corollary 1에서 포드-풀커슨 방법의 매 스텝을 거칠 때마다 흐름의 값은 fp|f_p|만큼 증가한다. 이때 주어진 간선들의 용량이 모두 정수이므로, 만약 f|f|가 정수라면 경로의 잔여 용량 cf(p)c_f(p) 또한 정수가 될 수 밖에 없고, 따라서 fp|f_p|도 정수다. 맨 처음 시작할 때 유량은 f=0f = 0이므로, 모든 스텝에서 흐르는 유량은 정수들이다.

ff^*가 네트워크의 최대 유량이라고 하자. 모든 간선이 정수 용량을 가지므로 f|f^*|도 정수가 될 수 밖에 없다. 매 스텝마다 흐름의 값이 적어도 1 이상의 정수만큼 증가하므로, 최대 f|f^*| 번 만큼 유량을 1씩 반복해서 증가시키면 최대 유량에 도달할 수 있다.

(1) 정수 용량 네트워크에서의 포드-풀커슨 시간 복잡도

유량 네트워크 G=(V,E)G = (V, E)가 주어졌다고 하자. 흐름 ff가 주어졌을 때, 잔여 네트워크 cfc_f에는 최대 2E2|E|개의 간선이 있을 수 있으므로, DFS, 혹은 BFS를 사용해 cfc_f에서 증가 경로를 찾는 데 걸리는 시간은 O(V+2E)=O(E)O(V + 2|E|) = O(E)가 된다.

앞서 ff^*가 네트워크의 최대 유량일 때, 최대 f|f^*|번 증가가 이루어질 수 있다고 했으므로, 전체 시간복잡도는 O(Ef)O(E|f ^*|)가 된다. 최대 유량일 때의 값 f|f^*|이 충분히 작을 때에야 괜찮겠지만, f|f^*|가 상당히 크고, 매번 유량이 1씩 증가하도록 증가 경로를 찾게 되는 경우, 이 시간복잡도는 실제로 사용하기에는 상당히 부담스러워진다.

위 유량 그래프의 최대 유량은 2,000,0002,000,000이다. suvts \rightarrow u \rightarrow v \rightarrow t로 1의 유량이 흐른 후, svuts \rightarrow v \rightarrow u \rightarrow t로 1의 유량이 흘렀다고 해보자. 이후로도 계속 suvts \rightarrow u \rightarrow v \rightarrow t, svuts \rightarrow v \rightarrow u \rightarrow t의 증가 경로를 고르는 경우, 유량을 1씩 증가시키기를 2,000,0002,000,000번 반복하게 된다.

0개의 댓글