
여러분이 상수도 공사의 직원이라고 해봅시다. 여러분의 업무는 물이 저장된 수원에서 물이 필요한 특정 지역까지 물을 공급하는 것입니다. 물을 공급하는 방법은 수원에서 해당 지역까지 연결된 수도관을 따라 흘려주는 것입니다. 해당 지역에는 사람도 많고 공단도 있어서 최대한 많은 물을 공급받고 싶어합니다. 만약 두 지점 사이를 잇는 수도관이 딱 하나 있다면 쉽게 해결되겠지만, 문제는 이보다 더 복잡합니다. 바로 수도관이 여러 사정에 의해 매우 얼기설기 설치되어 있기 때문입니다. 게다가 수도관마다 연식이나 제원도 달라서 수도관마다 견딜 수 있는 수압이나 용량도 정해져 있습니다. 과연 물을 어떻게 흘려야 수도관에 무리를 주지 않고 해당 지역으로 최대한 많은 물을 보내줄 수 있을까요?
이 문제는 유명한 최적화 문제인 최대 흐름 문제(maximum flow problem)를 나타낸 것입니다. 예제에서도 쉽게 유추할 수 있듯이 이 문제는 이론적으로 흥미로울 뿐 아니라 여러 분야에서 응용될 수 있기 때문에 예전부터 깊이 탐구되었습니다. 특히, 이 문제가 널리 알려지고 많이 발전하게 된 때는 미국과 소련이 경쟁하던 냉전 시대인데, 그 이유는 이 문제가 군사적으로도 매우 요긴하였기 때문이라고 알고 있습니다. 이 문제에 관한 기본적인 내용들은 모두 그 당시에 정립된 것이라고 생각하셔도 무방하답니다.
이번 포스트에서는 최대 흐름 문제를 알아 보도록 하겠습니다. 특히, 아래에서는 다음 내용들을 차례대로 다룰 예정입니다.
- 문제 정의
- 평행 간선(parallel edge)과 역평행 간선(anti-parallel edge)
- 잔여 네트워크(residual network)
- 증가 경로(augmenting path)
이 글에서 용어의 번역은 최대한 다른 사이트나 블로그의 번역들과 동일하게 맞추려고 노력하였습니다. 이 글 저 글 읽어 보시며 본인에게 맞는 내용의 글을 찾는 동안 혹여나 용어 때문에 헷갈리는 것을 방지하고자 함입니다.
문제 정의
이 절에서는 최대 흐름 문제가 무엇인지 엄밀히 정의해 보도록 하겠습니다. 이 문제에서는 어떤 방향이 있는 그래프(directed graph)
흐름 네트워크와 함께 특별한 두 정점
이 문제에서 우리가 구해야 하는 것은
- 용량 제약(capacity constraint) : 임의의 간선에 흐르는 양은 항상
보다 크거나 같고, 해당 간선의 용량을 초과하지 못한다. 다시 말해, 모든 간선 에 대해, 이다. - 흐름 보존 제약(flow conservation constraint) : 시점이나 종점이 아닌 모든 정점에 대해, 그 정점에서 흘러 나가는 양과 그 정점으로 흘러 들어오는 양은 동일하다. 다시 말해, 임의의
에 대해, 를 만족한다.
이 조건들이 흐름을 잘 표현하고 있다는 것을 알아 봅시다. 어떤 흐름이든
컴퓨터 과학에서는 항상 무언가를 최적화하려고 노력합니다. 여기서는 무엇을 최적화할까요? 어떤 네트워크에 적게 흘리는 방법은 쉽게 구할 수 있습니다. 아무것도 흘리지 않으면 되기 때문이죠. 따라서 우리의 목표는 최대한 많이 흘리는 것이 됩니다. 물이 생성되는 지점은 시점뿐이므로 그 양은 시점에서 흘러 나가는 양에서 흘러 들어오는 양을 제외한 값으로 정의할 수 있습니다. 다시 말해,
로 쓸 수 있겠죠. 아래서는 이를 흐름양(value of flow)이라고 부르며, 간단히

