Número esperado de veces para tirar un dado hasta que cada lado haya aparecido 3 veces

15

¿Cuál es el número esperado de veces que debes tirar un dado hasta que cada lado haya aparecido 3 veces?

Esta pregunta se hizo en la escuela primaria de Nueva Zelanda y se resolvió mediante simulaciones. ¿Cuál es la solución analítica para este problema?

Edgar Santos
fuente
66
Como los resultados de los rollos son aleatorios, no es posible saber de antemano cuántos rollos se necesitan. Si se busca la pregunta, por ejemplo, el número esperado de tiradas antes de que cada lado haya aparecido 3 veces, eso debe indicarse explícitamente. En ese caso, se aplica stats.stackexchange.com/tags/self-study/info .
Juho Kokkala
3
Dígales a esos niños de Nueva Zelanda que lean Norman L. Johnson, Samuel Kotz, N. Balakrishnan "Discrete Multivariate Distributions" wiley.com/WileyCDA/WileyTitle/productCd-0471128449.html .
Mark L. Stone

Respuestas:

28

Supongamos que todos los lados d=6 tienen las mismas posibilidades. Generalicemos y encontremos el número esperado de tiradas necesarias hasta que el lado 1 haya aparecido n1 veces, el lado 2 haya aparecido n2 veces, ..., y el lado d haya aparecido nd veces. Debido a que las identidades de los lados no importan (todos ellos tienen las mismas posibilidades), la descripción de este objetivo se puede condensar: supongamos que i0 lados no tienen que aparecer en absoluto, i1 de los lados es necesario que aparezca solo una vez, ... y inn=max(n1,n2,,nd)

i=(i0,i1,,in)
e(i)
e(0,0,0,6)i3=6

Una recurrencia fácil está disponible. En el próximo lanzamiento, el lado que aparece corresponde a uno de los : es decir, o no necesitábamos verlo, o necesitábamos verlo una vez, ..., o necesitábamos verlo más veces . es la cantidad de veces que necesitábamos verlo.ijnj

  • Cuando , no necesitábamos verlo y nada cambia. Esto sucede con probabilidad .j=0i0/d

  • Cuando entonces necesitábamos ver este lado. Ahora hay un lado menos que necesita verse veces y un lado más que necesita verse veces. Por lo tanto, convierte en e convierte en . Deje que esta operación en los componentes de se designe , para quej j - 1 i j i j - 1 i j - 1 i j + 1 i ijj>0jj1ijij1ij1ij+1iij

    ij=(i0,,ij2,ij1+1,ij1,ij+1,,in).

    Esto sucede con probabilidad .ij/re

Simplemente tenemos que contar esta tirada de dados y usar la recursión para decirnos cuántas tiradas más se esperan. Por las leyes de la expectativa y la probabilidad total,

mi(yo)=1+yo0 0remi(yo)+j=1norteyojremi(yoj)

(Comprendamos que siempre que , el término correspondiente en la suma es cero).yoj=0 0

Si , hemos terminado y . De lo contrario, podemos resolver para , dando la fórmula recursiva deseadae ( i ) = 0 e ( i )yo0 0=remi(yo)=0 0mi(yo)

(1)e(i)=d+i1e(i1)++ine(in)di0.

Tenga en cuenta que es el número total de eventos que deseamos ver. La operación reduce esa cantidad en uno para cualquier siempre que , que es siempre el caso. Por lo tanto, esta recursión termina a una profundidad precisa(igual a en la pregunta). Además (como no es difícil de verificar) el número de posibilidades en cada profundidad de recursión en esta pregunta es pequeño (nunca excede de ). En consecuencia, este es un método eficiente, al menos cuando las posibilidades combinatorias no son demasiado numerosas y recordamos los resultados intermedios (de modo que no haya valor dej j > 0 i j > 0 | yo | 3 ( 6 ) = 18 8 e

|i|=0(i0)+1(i1)++n(in)
jj>0ij>0|i|3(6)=188mi se calcula más de una vez).

que

mi(0 0,0 0,0 0,6 6)=22868786045088836998400000000032.677.

Eso me pareció terriblemente pequeño, así que realicé una simulación (usando R). Después de más de tres millones de tiradas de dados, este juego se jugó hasta su finalización más de 100,000 veces, con una longitud promedio de . El error estándar de esa estimación es : la diferencia entre este promedio y el valor teórico es insignificante, lo que confirma la precisión del valor teórico.0,02732,6690,027

La distribución de longitudes puede ser de interés. (Obviamente, debe comenzar a las , el número mínimo de rollos necesarios para recoger los seis lados tres veces cada uno).18 años

Figura

# Specify the problem
d <- 6   # Number of faces
k <- 3   # Number of times to see each
N <- 3.26772e6 # Number of rolls

# Simulate many rolls
set.seed(17)
x <- sample(1:d, N, replace=TRUE)

# Use these rolls to play the game repeatedly.
totals <- sapply(1:d, function(i) cumsum(x==i))
n <- 0
base <- rep(0, d)
i.last <- 0
n.list <- list()
for (i in 1:N) {
  if (min(totals[i, ] - base) >= k) {
    base <- totals[i, ]
    n <- n+1
    n.list[[n]] <- i - i.last
    i.last <- i
  }
}

# Summarize the results
sim <- unlist(n.list)
mean(sim)
sd(sim) / sqrt(length(sim))
length(sim)
hist(sim, main="Simulation results", xlab="Number of rolls", freq=FALSE, breaks=0:max(sim))

Implementación

