组合生成算法
Abstract
组合生成算法按照字典序系统地生成从 中选取 个元素的所有 个 -组合。算法的核心思想是:在递增序列中找到最右边的”可增位”,将其递增并重置后续位。总时间复杂度为 。
定义
字典序组合生成算法(Lexicographic Combination Generation)
给定当前 -组合 (满足 ),求其在字典序中的后继组合。算法步骤如下:
步骤1:从右向左找到最右边的可增位 ,即满足 的最大下标 。
- 直观含义: 还可以增大(增大后仍能为后续元素留出足够空间)。
步骤2:将 递增1,即 。
步骤3:将 之后的所有位重置为最小值:(对 )。
- 直观含义:在增大 后,后续位应取尽可能小的值以得到字典序中的下一个组合。
终止条件:当找不到满足 的位置 时,当前组合即为字典序最后一个组合 。
核心性质
| 编号 | 性质 | 说明 |
|---|---|---|
| 1 | 完备性 | 算法恰好生成所有 个 -组合,无遗漏、无重复 |
| 2 | 字典序保证 | 生成的组合序列严格按字典序递增 |
| 3 | 单步复杂度 | 每次求后继的时间复杂度为 (扫描+重置) |
| 4 | 总复杂度 | 生成所有组合的总复杂度为 |
| 5 | 与排列生成算法的类比 | 两者都基于”找可变位→修改→重置”的三步模式,但组合需维护递增约束 |
关系网络
graph TD A["组合生成算法"] --> B["字典序<br/>[[字典序]]"] A --> C["排列生成算法<br/>[[排列生成算法]]"] A --> D["算法复杂度<br/>$O(r \\cdot \\binom{n}{r})$"] B --> E["全序关系<br/>保证组合无遗漏"] C --> F["类似思想<br/>找最长递减后缀"] D --> G["最优下界<br/>$\\Omega(\\binom{n}{r})$(必须输出所有组合)"] A --> H["组合<br/>[[组合]]"] A --> I["可重排列<br/>[[可重排列]]"]
章节扩展
- 第6.6节:本概念是Rosen教材第6.6节的核心算法之一,与排列生成算法并列。
- 位向量法:另一种生成组合的方法,使用长度为 的二进制串(恰好 个1),按字典序枚举所有含 个1的二进制串。
- 应用场景:子集枚举、组合优化问题的穷举搜索、Apriori关联规则挖掘中的候选集生成。
补充
算法伪代码
procedure NextCombination(c[1..r], n) // 步骤1: 找最右可增位 i ← r while i ≥ 1 and c[i] = n - r + i do i ← i - 1 if i = 0 then return "无后继" // 当前为最后一个组合 // 步骤2: 递增该位 c[i] ← c[i] + 1 // 步骤3: 重置后续位 for j ← i + 1 to r do c[j] ← c[j-1] + 1 return c要生成所有 -组合,从 开始,反复调用
NextCombination直到返回”无后继”。
执行示例(n=5, r=3)
从 开始的字典序组合序列:
以 为例演示算法:
- 步骤1:从右检查,(不可增),(可增),故
- 步骤2:
- 步骤3:,得
以 为例:
- 步骤1:(不可增),(不可增),(可增),故
- 步骤2:
- 步骤3:,,得