跳轉到

第三部分:路徑規劃(續)

< 上一題:備援網路建設 | 返回目錄 | 下一題:部署順序規劃 >


場景:這條路最多能傳多少流量?

市場部說:「我們要在台北和法蘭克福之間傳輸大量資料,整個網路**最多能支撐多少頻寬**?」

不是問「走哪條路最快」,而是問「把所有可能的路都用上,總共能傳多少?」

「從 A 到 B,最多能流多少?」——這是 最大流(Maximum Flow) 問題。


第 7 題:頻寬容量分析 - Max Flow


(a) 流量網路定義

3 分大二

你需要知道:什麼是流量網路?什麼是合法的流?

題目

  1. 定義**流量網路(Flow Network)**

  2. 什麼是**合法流(Valid Flow)**?需要滿足什麼條件?

  3. 定義**最大流(Maximum Flow)**

解答

1. 流量網路

有向圖 \(G = (V, E)\),加上: - 源點(Source) \(s\):流量的起點 - 匯點(Sink) \(t\):流量的終點 - 容量(Capacity) \(c(u,v)\):邊 \((u,v)\) 能承載的最大流量

2. 合法流

函數 \(f: E \to \mathbb{R}^+\) 滿足:

  • 容量限制\(0 \leq f(u,v) \leq c(u,v)\)(不超過容量)
  • 流量守恆:對於 \(v \neq s, t\)
\[\sum_{u} f(u,v) = \sum_{w} f(v,w)\]

(流入 = 流出,中間節點不「儲存」流量)

3. 最大流

\[|f| = \sum_{v} f(s,v) = \sum_{u} f(u,t)\]

最大化 \(|f|\) 的流就是**最大流**。


(b) Ford-Fulkerson 方法

4 分大三

你需要知道:如何找最大流?

題目

  1. 什麼是**剩餘圖(Residual Graph)和**增廣路徑(Augmenting Path)

  2. 說明 Ford-Fulkerson 方法的步驟

  3. 為什麼需要「反向邊」?

解答

1. 剩餘圖與增廣路徑

剩餘容量: $\(c_f(u,v) = c(u,v) - f(u,v)\)$

剩餘圖 \(G_f\): - 正向邊:\(c_f(u,v) > 0\) 時存在 - 反向邊\(f(u,v) > 0\) 時,加入 \((v,u)\),容量為 \(f(u,v)\)

增廣路徑:剩餘圖中從 \(s\)\(t\) 的路徑。

2. Ford-Fulkerson 方法

def ford_fulkerson(graph, s, t):
    # 初始化流為 0
    flow = defaultdict(lambda: defaultdict(int))
    max_flow = 0

    while True:
        # 在剩餘圖中找增廣路徑(BFS 或 DFS)
        path, bottleneck = find_augmenting_path(graph, flow, s, t)
        if path is None:
            break

        # 沿路徑增廣
        max_flow += bottleneck
        for i in range(len(path) - 1):
            u, v = path[i], path[i+1]
            flow[u][v] += bottleneck
            flow[v][u] -= bottleneck  # 反向邊

    return max_flow

3. 為什麼需要反向邊?

反向邊代表「撤銷」之前的流量分配。

例:
    s → a → t(容量 1)
    s → b → t(容量 1)
    a → b(容量 1)

如果先走 s→a→b→t(流量 1),
沒有反向邊的話,s→a→t 就被堵住了。

有反向邊 b→a(容量 1),
可以再走 s→b→a→t... 等等,這不對。

正確例子:
    s → a → b → t(各容量 1)
    s → b(容量 1)

先走 s→a→b→t(流量 1)
反向邊 b→a 出現
再走 s→b,但 b→t 滿了,透過 b→a→??? 不通

實際上反向邊讓我們能「重新分配」流量。

直覺:反向邊讓演算法可以「後悔」之前的決定,重新分配流量以達到全局最優。


© Max-Flow Min-Cut 定理

4 分碩一

你需要知道:最大流等於什麼?

題目

  1. 定義 \(s\)-\(t\) 切割(Cut)**及其**容量

  2. 陳述並解釋 Max-Flow Min-Cut 定理

解答

1. \(s\)-\(t\) 切割

把頂點分成 \(S\)\(T = V - S\),其中 \(s \in S\), \(t \in T\)

切割容量

\[c(S, T) = \sum_{u \in S, v \in T} c(u,v)\]

