[그래프 알고리즘] 07. Maximum Flow Problem (Part 1)

jmt·2024년 6월 9일

알고리즘

목록 보기
15/18

Introduction

한 점에서 다른 점으로 가는 최소 경로를 찾기 위해 방향 그래프로 지도를 모델링할 수 있었다. 방향 그래프로 모델링할 수 있는 것은 이뿐만 아니라 flow network로도 모델링 가능하다. 예를 들면 어떤 물질이 source로부터 흘러들어와서 sink로 빠져나가는 배관을 상상해보자. 이를 방향 그래프로 나타내면 각 edge들은 특정 지점에서 다른 지점을 연결하는 pipe가 된다. 그리고 가중치(weigh)는 edge에 대한 비용이 아닌 물질이 해당 파이프(=edge)를 거쳐 흐를 수 있는 최대 수용량, 용량(capacity)을 의미한다. 물론 위 가정에서 유량(flow)이 유체가 아니여도 된다. 예를 들면 택배를 트럭으로 옮기는 상황을 가정해도 된다. 출발지에서 택배를 담아 도착지 터미널로 이동할 때, 중간에 허브 터미널을 거치게 된다. 이때 트럭에 최대로 담을 수 있는 택배의 양을 용량(capacity)로 줄 수도 있을 것이다. 또한 이런 상황을 가정했을 때 maximum flow problem은 출발지에서 도착지로 얼마나 많은 택배를 보낼 수 있는가? 가 될 것이다.

더 일반화하면, soruce에서 sink로 흐를 수 있는 최대 유량이 얼마인지를 계산하는 문제가 maximum flow rate라고 볼 수 있다.

Flow Network

flow network는 방향 그래프 G=(V,E)G = (V, E)로 표현한다. 이때 각 edge(u,v)(u, v)capacity c(u,v)0c(u,v) \ge 0를 만족해야한다. 만약 (u,v)E(u,v) \notin E이면, c(u,v)=0c(u,v) = 0이다. 그리고 (u,v)E(u,v) \in E이면, reverse edge인 (v,u)E(v,u) \notin E가 됨에 주의하자. 그리고 구분되는 두 vertex인 source ss와 sink tt에 대해 svts\rightsquigarrow v \rightsquigarrow t의 관계를 모든 vertex, vVv \in V에 대해 만족한다고 가정하자.

Flow

Maximum flow problem에서 구해야 하는 것은 결국 각 edge마다 흐를 수 있는 'flow(유량)'이다. 유량을 다음과 같은 함수로 정의한다고 하자.

f:(u,v)ERf : (u,v) \in E \rightarrow \bf{R}

그리고 ff는 1) capacity constraint와 2) flow conservation 을 만족해야한다.

  • 1) For all u,vVu, v \in V, 0f(u,v)c(u,v)0 \le f(u,v) \le c(u,v)
  • 2) For all uV{s,t}u \in V - \{s,t\},
    vVf(v,u)=vVf(u,v)\sum_{v \in V} f(v, u) = \sum_{v \in V} f(u, v)

정리하면, 유량은(flow) 최대 유량인 용량(capacity)를 넘지 않아야 하고 해당 vertex로 들어오는 양과 나가는 양은 같게끔 정해져야 한다. 그리고 ff의 값은 f|f|로 표기하며, 이는 다음과 같이 구할 수 있다.

f=vVf(s,v)vVf(v,s)=(Flow out of source)(Flow into source)\begin{aligned} |f| &= \sum_{v \in V} f(s,v) - \sum_{v \in V} f(v,s) \\ &= \text{(Flow out of source)} - \text{(Flow into source)} \end{aligned}

Maximum Flow Problem

최대 유량 문제는 방향 그래프 GG와 source ss, sink tt, capacity cc가 주어졌을 때, 그래프 GG의 최대 값을 갖는 flow를 찾는 문제이다. 그런데 우리는 주어지는 방향 그래프 GG에 대해 어떠한 제약 조건도 달지 않았다. 예를 들면 'cycle을 가져서는 안된다'가 있을 것이다. 이렇게 제약 조건을 달지 않는 이유는 최대 유량 문제를 풀 때 방향 그래프는 일반화가 가능하기 때문이다. 우선 방금 든 예시와 같이 'cycle'에 대해 생각해보자.

Cycle

방향 그래프에서 cycle은 결국 루프(loop)이다. 자기자신으로 다시 돌아오는 edge를 의미하는데, flow network에서 루프는 아무 의미가 없다. flow는 flow conservation을 만족해야하기 때문이다. 그렇기에 flow network에는 cycle, 즉 루프가 존재하지 않는다고 할 수 있다.

Parallel Edges

머리(head)와 꼬리(tail)가 동일한 edge를 평행 간선(parallel edge)이라고 한다. 하지만 다음과 같은 과정을 통해 flow network에는 이러한 평행 간선이 존재하지 않는다고 말할 수 있다.
asdf


