Skip to content

4.7 设计图而非算法

"将问题建模为图问题后,标准图算法自动解决。" — Steven Skiena, The Algorithm Design Manual


学习目标

  • 理解 Skiena 的"设计图而非算法"原则
  • 掌握常见问题到图问题的映射
  • 明确人机分工:建模是人的工作,执行是机器的工作
  • 识别 LLM 在图建模中的常见错误

Skiena 的核心原则

Skiena 在《算法设计手册》中提出一个深刻观点:

"设计图而非算法"

意思是:

  1. 图算法是一个成熟的算法库:BFS、DFS、拓扑排序、最短路、最大流……
  2. 一旦你把问题正确地建模为图问题,标准算法会自动解决它
  3. 真正的难点不是"用 BFS 还是 DFS",而是"这个问题能建模为图吗"

这个原则直接映射到 LLM 时代的人机分工:

┌─────────────────────────────────────────────────────────────────────┐
│  人机分工: 建模 vs 实现                                              │
│  ─────────────────────────────────────────────────────────────────  │
│                                                                     │
│  人负责(创造性):                                                   │
│  ├── 识别问题是否可建模为图                                         │
│  ├── 定义顶点、边、权                                               │
│  ├── 选择图算法类别(遍历、最短路、流)                             │
│  └── 判断建模是否正确                                               │
│                                                                     │
│  LLM 负责(机械性):                                                 │
│  ├── 实现标准图算法                                                 │
│  ├── 选择具体算法(BFS/DFS、Dijkstra/BF)                           │
│  ├── 生成代码                                                       │
│  └── 提供测试用例                                                   │
│                                                                     │
│  人必须判断:                                                        │
│  ├── 建模是否遗漏约束                                               │
│  ├── 算法选择是否匹配问题特性                                       │
│  └── 边界情况是否覆盖                                               │
└─────────────────────────────────────────────────────────────────────┘

经典映射

调度问题 → 拓扑排序

问题:有 n 门课程,有些课程有先修要求。求一个合法的修课顺序。

图建模

  • 顶点:课程
  • 边:A → B 表示"A 是 B 的先修课"
  • 问题:求一个拓扑序

算法:拓扑排序(Kahn 或 DFS 逆后序)

注意:如果图有环,说明先修关系矛盾。LLM 实现拓扑排序时容易忽略环检测


路径规划 → 最短路径

问题:城市之间有道路,求从 A 到 B 的最短路径。

图建模

  • 顶点:城市
  • 边:道路(有向或无向)
  • 权:距离、时间或费用
  • 问题:求最短路径

算法选择

条件算法
非负权,单源Dijkstra
负权可能存在Bellman-Ford
全源最短路Floyd-Warshall

常见错误:有权为负时用 Dijkstra。


资源分配 → 网络流

问题:工厂到仓库到零售商,每条运输线有容量限制,求最大运输量。

图建模

  • 顶点:工厂、仓库、零售商
  • 边:运输线
  • 权:容量
  • 问题:求从源点到汇点的最大流

算法:Ford-Fulkerson 或推送-重贴标签

建模细节

  • 源点:虚拟起点,连接所有工厂
  • 汇点:虚拟终点,连接所有零售商
  • 二部匹配是最大流的特例

连通性问题 → BFS/DFS

问题:社交网络中,判断两个人是否有连接;找出所有的圈子。

图建模

  • 顶点:用户
  • 边:好友关系
  • 问题:求连通分量

算法

  • BFS/DFS 可以求连通分量
  • 并查集适合动态连通性问题

环检测 → DFS

问题:任务调度是否有循环依赖?

图建模

  • 顶点:任务
  • 边:A → B 表示"A 必须在 B 之前完成"
  • 问题:检测有向图中是否有环

算法:DFS,如果发现后向边则图有环


常见建模错误

错误 1:遗漏约束

场景:物流配送,需要考虑时间窗约束。

错误建模

  • 顶点:配送点
  • 边:可达路径
  • 权:距离

问题:Dijkstra 只考虑距离,忽略了"某些客户只能在特定时间段收货"的约束。

正确建模:时间窗约束需要建模为时间扩展图(time-expanded graph),或使用约束规划。


错误 2:定义错误

场景:社交网络影响力传播。