드디어 최대 흐름 문제를 정의할 수 있게 되었습니다.
최대 흐름 문제 (Maximum flow problem)
어떤 흐름 네트워크와 특정 시점과 종점이 주어졌을 때, 이 네트워크에서 시점에서 시작해 종점으로 향하는 흐름 중에서 그 양이 가장 큰 것을 찾으시오.
평행 간선(Parallel Edge)과 역평행 간선(Anti-Parallel Edge)
위 정의에서는 흐름 네트워크의 방향 그래프에 아무런 제약을 달지 않았습니다. 하지만 방향 그래프에 몇 가지 제약을 추가해도 일반성을 잃지 않는다는 사실을 쉽게 보일 수 있습니다.
첫 번째는 루프(loop)입니다. 방향 그래프에서 루프는 한 정점에서 출발해 다시 자기 자신으로 돌아오는 간선을 의미합니다. 잘 생각해 보면 루프는 흐름 네트워크 상에서 아무런 도움이 되지 않습니다. 루프를 통해 나간 만큼 다시 자기 자신으로 돌아오기 때문이죠. 따라서 네트워크에 루프가 없다고 가정해도 괜찮습니다.
다음은 평행 간선(parallel edge)입니다. 방향 그래프에서 서로 다른 두 간선
이렇게 용량을 합쳐도 괜찮다는 것은 쉽게 보일 수 있습니다. 바로 기존의 네트워크에서의 어떤 흐름을 가지고 와도 그와 동일한 양을 갖는 흐름이 새로 만들어진 네트워크에서도 흐를 수 있음을 보일 수 있기 때문입니다. 방법은 간단합니다. 만약 평행한 간선

이것으로 네트워크에 평행 간선이 없어도 무방하다는 것을 보였습니다만, 아직 눈에 거슬리는 비슷한 종류의 간선이 남아있습니다. 바로 역평행 간선(anti-parallel edge)인데요. 한 간선
이러한 간선은 정점을 하나 추가함으로써 해소할 수 있습니다. 위와 같은
역평행 간선을 지운 네트워크도 기존의 네트워크와 동치라는 것을 쉽게 보일 수 있습니다. 새로 만들어진 간선들에다 원래 흐르던 유량을 그대로 흘려주면 되기 때문입니다. (역도 생각해 보세요.)

다만 여기서 주의할 점은 역평행 간선을 제거할 시 새로운 네트워크에 새로운 정점과 간선이 추가된다는 점입니다. 그러나 정점의 개수나 간선의 개수가 각각 최대
정리 1. 평행 간선과 역평행 간선이 없는 네트워크의 일반성
최대 흐름 문제를 풀 때, 우리는 일반성을 잃지 않고 흐름 네트워크에 루프, 평행 간선, 역평행 간선이 존재하지 않는다고 가정할 수 있다.

실제로 문제를 풀 때는 루프, 평행 간선만 없고 역평행 간선은 있을 수 있는 네트워크를 가정하는 경우가 훨씬 많습니다. 평행 간선은 간선이 없어지기만 할 뿐이어서 여러모로 도움이 되지만, 역평행 간선을 지우면 정점과 간선의 수가 늘어나므로 수행 시간에 손해를 주기 때문입니다. 다행히 앞으로 소개할 알고리즘들 모두 역평행 간선이 있는 경우에도 문제 없이 수행됩니다. 그럼에도 역평행 간선을 지운 이유는 분석이 훨씬 간단해지기 때문입니다. 따라서 아래 절에서는 평행 간선뿐 아니라 역평행 간선도 없는 네트워크를 가정하도록 하겠습니다.
잔여 네트워크(Residual Network)
어려운 개념을 공부하기 전에, 간단한 예시를 먼저 살펴 보도록 하죠. 다음 그림과 같은 흐름 네트워크가 주어졌다고 하겠습니다.

우리의 목표는 시점

위 그림에서 빨간색 경로를 따라서 물을 흘린다면 최대 얼마큼 흘릴 수 있을까요? 간선

아직 우리는 네트워크에

동시에 두 경로를 따라서 물을 흘린다고 생각하셔도 무방하고, 하나씩 흘린다고 보셔도 괜찮습니다. 두 경로를 따라서 흘릴 수 있는 물의 양은 얼마인가요? 두 경로 각각 최대

이 흐름의 양은 얼마인가요? 시점
그럼 이 흐름이 네트워크에서의 최대 흐름일까요? 아니죠. 다음 그림과 같이 간선

