Numero previsto Sarò acceso dopo aver pescato le carte finché non avrò un asso, 2, 3 e così via


12

Sto riscontrando dei problemi nel risolvere quanto segue.

Pesca carte da un mazzo standard da 52 carte senza sostituzione finché non ottieni un asso. Disegna da ciò che resta fino a quando non ottieni un 2. Continui con 3. Qual è il numero atteso che ti verrà dopo che l'intero mazzo si esaurirà?

Era naturale lasciarlo

  • Ti=first position of card whose value is i
  • Ui=last position of card whose value is i

Quindi il problema equivale essenzialmente a capire la probabilità che sarai su quando il mazzo si esaurisce, vale a dire:k

Pr(T1<<TkUk+1<Tk)

posso capire che

Pr(T1<<Tk)=1/k!andPr(Uk+1<Tk)=1/70

ma non potrei andare oltre ...


1
Cosa succede se hai già pescato tutti i secondi prima di pescare il tuo primo asso? 2
gung - Ripristina Monica

Il numero "previsto" significa davvero il numero "più probabile"?
whuber

Questo è un problema interessante, ma non sono sicuro della matematica che scrivi dopo "il problema equivale essenzialmente a". Nella prima affermazione intendevi scrivere anziché ? Anche allora, tuttavia, non sono sicuro che l'affermazione sia corretta. Considera l'inizio di una sequenza . Abbiamo e quindi , ma se capisco bene la descrizione del tuo testo possiamo ancora scegliere l'asso in seconda posizione e poi il 2 in quinta posizione? E quindi non è una condizione necessaria? T 1 = 2 , T 2 = 1 T 1 > T 2 T 1 < T 22AAA2T1=2,T2=1T1>T2T1<T2
TooTone,

@TooTone Oh, intendevo come hai detto, e hai ragione; non è una condizione necessaria ...T 1 < T 2T1<T2
fattura il

@gung In tal caso, il tuo mazzo si esaurirà e sarai ancora in posizione 2.
fattura il

Risposte:


0

seguendo l'idea di @ gung, credo che il valore atteso sarebbe 5,84? e dalla mia interpretazione dei commenti, presumo che "A" sia un valore quasi impossibile (a meno che le ultime quattro carte del mazzo non siano tutte assi). ecco i risultati di una simulazione di 100.000 iterazioni di monte carlo

results
    2     3     4     5     6     7     8     9     J     K     Q     T 
 1406  7740 16309 21241 19998 15127  9393  4906   976   190   380  2334 

ed ecco il codice R nel caso in cui ti piacerebbe giocarci ..

# monte carlo card-drawing functions from here
# http://streaming.stat.iastate.edu/workshops/r-intro/lectures/5-Rprogramming.pdf

# create a straightforward deck of cards
create_deck <-
    function( ){
        suit <- c( "H" , "C" , "D" , "S" )
        rank <- c( "A" , 2:9 , "T" , "J" , "Q" , "K" )
        deck <- NULL
        for ( r in rank ) deck <- c( deck , paste( r , suit ) )
        deck
    }

# construct a function to shuffle everything
shuffle <- function( deck ){ sample( deck , length( deck ) ) }

# draw one card at a time
draw_cards <-
    function( deck , start , n = 1 ){
        cards <- NULL

        for ( i in start:( start + n - 1 ) ){
            if ( i <= length( deck ) ){
                cards <- c( cards , deck[ i ] )
            }
        }

        return( cards )
    }

# create an empty vector for your results
results <- NULL

