Numero previsto di tiri di dado fino a quando ogni lato non appare 3 volte


15

Qual è il numero previsto di volte in cui devi tirare un dado fino a quando ogni lato non appare 3 volte?

Questa domanda è stata posta nella scuola elementare della Nuova Zelanda ed è stata risolta utilizzando simulazioni. Qual è la soluzione analitica per questo problema?


6
Poiché i risultati dei tiri sono casuali, non è possibile sapere in anticipo quanti tiri sono necessari. Se la domanda sta cercando, ad esempio, il numero previsto di tiri prima che ogni lato sia apparso 3 volte, questo dovrebbe essere dichiarato esplicitamente. In tal caso, si applica stats.stackexchange.com/tags/self-study/info .
Juho Kokkala,

3
Di 'a quei ragazzi neozelandesi di leggere Norman L. Johnson, Samuel Kotz, N. Balakrishnan "Distribuzioni multivariate discrete" wiley.com/WileyCDA/WileyTitle/productCd-0471128449.html .
Mark L. Stone,

Risposte:


28

Supponiamo che tutte le parti d=6 abbiano pari possibilità. Generalize e di Let trovare il numero atteso di rotoli necessari fino lato 1 è apparso n1 volte, parte 2 è apparso n2 volte, ..., e sul lato d è apparso nd volte. Poiché le identità dei lati non contano (hanno tutte le stesse possibilità), la descrizione di questo obiettivo può essere condensata: supponiamo che io0 lati non debbano apparire affatto, i1 dei lati devono apparire solo una volta, ... e indei lati devono apparire n=max(n1,n2,,nd) volte. Sia

i=(i0,i1,,in)
designare questa situazione e scrivere
e(i)
per il numero previsto di tiri. La domanda richiede e(0,0,0,6) : i3=6 indica che tutti e sei i lati devono essere visti tre volte ciascuno.

È disponibile una ricorrenza facile. Al tiro successivo, la parte che appare corrisponde a uno dei ij : che è, o non abbiamo bisogno di vederlo, o abbiamo bisogno di vedere una volta, ..., o abbiamo bisogno di vederlo n più volte. j è il numero di volte in cui abbiamo avuto bisogno di vederlo.

  • Quando j=0 , non abbiamo bisogno di vederlo e non cambia nulla. Questo accade con probabilità i0/d .

  • Quando allora abbiamo avuto bisogno di vedere questo lato. Ora c'è un lato in meno che deve essere visto j volte e un altro lato che deve essere visto j - 1 volte. Pertanto, i j diventa i j - 1 e i j - 1 diventa i j + 1 . Lascia che questa operazione sui componenti di i sia designata ij , in modo chej>0jj1ijij1ij1ij+1iij

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

    Questo accade con probabilità .ij/d

Dobbiamo semplicemente contare questo tiro di dado e usare la ricorsione per dirci quanti altri tiri sono previsti. Secondo le leggi di aspettativa e probabilità totale,

e(i)=1+i0de(i)+j=1nijde(ij)

(Comprendiamo che ogni volta che , il termine corrispondente nella somma è zero.)ij=0

Se , abbiamo finito ed e ( i ) = 0 . Altrimenti possiamo risolvere per e ( i ) , dando la formula ricorsiva desideratai0=de(i)=0e(i)

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

Si noti che è il numero totale di eventi che desideriamo vedere. L'operazione j riduce quella quantità di una per ogni j > 0 fornito i j > 0 , che è sempre il caso. Pertanto questa ricorsione termina a una profondità precisamente | io | (uguale a 3 ( 6 ) =

|i|=0(i0)+1(i1)++n(in)
jj>0ij>0|i| nella domanda). Inoltre (come non è difficile verificare) il numero di possibilità per ciascuna profondità di ricorsione in questa domanda è piccolo (mai superiore a 8 ). Di conseguenza, questo è un metodo efficiente, almeno quando le possibilità combinatorie non sono troppo numerose e memorizziamo i risultati intermedi (in modo che nessun valore di e sia calcolato più di una volta).3(6)=188e

Calcolo che

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

