将生日悖论扩展到2个人以上


29

在传统的“生日悖论”中,问题是“一群n人中的两个或两个以上的人共享生日的机会是多少”。我陷入一个问题,这是对此的扩展。

我不知道两个人分享生日的概率,而是需要扩展问题来知道x或更多人分享生日的概率是多少。在x=2您可以通过计算没有两个人分享生日并从减去生日的概率来做到这一点1,但是我认为我不能将此逻辑扩展到更大的x

为了使这一点进一步复杂化,我还需要一个适用于n(百万)和x(千)的非常大数的解决方案。


1
我认为这是生物信息学问题
csgillespie 2010年

3
这实际上是一个生物信息学问题,但是由于它归结为与生日悖论相同的概念,我想我会保留不相关的细节!
西蒙·安德鲁斯

4
通常,我会同意您的意见,但是在这种情况下,细节可能很重要,因为可能已经有符合您要求的生物导体包装。
csgillespie 2010年

如果您真的想知道,这是一个模式发现问题,在此问题中,我试图准确估计一组较大序列中给定子序列富集水平的概率。因此,我有一组带有相关计数的子序列,而且我知道我观察了多少个子序列,以及有多少理论上可观察到的序列。如果我在10,000次观察中看到10次特定序列,则需要知道偶然发生的可能性。
西蒙·安德鲁斯

差不多八年后,我在stats.stackexchange.com/questions/333471上发布了针对此问题的答案。该代码有没有工作大n,虽然,因为它需要二次时间n
ub

Answers:


17

这是一个计数的问题:有的可能的分配b到生日ñ人。其中,令q k ; n b 为不超过k个人共享生日但实际上至少k个人共享一个生日的作业数量。我们寻求的概率可以通过将适当的值的q k ; n b 相加并将结果乘以。bnbnq(k;n,b)kkq(k;n,b)kbn

对于小于几百的值,可以精确找到这些计数。但是,它们不会遵循任何简单的公式: 我们必须考虑可以分配生日的方式模式。我将说明这一点,而不是提供一般演示。令(这是最小的有趣情况)。可能是:nn=4

  • 每个人都有一个独特的生日;代码是{4}。
  • 正好两个人过生日。代码为{2,1}。
  • 两个人有一个生日,另外两个有另一个。代码为{0,2}。
  • 三个人过生日。代码为{1,0,1}。
  • 有四个人过生日。代码为{0,0,0,1}。

通常,代码是一个计数的元组,其元素规定正好有个人共享多少个不同的生日。因此,特别是{a[1],a[2],}kthk

1a[1]+2a[2]+...+ka[k]+=n.

注意,即使在这种简单的情况下,有两种方式达到最大的生日每两个人:一个与代码,另一个代码{ 2 1 }{0,2}{2,1}

我们可以直接计算与任何给定代码对应的可能生日分配的数量。该数字是三个术语的乘积。一个是多项式系数。它计算的分区方法数人进入一个[ 1 ]1[ 2 ]的组2,依此类推。由于组的顺序并不重要,我们必须通过划分这个多项式系数[ 1 ] 一个[ 2 ] na[1]1a[2]2a[1]!a[2]!; 它的倒数是第二项。最后,排列组并为每个组分配一个生日:第一个组有候选者,第二个组有b - 1个,依此类推。这些值必须相乘,形成第三项。它等于“阶乘产物” b 一个[ 1 ] + 一个[ 2 ] + 其中b 的装置b b - 1 b - + 1bb1b(a[1]+a[2]+)b(m)b(b1)(bm+1)

{a[1],,a[k]}{a[1],,a[k1]}na[k]a[k]ka[k]knx{a[1],,a[k1]}x

q(k;n,b)nk

b=5n=4

q(1)=q(1;4,5)=120q(2)=360+60=420q(3)=80q(4)=5.

5(80+5)/625=0.136

b=365n=23q(k;23,365)k

k=1:0.49270k=2:0.494592k=3:0.0125308k=4:0.000172844k=5:1.80449E6k=6:1.48722E8k=7:9.92255E11k=8:5.45195E13.