# run your simulation this many times..
for ( i in seq( 100000 ) ){
    # create a new deck
    sdeck <- shuffle( create_deck() )

    d <- sdeck[ grep('A|2' , sdeck ) ]
    e <- identical( grep( "2" , d ) , 1:4 )

    # loop through ranks in this order
    rank <- c( "A" , 2:9 , "T" , "J" , "Q" , "K" )

    # start at this position
    card.position <- 0

    # start with a blank current.draw
    current.draw <- ""

    # start with a blank current rank
    this.rank <- NULL

    # start with the first rank
    rank.position <- 1

    # keep drawing until you find the rank you wanted
    while( card.position < 52 ){

        # increase the position by one every time
        card.position <- card.position + 1

        # store the current draw for testing next time
        current.draw <- draw_cards( sdeck , card.position )

        # if you draw the current rank, move to the next.
        if ( grepl( rank[ rank.position ] , current.draw ) ) rank.position <- rank.position + 1

        # if you have gone through every rank and are still not out of cards,
        # should it still be a king?  this assumes yes.
        if ( rank.position == length( rank ) ) break        

    }

    # store the rank for this iteration.
    this.rank <- rank[ rank.position ]

    # at the end of the iteration, store the result
    results <- c( results , this.rank )

}

# print the final results
table( results )

# make A, T, J, Q, K numerics
results[ results == 'A' ] <- 1
results[ results == 'T' ] <- 10
results[ results == 'J' ] <- 11
results[ results == 'Q' ] <- 12
results[ results == 'K' ] <- 13
results <- as.numeric( results )

# and here's your expected value after 100,000 simulations.
mean( results )

Perché è Aimpossibile? Considera la sequenza di 48 carte seguite AAAAad esempio.
TooTone

hai ragione .. è uno su 270725 - o con il codice R1/prod( 48:1 / 52:5 )
Anthony Damico

1
Questa risposta non è corretta Considera il conteggio di "2": poiché ciò può risultare solo quando tutti i 2 vengono rilevati prima di uno qualsiasi, la sua probabilità è una su ogni e quindi la sua aspettativa nella simulazione è con un errore standard di . Il tuo output di è oltre sei errori standard troppo alti, rendendolo quasi sicuramente errato. Un valore accurato per la media (basato su una simulazione diversa con iterazioni) è . 105/ ( 8(84)=7037,516601065,833±0,004105/(84)1428.637.516601065.833±0.004
whuber

1
Sfortunatamente il tuo codice pesantemente documentato è molte volte più lungo e più lento di quanto debba essere. Ho dimostrato che il suo output non è corretto; anche se vorrei avere il tempo di eseguire il debug del codice, non è così e non è mio compito farlo. La mia tesi è questa: alla fine lavorerai su "2" se e solo se tutti i "2" precedono tutti gli "A". Tra i modi altrettanto probabili di organizzare i quattro "2" se quattro "A", esattamente uno di essi soddisfa questo criterio. Pertanto, il valore di sotto l'intestazione "2" dovrebbe essere vicino a , ma non lo è. 105/70=1429(4+44)=70results105/70=1429
whuber

1
Persino i moderatori non possono rimuovere i voti degli altri :-). Un test chi-quadrato ora suggerisce che i tuoi risultati concordano con i miei, ma sarebbe bello sapere come hai testato la tua simulazione, perché ciò migliorerebbe la fiducia nella tua risposta. In effetti, secondo una modifica che hai apportato al primo paragrafo della tua risposta, ora entrambi i nostri risultati sono sbagliati: dato che ho interpretato la tua domanda, non è mai possibile lavorare su un asso quando tutte le carte sono esaurite.
whuber

7

Per una simulazione è fondamentale essere corretti e veloci. Entrambi questi obiettivi suggeriscono di scrivere codice mirato alle funzionalità di base dell'ambiente di programmazione, nonché un codice quanto più breve e semplice possibile, poiché la semplicità conferisce chiarezza e chiarezza promuove la correttezza. Ecco il mio tentativo di raggiungere entrambi in R:

#
# Simulate one play with a deck of `n` distinct cards in `k` suits.
#
sim <- function(n=13, k=4) {
  deck <- sample(rep(1:n, k)) # Shuffle the deck
  deck <- c(deck, 1:n)        # Add sentinels to terminate the loop
  k <- 0                      # Count the cards searched for
  for (j in 1:n) {
    k <- k+1                          # Count this card
    deck <- deck[-(1:match(j, deck))] # Deal cards until `j` is found
    if (length(deck) < n) break       # Stop when sentinels are reached
  }
  return(k)                   # Return the number of cards searched
}