(從 \(S\)\(T\) 的邊容量總和)

2. Max-Flow Min-Cut 定理

最大流 = 最小切割容量

\[\max_f |f| = \min_{S: s \in S, t \notin S} c(S, T)\]

意義

  • 上界:任何流都不能超過任何切割的容量(因為流必須「穿過」切割)
  • 可達性:Ford-Fulkerson 找到的流恰好等於某個切割的容量

找最小割:當演算法結束時,從 \(s\) 在剩餘圖中可達的頂點集合就是 \(S\)

應用:網路可靠性

最小割 = 要斷開 \(s\)\(t\),至少要切斷多少容量的邊

這告訴你網路的「瓶頸」在哪裡。

如果最小割很小,表示網路脆弱,少數幾條邊失效就會癱瘓。


(d) Edmonds-Karp 演算法

3 分碩一

你需要知道:如何保證 Ford-Fulkerson 的效率?

題目

  1. Ford-Fulkerson 用 DFS 找增廣路徑有什麼問題?

  2. Edmonds-Karp 如何改進?時間複雜度是多少?

解答

1. DFS 的問題

如果容量是無理數(或很大的整數),DFS 可能找到「很差」的增廣路徑,導致: - 每次只增廣很少的流量 - 迭代次數可能非常多(甚至不終止)

2. Edmonds-Karp 改進

BFS 找增廣路徑(最短路徑,邊數最少)。

def find_augmenting_path_bfs(graph, flow, s, t):
    parent = {s: None}
    queue = deque([s])

    while queue:
        u = queue.popleft()
        for v in graph[u]:
            residual = graph[u][v] - flow[u][v]
            if v not in parent and residual > 0:
                parent[v] = u
                if v == t:
                    # 回溯找路徑和瓶頸
                    path = []
                    curr = t
                    bottleneck = float('inf')
                    while curr != s:
                        prev = parent[curr]
                        path.append(curr)
                        bottleneck = min(bottleneck, graph[prev][curr] - flow[prev][curr])
                        curr = prev
                    path.append(s)
                    return path[::-1], bottleneck
                queue.append(v)
    return None, 0

時間複雜度

  • 每次 BFS:\(O(E)\)
  • 最多 \(O(VE)\) 次增廣
  • 總時間\(O(VE^2)\)

為什麼最多 \(O(VE)\) 次?

BFS 保證每次找到的路徑是最短的。可以證明:增廣路徑的長度(邊數)是單調不減的,且每條邊最多成為「瓶頸」\(O(V)\) 次。


進階挑戰:二分圖最大匹配

3 分碩一

你需要知道:Max Flow 有什麼經典應用?

題目

說明如何用最大流解決**二分圖最大匹配(Bipartite Matching)**問題。

解答

問題:給定二分圖 \(G = (U, V, E)\),找最大數量的「配對」,使得每個頂點最多被配對一次。

建模成 Max Flow

  1. 添加源點 \(s\),連接所有 \(U\) 中的頂點,容量 1
  2. 添加匯點 \(t\),所有 \(V\) 中的頂點連接 \(t\),容量 1
  3. 原本的邊 \((u, v)\)\(u \in U\), \(v \in V\))保持,容量 1
    s → u₁ → v₁ → t
      ↘ u₂ → v₂ ↗
          ↘ v₃ ↗

最大流 = 最大匹配數

每個匹配對應一單位流量。


第 7 題小結:你的頻寬分析工具箱

「整個網路最多能傳多少?」
    ├─► (a) 問題定義?→ Max Flow
    │       → 源、匯、容量、流量守恆
    ├─► (b) 怎麼找?→ Ford-Fulkerson
    │       → 剩餘圖 + 增廣路徑
    │       → 反向邊允許「後悔」
    ├─► (c) 流和割的關係?→ Max-Flow = Min-Cut
    │       → 最大流等於最小割容量
    │       → 找出網路瓶頸
    └─► (d) 效率?→ Edmonds-Karp
            → BFS 找最短增廣路徑
            → O(VE²)
概念 重點
流量網路 有向圖 + 源 + 匯 + 容量
合法流 容量限制 + 流量守恆
Ford-Fulkerson 增廣路徑法
Max-Flow Min-Cut 最大流 = 最小割
Edmonds-Karp BFS,\(O(VE^2)\)

< 上一題:備援網路建設 | 返回目錄 | 下一題:部署順序規劃 >