어째서 이러한 결과가 나왔을까요? 네, 처음에 택한 경로 자체가 이상했기 때문입니다. 거기서
본론으로 돌아와서, 비록 "잘못된" 경로를 통해 물을 흘렸다고 할지라도 현재의 흐름을 수정하여 최대 흐름으로 만드는 방법은 없을까요? 만약 그런 방법이 전혀 불가능하다면 아무래도 문제 자체가 너무 어려워질 겁니다. 완전히 처음부터 모든 것을 생각해야 할테니 말이죠. 다행히도 현재 흐름에서 수정하는 방법이 존재합니다. 바로 다음 그림처럼 흐름을 '취소'하는 것이죠.

이 그림은 다음과 같이 해석할 수 있겠습니다. 일단
위 논의를 정리하면 다음과 같습니다. 일단 시점에서 종점까지 흘릴 수 있는대로 흘려보는 방법을 생각해 봅니다. 안타깝게도 그 방법은 그림 9에서 확인하였듯 최대 흐름을 얻지 못할 수 있습니다. 이를 해결하기 위해서는 과거에 잘못 흘린 부분을 번복할 필요도 있습니다. 이를 적절히 활용한다면 아마도 최대 흐름을 구할 수 있을 겁니다. 그러기 위해서는 네트워크의 간선마다 얼마큼의 물을 더 흘릴 수 있고, 반대로 얼마큼의 물을 취소할 수 있는지를 알려주는 무언가가 필요합니다.

그 개념을 정형화시킨 것이 바로 잔여 네트워크(residual network)입니다. 이를 정의하기 위해서는 몇 가지 준비물이 필요합니다. 첫 번째로는 잔여 네트워크에서 사용할 간선들입니다. 곰곰이 생각해 보면, 만약 어떤 간선에 흐름이 용량 가득 흐르고 있다면 더 이상 이 간선으로는 무언가를 흘릴 수 없을 것입니다. 반대로 어떤 간선에 아무것도 흐르고 있지 않다면, 이 간선에는 번복할 흐름이 없습니다. 따라서 어떤 흐름 네트워크
으로 정의하겠습니다. 첫 번째 집합에 속한 간선들은 바로 아직 여유분이 있어 해당 간선의 방향으로 흐름을 더 보낼 수 있는 간선들입니다. 반대로 두 번째 집합은 해당 간선으로 얼마큼의 흐름이 흐르고 있어서 그 역방향으로 이를 취소할 수 있는 것을 나타낸 것입니다. 첫 번째 종류의 간선을 전진 간선(forward edge), 두 번째는 후진 간선(backward edge)이라고 부릅니다.
앞에서 우리는 정리 1을 통해 입력되는 흐름 네트워크에 루프, 평행 간선, 역평행 간선이 없다고 가정하였습니다. 이렇게 가정한 게 여기서 드디어 빛을 발합니다. 바로 잔여 네트워크의 간선들이 원래 네트워크의 하나의 간선에 대응이 되기 때문입니다. 다음 정리를 보시죠.
정리 2. 원래 네트워크와 잔여 네트워크의 대응 관계
에도 루프와 평행 간선은 존재하지 않는다. 의 모든 간선은 정확히 하나의 에 있는 간선으로부터 정의된다.- 만약
라면, 에는 반드시 나 중 정확히 하나가 있어야 한다.
[증명] 명제 1이 거짓이 되기 위해서는
명제 2가 거짓이 되기 위해서는
마지막으로
잔여 네트워크도 일종의 흐름 네트워크이고 따라서 용량도 정의해 주어야 합니다. 그 용량을
반대로 모든 후진 간선

이제 잔여 네트워크를 정의할 수 있습니다. 임의의 흐름 네트워크

이렇게 만든 잔여 네트워크는 다음과 같은 흥미로운 성질을 갖고 있습니다. 이는 다음 절에서 요긴하게 사용됩니다.
정리 3. 잔여 네트워크 용량의 양수성
흐름
[증명] 어떤 간선
증가 경로(Augmenting Path)
위 절에서 우리는 임의의 흐름이 네트워크에 흐르고 있을 때 어떤 간선에는 얼마나 더 물을 흘려 넣을 수 있고, 어떤 간선에는 역으로 얼마큼 많은 양의 물을 취소할 수 있는지에 대한 정보를 담고 있는 잔여 네트워크에 대해서 알아 보았습니다. 우리가 이를 고안한 가장 큰 이유는 어떤 흐름을 유지하고 있을 때, 이를 기반으로 현재의 흐름보다 더 많은 양의 물을 흘려 넣는 방법을 만들기 위해서입니다.
이제 앞에서 정의한 잔여 네트워크가 우리가 의도한 대로 동작하는지를 따져볼 차례입니다. 잔여 네트워크에서
이 생각을 정형화 해보죠. 어떤 흐름
말인 즉슨,
이는