Applicare questo in modo riproducibile può essere fatto con la replicatefunzione dopo aver impostato il seme di numero casuale, come in

> set.seed(17);  system.time(d <- replicate(10^5, sim(13, 4)))
   user  system elapsed 
   5.46    0.00    5.46

È lento, ma abbastanza veloce da condurre ripetutamente simulazioni abbastanza lunghe (e quindi precise) senza aspettare. Esistono diversi modi in cui possiamo mostrare il risultato. Cominciamo con la sua media:

> n <- length(d)
> mean(d)
[1] 5.83488

> sd(d) / sqrt(n)
[1] 0.005978956

Quest'ultimo è l'errore standard: prevediamo che la media simulata sia compresa tra due o tre SE del valore reale. Ciò pone la vera aspettativa da qualche parte tra e5.8535.8175.853 .

Potremmo anche voler vedere una tabulazione delle frequenze (e dei loro errori standard). Il codice seguente predispone leggermente la tabulazione:

u <- table(d)
u.se <- sqrt(u/n * (1-u/n)) / sqrt(n)
cards <- c("A", "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K")
dimnames(u) <- list(sapply(dimnames(u), function(x) cards[as.integer(x)]))
print(rbind(frequency=u/n, SE=u.se), digits=2)

Ecco l'output:

                2       3      4      5      6      7       8       9       T       J       Q       K
frequency 0.01453 0.07795 0.1637 0.2104 0.1995 0.1509 0.09534 0.04995 0.02249 0.01009 0.00345 0.00173
SE        0.00038 0.00085 0.0012 0.0013 0.0013 0.0011 0.00093 0.00069 0.00047 0.00032 0.00019 0.00013

Come possiamo sapere se la simulazione è persino corretta? Un modo è testarlo esaurientemente per problemi minori. Per questo motivo questo codice è stato scritto per attaccare una piccola generalizzazione del problema, sostituendo carte distinte con e semi con . Tuttavia, per il test è importante essere in grado di alimentare il codice di un mazzo in un ordine predeterminato. Scriviamo un'interfaccia leggermente diversa per lo stesso algoritmo:413n4k

draw <- function(deck) {
  n <- length(sentinels <- sort(unique(deck)))
  deck <- c(deck, sentinels)
  k <- 0
  for (j in sentinels) {
    k <- k+1
    deck <- deck[-(1:match(j, deck))]
    if (length(deck) < n) break
  }
  return(k)
}