Mi è sembrato terribilmente piccolo, quindi ho eseguito una simulazione (usando R). Dopo oltre tre milioni di lanci di dadi, questo gioco è stato giocato fino al suo completamento oltre 100.000 volte, con una lunghezza media di . L'errore standard di tale stima è 0,027 : la differenza tra questa media e il valore teorico è insignificante, confermando l'accuratezza del valore teorico.32.6690.027

La distribuzione delle lunghezze può essere di interesse. (Ovviamente deve iniziare alle , il numero minimo di tiri necessari per raccogliere tutti e sei i lati tre volte ciascuno.)18

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))

Implementazione

Sebbene il calcolo ricorsivo di sia semplice, presenta alcune sfide in alcuni ambienti informatici. Il principale tra questi è la memorizzazione dei valori di e ( i ) mentre vengono calcolati. Questo è essenziale, altrimenti ogni valore verrà (ridondante) calcolato un numero molto grande di volte. Tuttavia, l'archiviazione potenzialmente necessaria per un array indicizzato da iee(i)i potrebbe essere enorme. Idealmente, dovrebbero essere memorizzati solo i valori di effettivamente rilevati durante il calcolo. Ciò richiede una sorta di array associativo.i

Per illustrare, ecco il Rcodice funzionante . I commenti descrivono la creazione di una semplice classe "AA" (array associativo) per la memorizzazione di risultati intermedi. I vettori vengono convertiti in stringhe e quelli vengono utilizzati per indicizzare in un elenco che conterrà tutti i valori. IliEoperazione ij è implementata come.ij%.%

Questi preliminari abilitano la funzione ricorsiva di definire e in modo piuttosto semplice in modo da mettere in parallelo la notazione matematica. In particolare, la lineae

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

è direttamente paragonabile alla formula sopra. Si noti che tutti gli indici sono stati aumentati di 1 perché inizia a indicizzare le sue matrici su 1 anziché su 0 .(1)1R10

Il tempismo mostra che occorrono secondi per il calcolo ; il suo valore è0.01e(c(0,0,0,6))

32,6771634160506

L'errore di arrotondamento in virgola mobile accumulato ha distrutto le ultime due cifre (che dovrebbero essere 68anziché 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))

Infine, ecco l' implementazione originale di Mathematica che ha prodotto la risposta esatta. La memorizzazione viene effettuata tramite l' e[i_] := e[i] = ...espressione idiomatica , eliminando quasi tutti i Rpreliminari. Internamente, però, i due programmi stanno facendo le stesse cose allo stesso modo.

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


5
+1 Immagino che una parte della notazione sarebbe difficile da seguire per gli studenti a cui è stata posta questa domanda (non che io abbia qualche alternativa concreta da suggerire in questo momento). D'altra parte, mi chiedo che cosa intendessero fare con una domanda del genere.
Glen_b -Restate Monica

1
@Glen_b Potrebbero imparare molto tirando i dadi (e calcolando i risultati). Sembra un buon modo per tenere una lezione occupata per mezz'ora mentre l'insegnante riposa :-).
whuber

12

La versione originale di questa domanda ha iniziato la sua vita chiedendo:

quanti tiri sono necessari fino a quando ogni lato non appare 3 volte

Perché no? Il problema si riduce a 1 liner.

Distribuzione del numero di rotoli richiesti ... in modo tale che ogni lato appaia 3 volte

nXiii{1,,6}. Then, the joint pmf of (X1,X2,,X6) is Multinomial(n,16) i.e.:

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

Let: N=min{n:Xi3i}. Then the cdf of N is: P(Nn)=P(Xi3|n)

i.e. To find the cdf P(Nn), simply calculate for each value of n={18,19,20,}:

P(X13,,X63) where (X1,,X6)Multinomial(n,16)

Here, for example, is Mathematica code that does this, as n increases from 18 to say 60. It is basically a one-liner:

 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}]

... which yields the exact cdf as n increases:

1814889875110199605761928290762544079842304203111983875176319369216211168408491253173748645888223283142988125507799783342082361483465418375609359740010496

Here is a plot of the cdf P(Nn), as a function of n:

enter image description here

To derive the pmf P(N=n), simply first difference the cdf:

enter image description here

Of course, the distribution has no upper bound, but we can readily solve here for as many values as practically required. The approach is general and should work just as well for any desired combination of sides required.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.