Skip to content

8.9 综合练习

本章综合应用:归约设计、近似分析、NP完全性判定、LLM协同实验


练习设计理念

本章练习不使用固定的"基础/进阶/挑战"三层结构,而是多样化类型,强调:

  • 理解"为什么"而非机械模仿
  • 从错误中学习(诊断练习)
  • 探索边界条件(变式练习)
  • 人机协作设计(LLM协同)

一、问题情境与直觉(建立理解)

1. 验证与发现的直觉

问题:举一个日常生活中的"验证易、发现难"的例子(非TSP),并解释其与NP理论的关联。

参考答案要点

  • 数独:验证填好的数独只需检查每行、每列、每宫不重复(秒级),但从空盘找解需要尝试大量组合(可能数小时)
  • 密码:验证密码是否正确只需一次尝试比对(微秒),但破解密码需要尝试所有可能(可能永远无法破解)
  • 区块链验证:验证区块合法性只需检查哈希和签名(秒级),但挖矿找合法区块需要大量计算(分钟到小时)

追问:这些例子中,"证书"是什么?验证器是什么?


2. P vs NP的直觉

问题:用"考试"类比解释P和NP的区别。如果P=NP,考试会发生什么变化?

直觉建立

  • P问题 = 有确定答案的考试,老师在规定时间内能完成评分
  • NP问题 = 有答案的考试,老师能快速验证答案是否正确,但学生可能无法快速找到答案
  • P=NP = 学生总能像老师一样快速找到答案 → 所有考试都变简单了

追问:为什么大多数人相信P≠NP?这个信念有什么依据?


3. Cook定理的直觉

问题:为什么说SAT是"NP问题的通用语言"?Cook定理的核心洞察是什么?

直觉建立

  • 任何NP问题都可以用"验证器"描述
  • 验证器是一个程序(图灵机)
  • 程序的执行过程可以编码为布尔约束
  • 因此,任何NP问题都可以转化为SAT

追问:这给我们什么启示?(答案:SAT求解器的进步可以推动所有NP问题的求解)


4. 归约的直觉

问题:为什么归约像"翻译"?翻译能保持问题的难度吗?

直觉建立

  • 归约 = 把A问题的实例翻译成B问题的实例
  • 翻译不能改变问题的"是否有解"
  • 翻译过程不能太复杂(多项式时间)
  • 如果翻译后容易解,则原问题也容易解

追问:归约方向如何选择?为什么A ≤ₚ B意味着"A不比B更难"?


5. 近似算法的直觉

问题:为什么顶点覆盖的贪心算法(选边→加两个端点)是2-近似?关键洞察是什么?

直觉建立

  • 算法选的边不共享顶点(每选一条边,删除所有相连边)
  • 每条边至少需要一个顶点来覆盖
  • 因此最优解至少要选算法选的边数那么多顶点
  • 算法选了2倍边数的顶点 → 近似比为2

追问:为什么这个证明成立?关键是什么?(答案:边不共享顶点)


二、方法应用与实现(掌握操作)

6. SAT验证器实现

实现要求

python
def sat_verify(formula, assignment):
    """
    SAT验证器:检查给定赋值是否使公式为真
    
    参数:
    - formula: 合取范式,列表的列表,每个子句是文字列表
      文字表示:(变量名, 是否否定) 如 ('x1', True) 表示 ¬x1
    - assignment: 变量赋值字典 {'x1': True, 'x2': False, ...}
    
    返回:True 如果赋值使公式为真
    """
    pass

测试用例

python
formula = [
    [('x1', False), ('x2', True)],   # (x1 ∨ ¬x2)
    [('x1', True), ('x3', False)],   # (¬x1 ∨ x3)
    [('x2', False), ('x3', False)]   # (x2 ∨ x3)
]
assignment1 = {'x1': True, 'x2': False, 'x3': True}  # 应返回True
assignment2 = {'x1': False, 'x2': False, 'x3': False}  # 应返回False

7. SAT到3-SAT归约实现

实现要求

python
def sat_to_3sat(formula):
    """
    SAT到3-SAT归约
    
    参数:
    - formula: SAT实例,每个子句长度任意
    
    返回:
    - 3sat_formula: 每个子句恰好3文字
    - auxiliary_vars: 辅助变量列表
    """
    pass

要求

  • 处理长子句(>3文字):引入辅助变量分组
  • 处理短子句(<3文字):引入重复文字
  • 返回转化后的公式和新变量列表

8. 顶点覆盖2-近似实现

实现要求

python
def approx_vertex_cover(edges):
    """
    顶点覆盖2-近似算法
    
    参数:
    - edges: 边列表 [(u, v), ...]
    
    返回:
    - cover: 覆盖集合(顶点列表)
    """
    pass