지금까지 우리가 하고자 하는 것을 수학적인 기호로 표현해 보았으니 남은 것은 실제로 우리가 의도한 대로 주어진 흐름에서 해당 경로를 따라 물을 더 흘려주는 방법을 찾을 수 있는지 검증하는 것입니다. 이를 위해서 몇 가지 재미있는 정리들을 증명하도록 하겠습니다. 첫 번째 정리는 잔여 네트워크에서 이 경로를 따라 흐르는 양은 양수라는 점입니다.
정리 4. 증가 경로 흐름의 양수성
어떤 흐름
[증명] 정리 3에서 임의의
다음 정리는 이번 글에서 가장 중요한 정리로,
정리 5. 증가 경로 적용하는 방법
어떤 흐름
[증명] 먼저
ㄱ. 용량 제약. 임의의
다음은
마지막으로
ㄴ. 흐름 보존 제약.
로 쓸 수 있습니다.
만약
반대로
ㄷ. 흐름양의 증가.
정리 5를 통해 우리는 최대 흐름이라면 다음과 같은 성질을 만족한다는 것을 보일 수 있습니다.
정리 6. 최대 흐름이 갖는 성질
만약
[증명] 그렇지 않다면
마치며
이것으로 최대 흐름 문제가 어떤 문제이고 최대 흐름은 어떤 특징을 갖고 있는지에 대해서 알아 보았습니다. 위 내용을 가볍게 정리하면 다음과 같습니다.
- 최대 흐름 문제는 어떤 흐름 네트워크가 주어졌을 때 용량 제약과 흐름 보존 제약을 만족하면서 미리 정해지는 시점에서 종점으로 최대한 많은 양의 물을 흘려 보내는 방법을 찾는 문제입니다.
- 일반성을 잃지 않고 흐름 네트워크에는 루프, 평행 간선, 역평행 간선이 존재하지 않는다고 가정할 수 있습니다.
- 어떤 흐름 네트워크 위에서 흐를 수 있는 흐름이 하나 주어졌을 때, 그 흐름을 기준으로 어떤 간선에는 물을 얼마큼 더 흘려줄 수 있고 어느 간선에는 물을 얼마나 취소할 수 있는지에 대한 정보를 갖는 보조 네트워크를 해당 흐름의 잔여 네트워크라고 부릅니다.
- 잔여 네트워크 위에서
에서 로 향하는 단순 경로가 존재한다면, 이를 활용하여 현재의 흐름보다 더 많은 양의 물이 흐르는 흐름을 만들 수 있습니다. 따라서, 최대 흐름에는 그것의 잔여 네트워크 위에 에서 로 도달할 수 없습니다.
정리하고 보니 무겁군요. 그만큼 깊이 연구된 분야라서 그렇다고 생각합니다.
정리 6은 최대 흐름에 대한 잔여 네트워크에서는
또한, 위에서 네트워크의 용량은 모두 유한하다고 가정하였습니다. 하지만 경우에 따라서는 어떤 간선의 용량이 무한하다고 가정할 필요가 있을 수도 있습니다. 이 경우에는 최대 흐름 문제를 해결하지 못하는 걸까요? 그렇지 않습니다. 다만, 무한의 용량을 갖는 간선들을 잘 다루어 주어야 합니다. 이와 관련해서도 다음에 포스트해 보도록 하겠습니다.
긴 글을 모두 읽어 주셔서 고맙습니다. 혹시 잘못된 점이 있거나 궁금하신 점이 있으시면, 알려 주시기 바랍니다.
참조
[1] Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. Introduction to algorithms. MIT press, 2009. (a.k.a. CLRS)
'조합론적 최적화 > Flow & Circulation' 카테고리의 다른 글
서큘레이션 (Circulation) (3) | 2023.12.23 |
---|---|
디니츠의 알고리즘 (Dinitz' Algorithm) (6) | 2021.02.27 |
에드몬즈-카프 알고리즘 (Edmonds-Karp Algorithm) (6) | 2021.02.21 |
포드-풀커슨 방법 (Ford-Fulkerson Method) (3) | 2020.08.30 |
최대 흐름 최소 절단 정리 (Max-Flow Min-Cut Theorem) (13) | 2020.08.29 |