Skip to content

方法Method

容斥算法

施工中 · 内容逐步修订

inclusion-exclusion algorithms · subset transforms

把容斥恒等式实现为指数时间精确计数,并以子集 zeta/Möbius 变换复用交集和。

形式陈述 ​

从恒等式到算法 ​

把容斥原理转成算法时,若对象全集 Ω 为有限集,坏性质对应 A1,…,An,满足所有约束的对象数为

|Ω∖⋃iAi|=∑S⊆[n](−1)|S||⋂i∈SAi|.

算法价值取决于给定 S 时交集计数是否足够便宜;2n 项不会因写成容斥就自动高效。

子集变换 ​

令 n≥0,R 为加法阿贝尔群,对函数 f:2[n]→R 定义 zeta transform

F(S)=∑T⊆Sf(T)

可用逐元素 DP:初始化 F=f,对每位 i,给含 i 的状态加上去掉 i 的值。计入数组初始化,成本为 O((n+1)2n) 次群操作或读写,空间为 O(2n) 个元素。Möbius 逆变换把加法改为减法恢复 f。单独做正向求和只需交换幺半群;可逆变换还要加法逆元。

直觉

容斥用交替符号修正“至少违反一个约束”中的重复计数;子集变换则把许多彼此重叠的子集和沿布尔格边逐维复用。两者的效率都取决于坏性质数量 n,以及固定交集或局部转移能否快速计算,而不是对象全集本身是否庞大。

容斥算法的交集层级与正负贡献
例子与边界

满射计数例子 ​

设 m,n 为非负整数。从 m 个带标号元素映到 n 个盒子的满射数,令 Ai 为盒 i 为空。固定 S 为空盒后有 (n−|S|)m 个函数,因此满射数

∑S⊆[n](−1)|S|(n−|S|)m.

本例每项只依赖 |S|,可以按空盒数量合并,进一步写成

∑k=0n(−1)k(nk)(n−k)m.

因此只需 n+1 个不同项,另计整数幂、二项式系数与大整数求和成本。这里约定 00=1,使空集到空集的唯一函数也被计入;m=0<n 或 n=0<m 时结果均为零。例如 m=3,n=2 时得到 23−2⋅13=6。

数值与边界 ​

符号交替会产生巨大中间整数和严重浮点消去,精确计数应使用大整数或模运算;模数下减法需正规化。空集项符号和 ⋂∅Ai=Ω 约定不能漏。概率容斥的输入参数与算法的指数维度不同,不要把概率公式的项数当作多项式。

推论与应用

当每个子集的交集贡献可按子集状态复用时,容斥可与动态规划结合,通过子集递推、zeta/Möbius 变换或按最后元素转移避免重复计算所有交。

原地 transform 不变量 ​

Zeta transform 处理完一组坐标后,数组 F[S] 已对这些坐标上的所有子选择求和,而其余坐标保持与 S 相同。处理下一位 i 时,对含 i 的 S 执行 F[S]←F[S]+F[S∖{i}],恰加入缺少该位的子集。每轮只读取不含该位的源项,所以原地更新不会污染同轮来源。逆变换在同一位置做减法;不同坐标的更新算子彼此交换,因此逆变换可以沿原来的位次序执行。

Subset convolution 不是普通 zeta 后逐点相乘即可;通常还要按子集大小分层做 ranked transform,避免把重叠子集对计入。相邻 transform 的名字相近,运算域和目标卷积必须写清。

变换方向的最小核对例 ​

对两元素集合,zeta transform 把 f[∅],f[{1}],f[{2}],f[{1,2}] 变成每个子集所有子集值之和。若原数组依次为 (1,2,3,4),处理第一位后得到 (1,3,3,7),再处理第二位得到 (1,3,4,10)。以同样位次序减去源项,先得 (1,2,4,6),再恢复 (1,2,3,4)。

若在处理同一位时又反向更新源状态,会重复计数。数组项为大整数时,上述变换界只计算加减法次数,实际时间还取决于中间值位数。

参考资料
  • Richard Karp, Dynamic Programming Meets the Principle of Inclusion and Exclusion, Operations Research Letters, 1982.
  • Andreas Björklund et al., Fourier Meets Möbius: Fast Subset Convolution, STOC, 2007.
关系图谱12 个相邻概念 · 2 类关系

拖动节点调整位置。

显示关系

显示:依赖

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

使用的工具

被这些条目使用