验证:在以下图上运行,验证近似比不超过2:

  • 完全图K₄:4个顶点,6条边
  • 星形图:5个顶点,中心顶点连接4个外围顶点

9. 补图构造实现

实现要求

python
def complement_graph(vertices, edges):
    """
    构造补图
    
    参数:
    - vertices: 顶点列表
    - edges: 边列表
    
    返回:
    - complement_edges: 补图的边列表
    """
    pass

用途:用于Vertex Cover到CLIQUE的归约


三、错误诊断与反例(识别错误)

10. 归约方向错误诊断

错误描述

某人声称:"我证明了顶点覆盖是NP完全的,
方法是构造从顶点覆盖到3-SAT的归约。"

诊断任务

  • 这个归约方向正确吗?
  • 为什么这个方向不能证明NP完全性?
  • 正确的归约方向是什么?

关键点:归约方向错误 → 证明无效


11. 归约构造错误诊断

错误描述

某人设计SAT到Vertex Cover的归约:
"把每个变量变成一个顶点,每个子句变成一条边,
子句边连接子句中的所有变量顶点。"

诊断任务

  • 这个构造有什么问题?
  • 为什么不能保证等价性?
  • 构造一个反例:SAT可满足但构造的图无小覆盖

关键点:变量器件缺失 → 无法强制二选一


12. 近似算法反例

反例任务: 构造一个图,使得"贪心选度最大顶点"的顶点覆盖算法近似比超过常数。

提示

  • 设计一个图,度最大的顶点覆盖很少边
  • 剩余边需要大量顶点覆盖
  • 对比最优解(选度小的顶点覆盖更多边)

示例构造

考虑"大星星+小星星"结构:
- 中心顶点v0连接n个外围顶点v1...vn
- 每个外围顶点vi又连接k个小顶点
- 贪心选v0(度=n),但剩余边需要nk个小顶点
- 最优解选外围顶点(n个),覆盖所有边

13. Dijkstra负权反例迁移

问题:在图算法中,我们学习了Dijkstra不能处理负权边。这与NP完全性有什么关系?

诊断任务

  • 负权最短路径问题是否NP完全?
  • 为什么Dijkstra失败?贪心选择被破坏
  • 负权最短路径有什么特殊性质?

关键洞察:有些问题因为特殊结构变简单,有些因为负权/负环变复杂


四、方案比较与权衡(理解适用场景)

14. 应对策略比较

比较任务: 对于以下NP完全问题场景,选择最合适的应对策略:

场景问题规模需求建议策略
物流路线规划(20个城市)需要最优解
课程排课(100门课)可接受近似
蛋白质折叠预测实用效果
SAT求解(100变量)快速求解

要求:说明选择理由,分析各策略优劣


15. 近似算法比较

比较任务: 比较顶点覆盖问题的三种方法:

方法时间复杂度近似比适用场景
精确算法(分支限界)O(2^n) 最坏1(最优)小规模
2-近似贪心O(E)2需要保证
度贪心启发式O(V·E) 或更好无保证实用

讨论:为什么有保证的近似算法优于无保证的启发式?什么时候启发式更好?


16. 归约源问题选择

决策任务: 对于以下新问题,选择合适的归约源问题:

新问题核心特征建议源问题原因
课程排课冲突检测时间约束、资源分配
社交网络影响力最大化选择顶点、覆盖邻居
DNA序列拼接路径、连接
任务调度(带依赖)DAG、顺序

要求:根据问题特征(布尔约束、数值、图、路径)选择四核心源


17. LLM温度与模拟退火温度

比较任务: LLM采样温度和模拟退火温度有什么相似之处?

特征模拟退火温度LLM采样温度
高温
低温
温度调度
目的

追问:这个类比告诉我们什么设计原则?


五、变式与边界条件(探索边界)

18. 特殊结构变简单

问题: 如果图是树结构,顶点覆盖问题是否多项式时间可解?

分析任务

  • 为什么树的顶点覆盖变简单?
  • 设计一个树上的顶点覆盖算法
  • 时间复杂度是什么?

提示:树上没有环,可以用动态规划


19. 限制条件变化

问题: 如果限制每个顶点度数不超过d,问题复杂度如何变化?

分析任务

  • d=1:问题变简单吗?
  • d=2:问题变简单吗?
  • d=3:问题变简单吗?
  • 一般情况:度数限制有什么影响?

关键洞察:有些限制使问题变简单,有些不改变NP完全性


20. 2-SAT的特殊性

问题: 为什么2-SAT(每个子句最多2文字)是多项式时间可解的?

分析任务

  • 2-SAT与3-SAT有什么本质区别?
  • 为什么子句长度从3变成2,复杂度骤降?
  • 2-SAT的多项式算法是什么?(提示:强连通分量)

关键洞察:临界点——2与3的差异


21. 空实例与极端情况