"출처 https://gazelle-and-cs.tistory.com/60"

위와 같이 동일한 방향을 갖는 edge가 2개 존재하여도 하나로 합칠 수 있다. 이 과정을 parallel edges에 대해 적용하면 결국 parallel edge가 없는 그래프와 동일하다.

AntiParallel Edges

사실 앞에서 edge에 대한 제약 조건을 하나 달았었다. 해당 조건은 (u,v)E(u,v) \in E이면 (v,u)E(v,u) \notin E였다. 즉 특정 방향을 갖는 두 vertex를 연결하는 edge가 존재하면, 해당 edge의 역방향 edge는 존재하지 않는다는 것이다. 그런데 사실 이 조건이 없어도 큰 문제는 없다. 그 이유는 다음 그림을 보면 알 수 있다.


"출처 https://gazelle-and-cs.tistory.com/60"

즉, 역평행 간선(antiparallel edge)가 존재한다면, 새로운 node(=vertex)를 만들고 해당 node와 기존 node를 연결하는 edge를 추가하여 antiparallel edges가 존재하지 않는 그래프로 만들 수 있다.

결론적으로 flow network는 루프 / 평행 간선 / 역평행 간선이 존재하지 않는 방향 그래프이다. 라고 말할 수 있다.

Multiple Sources and Sinks

여러개의 source와 sink가 존재하는 flow network에 대해 최대 유량을 구하고자 한다면 어떻게 해야할까? 이는 supersource와 supersink라는 개념을 통해 간단히 일반적인 flow network로 만들 수 있다. 위 그림 (a)를 (b)로 만드는 것이다. supersource를 ss라고 하고, edge(s,si)(s, s_i)를 추가해주면 된다.

edge(s,si) with c(s,si)= for each i=1,2,,m\text{edge}(s, s_i) \text{ with }c(s, s_i)=\infin \text{ for each }i=1,2,\cdots,m

sinks에 대해서도 마찬가지이다. supersink를 tt라 정의하고, edge(ti,t)(t_i, t)를 추가해주면 된다.

edge(ti,t) with c(ti,t)= for each i=1,2,,m\text{edge}(t_i, t) \text{ with }c(t_i, t) = \infin \text{ for each }i=1, 2, \cdots, m

Residual Network

앞에서 flow network를 표현하는 방법과 여러 정의에 대해 다루었다. 이제 어떻게 주어진 flow network에서 maximum flow를 구할 수 있는지 알아보자. maximum flow를 구하기 위해 사용되는 것이 바로 잔여 네트워크(Residual Network)이다. 다음과 같은 간단한 예시를 살펴보자.


위와 같은 flow network가 주어졌다고 하자. 각 edge마다 얼마의 flow를 흘려보내야 maximum flow가 될까? 우선 (s,a),(a,b),(b,t)(s, a), (a,b), (b,t)의 edge를 지나는 경로로 1만큼의 유량(flow)를 흘려보냈다고 가정하자. 1보다 큰 유량은 c(a,b)c(a,b)에 의해 흘려보낼 수 없다. 그리고 (s,a),(a,t)(s,a), (a,t)(s,b),(b,t)(s,b), (b,t)로 1씩 더 흘려보낸다고 가정하자. 더 이상 추가할 수 있는 flow가 존재하지 않게된다. 이때의 flow는 3이되는데(ss에서 출발한 양이 3이므로 flow conservation에 의해 flow network를 흐르는 유량은 3이다.), 이것이 maximum flow일까? 그렇지 않다. 중간에 (s,a),(a,b),(b,t)(s, a), (a,b), (b,t)의 edge를 지나는 경로로 1만큼의 유량(flow)을 보내지 않고, 바로 (s,a),(a,t)(s, a), (a,t)로 2씩 흘려보낸다면 최대 유량은 4가 된다. 즉, (a,b)(a,b)를 지나갈 이유가 없다. 우리는 사람이기에 잘못된 경로를 찾아내어 수정할 수 있다. 하지만 컴퓨터가 이를 어떻게 연산할까? 잘못된 경로로 flow를 주었을 때 다시 처음으로 돌아가 계산을 해야할까?

(a,b)(a,b)를 지나가는 경로를 취소하는 것이 아니라, (s,b)(s,b)로 1의 흐름을 더 준다고 가정해보자. 그럼 flow conservation에 의해 bb에는 1의 초과 유량이 존재한다. 이를 상쇄하기 위해 (b,a)(b,a)로 1을 흘려보낸다고 하자. 그럼 다시 aa에도 1의 초과 유량이 발생하고 이를 상쇄하기 위해 (a,t)(a, t)로 1을 흘려보내면, capacity constraint와 flow conservation을 만족하는 flow가 형성되고, 최대 유량은 4가 된다. 이 과정을 개념화한 것이 바로 Residual Network이다.