n

n/bbn/bnF(k)bFn=23b=365

k=1:0.498783k=2:0.496803k=3:0.014187k=4:0.000225115.

nb

n=10,000b=1000000

k=1:0k=2:0.8475+k=3:0.1520+k=4:0.0004+k>4:<1E6.

nb

顺便提一下,正如Shane所暗示的那样,模拟可以提供有用的检查。使用以下函数创建Mathematica仿真

simulate[n_, b_] := Max[Last[Transpose[Tally[RandomInteger[{0, b - 1}, n]]]]];

n=10000b=1000000

Tally[Table[simulate[10000, 1000000], {n, 1, 10000}]] // TableForm

它的输出是

2 8503

3 1493

4 4

这些频率与泊松近似预测的频率非常吻合。


太好了,非常感谢@whuber。
JKnight 2014年

“有一个明显且相当简单的递归” –即?
Kodiologist '16

1
@Kodiologist我插入了这个想法的简短描述。
ub

+1,但您在原始问题中的哪个位置看到n = 10000和b = 1mln?OP看起来好像在询问n = 1mln和k = 10000,其中b未指定(大概b = 365)。这一点并不重要:)
变形虫说恢复莫妮卡

1
nx

2

始终可以使用蒙特卡洛解决方案解决此问题,尽管这远非最有效。这是R中的2人问题的简单示例(来自去年的演讲;我将其用作低效率代码的示例),可以轻松调整以解决超过2个问题:

birthday.paradox <- function(n.people, n.trials) {
    matches <- 0
    for (trial in 1:n.trials) {
        birthdays <- cbind(as.matrix(1:365), rep(0, 365))
        for (person in 1:n.people) {
            day <- sample(1:365, 1, replace = TRUE)
            if (birthdays[birthdays[, 1] == day, 2] == 1) {
                matches <- matches + 1
                break
            }
            birthdays[birthdays[, 1] == day, 2] <- 1
        }
        birthdays <- NULL
    }
    print(paste("Probability of birthday matches = ", matches/n.trials))
}

我不确定多类型解决方案是否会在这里工作。

我认为一般化仍然只适用于两个或两个以上共享生日的人-只是您可以拥有不同的子类别的人。
西蒙·安德鲁斯

1

这是一种通用解决方案。可能有一些错误,请谨慎使用!

首先一些符号:

P(x,n)xn

P(y|n) yn

笔记:

  1. P(.)

  2. yy

然后,所需的概率由下式给出:

P(x,n)=1P(0|n)P(2|n)P(3|n)....P(x1|n)

现在,

P(y|n)=(ny)(365365)y k=1k=ny(1k365)

这是逻辑:您需要正好有个人分享生日的概率。y

y(ny)

(365365)y

nyyk=1k=ny(1k365)

x


这个解决方案会遭受维度的诅咒吗?如果不是n = 365,而是n = 10 ^ 6,这种解决方案是否仍然可行?
csgillespie 2010年

一些近似值可能必须用于处理高尺寸。也许,对二项式系数中的阶乘使用斯特林近似。要处理乘积项,您可以获取日志并计算总和而不是乘积,然后取总和的对数。

使用例如指数函数的泰勒级数展开式,还有其他几种近似形式。有关这些近似值,请参见Wiki页面:en.wikipedia.org/wiki/Birthday_problem#Approximations

假设y = 2,n = 4,并且只有两个生日。您的公式通过将365替换为2来改写,似乎是说正好有2个人共享生日的概率为Comb(4,2)*(2/2)^ 2 *(1-1 / 2)*(1-2 / 2)=0。(实际上,很容易就可以通过暴力枚举看出2、3或4个人共享一个“生日”的概率是6 / 16、8 / 16,和分别为2/16。)的确,每当ny> = 365时,您的公式得出0,而当n变大且y固定时,概率应在n达到365 * y之前增加到非零最大值,然后减小,但从来没有到0
whuber

n
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.