分析任务: 分析以下边界情况:

情况SATVertex CoverTSP
空输入(无变量/顶点)
单元素
无约束(空公式/无边)
全约束(矛盾公式/完全图)

要求:说明每种情况是否有解,最优解是什么


六、归约设计练习(综合应用)

22. 简单归约设计

任务:设计从CLIQUE到Vertex Cover的归约

要求

  • 说明归约构造(如何把团问题实例转换为顶点覆盖实例)
  • 论证等价性(正向和反向)
  • 分析归约时间复杂度

提示:利用补图变换定理:S是G的覆盖 ⟺ V\S是G'的团


23. 归约器件构造

任务:给定3-SAT实例:(x∨y∨¬z)∧(¬x∨y∨z)∧(x∨¬y∨z)

要求

  • 画出对应的Vertex Cover器件图
  • 标注变量器件和子句器件
  • 给出一个可满足赋值,构造对应覆盖
  • 给出覆盖大小k = n + 2c = 3 + 6 = 9

24. 新问题NP完全性证明(开放)

任务:判断以下问题是否NP完全,并尝试证明

问题:Exact Cover by 3-Sets (X3C)

  • 输入:集合X(|X|=3q),3-元组集合C
  • 问题:是否存在C的子集S,使得S中所有元组恰好覆盖X每个元素一次?

分析步骤

  1. 证明问题在NP中(设计验证器)
  2. 选择源问题(3-SAT或Vertex Cover)
  3. 设计归约构造
  4. 论证等价性

提示:可以用3-SAT归约,变量器件确保选择,子句器件确保覆盖


七、思考题(深层理解)

25. 为什么P=NP是猜想?

思考

  • 为什么P=NP(或P≠NP)至今未被证明?
  • 证明P≠NP有什么困难?
  • 证明P=NP有什么困难?
  • 这个问题为什么重要?

关键点:证明不存在性 vs 发现存在性


26. 为什么SAT是NP完全?

思考

  • Cook定理的核心是什么?
  • 为什么任何NP问题都能转化为SAT?
  • 这给我们什么实践启示?

关键洞察:SAT是"计算的语言"


27. 为什么归约器件这样构造?

思考

  • 3-SAT → VC的变量器件为什么是一条边?
  • 子句器件为什么是三角形?
  • 为什么连接要这样设计?

追问:器件设计有什么原则?(参考Skiena六法则)


28. 为什么近似算法有保证?

思考

  • 2-近似算法的证明关键是什么?
  • 为什么"边不共享顶点"这个性质重要?
  • 这个性质如何保证近似比?

关键洞察:证明依赖于算法选择的特殊性质


29. 为什么验证比生成容易?

思考

  • 这个现象是偶然的吗?
  • 与计算的本质有什么关系?
  • 对AI系统设计有什么启示?

深层理解:NP理论揭示了计算的非对称性


八、LLM协同实验(人机协作)

30. 让LLM验证归约正确性

实验任务: 让LLM验证3-SAT到Vertex Cover归约的正确性。

输入给LLM

请验证以下归约构造的正确性:

归约:3-SAT到Vertex Cover

构造方法:
1. 对每个变量x,创建顶点x和¬x,连一条边(x, ¬x)
2. 对每个子句(x∨y∨z),创建三角形
3. 子句器件的顶点连接到对应的变量器件顶点
4. 目标覆盖大小k = n + 2c(n变量,c子句)

等价性论证:
正向:如果3-SAT可满足,则存在覆盖...
反向:如果存在覆盖,则3-SAT可满足...

请检查:
1. 多项式时间变换
2. 器件正确连接
3. 等价性论证完整性
4. 边界条件覆盖

评价任务

  • LLM发现了哪些问题?
  • LLM遗漏了哪些问题?
  • 如何改进LLM验证流程?

31. 让LLM设计启发式规则

实验任务: 让LLM为TSP设计一个启发式规则。

输入给LLM

请为旅行商问题(TSP)设计一个启发式规则。
要求:
1. 规则简单易实现
2. 在小规模实例上效果好
3. 说明规则的设计思路

测试任务

  • 在10个城市的实例上测试LLM设计的规则
  • 与随机路线、贪心规则比较
  • 评价LLM规则的质量

32. 让LLM分析问题NP完全性

实验任务: 让LLM分析一个新问题的NP完全性。

输入给LLM

分析以下问题的复杂性:

问题:任务调度冲突
- 输入:任务列表T,每个任务有开始时间和结束时间
- 问题:是否能在k个时间段内完成所有任务(无冲突)?

请回答:
1. 这个问题是否在NP中?
2. 是否可能是NP完全的?
3. 应该用什么源问题归约?

评价任务

  • LLM的分析是否正确?
  • LLM的归约建议是否合理?
  • LLM遗漏了什么考虑?

