Ford-Fulkerson Algorithm & Edmons-Karp Algorithm
2020-1ํ๊ธฐ, ๋ํ์์ โ์๊ณ ๋ฆฌ์ฆโ ์์ ์ ๋ฃ๊ณ ๊ณต๋ถํ ๋ฐ๋ฅผ ์ ๋ฆฌํ ๊ธ์ ๋๋ค. ์ง์ ์ ์ธ์ ๋ ํ์์ ๋๋ค :)
์ด๋ฒ ํฌ์คํธ๋ Network Flow ํฌ์คํธ์ ํ์ ํฌ์คํธ์ ๋๋ค. Network Flow ๋ฌธ์ ์ ํต์ฌ์ด ๋๋ ์ ๋ฆฌ์ธ <Max-Flow Min-Cut Theorem>์ ๋ํด ๊ถ๊ธํ๋ค๋ฉด ์ด์ ํฌ์คํธ๋ฅผ ์ฐธ๊ณ ํด์ฃผ์ธ์! ๐
์ด๋ฒ ํฌ์คํธ์ ์ฝ๋๋ ๋ฐฑ์ค 6086๋ฒ: ์ต๋ ์ ๋ ๋ฌธ์ ๋ฅผ ๊ธฐ์ค์ผ๋ก ์์ฑ๋์์ต๋๋ค ๐จโ๐ป
Network Flow ํฌ์คํธ์์ ์ด๋ป๊ฒ Max Flow๋ฅผ ๊ตฌํ ์ง <Max-Flow Min-Cut Theorem>์ ํตํด ์ดํด๋ณด์๋ค. ์ด๋ฒ ํฌ์คํธ์์๋ Residual Graph๋ฅผ ์ฌ์ฉํ๋ ํด๋น ์๊ณ ๋ฆฌ์ฆ์ ์ง์ ๊ตฌํํด๋ณธ๋ค.
Ford-Fulkerson Algorithm
์ฌ์ค Network Flow ํฌ์คํธ์์ ์ค๋ช ํ Max-Flow๋ฅผ ์ฐพ๋ ๋ฐฉ๋ฒ์ ์ฝ๋๋ก ๊ตฌํํ ๊ฒ์ ๋ถ๊ณผํ๋ค. ํฐ ๋ฒ์ฃผ๋ก ๋ดค์ ๋๋ Brute Force Algorithm์ ์ํ๋ค.
1. source์์ sink๋ก ๊ฐ๋ ์ ๋์ ๋ณด๋ผ ์ ์๋ ๊ฒฝ๋ก $p$๋ฅผ ํ๋ ์ฐพ๋๋ค. DFS ๋๋ BFS๋ฅผ ์ด์ฉํ๋ฉด ๋๋ค.
2. ์ฐพ์๋ธ ๊ฒฝ๋ก $p$๋ก ๋ณด๋ผ ์ ์๋ ์ต๋ํ์ ์ ๋์ ๊ตฌํ๋ค. ์ต๋ํ์ ์ ๋์ ๊ฒฝ๋ก $p$๋ฅผ ํ์(traversal)ํ๋ฉฐ ๊ฐ์ฅ ์์ ๋จ์ capacity๊ฐ ๋๋ค.
3. ์ฐพ์๋ธ ๊ฒฝ๋ก $p$์ ์ต๋ ์ ๋์ ์ค์ ๋ก ํ๋ ค๋ณด๋ธ๋ค. ์ด ๊ณผ์ ์์ ์๋ฐฉํฅ์ ์ ๋์ ์ถ๊ฐํ๊ณ , ์ญ๋ฐฉํฅ์ ์ ๋์ ๋บ๋ค.
์๋ฅผ ๋ค์ด ์ฐพ์๋ธ ๊ฒฝ๋ก $p$๊ฐ $a \rightarrow b \rightarrow c$๋ผ๋ฉด,
// ์๋ฐฉํฅ
f(a, b) += flow
f(b, c) += flow
// ์ญ๋ฐฉํฅ
f(b, a) -= flow
f(c, b) -= flow
์ฃผ๋ชฉํ ์ ์ [3.] ๊ณผ์ ์์ ์ญ๋ฐฉํฅ์ ์ฒ๋ฆฌํ ๋์ธ๋ฐ, ๋ง์ฝ $f(b, a) = 0$์ด์๋ค๋ฉด $f(b, a) < 0$๋ก ์์๊ฐ ๋๋ค. ๊ทธ๋ฐ๋ฐ ์ด๋ฐ ์์ ์ ๋์ ํ๋ ค๋ณด๋ด๋ ๊ฒ์ ๊ฐ๋ฅํ๋ฐ, $f(b, a)$์ capacity๋ $c(b, a) = 0$์ด๋ฏ๋ก ๊ฒฐ๊ตญ $f(b, a) < 0 = c(b, a)$๋ก ์ ๋์ ๋ํ ๋ฒ์น์ ์ ํ ๊นจ๋จ๋ฆฌ์ง ์๋๋ค!
์ฝ๋๋ก ์์ฑํ๊ธฐ ์ ์ ์์ผ๋ก ์ด ์๊ณ ๋ฆฌ์ฆ์ ๋ฐ๋ผ๊ฐ๋ณด์. ์ด ๋ถ๋ถ์ ์ข์ ์๋ฃ๊ฐ ์์ด์ ํด๋น ์๋ฃ๋ก ๋์ฒดํ๊ฒ ๋ค. ๐ ์์ผ๋ก ํธ๋ Ford-Fulkerson Algorithm
์ด์ ์ฝ๋๋ก ์ดํด๋ณด์.
โจ Tip: ์ด ๋ฌธ์ ์ ๊ฒฝ์ฐ ๊ทธ๋ํ๋ฅผ Adjacency List ๋ณด๋ค๋ Adjacency Matrix๋ก ํํํ๋๊ฒ ์๊ณ ๋ฆฌ์ฆ์ ์ง๊ธฐ ํจ์ฌ ํธํด์ง๋ค! ๐
๋จผ์ ๋ฌธ์ ์ ์
๋ ฅ์ ๋ณด๋ฉด, ๋
ธ๋๊ฐ Alphabet ๋์๋ฌธ์๋ก ๋ค์ด์จ๋ค. ๋ณธ์ธ์ ์๋ฌธ์๋ก๋ ๋ค์ด์จ๋ค๋ ๊ฑธ ๋์ค์ ๊นจ๋ฌ์๋ค ๐ฑ ์
๋ ฅ์ ์ ๊ทํํ๊ธฐ ์ํด์ 'A'
๋ก ๋นผ์ฃผ๋ฉด ๋๋ค. ๊ทธ๋ฌ๋ฉด ๋
ธ๋๋ [A-Z]: [0, 26], [a-z]: [32, 57]
์ ๋ฒํธ๋ฅผ ๊ฐ๊ฒ ๋๋ค.
์ฐ๋ฆฌ๋ int capacity[][]
๋ผ๋ ๋ฐฐ์ด์ ํ์ดํ์ ํ๋ฅผ ์ ์๋ ์ ๋์ capacity๋ฅผ ๊ธฐ๋กํ๋ค. ๊ทธ๋์ ์
๋ ฅ์ ํตํด Graph๋ฅผ ๊ตฌ์ถํ๋ฉด ์๋์ ๊ฐ๋ค.
#define MAX 80
int capacity[MAX][MAX];
for (int i = 0; i < N; i++) {
char s, e;
int c;
cin >> s >> e >> c;
capacity[s - 'A'][e - 'A'] += c;
capacity[e - 'A'][s - 'A'] += c;
}
์ด์ ์ค๋น๋ ๋๋ฌ๊ณ , ๋ณธ๊ฒฉ์ ์ผ๋ก <\Ford-Fulkerson Algorithm>์ ๊ตฌํํด๋ณด์.
long long FordFulkerson(int source, int sink) {
long long ret = 0;
// find path and update residual graph
while (1) {
...
// dfs
while (!s.empty()) {
...
}
// escape: no possible path
if (Prev[sink] == -1) break;
// find possible max-flow
// flow the max-flow
total_flow += flow;
}
return total_flow;
}
๋จผ์ dfs ๊ตฌํ ๋ถ๋ถ์ ์ดํด๋ณด์.
int Prev[MAX];
fill(Prev, Prev + MAX, -1);
Prev[source] = source;
stack<int> s;
s.push(source);
// dfs
while (!s.empty()) {
int curr = s.top();
s.pop();
if(curr == sink) break;
for (int i = 0; i < MAX; i++) {
if (Prev[i] == -1 && capacity[curr][i] > 0) {
s.push(i);
Prev[i] = curr;
}
}
}
// escape: no possible path
if (Prev[sink] == -1) break;
stack<int>
๋ฅผ ์ด์ฉํด DFS๋ฅผ ๊ตฌํํ์ผ๋ฉฐ, Prev[]
์ path history๋ฅผ ๊ธฐ๋กํ๋ค. ๋ง์ฝ sink
์ ๋๋ฌํ๋ค๋ฉด, ๊ทธ๋ํ ํ์์ ์ข
๋ฃํ๋ค. ๋ง์ฝ sink
์ ๋๋ฌํ์ง ๋ชป ํ๋ค๋ฉด ์ฆ sink๋ก ๊ฐ๋ ๊ฒฝ๋ก๋ฅผ ์ฐพ์ง ๋ชป ํ๋ค๋ฉด, Prev[sink]
์ ๊ฐ์ด ๊ฐฑ์ ๋์ง ์์ผ๋ฏ๋ก Prev[sink] == -1
์ด ๋๋ค. ์ด ๊ฒฝ์ฐ๋ผ๋ฉด, ์๊ณ ๋ฆฌ์ฆ์ ์ข
๋ฃํ๋ค.
์ฌ์ค ์์ ์๊ณ ๋ฆฌ์ฆ์ ์๋์ ๊ฐ์ด ์ตธํผ ๊ฐ์ ํ ์ ์๋ค.
int Prev[MAX];
fill(Prev, Prev + MAX, -1);
Prev[source] = source;
stack<int> s;
s.push(source);
// dfs
while (!s.empty()) {
int curr = s.top();
s.pop();
for (int i = 0; i < MAX; i++) {
if (Prev[i] == -1 && capacity[curr][i] > 0) {
s.push(i);
Prev[i] = curr;
if (i == sink) break;
}
}
if (Prev[sink] != -1) break;
}
// escape: no possible path
if (Prev[sink] == -1) break;
๋ค๋ง ์ฒ์์ ์ฝ๋์ฒ๋ผ ๊ตฌํํด๋ ํต๊ณผํ๊ธฐ ๋๋ฌธ์ ํฌ๊ฒ ์ ๊ฒฝ์ฐ์ง๋ ๋ง์.
๋ค์์ ์ฐพ์ ๊ฒฝ๋ก๋ฅผ ์ด์ฉํด ๊ทธ๋ํ์ ํ๋ฆด ์ ๋์ ์ฐพ์์ผ ํ๋ค. ์ด๊ฒ์ ์๋์ ์ฝ๋๋ก ์ํํ ์ ์๋ค.
// find possible max-flow
int flow = INT_MAX;
for (int v = sink; v != source; v = Prev[v]) {
flow = min(flow, capacity[Prev[v]][v]);
}
for (int v = sink; v != source; v = Prev[v])
ํจํด์ ๊ทธ๋ํ ํ์์์ ๊ฒฝ๋ก๋ฅผ ์ฌ๊ตฌ์ฑ ํ ๋ ์์ฃผ ์ฐ๋ ํ
ํฌ๋์ด๋ฏ๋ก ์์ง ํ๋๋ก ํ์. ๐
๋ค์์ ๊ฒฝ๋ก์ ์ ๋ flow
๋ฅผ ํ๋ฅด๊ฒ ํ๋ ์์
์ด๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก ๊ฒฝ๋ก๋ฅผ ์ฌํ์ํ๋ฉฐ ์ ๋์ ํ๋ ค๋ณด๋ด๋ฉด ๋๋ค.
// flow the max-flow
for (int v = sink; v != source; v = Prev[v]) {
capacity[Prev[v]][v] -= flow;
capacity[v][Prev[v]] += flow;
}
// update total flow!
total_flow += flow;
์ด๋, ์ญ๋ฐฉํฅ์ผ๋ก๋ capacity๊ฐ ๋์ด๋๋ค๋ ์ฌ์ค์ ์ ์ํ์.
์๊ฐ ๋ณต์ก๋
์์ ๊ทธ๋ฆผ์ <Ford-Fulkerson Algorithm>์์ ์ต์ ์ ์ํฉ์ ์์์ด๋ค. DFS๋ก ๊ฒฝ๋ก๋ฅผ ์ฐพ๋ ๋งค ์ํ๋ง๋ค ์ฉ๋ 1์ ๊ฐ์ด๋ฐ ๊ฐ์ ์ ์ง๋๋ค๊ณ ํ์. ๊ทธ๋ฌ๋ฉด ์ฉ๋ 1,000์ ์ฑ์ฐ๊ธฐ ์ํด 1,000์ iteration์ ์ํํด์ผ ํ๋ค. ์ด๊ฒ์ DFS๋ก ๊ฒฝ๋ก๋ฅผ ํ์ํ๋ <Ford-Fulkerson Algorithm>์ ํ๊ณ์ด๋ค ๐ฅ
์์ ์ํฉ์ ๋ฐํ์ผ๋ก <Ford-Fulkerson Algorithm>์ ์๊ฐ ๋ณต์ก๋๋ฅผ ์ ๋ํด๋ณด์. ๊ทธ๋ํ $G_f$์์ ์ต๋ ์ฉ๋์ด $f_{\max}$๋ผ๊ณ ํ์. ํ๋ฒ์ DFS ํ์์ผ๋ก ํ๋ฆด ์ ์๋ ์ ๋์ ์ต์๊ฐ์ 1์ด๋ฏ๋ก ์ด $f_{\max}$๋ฒ์ DFS๋ฅผ ์ํํด์ผ ํ๋ค. ์ด๋, DFS์ ์๊ฐ๋ณต์ก๋๊ฐ $O(V + E)$์ด๋ฏ๋ก, <Ford-Fulkerson Algorithm>์ $O((V + E) f_{\max})$ ๋งํผ์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ์ง๋ค! ๋ง์ฝ ์ ์ ์ ๊ฐฏ์ $V$๊ฐ ๋ฌด์ํ ๋งํผ ์ ๋ค๋ฉด $O(E \cdot f_{\max})$๋ผ๊ณ ์ ๊ธฐ๋ ํ๋ค.
Edmonds-Karp Algorithm
์์ <Ford-Fulkerson Algorithm>์ ์ฝ๋์์๋ DFS๋ฅผ ํตํด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค. ์ด๋, ๊ฐ์ ์ ์ฐพ๋ ๊ณผ์ ์ BFS๋ก ์ํํ๋ค๋ฉด, <Edmonds-Karp Algorithm>์ด ๋๋ค!
<Edmonds-Karp Algorithm>์ ๊ธฐ์กด <Ford-Fulkerson Algorithm>์ด ์ต๋ ์ฉ๋ $f_{\max}$๊ฐ ํฐ ๊ฒฝ์ฐ์ ์ ๋์ํ์ง ๋ชปํ๋ค๋ ์ ๋๋ฌธ์ ์ ์๋ ์๊ณ ๋ฆฌ์ฆ์ด๋ค. ๊ทธ๋ฐ๋ฐ DFS์์ BFS๋ก ๋ฐ๊พธ๋ฉด ๋ฌด์์ด ๋ฌ๋ผ์ง๋ ๊ฑธ๊น?
๋ค์ ์์ ์์ ๋ฅผ ํตํด ์ดํด๋ณด์.
์ผ๋จ ๋งจ์ฒ์์๋ A - B - C - D
์ ๊ฒฝ๋ก๋ก ์ ๋์ด ํ๋ ๋ค๊ณ ํ์. ๊ทธ ๋ค์์ ํ๋ฅผ ์ ๋์ ์ดํด๋ณด๋ฉด,
- ๋ฐฉ๋ฌธ: [A], ํ: [B, C]
- ๋ฐฉ๋ฌธ: [A, B], ํ: [D] (B -> C๋ ์ด๋ฏธ ์ฉ๋์ด ๋ค ์ฐผ๊ธฐ ๋๋ฌธ์ ๋๋ฌํ ์ ์๋ค)
- ๋ฐฉ๋ฌธ: [A, B, D], ํ: []
- 999๋งํผ์ ์ ๋์ ํ๋ ค๋ณด๋ธ๋ค.
์ด ๊ณผ์ ์ ๋ฐ๋ณตํ๋ฉด ๊ธฐ์กด์ <Ford-Fulkerson Algorithm> ๋ณด๋ค ํจ์ฌ ์ ์ iteration์ผ๋ก ์ด์ ๋์ ๊ตฌํ ์ ์๋ค.
<Edmonds-Karp Algorithm>์ flow์ ๊ฐ๋ณด๋ค๋ edge $E$์ ๋ ์ํฅ์ ๋ฐ๊ฒ ๋๋ค. ์์ธํ ์ฆ๋ช
์ ๊ตฌ์ฌ๊ณผ๋์ ๋ธ๋ก๊ทธ๋ฅผ ํตํด ์ดํด๋ณด์ ๐ ๋์ค์ ์ ๋ฆฌํ๊ฒ ์ต๋๋คโฆ
๊ฒฐ๋ก ์ <Edmonds-Karp Algorithm>์ด $O(VE^2)$์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ์ง๋ค!!
์ด๊ฒ์ผ๋ก ๋คํธ์ํฌ ํ๋ก์ฐ ๋ฌธ์ ์ ๊ธฐ๋ณธ์ ์ธ ๋ ์๊ณ ๋ฆฌ์ฆ์ธ <Ford-Fulkerson Algorithm>๊ณผ <Edmonds-Karp Algorithm>์ ์ดํด๋ณด์๋ค. ๋ ์๊ณ ๋ฆฌ์ฆ์ ์๊ฐ๋ณต์ก๋๊ฐ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ์ํฉ์ ๋ง๊ฒ ์ ์ ํ๊ฒ ์ ํํด ์ฌ์ฉํ๋ฉด ๋๋ค.
๋ค์ ํฌ์คํธ๋ก๋ ๋คํธ์ํฌ ํ๋ก์ฐ๋ฅผ ์ด์ฉํด ํด๊ฒฐํ ์ ์๋ ๋ฌธ์ ๋ค์ ๋ํด ๋ค๋ฃฌ๋ค. ๋ํ์ ์ธ ๋ฌธ์ ๋ก <Bipartite Matching; ์ด๋ถ ๋งค์นญ>๊ณผ ๋คํธ์ํฌ ํ๋ก์ฐ์ ์ ์ฝ(constraint)๋ฅผ ์ถ๊ฐํ ๋ฒ์ ์ ๋ฌธ์ ๋ค์ ์ดํด๋ณผ ์์ ์ด๋ค ๐
๐ Bipartite Matching