Residual Capacity

residual network를 구하기 위해서는 residual capacity를 구해야 한다. 이는 다음과 같이 정의된다.

cf(u,v)={c(u,v)f(u,v) if (u,v)E,f(v,u) if (v,u)E,0otherwise.c_f (u,v) = \begin{cases} c(u,v) - f(u,v) &\text{ if }(u,v)\in E,\\ f(v,u) &\text{ if }(v, u)\in E,\\ 0 &\text{otherwise.} \end{cases}

residual capacity를 활용해 residual network의 간선 EfE_f를 다음과 같이 정의한다.

Ef={(u,v)V×V:cf(u,v)>0}E_f = \{(u,v) \in V \times V:c_f(u,v) > 0 \}

그러면 residual network는 Gf=(V,Ef)G_f=(V, E_f)이다. residual capacity를 구하여 residual network를 구해보면 다음과 같다.

cf(s,w)c_f(s,w)(s,w)E(s,w) \in E이므로 첫번째 case로 31=23-1=2가 된다. cf(w,s)c_f(w,s)(u,s)E(u,s) \in E이므로 두번째 case라 11이 된다. 해당 과정을 모든 edge (u,v)V×V(u,v) \in V \times V에 대해 적용하여, cfc_f를 구하고 이를 통해 GfG_f를 그리면 위 그림의 우측 그래프와 같다. residual network로 알 수 있는 점은 기존 그래프의 방향과 동일한 edge에 residual capacity가 존재하면, 해당 양만큼 더 flow를 가할 수 있다는 의미이고, 역방향 edge에 residual capacity가 존재하면, 해당 양만큼 flow를 취소할 수 있다는 의미이다. 아주 중요하다!

Augmenting Path

residual network를 통해 어떻게 maximum flow를 구할 수 있을까? residual network를 구한 이유는 어떤 flow가 그래프 상에 존재할 때, 이를 기반으로 현재 최대 유량보다 더 많은 flow를 가하는 방법을 찾기 위함이다. 우선, 임의의 흐름 ff에 대한 residual capacity cfc_f를 구하고, residual network GfG_f를 구했다고 하자. 여기서 sstt를 잇는 아무 경로 pEfp \subseteq E_f를 가정하자. 해당 경로 ppaugmenting path라 한다.

cf(p)c_f(p)

경로 pp에 대한 residual capacity, cf(p)c_f(p)를 다음과 같이 정의하자. edge에 대한 residual capacity가 아닌 경로(path) pp에 대한 residual capacity임에 주의하자!

cf(p)=min{cf(u,v):(u,v)p}c_f (p) = \text{min} \{c_f(u,v) : (u,v) \in p \}

그리고 이 경로에 존재하는 edge에 대한 흐름(flow), f(u,v)f^{\prime}(u,v)을 다음과 같이 정의하자.

f(u,v)={cf(p)if (u,v) is on p,0otherwisef^{\prime}(u,v) = \begin{cases} c_f(p) &\text{if }(u,v)\text{ is on }p,\\ 0 &\text{otherwise} \end{cases}

Augmentation

그리고 augmentation 연산을 적용한다. augmentation은 다음과 같다.

ff(u,v)={f(u,v)+f(u,v)f(v,u)if (u,v)E0otherwisef \uparrow f^{\prime}(u,v) = \begin{cases} f(u,v) + f^{\prime}(u,v) - f^{\prime}(v,u) &\text{if }(u,v) \in E\\ 0 &\text{otherwise} \end{cases}

이제 위에서 예시로 든 G,GfG, G_f에 augmenting path를 다음과 같이 정의하자.

p={(s,w),(w,y),(y,z),(z,x),(x,t)}p = \{(s,w), (w, y), (y,z), (z,x), (x,t) \}

그럼 cf(p)=c(w,y)=c(y,z)=c(x,t)=1c_f(p) = c(w,y) = c(y,z) = c(x,t) = 1이 된다. 그러므로 f(e)=1, where epf^{\prime}(e) = 1\text{, where }e \in p. 이를 바탕으로 augmentation ffp(e)f \uparrow f^{p}(e)를 수행하면, 그 결과는 아래 그림의 오른쪽 그래프와 같다.

residual network를 구하고 augmentation 연산을 수행한 결과로 얻어진 GG의 flow는 이제 4가 되었다. 기존의 flow network의 flow는 3이였다. 그렇다면 4가 주어진 flow network의 최대 유량일까? 이를 확인하기 위해 새로운 residual network GfG_f를 구해본다. 이는 위 그림의 오른쪽 그래프에 해당한다. GfG_f에서 ssvv를 잇는 어떠한 augmenting path, pp를 찾을 수 없다. 그렇기에 현재 그래프 GG의 flow가 주어진 flow network의 최대 유량이 된다.

profile
고분자/컴공

0개의 댓글