Aunque el cálculo recursivo de es simple, presenta algunos desafíos en algunos entornos informáticos. El principal de ellos es almacenar los valores de medida que se calculan. Esto es esencial, ya que de lo contrario cada valor se calculará (de forma redundante) una cantidad muy grande de veces. Sin embargo, el almacenamiento potencialmente necesario para una matriz indexada por podría ser enorme. Idealmente, solo los valores de que realmente se encuentran durante el cálculo deben almacenarse. Esto requiere un tipo de matriz asociativa.mimi(yo)yoyo

Para ilustrar, aquí está el Rcódigo de trabajo . Los comentarios describen la creación de una clase simple "AA" (matriz asociativa) para almacenar resultados intermedios. Los vectores se convierten en cadenas y se usan para indexar en una lista que contendrá todos los valores. La operación se implementa como .yoEyoj%.%

Estos preliminares permiten que la función recursiva se defina de manera bastante simple de forma paralela a la notación matemática. En particular, la líneami

x <- (d + sum(sapply(1:n, function(i) j[i+1]*e.(j %.% i))))/(d - j[1])

es directamente comparable a la fórmula anterior. Tenga en cuenta que todos los índices se han incrementado en porque comienza a indexar sus matrices en lugar de .(1)1R10 0

El tiempo muestra que toma segundos calcular ; su valor es0,01e(c(0,0,0,6))

32.6771634160506

El error de redondeo de punto flotante acumulado ha destruido los dos últimos dígitos (lo que debería ser en 68lugar de 06).

e <- function(i) {
  #
  # Create a data structure to "memoize" the values.
  #
  `[[<-.AA` <- function(x, i, value) {
    class(x) <- NULL
    x[[paste(i, collapse=",")]] <- value
    class(x) <- "AA"
    x
  }
  `[[.AA` <- function(x, i) {
    class(x) <- NULL
    x[[paste(i, collapse=",")]]
  }
  E <- list()
  class(E) <- "AA"
  #
  # Define the "." operation.
  #
  `%.%` <- function(i, j) {
    i[j+1] <- i[j+1]-1
    i[j] <- i[j] + 1
    return(i)
  }
  #
  # Define a recursive version of this function.
  #
  e. <- function(j) {
    #
    # Detect initial conditions and return initial values.
    #
    if (min(j) < 0 || sum(j[-1])==0) return(0)
    #
    # Look up the value (if it has already been computed).
    #
    x <- E[[j]]
    if (!is.null(x)) return(x)
    #
    # Compute the value (for the first and only time).
    #
    d <- sum(j)
    n <- length(j) - 1
    x <- (d + sum(sapply(1:n, function(i) j[i+1]*e.(j %.% i))))/(d - j[1])
    #
    # Store the value for later re-use.
    #
    E[[j]] <<- x
    return(x)
  }
  #
  # Do the calculation.
  #
  e.(i)
}
e(c(0,0,0,6))

Finalmente, aquí está la implementación original de Mathematica que produjo la respuesta exacta. La memorización se realiza a través de la e[i_] := e[i] = ...expresión idiomática , eliminando casi todos los Rpreliminares. Sin embargo, internamente, los dos programas están haciendo las mismas cosas de la misma manera.

shift[j_, x_List] /; Length[x] >= j >= 2 := Module[{i = x},
   i[[j - 1]] = i[[j - 1]] + 1;
   i[[j]] = i[[j]] - 1;
   i];
e[i_] := e[i] = With[{i0 = First@i, d = Plus @@ i},
    (d + Sum[If[i[[k]] > 0, i[[k]]  e[shift[k, i]], 0], {k, 2, Length[i]}])/(d - i0)];
e[{x_, y__}] /; Plus[y] == 0  := e[{x, y}] = 0

e[{0, 0, 0, 6}]

228687860450888369984000000000

whuber
fuente
55
+1 Me imagino que parte de la notación sería difícil de seguir para los estudiantes a quienes se les hizo esta pregunta (no es que tenga ninguna alternativa concreta que sugerir en este momento). Por otro lado, me pregunto qué pretendían hacer con tal pregunta.
Glen_b: reinstala a Monica
1
@Glen_b Podrían aprender mucho tirando los dados (y contando los resultados). Parece una buena manera de mantener ocupada una clase durante media hora mientras el maestro descansa :-).
whuber
12

La versión original de esta pregunta comenzó su vida preguntando:

cuántos rollos se necesitan hasta que cada lado haya aparecido 3 veces

Distribución de la cantidad de rollos necesarios ... de modo que cada lado aparezca 3 veces

nXiii{1,,6}(X1,X2,,X6)Multinomial(n,16)

P(X1=x1,,X6=x6)=n!x1!x6!16n subject to: i=16xi=n

Dejar: N=min{n:Xi3i}.NP(Nn)=P(Xyo3El |norte)

PAG(nortenorte)norte={18 años,19,20,...}

PAG(X13,...,X6 63) dónde (X1,...,X6 6)Multinomial(norte,16 6)

norte

 cdf = ParallelTable[ 
   Probability[x1 >= 3 && x2 >= 3 && x3 >= 3 && x4 >= 3 && x5 >= 3 &&  x6 >= 3, 
       {x1, x2, x3, x4, x5, x6} \[Distributed] MultinomialDistribution[n, Table[1/6, 6]]],
    {n, 18, 60}]

norte

18 años14889875110199605761928290762544079842304203111983875176319369216211168408491253173748645888223283142988125507799783342082361483465418375609359740010496

PAG(nortenorte)norte

ingrese la descripción de la imagen aquí

PAG(norte=norte)

ingrese la descripción de la imagen aquí

Por supuesto, la distribución no tiene límite superior, pero aquí podemos resolver fácilmente tantos valores como sea prácticamente necesario. El enfoque es general y debería funcionar igual de bien para cualquier combinación deseada de lados requerida.

lobos
fuente