Skip to content

方法Method

子集动态规划

施工中 · 内容逐步修订

Subset dynamic programming

以所有子集为状态执行精确指数动态规划,并准确计算转移枚举量。

形式陈述 ​

状态空间 ​

给定含 n 个元素的有限全集 U,子集动态规划以子集 S⊆U 为状态,必要时再加终点、容量或边界摘要。它沿用动态规划的重叠子问题原则,适合子问题只依赖更小子集、而不同排列能汇入同一摘要的精确指数算法。

状态数 2n 不等于运行时间。若每个 S 只枚举其中的元素,总量为 O(n2n);若每个 S 枚举全部 T⊆S,转移数会增长到 3n。

Hamilton 路状态与证明 ​

给定顶点集为 U、n≥1 的有限简单无向图 G=(U,E)。令 dp[S,v](v∈S)表示存在一条恰好访问 S、终点为 v 的简单路径。基例为 dp[{v},v]=true。当 |S|>1 时,

dp[S,v]=⋁u∈S∖{v}uv∈Edp[S∖{v},u].

必要性来自删除目标路径的最后一条边:前驱必为某个相邻 u,余下路径恰访问 S∖{v}。充分性则把 v 接到已有路径末端;由于 v∉S∖{v},不会重复顶点。按 |S| 归纳便得到“当且仅当”不变量。

三点路径 1−2−3 中,单点状态为真;dp[{1,2},2] 由 1 转移,dp[{1,2,3},3] 再由 2 转移。dp[{1,3},3] 为假,因为缺少边 13。若要输出路径,父指针还需记录让状态成立的 u。

有效 (S,v) 状态共有 n2n−1 个,每个最多枚举 n 个前驱,在状态和邻接查询为常数成本时,直接时间为 O(n22n),空间为 O(n2n)。按邻接 bitset 过滤前驱能改善常数或字操作数,却不改变这一指数状态规模。

直觉

子集状态记录已经使用哪些对象,附加端点或边界状态则保留下一步转移真正需要的历史。每次删除最后一个选择会落到更小子集,表可按 popcount 分层;指数成本来自必须区分 2n 种使用模式,而不是集合操作的语法。

子集动态规划的 bitmask 分层与端点转移
例子与边界

枚举量推导 ​

子掩码循环

T=S,T=(T−1)&S

从 T=S 开始,每轮先处理 T;若 T=0 就结束,否则才执行下一次更新。这样恰好枚举全部 T⊆S,包括空集。若处理零后还继续更新,在固定宽度无符号或通常的按位整数语义下会回到 S,形成循环。对一对 (T,S),每个元素恰有“不属于 S”“属于 S∖T”“属于 T”三种状态,因此

∑S⊆U2|S|=3n.

位技巧让一次得到下个子掩码很便宜,却不能把总转移数写成 O(n2n)。

推论与应用

表示与恢复 ​

当 n≤w 时,bitmask 可放入一个机器字;表地址与索引也须能用该机器模型表示。更大的宇宙需要多字位集,集合差与哈希等操作须按实际访问的字数计费;单元素成员测试仍可用字下标直接定位。按 |S| 分层可为只依赖上一层的 DP 滚动空间,但 Hamilton 路重构仍需父信息或第二次计算。

n=50 时 2n 已远超常规内存,位运算常数不会改变可行性。Meet-in-the-middle 依赖两半之间可组合的摘要,subset DP 依赖重叠子集状态;Held–Karp TSP 则把布尔可达改为以终点为索引的最小费用。这些算法的指数界须连同所选参数解释。以全集大小 n 为参数,O(n22n) 确实具有 FPT 形式;若参数另取解大小 k,同一界就没有把指数限制在 k 上。是否伪多项式则取决于数值大小与输入编码长度,使用 bitmask 本身不能回答这个问题。

参考资料
  • Held, Karp, “A Dynamic Programming Approach to Sequencing Problems,” 1962.
  • Björklund et al., “Fourier Meets Möbius,” STOC 2007.
  • Cygan et al., Parameterized Algorithms, 2015.
关系图谱11 个相邻概念 · 3 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
分类位置

上位 / 更一般

下位 / 直接特例

暂未标注直接特例。

类型化关系