Project Euler 584
Project Euler 584
题目
Birthday Problem Revisited
A long long time ago in a galaxy far far away, the Wimwians, inhabitants of planet WimWi, discovered an unmanned drone that had landed on their planet. On examining the drone, they uncovered a device that sought the answer for the so called “Birthday Problem”. The description of the problem was as follows:
If people on your planet were to enter a very large room one by one, what will be the expected number of people in the room when you first find \(\mathbf{3}\) people with Birthdays within \(\mathbf{1}\) day from each other.
The description further instructed them to enter the answer into the device and send the drone into space again. Startled by this turn of events, the Wimwians consulted their best mathematicians. Each year on Wimwi has \(10\) days and the mathematicians assumed equally likely birthdays and ignored leap years (leap years in Wimwi have \(11\) days), and found \(5.78688636\) to be the required answer. As such, the Wimwians entered this answer and sent the drone back into space.
After traveling light years away, the drone then landed on planet Joka. The same events ensued except this time, the numbers in the device had changed due to some unknown technical issues. The description read:
If people on your planet were to enter a very large room one by one, what will be the expected number of people in the room when you first find \(\mathbf{3}\) people with Birthdays within \(\mathbf{7}\) days from each other.
With a \(100\)-day year on the planet, the Jokars (inhabitants of Joka) found the answer to be \(8.48967364\) (rounded to \(8\) decimal places because the device allowed only \(8\) places after the decimal point) assuming equally likely birthdays. They too entered the answer into the device and launched the drone into space again.
This time the drone landed on planet Earth. As before the numbers in the problem description had changed. It read:
If people on your planet were to enter a very large room one by one, what will be the expected number of people in the room when you first find \(\mathbf{4}\) people with Birthdays within \(\mathbf{7}\) days from each other.
What would be the answer (rounded to eight places after the decimal point) the people of Earth have to enter into the device for a year with \(365\) days? Ignore leap years. Also assume that all birthdays are equally likely and independent of each other.
解决方案
简而言之,题目是说一年共有 \(Y=365\) 天,生日均匀独立分布在 \({0,1,\dots,Y-1}\) 上,并按圆环距离定义相隔不超过 \(w=7\) 天。
题目要求的触发条件是:存在 \(K=4\) 个人,他们的生日都落在某个长度为 \(w+1\) 的连续区间内(按圆环取模)。
记随机变量 \(N\) 为第一个触发条件出现时,房间里的人数,求 \(\mathbb E[N]\)。
设事件 \(B_n\) 表示“前 \(n\) 个人中尚未出现触发条件”,则
- \(\mathbb P(N>n)=\mathbb P(B_n)\)
- \(\mathbb P(N=n)=\mathbb P(B_{n-1})-\mathbb P(B_n)\)
于是\(\displaystyle{\mathbb E[N]=\sum_{n\ge1} n\big(\mathbb P(B_{n-1})-\mathbb P(B_n)\big)= \sum_{n\ge0}\mathbb P(B_n).}\)因此问题化为:计算所有 \(n\) 的 \(\mathbb P(B_n)\) 并求和。
令\(\displaystyle{x_0,x_1,\dots,x_{Y-1}\ge 0, \sum_{i=0}^{Y-1}x_i=n,}\)其中 \(x_i\) 表示第 \(i\) 天生日的人数。在给定计数向量 \(x\) 时,其概率为多项分布:
\[ \mathbb P(x)=\frac{n!}{Y^n\prod_{i=0}^{Y-1} x_i!}. \]
因此,触发条件:存在某个长度 \(w+1\) 的连续区间内至少有 \(K\) 人可以转换成另一种表达:对所有 \(j\)(按模 \(Y\)),都有\(\displaystyle{\sum_{t=0}^w x_{(j+t)\%Y}\le K-1}\)。
因此
\[ \mathbb P(B_n)= \sum_{\substack{x_0+\cdots+x_{Y-1}=n\\ \forall j:\sum_{t=0}^{w}x_{(j+t)\%Y}\le K-1}} \frac{n!}{Y^n\prod_{i=0}^{Y-1} x_i!}. \]
代入 \(\displaystyle{\mathbb E[N]=\sum_{n\ge0}\mathbb P(B_n)}\) 得
\[ \mathbb E[N]= \sum_{\substack{x_0,\dots,x_{Y-1}\ge 0\\ \forall j:\sum_{t=0}^{w}x_{(j+t)\%Y}\le K-1}} \frac{\big(\sum_{i=0}^{Y-1}x_i\big)!}{Y^{\sum_{i=0}^{Y-1}x_i}\prod_{i=0}^{Y-1} x_i!}. \]
为了简便计算,我们使用伽马函数把阶乘去除。可见,有\(\displaystyle{n! = \int_{0}^{\infty} e^{-u}u^ndu,}\)则每个配置的贡献\(\displaystyle{\frac{n!}{Y^n\prod_{i=0}^{Y-1} x_i!}=\int_{0}^{\infty} e^{-u}\frac{(u/Y)^n}{\prod_{i=0}^{Y-1} x_i!}du.}\)
交换求和与积分,得到\(\displaystyle{\mathbb E[N]=\int_{0}^{\infty} e^{-u}H\left(\frac{u}{Y}\right)du}\),其中\(\displaystyle{H(z)=\sum_{\substack{x_0,\dots,x_{Y-1}\ge 0\\\forall j:\sum_{t=0}^{w}x_{j+t}\le K-1}}\frac{z^{\sum_{i=0}^{Y-1} x_i}}{\prod_{i=0}^{Y-1} x_i!}.}\)
所以核心变成:对给定 \(z\) 高效计算 \(H(z)\)。
令\(L=w+1, B=K-1.\)约束是“任意长度 \(L\) 的连续窗口总和 \(\le B\)”。定义状态为最近 \(L-1\) 天的计数:\(\displaystyle{s=(a_1,a_2,\dots,a_{L-1}), a_i\ge 0, \sum_{i=1}^{L-1}a_i\le B.}\)
如果下一天放入 \(t\) 个人,则新状态为\(s'=\text{shift}(s,t)=(a_2,a_3,\dots,a_{L-1},t),\)并且必须满足窗口约束\(\displaystyle{\sum_{i=1}^{L-1}a_i+t\le B.}\)
每次添加 \(t\) 贡献对应权重:\(\dfrac{z^t}{t!}.\)因此形成一个转移矩阵 \(T(z)\)(大小为状态数 \(S\)):
\[ T(z)_{s',s}= \begin{cases} \dfrac{z^t}{t!} &\text{if} \quad s'=\text{shift}(s,t) \land \displaystyle{\sum_{i=1}^{L-1} a_i}+t\le B\\ 0,&\text{else}. \end{cases} \]
然而,上面的转移只保证了线性序列内部的所有长度 \(L\) 窗口都合法。
但一年是圆环,还需要检查跨越边界的窗口,即:
把开头的 \(L-1\) 天记作起始状态 \(p\),末尾的 \(L-1\) 天记作结束状态 \(e\)。
对于每个 \(j=1,2,\dots,L-1\),跨边界窗口包含:
- 结束状态 \(e\) 的最后 \(j\) 项
- 起始状态 \(p\) 的最前 \(L-j\) 项
因此必须满足\(\displaystyle{\sum_{t=L-j}^{L-1} e_t+\sum_{t=1}^{L-j} p_t \le B.}\)记兼容矩阵\(C_{p,e}=1\)当且仅当\((p,e)\)满足所有跨边界窗口约束,否则\(C_{p,e}=0\)。
固定起始状态 \(p\),其自身对应前 \(L-1\) 天的权重为\(\displaystyle{W_p(z)=\frac{z^{\sum_{t=1}^{L-1} p_t}}{\prod_{t=1}^{L-1} p_t!}.}\)
剩余的 \(Y-(L-1)\) 天用矩阵推进。设\(P(z)=T(z)^{Y-(L-1)}.\)则从 \(p\) 走到 \(e\) 的总权重为 \(P(z)_{e,p}\)。
最后乘上首尾兼容性 \(C_{p,e}\) 并对所有 \(p,e\) 求和:
\[ H(z)=\sum_{p}\sum_{e} W_p(z)P(z)_{e,p}C_{p,e}. \]
最终,我们需要 \[ \mathbb E[N]=\int_{0}^{\infty} e^{-u}H\left(\frac{u}{Y}\right)du. \]
Gauss–Laguerre 公式直接针对权重 \(e^{-u}\):\(\displaystyle{\int_0^\infty e^{-u} f(u),du \approx \sum_{i=1}^{m} w_i f(x_i),}\)所以只需在若干节点 \(x_i\) 处计算 \(H(x_i/Y)\) 并加权求和即可。
代码
1 | from tools import fac |