错排
个人各交一顶帽子,主持人洗乱后随机发回。没有一个人拿回自己那顶的发法数记作 ,称错排(derangement)。它的定义是减法式的:从全排列 里扣掉「至少有一人拿对」的发法。可这些发法按「谁拿对了」分类时互相重叠,同一种发法可能被两三个人同时认领,两条计数原理里的加法原理要求各类互斥,此处并不满足,扣除只能交给容斥原理。
1 · 不动点与错排
把一种发法看成排列 :第 人拿到第 顶帽子。满足 的位置称不动点(fixed point),错排即没有不动点的排列。 时唯一的排列全是不动点,; 时只有互换一种发法,; 的六个排列里合格的是两个三轮换,。空排列没有位置可违约,约定 ,这条约定让后面的递推与求和式在起点处也成立。
2 · 容斥求和式
设 是「第 人拿到自己帽子」的全部排列构成的集合。给定下标集合 ,交集 要求 里每人都拿对,其余 人随意排列,于是
这个大小只取决于 ,与具体是哪几个人无关。大小为 的下标集合有 个,容斥的第 层因而合并成单独一项:
第二个等号只需代入 。
例 2.1 时逐层相消:,与枚举 24 个排列筛出的 9 个错排吻合。
警示 · 把求和式照抄成浮点代码,在
上会给出错的整数。derangementSeries 按
计算,
的结果已经是 9.000000000000002;取整后两式一直吻合到
,而
时双精度给出 2355301661033953.5,取整得 2355301661033954,递推与 BigInt 精确值则都是 2355301661033953。再往上递推自己也失守:
的精确值是 44750731559645106,双精度递推给出 44750731559645100,此处
已越过 Number.MAX_SAFE_INTEGER。交错级数的逐项相消是数值上的经典陷阱,需要精确整数时应走 BigInt。
3 · 递推与组合解释
求和式给出闭式,递推给出更快的算法。考察第 1 人:他拿到的帽子有 种可能,设为第 顶。再看第 人的去向,两种情形互斥且穷尽:
- 第 人拿了第 1 顶,两人互换退出,剩下 人自成一个错排问题,有 种;
- 第 人没拿第 1 顶,此时把第 1 顶帽子改称「第 人的帽子」,剩下的 人(含第 人)恰好构成一个不许拿到自己帽子的错排问题,有 种。
乘上第 1 人的 种选择:
与求和式对照还能整理出一条只回溯一步的形式,:整个交错级数被压成一个 的修正项。本页的测试对 逐项断言了这条恒等式,超出这个范围两边都已不是精确整数。
4 · 与 1/e 的距离
就是随机发帽子时无人拿对的概率。按求和式,它等于交错级数 的部分和, 趋于无穷时收敛到 。交错级数的截断误差不超过首个被丢弃的项 ,收敛因而快得不像话:实测截到 时与 的差是 ,截到 就降到 ,即从第 9 项起差已小于 。
由此得到一个与直觉相左的结论:无人拿对的概率几乎不随人数变化。 时是 , 与 时仍在 附近,差别落在小数点后一百多位。排列 P(n, k) 与 本身随 爆炸式增长,两个爆炸量的比值却稳定在一个常数上。收敛之快还带来一条工程上的便利: 等于 四舍五入的结果,即 ,对一切 成立。
5 · 参考文献
- Derangement. Wikipedia. 错排的容斥推导、两条递推与取整公式 。https://en.wikipedia.org/wiki/Derangement
- Inclusion–exclusion principle. Wikipedia. 容斥原理的一般形式,错排是它最标准的应用。https://en.wikipedia.org/wiki/Inclusion%E2%80%93exclusion_principle
- Rencontres numbers. Wikipedia. 恰有 个不动点的排列数,错排是 的那一列。https://en.wikipedia.org/wiki/Rencontres_numbers