Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

第五章:圖與路徑:從流程網路找到最短可行路線

本章目標
情境與限制
可重現規則

什麼是圖

在資料結構裡,「圖」不是長條圖或折線圖,而是一種由節點(node)和(edge)組成的結構。

用最直覺的方式來想:

舉一個辦公室簽核的例子。假設一份申請需要從「整理需求」出發,可以先走向「完成文件」,也可以走向「法務確認」,最後才到「送審」。每一步的等待天數不同,這就是圖的基本形狀。

整理需求 ──(2天)──> 完成文件 ──(3天)──> 送審
    \                                      ↑
     \──(5天)──> 法務確認 ──(1天)──────────/

在程式裡,這張圖可以用一個字典來表示:

graph = {
    "整理需求": {"完成文件": 2, "法務確認": 5},
    "完成文件": {"送審": 3},
    "法務確認": {"送審": 1},
    "送審": {},
}

每個鍵是一個節點,對應的字典裡記錄了鄰居節點與邊的成本。

有向圖與無向圖

圖依照邊的方向性,可以分成兩種:

類型意思生活情境
有向圖邊有方向,A → B 不代表 B → A簽核流程、資料管線、網頁連結
無向圖邊沒有方向,A — B 兩側都可走道路地圖(雙向通行)、社交關係

本章使用的是有向圖:從「整理需求」可以走到「完成文件」,但流程不會逆轉。這對表達工作流程非常自然。

BFS 與 Dijkstra:找路的兩種方式

同樣是「從 A 到 B 怎麼走」,不同情境適合不同算法:

方法適合情境找到的是
BFS(廣度優先搜尋)邊的成本全部相同(或不在乎成本)經過節點最少的路徑
Dijkstra邊的成本不同(有權重)總成本最低的路徑

為什麼最短路徑不一定是「跳數最少」?

想像你要從台北到高雄。走國道可能只需「1 段路」,但路途遙遠;搭高鐵要「換乘 2 次」,但時間最短。如果你的目標是節省時間,那跳數少的那條路根本不是最好的選擇。

這就是 Dijkstra 比 BFS 更適合有成本場景的原因:它評估的是累積代價,而不是步數

Dijkstra 的運作邏輯

Dijkstra 的核心想法是:

每次從「目前已知成本最低的未確認節點」開始擴展。

具體步驟如下:

  1. 把起點的成本設為 0,其他所有節點設為無限大。

  2. 用優先佇列(min-heap)維護「待探索的節點 + 目前已知最低成本」。

  3. 每次從優先佇列取出成本最低的節點,嘗試更新它的所有鄰居。

  4. 如果經過這個節點的路徑比先前記錄的更短,就更新並記下「從哪裡來」。

  5. 到達終點時停止,沿「從哪裡來」往回還原完整路徑。

用上面簽核流程的例子走一遍:

步驟目前節點已知最低成本
起始整理需求整理需求=0, 其他=∞
第 1 步整理需求完成文件=2, 法務確認=5
第 2 步完成文件(成本 2 最低)送審=5(經完成文件)
第 3 步送審(成本 5) vs 法務確認(成本 5)法務確認→送審=6,不更新
結果整理需求 → 完成文件 → 送審總成本 = 5 天

實作範例

請參考 examples/ch05/routing.py。請在專案根目錄執行程式,以確保路徑正確。

from examples.ch05.routing import shortest_route

graph = {
    "A": {"B": 4, "C": 2},
    "B": {"D": 5},
    "C": {"B": 1, "D": 8},
    "D": {},
}

cost, path = shortest_route(graph, "A", "D")
print(cost)   # 8
print(path)   # ["A", "C", "B", "D"]

這個例子中,A → B → D 看起來只走 2 步(跳數最少),但總成本是 9;而 A → C → B → D 走了 3 步,總成本卻只有 8。Dijkstra 正確地找出了成本更低的那條路。

示範流程包含:

哪些問題可以用圖來想

圖不只是地圖問題專用。只要問題裡有「從 A 到 B,中間要經過哪些步驟」的結構,通常都可以用圖來描述:

日常情境節點邊的成本
通勤路線車站、換乘點行車時間、步行距離
簽核流程部門、審核角色審核天數、轉交等待時間
資料管線資料轉換步驟處理時間、儲存成本
任務依賴排序任務節點是否有前置依賴(下一章主題)

當你開始用「節點 + 邊 + 成本」的方式看問題,很多原本覺得說不清楚的流程卡關,都會變得容易診斷。