分治算法
Abstract
分治算法(Divide-and-Conquer Algorithm)是一种将规模为 的问题分解为若干规模更小的子问题、递归求解后合并结果的算法设计范式。其复杂度由分治递推关系 刻画,其中 为子问题个数, 为缩小因子, 为合并开销。经典应用包括归并排序 、二分查找 、快速整数乘法 和 Strassen 矩阵乘法 。
定义
分治算法(Divide-and-Conquer Algorithm)
分治算法遵循”分而治之”(Divide et impera)的策略,包含三个步骤:
- 分解(Divide):将规模为 的问题分解为 个规模为 的子问题
- 解决(Conquer):递归地求解每个子问题
- 合并(Combine):将子问题的解合并为原问题的解,合并开销为
若 表示求解规模为 的问题所需的总操作数,则
这称为分治递推关系。
- :子问题的个数
- :问题规模缩小的因子( 的整数)
- :合并步骤的额外开销
- 当 不是 的幂时,子问题规模取 或
递推展开公式
核心性质
| 编号 | 经典算法 | 递推关系 | 参数 | 复杂度 | 说明 |
|---|---|---|---|---|---|
| 1 | 二分查找 | 每次缩减为规模 的子问题 | |||
| 2 | 最大最小值查找 | 两个子序列分别查找后合并比较 | |||
| 3 | 归并排序 | 合并两个有序子列表需 次比较 | |||
| 4 | 快速整数乘法 | 分解为 3 个 位乘法, | |||
| 5 | Strassen 矩阵乘法 | 7 个子矩阵乘法, | |||
| 6 | 最近点对 | 带状区域每个点至多比较 7 个其他点 |
| 编号 | 设计要素 | 影响 | 优化方向 |
|---|---|---|---|
| A | 子问题个数 | 越少越好 | 减少递归分支 |
| B | 规模缩小因子 | 越大越好 | 问题缩小得越快 |
| C | 合并开销 | 越小越好 | 高效的合并策略 |
关系网络
graph LR A["分治算法"] -->|"复杂度刻画"| B["[[离散数学/concepts/主定理]]"] A -->|"递推关系"| C["[[离散数学/concepts/递推关系]]"] A -->|"效率度量"| D["[[离散数学/concepts/算法复杂度]]"] A -->|"设计范式"| E["[[离散数学/concepts/算法]]"] A -->|"实现方式"| F["[[离散数学/concepts/递归算法]]"] A -->|"分析工具"| G["[[离散数学/concepts/大O记号]]"] A -->|"经典案例"| H["归并排序 O(n log n)"] A -->|"经典案例"| I["二分查找 O(log n)"] A -->|"经典案例"| J["快速整数乘法 O(n^1.585)"] A -->|"经典案例"| K["Strassen 矩阵乘法 O(n^2.807)"] A -->|"经典案例"| L["最近点对 O(n log n)"] B -->|"直接求解"| M["分治递推关系"] C -->|"建立"| M G -->|"表示复杂度"| D
章节扩展
第08章 高级计数技术 — 8.3 分治算法与递推关系
分治算法是 8.3 节的核心主题,本节系统介绍了分治递推关系的建立与求解方法:
- 分治递推关系:一般形式 ,通过递推展开法可得闭式
- Theorem 1( 的特殊情况): 的解为 ()或 ()
- 主定理: 的三种情况判定,详见主定理
- 最近点对问题:Michael Shamos 提出的分治算法,通过递归分割 + 带状区域检查实现 复杂度
递归树法分析
递归树法是理解分治算法复杂度的直观方法,将递推关系展开为一棵树:
- 根节点:原问题,工作量为
- 第 层: 个子问题,每个规模为 ,每层总工作量
- 叶子节点: 个,每个工作量为
- 总工作量:所有层的工作量之和
三种典型模式:
- 每层工作量递减():根节点主导,
- 每层工作量相同(): 层等量相加,
- 每层工作量递增():叶子节点主导,
补充
分治思想的历史与直觉
“分而治之”(Divide et impera)的思想可追溯到古罗马的凯撒大帝。在计算机科学中,分治策略是最高效的算法设计范式之一。其核心直觉可以用”组织大型活动”来类比:如果要组织 1000 人的活动,直接管理所有人效率极低( 的沟通成本);更好的方式是将 1000 人分成若干小组,每组指定组长,再由组长管理组员——这就是分治思想的本质。
分治算法的效率取决于三个因素:子问题个数 (越少越好)、规模缩小因子 (越大越好)、合并开销 (越小越好)。主定理精确地刻画了这三个因素如何共同决定最终复杂度。
Strassen 矩阵乘法的突破意义
Volker Strassen 于 1969 年发明的方法将两个 矩阵的乘法从传统的 降低到 。这一突破打破了”矩阵乘法不可能快于 “的长期直觉,开启了快速矩阵乘法的研究热潮。此后 Coppersmith-Winograd 等算法进一步将复杂度降至 以下。