(È possibile utilizzare drawal posto di simovunque, ma il lavoro extra fatto all'inizio drawlo rende due volte più lento di sim.)

Possiamo usarlo applicandolo a ogni shuffle distinto di un determinato mazzo. Poiché lo scopo qui è solo alcuni test una tantum, l'efficienza nella generazione di questi shuffle è irrilevante. Ecco un modo rapido per la forza bruta:

n <- 4 # Distinct cards
k <- 2 # Number of suits
d <- expand.grid(lapply(1:(n*k), function(i) 1:n))
e <- apply(d, 1, function(x) var(tabulate(x))==0)
g <- apply(d, 1, function(x) length(unique(x))==n)
d <- d[e & g,]

Ora dè un frame di dati le cui righe contengono tutti i riordini. Applica drawa ogni riga e conta i risultati:

d$result <- apply(as.matrix(d), 1, draw)
    (counts <- table(d$result))

L'output (che utilizzeremo per un momento in un test formale) è

   2    3    4 
 420  784 1316 

(Il valore di è facile da capire, a proposito: lavoreremo ancora sulla carta se e solo se tutti e due precedessero tutti gli assi. La possibilità che ciò accada (con due semi) è . Su shuffle distinti, hanno questa proprietà.)2420225202520/6=4201/(2+22)=1/625202520/6=420

Possiamo testare l'output con un test chi-quadrato. A tal fine, applico volte a questo caso di carte distinte in semi:sim n = 4 k = 210,000n=4k=2

>set.seed(17)
>d.sim <- replicate(10^4, sim(n, k))
>print((rbind(table(d.sim) / length(d.sim), counts / dim(d)[1])), digits=3)

         2     3     4
[1,] 0.168 0.312 0.520
[2,] 0.167 0.311 0.522

> chisq.test(table(d.sim), p=counts / dim(d)[1])

    Chi-squared test for given probabilities

data:  table(d.sim) 
X-squared = 0.2129, df = 2, p-value = 0.899

Poiché è così elevato, non troviamo alcuna differenza significativa tra ciò che dice e i valori calcolati dall'enumerazione esaustiva. Ripetendo questo esercizio per alcuni altri (piccoli) valori di e ottengono risultati comparabili, dandoci un'ampia ragione di fiducia quando applicati a e .n k n = 13 k = 4psimnksimn=13k=4

Infine, un test chi-quadrato a due campioni confronterà l'output di simcon l'output riportato in un'altra risposta:

>y <- c(1660,8414,16973,21495,20021,14549,8957,4546,2087,828,313,109)
>chisq.test(cbind(u, y))

data:  cbind(u, y) 
X-squared = 142.2489, df = 11, p-value < 2.2e-16

L'enorme statistica chi-quadrata produce un valore p essenzialmente pari a zero: senza dubbio, simnon è d'accordo con l'altra risposta. Esistono due possibili risoluzioni del disaccordo: una (o entrambe!) Di queste risposte è errata o implementano interpretazioni diverse della domanda. Ad esempio, ho interpretato "dopo che il mazzo si è esaurito" nel senso che dopo aver osservato l'ultima carta e, se consentito, aggiornando il "numero in cui ti troverai" prima di terminare la procedura. Concepibilmente quell'ultimo passo non doveva essere fatto. Forse una tale sottile differenza di interpretazione spiegherà il disaccordo, a quel punto possiamo modificare la domanda per rendere più chiaro ciò che viene chiesto.


4

Esiste una risposta esatta (sotto forma di un prodotto a matrice, presentato al successivo punto 4). Esiste un algoritmo ragionevolmente efficiente per calcolarlo, derivante da queste osservazioni:

  1. Una mescolanza casuale di carte può essere generata mescolando casualmente carte e quindi alternando casualmente le rimanenti carte al loro interno.N kN+kNk

  2. Mischiando solo gli assi e quindi (applicando la prima osservazione) intervallando i due, poi i tre e così via, questo problema può essere visto come una catena di tredici passi.

  3. Dobbiamo tenere traccia di più del valore della carta che stiamo cercando. Nel fare ciò, tuttavia, non è necessario tenere conto della posizione del segno rispetto a tutte le carte, ma solo della sua posizione rispetto a carte di valore uguale o inferiore.

    Immagina di mettere un segno sul primo asso, quindi di segnare i primi due trovati dopo di esso, e così via. (Se in qualsiasi momento il mazzo si esaurisce senza visualizzare la carta che stiamo attualmente cercando, lasceremo tutte le carte non segnate.) Lascia che il "posto" di ogni segno (quando esiste) sia il numero di carte di valore uguale o inferiore che sono stati distribuiti al momento del marchio (inclusa la carta contrassegnata stessa). I luoghi contengono tutte le informazioni essenziali.

  4. Il posto dopo il segno è un numero casuale. Per un determinato mazzo, la sequenza di questi luoghi forma un processo stocastico. In realtà è un processo di Markov (con matrice di transizione variabile). Una risposta esatta può quindi essere calcolata da dodici moltiplicazioni di matrice.ith

Utilizzando queste idee, questa macchina ottiene un valore di (calcolo in virgola mobile a precisione doppia) in secondo. Questa approssimazione del valore esatto è precisa per tutte le cifre visualizzate.5.83258855290199651/9

1982600579265894785026945331968939023522542569339917784579447928182134345929899510000000000

Il resto di questo post fornisce dettagli, presenta un'implementazione funzionante (in R) e conclude con alcuni commenti sulla domanda e sull'efficienza della soluzione.


Generazione di mescolanze casuali di un mazzo

In realtà è concettualmente più chiaro e matematicamente non è più complicato considerare un "mazzo" (aka multiset ) di carte di cui ci sono della denominazione più bassa, della successiva più bassa, e così via . (La domanda posta riguarda il mazzo determinato dal vettore .)N=k1+k2++kmk1k213(4,4,,4)

Uno "shuffle casuale" di carte è una permutazione presa in modo uniforme e casuale dalla permutazioni delle carteQuesti shuffle si dividono in gruppi di configurazioni equivalenti perché permutare i "assi" tra loro non cambia nulla, permettendo ai "due" tra loro anche cambiare nulla, e così via. Pertanto ogni gruppo di permutazioni che sembrano identiche quando i semi delle carte vengono ignorate contienepermutazioni. Questi gruppi, il cui numero è quindi dato dal coefficiente multinomialeNN!=N×(N1)××2×1Nk1k2k1!×k2!××km!

(Nk1,k2,,km)=N!k1!k2!km!,

sono chiamate "combinazioni" del mazzo.

C'è un altro modo per contare le combinazioni. Le prime carte possono formare solo combinazione. Lasciano "slot" tra e intorno a loro in cui possono essere posizionate le successive carte. Potremmo indicare questo con un diagramma dove " " designa una delle carte e " " indica uno slot che può contenere tra e carte supplementari:k1k1!/k1!=1k1+1k2k1_0k2

_____k1 stars

Quando si carte aggiuntive, il modello di stelle e nuove carte suddivide le carte in due sottoinsiemi. Il numero di tali sottoinsiemi distinti è .k2k1+k2(k1+k2k1,k2)=(k1+k2)!k1!k2!

Ripetendo questa procedura con "tre", troviamo che ci sono modi di separarli tra le prime carte. Pertanto, il numero totale di modi distinti per disporre le prime in questo modo è ugualek3((k1+k2)+k3k1+k2,k3)=(k1+k2+k3)!(k1+k2)!k3!k1+k2k1+k2+k3

1×(k1+k2)!k1!k2!×(k1+k2+k3)!(k1+k2)!k3!=(k1+k2+k3)!k1!k2!k3!.

Dopo aver finito le ultime carte e aver continuato a moltiplicare queste frazioni telescopiche, troviamo che il numero di combinazioni distinte ottenute è uguale al numero totale di combinazioni come precedentemente contate, . Pertanto non abbiamo trascurato nessuna combinazione. Ciò significa che questo processo sequenziale di mescolare le carte cattura correttamente le probabilità di ciascuna combinazione, supponendo che in ogni fase ogni possibile modo distinto di intercalare le nuove carte tra le vecchie sia preso con uniformemente uguale probabilità.kn(Nk1,k2,,km)

Il processo del luogo

Inizialmente, ci sono assi e ovviamente il primo è contrassegnato. Nelle fasi successive ci sono carte, il posto (se esiste una carta segnata) è uguale a (un valore compreso tra e ) e stiamo per intercalare carte attorno a loro. Possiamo visualizzarlo con un diagramma similek1n=k1+k2++kj1p1nk=kj

_____p1 stars____np stars

dove " " indica il simbolo attualmente contrassegnato. In base a questo valore del posto , desideriamo trovare la probabilità che il posto successivo sia uguale a (un valore compreso tra e ; in base alle regole del gioco, il posto successivo deve venire dopo , da cui ). Se riusciamo a trovare quanti modi ci sono per separare le nuove carte negli spazi vuoti in modo che il posto successivo sia uguale a , allora possiamo dividere per il numero totale di modi per separare queste carte (uguale a , come abbiamo visto) per ottenere il filepq1n+kpqp+1kq(n+kk)probabilità di transizione che il luogo cambi da a . (Ci sarà anche una probabilità di transizione per far scomparire del tutto il luogo quando nessuna delle nuove carte segue la carta segnata, ma non è necessario calcolarla esplicitamente.)pq

Aggiorniamo il diagramma per riflettere questa situazione:

_____p1 starss stars | ____nps stars

La barra verticale " " mostra dove la prima nuova carta avviene dopo la carta contrassegnata: no nuove carte può quindi apparire tra il e (e pertanto nessun slot sono mostrati in quell'intervallo). Non sappiamo quante stelle ci sono in questo intervallo, quindi ho appena chiamato (che può essere zero) l'ignoto spariranno una volta che troviamo il rapporto tra essa e .||ssq

Supponiamo, quindi, di separare nuove carte attorno alle stelle prima del e quindi - indipendentemente da ciò - separiamo le rimanenti nuove carte attorno alle stelle dopo il . Ci sonojkj1|

τn,k(s,p)=((p1)+jj)((nps)+(kj)1kj1)

modi per farlo. Si noti, tuttavia - questa è la parte più difficile dell'analisi - che il posto di uguale a perché|p+s+j+1

  • Ci sono "vecchie" carte in corrispondenza o prima del segno.p
  • Ci sono vecchie carte dopo il marchio, ma prima di .s|
  • Ci sono nuove carte prima del segno.j
  • C'è la nuova carta rappresentata da stesso.|

Pertanto, ci fornisce informazioni sulla transizione da luogo a luogo . Quando seguiamo attentamente queste informazioni per tutti i possibili valori di e sommiamo tutte queste possibilità (disgiunte), otteniamo la probabilità condizionale del posto dopo il posto ,τn,k(s,p)pq=p+s+j+1sqp

Prn,k(q|p)=(j(p1+jj)(n+kqkj1))/(n+kk)

dove la somma inizia da e termina in . (La lunghezza variabile di questa somma suggerisce che c'è è improbabile che sia una formula chiusa per esso in funzione di e , tranne in casi speciali.)j=max(0,q(n+1))j=min(k1,q(p+1)n,k,q,p

L'algoritmo

Inizialmente c'è la probabilità che il posto sia e la probabilità avrà qualsiasi altro valore possibile in . Questo può essere rappresentato da un vettore .1102,3,,k1p1=(1,0,,0)

Dopo aver sparpagliato le successive carte , il vettore viene aggiornato a moltiplicandolo (a sinistra) per la matrice di transizione . Questo si ripete fino a quando tutte le carte sono state piazzate. Ad ogni stadio , la somma delle voci nel vettore di probabilità è la possibilità che una carta sia stata segnata. Qualunque cosa rimanga per rendere il valore uguale a quindi, è la possibilità che nessuna carta rimanga segnata dopo il passaggiok2p1p2(Prk1,k2(q|p),1pk1,1qk2)k1+k2++kmjpj1j. Le successive differenze di questi valori ci danno quindi la probabilità che non siamo riusciti a trovare una carta di tipo da marcare: questa è la distribuzione di probabilità del valore della carta che stavamo cercando quando il mazzo si esaurisce alla fine del gioco .j


Implementazione

Il Rcodice seguente implementa l'algoritmo. Parallela alla discussione precedente. Innanzitutto, il calcolo delle probabilità di transizione viene eseguito da t.matrix(senza normalizzazione con la divisione per , facilitando il tracciamento dei calcoli durante il test del codice):(n+kk)

t.matrix <- function(q, p, n, k) {
  j <- max(0, q-(n+1)):min(k-1, q-(p+1))
  return (sum(choose(p-1+j,j) * choose(n+k-q, k-1-j))
}

Questo è usato da transitionaggiornare a . Calcola la matrice di transizione ed esegue la moltiplicazione. Si occupa anche di calcolare il vettore iniziale se l'argomento è un vettore vuoto:pj1pjp1p

#
# `p` is the place distribution: p[i] is the chance the place is `i`.
#
transition <- function(p, k) {
  n <- length(p)
  if (n==0) {
    q <- c(1, rep(0, k-1))
  } else {
    #
    # Construct the transition matrix.
    #
    t.mat <- matrix(0, nrow=n, ncol=(n+k))
    #dimnames(t.mat) <- list(p=1:n, q=1:(n+k))
    for (i in 1:n) {
      t.mat[i, ] <- c(rep(0, i), sapply((i+1):(n+k), 
                                        function(q) t.matrix(q, i, n, k)))
    }
    #
    # Normalize and apply the transition matrix.
    #
    q <- as.vector(p %*% t.mat / choose(n+k, k))
  }
  names(q) <- 1:(n+k)
  return (q)
}

Ora possiamo facilmente calcolare le probabilità non-mark in ogni fase per qualsiasi mazzo:

#
# `k` is an array giving the numbers of each card in order;
# e.g., k = rep(4, 13) for a standard deck.
#
# NB: the *complements* of the p-vectors are output.
#
game <- function(k) {
  p <- numeric(0)
  q <- sapply(k, function(i) 1 - sum(p <<- transition(p, i)))
  names(q) <- names(k)
  return (q)
}

Eccoli per il mazzo standard:

k <- rep(4, 13)
names(k) <- c("A", 2:9, "T", "J", "Q", "K")
(g <- game(k))

L'output è

         A          2          3          4          5          6          7          8          9          T          J          Q          K 
0.00000000 0.01428571 0.09232323 0.25595013 0.46786622 0.66819134 0.81821790 0.91160622 0.96146102 0.98479430 0.99452614 0.99818922 0.99944610

Secondo le regole, se un re fosse segnato, non cercheremmo altre carte: questo significa che il valore di deve essere aumentato a . Nel fare ciò, le differenze danno la distribuzione del "numero in cui ti troverai quando il mazzo si esaurisce":0.99944611

> g[13] <- 1; diff(g)
          2           3           4           5           6           7           8           9           T           J           Q           K 
0.014285714 0.078037518 0.163626897 0.211916093 0.200325120 0.150026562 0.093388313 0.049854807 0.023333275 0.009731843 0.003663077 0.001810781

(Confronta questo con l'output che riporto in una risposta separata che descrive una simulazione Monte-Carlo: sembrano essere gli stessi, fino alle quantità previste di variazione casuale.)

Il valore atteso è immediato:

> sum(diff(g) * 2:13)
[1] 5.832589

Tutto sommato, ciò richiedeva solo una dozzina di righe di codice eseguibile. L'ho verificato rispetto ai calcoli manuali per piccoli valori di (fino a ). Pertanto, se si riscontra una discrepanza tra il codice e la precedente analisi del problema, affidarsi al codice (poiché l'analisi potrebbe contenere errori tipografici).k3


Osservazioni

Rapporti con altre sequenze

Quando ce n'è una per ogni carta, la distribuzione è una sequenza di reciproci di numeri interi:

> 1/diff(game(rep(1,10)))
[1]      2      3      8     30    144    840   5760  45360 403200

Il valore al posto sono(a partire dal posto ). Questa è la sequenza A001048 nell'Enciclopedia online delle sequenze di numeri interi. Di conseguenza, potremmo sperare in una formula chiusa per i mazzi con costante (i mazzi "adatti") che generalizzi questa sequenza, che a sua volta ha alcuni significati profondi. (Ad esempio, conta le dimensioni delle classi di coniugazione più grandi nei gruppi di permutazione ed è anche correlata ai coefficienti trinomiali .) (Sfortunatamente, i reciproci nella generalizzazione per non sono generalmente numeri interi).ii!+(i1)!i=1kik>1

Il gioco come processo stocastico

La nostra analisi chiarisce che coefficienti iniziali dei vettori , , sono costanti. Ad esempio, seguiamo l'output di come elabora ogni gruppo di carte:ipjjigame

> sapply(1:13, function(i) game(rep(4,i)))

[[1]]
[1] 0

[[2]]
[1] 0.00000000 0.01428571

[[3]]
[1] 0.00000000 0.01428571 0.09232323

[[4]]
[1] 0.00000000 0.01428571 0.09232323 0.25595013

...

[[13]]
 [1] 0.00000000 0.01428571 0.09232323 0.25595013 0.46786622 0.66819134 0.81821790 0.91160622 0.96146102 0.98479430 0.99452614 0.99818922 0.99944610

Ad esempio, il secondo valore del vettore finale (che descrive i risultati con un mazzo completo di 52 carte) è già apparso dopo l'elaborazione del secondo gruppo (ed è uguale a ). Pertanto, se si desidera solo informazioni sul markup attraverso il valore della carta , è necessario eseguire il calcolo solo per un mazzo di card.1/(84)=1/70jthk1+k2++kj

Perché la possibilità di non segna una carta di valore di si sta rapidamente vicino al come aumenta, dopo tipi di carte in quattro semi abbiamo quasi raggiunto il valore limite per l'attesa. In effetti, il valore limite è di circa (calcolato per un mazzo di carte, a quel punto un errore di arrotondamento a doppia precisione impedisce di andare oltre).j1j135.8333554×32

sincronizzazione

Osservando l'algoritmo applicato a -vector , vediamo che il suo tempismo dovrebbe essere proporzionale a e - usando un limite superiore grezzo - non peggio che proporzionale a . Sincronizzando tutti i calcoli per a e a e analizzando solo quelli che richiedono tempi relativamente lunghi ( secondo o più), stimo che il tempo di calcolo sia approssimativamente , a sostegno di questa valutazione del limite superiore.( k , k , ... , k ) k 2 m 3 k = 1 7 n = 10 30 1 / 2 O ( k 2 n 2.9 )m(k,k,,k)k2m3k=17n=10301/2O(k2n2.9)

Un uso di questi asintotici è di proiettare i tempi di calcolo per problemi più grandi. Ad esempio, visto che il caso richiede circa secondi, stimeremmo che il caso (molto interessante) richiederebbe circa secondi. (In realtà ci vogliono secondi.)1,31 k = 1 , n = 100 1.31 ( 1 / 4 ) 2 ( 100 / 30 ) 2,92,7 2,87k=4,n=301.31k=1,n=1001.31(1/4)2(100/30)2.92.72.87


0

un semplice Monte Carlo in Perl e trovato circa .5.8329

#!/usr/bin/perl

use strict;

my @deck = (1..13) x 4;

my $N = 100000; # Monte Carlo iterations.

my $mean = 0;

for (my $i = 1; $i <= $N; $i++) {
    my @d = @deck;
    fisher_yates_shuffle(\@d);
    my $last = 0;
        foreach my $c (@d) {
        if ($c == $last + 1) { $last = $c }
    }
    $mean += ($last + 1) / $N;
}

print $mean, "\n";

sub fisher_yates_shuffle {
    my $array = shift;
        my $i = @$array;
        while (--$i) {
        my $j = int rand($i + 1);
        @$array[$i, $j] = @$array[$j, $i];
    }
}

Data la forte discrepanza tra questa e tutte le risposte precedenti, incluse due simulazioni e una teorica (esatta), sospetto che tu stia interpretando la domanda in modo diverso. In assenza di qualsiasi spiegazione da parte tua, dobbiamo solo prenderlo come sbagliato. (Sospetto che tu ne stia contando uno in meno, nel qual caso il tuo 4.8 dovrebbe essere confrontato con 5.83258 ...; ma anche in questo caso, le tue due cifre significative di precisione non forniscono ulteriori informazioni su questo problema.)
whuber

1
Sì! Si è verificato un errore uno a uno.
Zen,
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.