33. 人机协同归约设计

实验任务: 实践"人类设计战略+LLM验证细节"的协作模式。

流程

  1. 人类:选择源问题、设计整体对应关系
  2. LLM:验证器件覆盖完整性
  3. 人类:构造关键器件、论证等价性
  4. LLM:检查论证漏洞、生成反例

记录

  • 协作过程中发现了哪些问题?
  • 人和LLM各自的优势是什么?
  • 如何改进协作流程?

34. Self-Consistency实验

实验任务: 验证Self-Consistency机制的效果。

步骤

  1. 给LLM一个NP完全相关问题(如SAT实例)
  2. 让LLM生成5个候选答案(不同温度)
  3. 验证每个答案的正确性
  4. 选择最一致的答案

分析

  • Self-Consistency是否提高了正确率?
  • 多样性生成是否重要?
  • 这与NP验证思想有什么关系?

九、Agent设计练习(系统设计)

35. 归约识别器Skill设计

设计任务: 设计一个归约识别器Skill的接口和流程。

要求

Skill名称:NP-Complete-Identifier
功能:输入问题描述,输出NP完全性判断及归约建议

接口设计:
- 输入:问题描述文本
- 输出:{
    is_np_complete: boolean,
    confidence: float,
    suggested_source: string,
    reduction_hint: string
  }

流程设计:
1. 问题特征提取
2. 与四核心源问题匹配
3. 归约可行性分析
4. 输出判断和建议

提交:接口定义、流程图、示例输入输出


36. LLM验证Agent设计

设计任务: 设计一个LLM验证Agent,用于验证归约构造的正确性。

要求

  • 输入:归约构造描述文档
  • 输出:验证报告(通过项、警告项、失败项、改进建议)
  • 检查清单:多项式时间、器件连接、等价性、边界条件、NP成员证明

设计要点

  • Agent需要什么能力?
  • 如何组织检查清单?
  • 如何生成改进建议?

37. NP完全问题求解器设计

设计任务: 设计一个NP完全问题求解系统,结合近似算法和LLM启发式。

系统架构

输入:问题实例
1. 问题识别(是否NP完全?)
2. 策略选择(精确/近似/启发式)
3. 近似算法求解(有保证)
4. LLM启发式改进(多样性)
5. 验证最终解
输出:解 + 质量评估

要求:说明各模块功能、决策流程、LLM的角色


十、学习目标自检

完成本章后,你应能回答:

验证与发现

  1. 什么是"计算的非对称性"?
  2. 为什么验证比发现容易?
  3. 这与LLM有什么关系?

P与NP: 4. P类问题是什么? 5. NP类问题是什么? 6. P=NP问题为什么重要?

NP完全性: 7. NP-complete和NP-hard有什么区别? 8. Cook定理的核心是什么? 9. 为什么SAT是NP完全的?

归约: 10. 归约的本质是什么? 11. Skiena六法则是什么? 12. 如何设计归约器件?

经典归约链: 13. SAT到Vertex Cover的器件是什么? 14. Vertex Cover到CLIQUE为什么用补图? 15. 归约链有什么意义?

NP完全性证明: 16. NP完全性证明的五步法是什么? 17. 如何选择归约源问题? 18. 常见错误有哪些?

应对策略: 19. 五种应对策略是什么? 20. 2-近似算法为什么有保证? 21. 启发式方法有什么特点?

LLM时代: 22. Self-Consistency与NP理论有什么关系? 23. LLM能做什么?不能做什么? 24. Prompt设计有什么原则?


十一、项目式综合练习(可选)

项目1:SAT求解器实现

任务:实现一个简单的SAT求解器,测试在不同规模实例上的表现。

要求

  • 实现DPLL算法(回溯+剪枝)
  • 测试10-50变量实例
  • 分析求解时间与变量数的关系
  • 讨论为什么SAT求解器在实践中效果比理论预期好

项目2:归约可视化工具

任务:开发一个归约器件可视化工具。

要求

  • 输入3-SAT实例
  • 输出Vertex Cover器件图的可视化
  • 支持交互:点击器件查看对应关系
  • 支持赋值/覆盖的同步显示

项目3:近似算法性能分析

任务:分析顶点覆盖2-近似算法的实际性能。

要求

  • 生成随机图实例(不同规模)
  • 运行2-近似算法
  • 计算实际近似比(需要最优解,小规模)
  • 分析平均性能与最坏情况的差距

练习设计完成于 2026-06-20


参考答案提示

本练习章节不提供完整答案,而是提供思考方向和关键点,鼓励读者独立思考和验证。

建议学习方法

  1. 先尝试独立解答
  2. 与同学讨论或让LLM验证
  3. 参考本章内容验证答案
  4. 对于LLM协同实验,记录实验结果并分析

新时代的算法课程