Esta es una generalización del famoso problema de cumpleaños : dado individuos que tienen "cumpleaños" aleatorios y distribuidos de manera uniforme entre un conjunto de posibilidades, ¿cuál es la posibilidad de que más de individuos no compartan cumpleaños ?n=100d=6m=20
Un cálculo exacto arroja la respuesta (con doble precisión). Dibujaré la teoría y proporcionaré el código para El tiempo asintótico del código es lo que lo hace adecuado para un gran número de cumpleaños y proporciona un rendimiento razonable hasta que esté en los miles. En ese punto, la aproximación de Poisson discutida en Extender la paradoja del cumpleaños a más de 2 personas debería funcionar bien en la mayoría de los casos.0.267747907805267n,m,d.O(n2log(d))dn
Explicación de la solución.
La función de generación de probabilidad (pgf) para los resultados de tiradas independientes de un dado de lado esnd
d−nfn(x1,x2,…,xd)=d−n(x1+x2+⋯+xd)n.
El coeficiente de en la expansión de este multinomial da el número de formas en las que se enfrentan puedo aparecer exactamente veces, i e i i = 1 , 2 , … , d .xe11xe22⋯xeddieii=1,2,…,d.
Limitar nuestro interés a no más de apariencias por cualquier cara equivale a evaluar módulo la ideal que mediante Para realizar esta evaluación, utilice el teorema binomial de forma recursiva para obtenerf n I x m + 1 1 , x m + 1 2 , … , x m + 1 d .mfnIxm+11,xm+12,…,xm+1d.
fn(x1,…,xd)=((x1+⋯+xr)+(xr+1+xr+2+⋯+x2r))n=∑k=0n(nk)(x1+⋯+xr)k(xr+1+⋯+x2r)n−k=∑k=0n(nk)fk(x1,…,xr)fn−k(xr+1,…,x2r)
cuando es par. Escribiendo ( términos), tenemosd=2rf(d)n=fn(1,1,…,1)d
f(2r)n=∑k=0n(nk)f(r)kf(r)n−k.(a)
Cuando es impar, use una descomposición análogad=2r+1
fn(x1,…,xd)=((x1+⋯+x2r)+x2r+1)n=∑k=0n(nk)fk(x1,…,x2r)fn−k(x2r+1),
dando
f(2r+1)n=∑k=0n(nk)f(2r)kf(1)n−k.(b)
En ambos casos, también podemos reducir todo el módulo , que se lleva a cabo fácilmente comenzando conI
fn(xj)≅{xn0n≤mn>mmodI,
proporcionando los valores iniciales para la recursividad,
f(1)n={10n≤mn>m
Lo que hace que esto sea eficiente es que al dividir las variables en dos grupos de variables de igual tamaño y establecer todos los valores de las variables en solo tenemos que evaluar todo una vez para un grupo y luego combinar los resultados. Esto requiere calcular hasta términos, cada uno de ellos necesita un cálculo de para la combinación. Ni siquiera necesitamos una matriz 2D para almacenar , porque al calcular solo se requieren y .dr1,n+1O(n)f(r)nf(d)n,f(r)nf(1)n
El número total de pasos es uno menos que el número de dígitos en la expansión binaria de (que cuenta las divisiones en grupos iguales en la fórmula ) más el número de unos en la expansión (que cuenta todas las veces un número impar se encuentra un valor que requiere la aplicación de la fórmula ). Eso sigue siendo solo pasos .d(a)(b)O(log(d))
En R
una estación de trabajo de una década, el trabajo se realizó en 0.007 segundos. El código aparece al final de esta publicación. Utiliza logaritmos de las probabilidades, en lugar de las probabilidades en sí, para evitar posibles desbordamientos o acumular demasiados desbordamientos. Esto hace posible eliminar el factor en la solución para que podamos calcular los recuentos que subyacen a las probabilidades.d−n
Tenga en cuenta que este procedimiento da como resultado el cálculo de toda la secuencia de probabilidades a la vez, lo que nos permite estudiar fácilmente cómo cambian las posibilidades con .f0,f1,…,fnn
Aplicaciones
La distribución en el problema de cumpleaños generalizado es calculada por la función tmultinom.full
. El único desafío radica en encontrar un límite superior para el número de personas que deben estar presentes antes de que la posibilidad de una colisión sea demasiado grande. El siguiente código hace esto por fuerza bruta, comenzando con una pequeña y duplicándola hasta que sea lo suficientemente grande. Por lo tanto, todo el cálculo lleva tiempo donde es la solución. Se calcula la distribución completa de probabilidades para el número de personas hasta .m+1nO(n2log(n)log(d))nn
#
# The birthday problem: find the number of people where the chance of
# a collision of `m+1` birthdays first exceeds `alpha`.
#
birthday <- function(m=1, d=365, alpha=0.50) {
n <- 8
while((p <- tmultinom.full(n, m, d))[n] > alpha) n <- n * 2
return(p)
}
Como ejemplo, el número mínimo de personas que se necesitan en una multitud para que sea más probable que al menos ocho de ellos compartan un cumpleaños es , según el cálculo . Solo toma un par de segundos. Aquí hay una gráfica de parte de la salida:798birthday(7)
Una versión especial de este problema se aborda en Extender la paradoja del cumpleaños a más de 2 personas , que se refiere al caso de un dado de lados que se lanza una gran cantidad de veces.365
Código
# Compute the chance that in `n` independent rolls of a `d`-sided die,
# no side appears more than `m` times.
#
tmultinom <- function(n, m, d, count=FALSE) tmultinom.full(n, m, d, count)[n+1]
#
# Compute the chances that in 0, 1, 2, ..., `n` independent rolls of a
# `d`-sided die, no side appears more than `m` times.
#
tmultinom.full <- function(n, m, d, count=FALSE) {
if (n < 0) return(numeric(0))
one <- rep(1.0, n+1); names(one) <- 0:n
if (d <= 0 || m >= n) return(one)
if(count) log.p <- 0 else log.p <- -log(d)
f <- function(n, m, d) { # The recursive solution
if (d==1) return(one) # Base case
r <- floor(d/2)
x <- double(f(n, m, r), m) # Combine two equal values
if (2*r < d) x <- combine(x, one, m) # Treat odd `d`
return(x)
}
one <- c(log.p*(0:m), rep(-Inf, n-m)) # Reduction modulo x^(m+1)
double <- function(x, m) combine(x, x, m)
combine <- function(x, y, m) { # The Binomial Theorem
z <- sapply(1:length(x), function(n) { # Need all powers 0..n
z <- x[1:n] + lchoose(n-1, 1:n-1) + y[n:1]
z.max <- max(z)
log(sum(exp(z - z.max), na.rm=TRUE)) + z.max
})
return(z)
}
x <- exp(f(n, m, d)); names(x) <- 0:n
return(x)
}
La respuesta se obtiene con
print(tmultinom(100,20,6), digits=15)
0.267747907805267