错误建模

  • 顶点:用户
  • 边:关注关系
  • 问题:求影响力最大的 k 个用户

问题:影响力传播不是简单的最短路或最大流。需要使用 Influence Maximization 算法(如 CELF)。

教训:问题名称相似不代表算法相同。


错误 3:算法选择错误

场景:带负权的最短路径。

错误:使用 Dijkstra。

正确:Bellman-Ford 可以处理负权,并检测负权环。


错误 4:环检测遗漏

场景:课程排课。

错误:LLM 实现拓扑排序时,直接返回排序结果,不检测环。

后果:如果课程依赖关系有循环,拓扑排序结果无意义,但程序不报错。

正确:拓扑排序必须包含环检测。


LLM 融合点

任务:让 LLM 建模

给 LLM 一个问题描述,让它建模为图问题。

提示词

问题描述:某公司有 n 个项目,某些项目有依赖关系(A 必须在 B 之前完成)。
请将这个问题建模为图问题,定义:
1. 顶点是什么
2. 边是什么
3. 边是否有向
4. 问题是求什么

你需要判断

  1. 建模是否正确?
  2. 是否遗漏约束?
  3. 算法选择是否正确?

任务:让 LLM 实现,你审查

给 LLM 一个建模好的图问题,让它实现算法。

提示词

图结构:
- 顶点:{A, B, C, D, E}
- 边:A→B, A→C, B→D, C→D, D→E

任务:实现拓扑排序。

要求:
1. 包含环检测
2. 如果有环,返回错误
3. 用 Python 实现

你需要审查

  1. 是否真的包含环检测?
  2. 环检测逻辑是否正确?
  3. 边界情况是否处理(空图、单顶点)?

实战练习

练习 1:课程排课

某专业有 8 门必修课,先修关系如下:

  • C1 需要先修 C0
  • C2 需要先修 C0
  • C3 需要先修 C1, C2
  • C4 需要先修 C3
  • C5 需要先修 C3
  • C6 需要先修 C4, C5
  • C7 需要先修 C6

任务

  1. 将问题建模为图(定义顶点、边)
  2. 用拓扑排序求合法修课顺序
  3. 如果加入约束"C5 需要先修 C7",会发生什么?

练习 2:网络路由

某网络有 6 个路由器,延迟矩阵如下:

     R1   R2   R3   R4   R5   R6
R1   0    10   inf  30   inf  inf
R2   10   0    20   inf  inf  inf
R3   inf  20   0    10   20   inf
R4   30   inf  10   0    inf  20
R5   inf  inf  20   inf  0    10
R6   inf  inf  inf  20   10   0

任务

  1. 将问题建模为图
  2. 用 Dijkstra 求 R1 到所有路由器的最短路径
  3. 如果 R3→R4 的延迟变为 -5(奖励链路),还能用 Dijkstra 吗?

练习 3:二部匹配

某公司有 5 个职位和 5 个候选人,候选人的适配情况:

  • 候选人 1 适合职位 A, C
  • 候选人 2 适合职位 A, B
  • 候选人 3 适合职位 B, D
  • 候选人 4 适合职位 C, E
  • 候选人 5 适合职位 D, E

任务

  1. 将问题建模为二部图
  2. 建模为网络流问题
  3. 用最大流求最大匹配

小结

"设计图而非算法"原则

  1. 问题建模为图问题后,标准算法自动解决
  2. 建模是创造性的工作,需要人对问题的深刻理解
  3. LLM 可以实现算法,但不能替代建模判断

人机分工

任务人/LLM说明
识别是否为图问题需要对问题的理解
定义顶点、边、权建模核心
选择算法类别需要判断问题特性
判断建模正确性关键判断点
实现标准算法LLM机械性工作
选择具体算法LLM在人类确定的类别内选择
生成代码LLM翻译工作
提供测试用例LLM机械性工作

常见错误:遗漏约束、定义错误、算法选择错误、环检测遗漏


参考文献

  • Skiena, The Algorithm Design Manual, 3rd ed., Chapter 5
  • CLRS, Introduction to Algorithms, 4th ed., Chapters 22-26
  • "LLMs+Graphs: Toward Graph-Native, Synergistic AI Systems", arXiv 2026-06

新时代的算法课程