Nombre prévu sur lequel je serai après avoir pioché des cartes jusqu'à ce que j'obtienne un as, 2, 3, etc.

12

J'ai du mal à résoudre les problèmes suivants.

Vous piochez des cartes d'un jeu standard de 52 cartes sans les remplacer jusqu'à ce que vous obteniez un as. Vous tirez de ce qui reste jusqu'à ce que vous obteniez un 2. Vous continuez avec 3. Quel est le nombre attendu sur lequel vous serez après que le deck entier soit épuisé?

Il était naturel de laisser

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

Donc, le problème revient essentiellement à déterminer la probabilité que vous soyez sur lorsque le jeu s'épuise, à savoir:k

Pr(T1<<TkUk+1<Tk)

je peux voir ça

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

mais n'a pas pu aller plus loin ...

facture
la source
1
Que se passe-t-il si vous avez déjà tiré tous les au moment où vous tirez votre premier as? 2
gung - Rétablir Monica
Le nombre «attendu» signifie-t-il vraiment le nombre «le plus probable»?
whuber
C'est un problème intéressant, mais je ne suis pas sûr des mathématiques que vous écrivez après "le problème revient essentiellement à". Dans la première déclaration, vouliez-vous écrire plutôt que ? Même alors, cependant, je ne suis pas sûr que la déclaration soit correcte. Considérons un début de séquence . Nous avons et donc , mais si je comprends bien votre description textuelle, nous pouvons toujours choisir l'As à la deuxième position, puis le 2 à la cinquième position? Et donc n'est pas une condition nécessaire? T 1 = 2 , T 2 = 1 T 1 > T 2 T 1 < T 22AAA2T1=2,T2=1T1>T2T1<T2
TooTone
@TooTone Oh, je voulais dire comme vous l'avez dit, et vous avez raison; n'est pas une condition nécessaire ...T 1 < T 2T1<T2
facture
@gung Dans ce cas, votre deck sera épuisé et vous serez toujours sur 2.
bill

Réponses:

0

suivant l'idée de @ gung, je crois que la valeur attendue serait de 5,84? et d'après mon interprétation des commentaires, je suppose que "A" est une valeur presque impossible (sauf si les quatre dernières cartes du jeu sont toutes des as). voici les résultats d'une simulation de 100 000 itérations de 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 

et voici le code R au cas où vous voudriez jouer avec lui ..

# 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 )
Anthony Damico
la source
Pourquoi est-ce Aimpossible? Considérez la séquence de 48 cartes suivie par AAAAexemple.
TooTone
vous avez raison .. c'est un sur 270725 - ou avec le code R1/prod( 48:1 / 52:5 )
Anthony Damico
1
Cette réponse est incorrecte. Considérez le nombre de "2": car cela ne peut se produire que lorsque tous les 2 sont rencontrés avant l'un des 1, sa probabilité est de un sur chaque et donc son attente dans votre simulation est de avec une erreur standard de . Votre sortie de est supérieure à six erreurs standard, ce qui la rend presque sûrement erronée. Une valeur précise pour la moyenne (basée sur une simulation différente avec itérations) est . 105/ ( 8(84)=70105/(84)1428.61660 10 6 5,833 ± 0,00437.516601065.833±0.004
whuber
1
Votre code très documenté est malheureusement plusieurs fois plus long et plus lent qu'il ne devrait l'être. J'ai démontré que sa sortie est incorrecte; même si je souhaite avoir eu le temps de déboguer votre code, je ne le fais pas et ce n'est pas ma tâche de le faire. Mon argument est le suivant: vous travaillerez toujours sur "2" à la fin si et seulement si tous les "2" précèdent tous les "A". Parmi les façons également probables d'organiser les quatre "2" et les quatre "A", exactement l'une d'entre elles satisfait à ce critère. Par conséquent, votre valeur de sous la rubrique "2" devrait être proche de , mais ce n'est pas le cas. 105/70=1.429(4+44)=70results105/70=1429
whuber
1
Même les modérateurs ne peuvent pas supprimer les votes des autres :-). Un test du chi carré suggère maintenant que vos résultats sont d'accord avec les miens, mais ce serait bien de savoir comment vous avez testé votre simulation, car cela améliorerait la confiance dans votre réponse. En fait, selon une modification que vous avez apportée au premier paragraphe de votre réponse, maintenant nos deux résultats sont faux: comme j'ai interprété votre question, il n'est jamais possible de travailler sur un as quand toutes les cartes sont épuisées.
whuber
7

Pour une simulation, il est essentiel d'être correct et rapide. Ces deux objectifs suggèrent d'écrire du code qui cible les capacités de base de l'environnement de programmation ainsi qu'un code aussi court et simple que possible, car la simplicité donne de la clarté et la clarté favorise l'exactitude. Voici ma tentative d'atteindre les deux en 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
}

L'application de cette manière de manière reproductible peut être effectuée avec la replicatefonction après avoir défini la valeur de départ aléatoire, comme dans

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

C'est lent, mais assez rapide pour effectuer des simulations assez longues (et donc précises) à plusieurs reprises sans attendre. Il existe plusieurs façons d'exposer le résultat. Commençons par sa moyenne:

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

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

Ce dernier est l'erreur standard: nous nous attendons à ce que la moyenne simulée soit à deux ou trois SE de la valeur réelle. Cela place la vraie attente entre et5.8535.8175.853 .

Nous pourrions également souhaiter voir une tabulation des fréquences (et leurs erreurs standard). Le code suivant embellit un peu la tabulation:

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)

Voici la sortie:

                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

Comment pouvons-nous savoir que la simulation est même correcte? Une façon consiste à le tester de manière exhaustive pour les petits problèmes. Pour cette raison, ce code a été écrit pour attaquer une petite généralisation du problème, en remplaçant cartes distinctes par et combinaisons avec . Cependant, pour les tests, il est important de pouvoir alimenter le code d'un jeu dans un ordre prédéterminé. Écrivons une interface légèrement différente au même algorithme: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)
}

(Il est possible de l'utiliser drawà la place de simpartout, mais le travail supplémentaire effectué au début de le drawrend deux fois plus lent que sim.)

Nous pouvons l'utiliser en l'appliquant à chaque shuffle distinct d'un deck donné. Étant donné que le but ici n'est que quelques tests uniques, l'efficacité de la génération de ces mélanges n'est pas importante. Voici un moyen rapide par force brute:

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

dEst maintenant un bloc de données dont les lignes contiennent tous les shuffles. Appliquer drawà chaque ligne et compter les résultats:

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

La sortie (que nous utiliserons momentanément dans un test formel) est

   2    3    4 
 420  784 1316 

(La valeur de est facile à comprendre, soit dit en passant: nous travaillerions toujours sur la carte si et seulement si tous les deux précédaient tous les as. La chance que cela se produise (avec deux combinaisons) est de . Sur les mélanges différents, ont cette propriété.)2 1 / ( 2 + 2420225202520/6=4201/(2+22)=1/625202520/6=420

Nous pouvons tester la sortie avec un test du chi carré. À cette fin, j'applique fois à ce cas de cartes distinctes en couleurs: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

Parce que est si élevé, nous ne trouvons aucune différence significative entre ce qui est dit et les valeurs calculées par énumération exhaustive. La répétition de cet exercice pour d'autres (petites) valeurs de et produit des résultats comparables, ce qui nous donne amplement raison de faire confiance lorsqu'il est appliqué à et .n k n = 13 k = 4psimnksimn=13k=4

Enfin, un test du chi carré à deux échantillons comparera la sortie de simla sortie signalée dans une autre réponse:

>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'énorme statistique du chi carré produit une valeur de p qui est essentiellement nulle: sans aucun doute en simdésaccord avec l'autre réponse. Il existe deux résolutions possibles du désaccord: l'une (ou les deux!) De ces réponses est incorrecte ou elles mettent en œuvre des interprétations différentes de la question. Par exemple, je l' ai interprété « après le pont se épuise » signifie après l' observation de la dernière carte et, si admissible, la mise à jour du « numéro vous serez sur » avant de terminer la procédure. Il est concevable que cette dernière étape ne devait pas être franchie. Peut-être qu'une telle subtile différence d'interprétation expliquera le désaccord, à quel point nous pouvons modifier la question pour clarifier ce qui est demandé.

whuber
la source
4

Il existe une réponse exacte (sous la forme d'un produit matriciel, présenté au point 4 ci-dessous). Il existe un algorithme raisonnablement efficace pour le calculer, dérivant de ces observations:

  1. Un mélange aléatoire de cartes peut être généré en mélangeant au hasard cartes et en intercalant ensuite au hasard les cartes restantes en leur sein.N+kNk

  2. En mélangeant uniquement les as, puis (en appliquant la première observation) en intercalant les deux, puis les trois, etc., ce problème peut être considéré comme une chaîne de treize étapes.

  3. Nous devons garder une trace de plus que la valeur de la carte que nous recherchons. En faisant cela, cependant, nous n'avons pas besoin de tenir compte de la position de la marque par rapport à toutes les cartes, mais seulement de sa position par rapport aux cartes de valeur égale ou inférieure.

    Imaginez que vous placez une marque sur le premier as, puis que vous marquez les deux premiers trouvés après, et ainsi de suite. (Si à n'importe quel stade le jeu s'épuise sans afficher la carte que nous recherchons actuellement, nous laisserons toutes les cartes non marquées.) Soit la "place" de chaque marque (lorsqu'elle existe) soit le nombre de cartes de valeur égale ou inférieure qui ont été distribués lorsque la marque a été faite (y compris la carte marquée elle-même). Les lieux contiennent toutes les informations essentielles.

  4. L'emplacement après la marque est un nombre aléatoire. Pour un jeu donné, la séquence de ces lieux forme un processus stochastique. Il s'agit en fait d'un processus de Markov (à matrice de transition variable). Une réponse exacte peut donc être calculée à partir de douze multiplications matricielles.ith

En utilisant ces idées, cette machine obtient une valeur de (calcul en virgule flottante double précision) en seconde. Cette approximation de la valeur exacte est précise pour tous les chiffres affichés.5.83258855290199651/9

1982600579265894785026945331968939023522542569339917784579447928182134345929899510000000000

Le reste de cet article fournit des détails, présente une implémentation fonctionnelle (en R) et se termine par quelques commentaires sur la question et l'efficacité de la solution.


Générer des shuffles aléatoires d'un deck

Il est en fait plus clair sur le plan conceptuel et pas plus compliqué mathématiquement de considérer un "jeu" (aka multiset ) de cartes dont il y a de la plus petite dénomination, de la plus basse suivante, etc. . (La question posée concerne le jeu de cartes déterminé par le vecteur .)N=k1+k2++kmk1k213(4,4,,4)

Un "mélange aléatoire" de cartes est une permutation prise uniformément et au hasard parmi les permutations des cartes. Ces shuffles se répartissent en groupes de configurations équivalentes parce que la permutation des "as" entre eux ne change rien, la permutation des "deux" entre eux ne change rien non plus, et ainsi de suite. Par conséquent, chaque groupe de permutations qui semblent identiques lorsque les combinaisons des cartes sont ignorées contientpermutations. Ces groupes, dont le nombre est donc donné par le coefficient multinomialN ! = N × ( NNN!=N×(N1)××2×1Nk1k2k1!×k2!××km!

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

sont appelés "combinaisons" du jeu.

Il existe une autre façon de compter les combinaisons. Les premières cartes ne peuvent former que combinaison. Ils laissent "emplacements" entre eux et autour d'eux dans lesquels les prochaines cartes peuvent être placées. Nous pourrions l'indiquer avec un diagramme où " " désigne l'une des cartes et " " désigne un emplacement pouvant contenir entre et cartes supplémentaires:k 1 !k1k1!/k1!=1k1+1k2k1_0k2

_____k1 stars

Lorsque cartes supplémentaires sont intercalées, le motif d'étoiles et de nouvelles cartes partitionne les cartes en deux sous-ensembles. Le nombre de ces sous-ensembles distincts est .k2k1+k2(k1+k2k1,k2)=(k1+k2)!k1!k2!

En répétant cette procédure avec "trois", nous constatons qu'il y a façons de les intercaler parmi les premières cartes. Par conséquent, le nombre total de façons distinctes d'organiser les premières cartes de cette manière est égal àk3((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!.

Après avoir terminé les dernières cartes et continué à multiplier ces fractions télescopiques, nous constatons que le nombre de combinaisons distinctes obtenues est égal au nombre total de combinaisons comptées précédemment, . Nous n'avons donc négligé aucune combinaison. Cela signifie que ce processus séquentiel de mélange des cartes capture correctement les probabilités de chaque combinaison, en supposant qu'à chaque étape, chaque manière distincte possible d'interpénétrer les nouvelles cartes parmi les anciennes est prise avec une probabilité uniformément égale.kn(Nk1,k2,,km)

Le processus d'endroit

Initialement, il y a as et évidemment le tout premier est marqué. Aux stades ultérieurs, il y a cartes, l'endroit (si une carte marquée existe) est égal à (une valeur de à ), et nous sommes sur le point de croiser cartes autour d'eux. Nous pouvons visualiser cela avec un diagramme comme n = k 1 + k 2k1n=k1+k2++kj1p1nk=kj

_____p1 stars____np stars

où " " désigne le symbole actuellement marqué. Conditionnellement à cette valeur de la place , nous souhaitons trouver la probabilité que la prochaine place soit égale à (une valeur de à ; selon les règles du jeu, la prochaine place doit venir après , d'où ). Si nous pouvons trouver combien de façons il y a pour intercaler les nouvelles cartes dans les blancs afin que la prochaine place soit égale à , alors nous pouvons diviser par le nombre total de façons d'interpénétrer ces cartes (égal à , comme nous l'avons vu) pour obtenir lepq1n+kpqp+1kq(n+kk)probabilité de transition que le lieu passe de à . (Il y aura également une probabilité de transition pour que l'endroit disparaisse complètement lorsqu'aucune des nouvelles cartes ne suit la carte marquée, mais il n'est pas nécessaire de le calculer explicitement.)pq

Mettons à jour le diagramme pour refléter cette situation:

_____p1 starss stars | ____nps stars

La barre verticale " " indique où la première nouvelle carte apparaît après la carte marquée: aucune nouvelle carte ne peut donc apparaître entre le et le (et donc aucun emplacement n'est affiché dans cet intervalle). Nous ne savons pas combien d'étoiles il y a dans cet intervalle, je viens donc de l'appeler (qui peut être zéro). L'inconnu disparaîtra une fois que nous aurons trouvé la relation entre lui et .||ssq

Supposons donc que nous entremêlons nouvelles cartes autour des étoiles avant le puis - indépendamment de cela - nous entremêlons les nouvelles cartes restantes autour des étoiles après le . Il y ajkj1|

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

façons de le faire. Remarquez cependant - c'est la partie la plus délicate de l'analyse - que la place de est égale à car|p+s+j+1

  • Il y a "anciennes" cartes à la marque ou avant.p
  • Il y a vieilles cartes après la marque , mais avant .s|
  • Il y a nouvelles cartes avant la marque.j
  • Il y a la nouvelle carte représentée par lui-même.|

Ainsi, nous donne des informations sur la transition du lieu au lieu . Lorsque nous suivons attentivement ces informations pour toutes les valeurs possibles de et que nous additionnons toutes ces possibilités (disjointes), nous obtenons la probabilité conditionnelle du lieu suivant le lieu ,τn,k(s,p)pq=p+s+j+1sqp

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

où la somme commence à et se termine à . (La longueur variable de cette somme suggère qu'il y a ne sera probablement pas une formule fermée pour elle en fonction de et , sauf dans des cas particuliers.)j=max(0,q(n+1))j=min(k1,q(p+1)n,k,q,p

L'algorithme

Initialement, il y a une probabilité que le lieu soit et une probabilité il aura toute autre valeur possible dans . Ceci peut être représenté par un vecteur .1102,3,,k1p1=(1,0,,0)

Après avoir intercalé les cartes suivantes, le vecteur est mis à jour à en le multipliant (à gauche) par la matrice de transition . Ceci est répété jusqu'à ce que toutes les aient été placées. A chaque étape , la somme des entrées du vecteur de probabilité est la chance que certaines cartes a été marquée. Tout ce qui reste pour rendre la valeur égale à est donc la chance qu'aucune carte ne soit laissée marquée après l'étapek2p1p2(Prk1,k2(q|p),1pk1,1qk2)k1+k2++kmjpj1j. Les différences successives de ces valeurs nous donnent donc la probabilité de ne pas trouver une carte de type à marquer: c'est la distribution de probabilité de la valeur de la carte que nous cherchions lorsque le jeu s'épuise à la fin de la partie .j


la mise en oeuvre

Le Rcode suivant implémente l'algorithme. Il est parallèle à la discussion précédente. Tout d'abord, le calcul des probabilités de transition est effectué par t.matrix(sans normalisation avec la division par , ce qui facilite le suivi des calculs lors du test du code):(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))
}

Ceci est utilisé par transitionpour mettre à jour en . Il calcule la matrice de transition et effectue la multiplication. Il prend également en charge le calcul du vecteur initial si l'argument est un vecteur vide: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)
}

Nous pouvons maintenant facilement calculer les probabilités non marquées à chaque étape pour n'importe quel deck:

#
# `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)
}

Les voici pour le deck standard:

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

La sortie est

         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

Selon les règles, si un roi était marqué, nous ne chercherions plus de cartes: cela signifie que la valeur de doit être augmentée à . Ce faisant, les différences donnent la distribution du "numéro sur lequel vous serez lorsque le jeu sera épuisé":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

(Comparez cela à la sortie que je rapporte dans une réponse séparée décrivant une simulation de Monte-Carlo: ils semblent être les mêmes, jusqu'à des niveaux de variation aléatoire attendus.)

La valeur attendue est immédiate:

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

Tout compte fait, cela ne nécessitait qu'une douzaine de lignes environ de code exécutable. Je l'ai vérifié par rapport aux calculs manuels pour les petites valeurs de (jusqu'à ). Ainsi, si une divergence apparaît entre le code et l'analyse précédente du problème, faites confiance au code (car l'analyse peut contenir des erreurs typographiques).k3


Remarques

Relations avec d'autres séquences

Lorsqu'il y en a une de chaque carte, la distribution est une séquence de réciproques de nombres entiers:

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

La valeur à l'endroit est(à partir de la place ). Il s'agit de la séquence A001048 dans l'Encyclopédie en ligne des séquences de nombres entiers. En conséquence, nous pourrions espérer une formule fermée pour les ponts à constant (les ponts "adaptés") qui généraliserait cette séquence, qui a elle-même des significations profondes. (Par exemple, il compte les tailles des plus grandes classes de conjugaison dans les groupes de permutation et est également lié aux coefficients trinomiaux .) (Malheureusement, les inverses dans la généralisation pour ne sont généralement pas des nombres entiers.)ii!+(i1)!i=1kik>1

Le jeu comme processus stochastique

Notre analyse montre clairement que les coefficients initiaux des vecteurs , , sont constants. Par exemple, suivons la sortie de car il traite chaque groupe de cartes: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

Par exemple, la deuxième valeur du vecteur final (décrivant les résultats avec un jeu complet de 52 cartes) est déjà apparue après le traitement du deuxième groupe (et est égale à ). Ainsi, si vous souhaitez uniquement des informations sur les marques jusqu'à la valeur de la carte , il vous suffit d'effectuer le calcul pour un jeu de .jème1/(84)=1/70jthk1+k2++kj

Parce que la chance de ne pas marquer une carte de valeur se rapproche rapidement de mesure que augmente, après types de cartes dans quatre couleurs, nous avons presque atteint une valeur limite pour l'attente. En effet, la valeur limite est d'environ (calculée pour un jeu de cartes, point auquel l'erreur d'arrondi double précision empêche d'aller plus loin).1j1j135.8333554×32

Horaire

En regardant l'algorithme appliqué au vecteur , nous voyons que son timing devrait être proportionnel à et - en utilisant une limite supérieure brute - pas pire que proportionnel à . En chronométrant tous les calculs pour à et à , et en analysant uniquement ceux qui prennent des temps relativement longs ( seconde ou plus), j'estime que le temps de calcul est approximativement , soutenant cette évaluation de la limite supérieure.( k , k , , k ) k 2 m 3 k = 1 7 n = 10 30m(k,k,,k)k2m3k=17n=1030O ( k 2 n 2.9 )1/2O(k2n2.9)

Une utilisation de ces asymptotiques est de projeter des temps de calcul pour des problèmes plus importants. Par exemple, vu que le cas prend environ seconde, nous estimons que le cas (très intéressant) prendrait environ secondes. (Cela prend en fait secondes.)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

whuber
la source
0

Hacké un simple Monte Carlo en Perl et trouvé environ .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];
    }
}
Zen
la source
Étant donné la forte divergence entre cette réponse et toutes les réponses précédentes, y compris deux simulations et une théorique (exacte), je soupçonne que vous interprétez la question d'une manière différente. En l’absence de toute explication de votre part, nous devons simplement le considérer comme erroné. (Je soupçonne que vous en comptez un de moins, auquel cas votre 4.8 devrait être comparé à 5.83258 ...; mais même dans ce cas, vos deux chiffres significatifs de précision n'apportent aucun aperçu supplémentaire sur ce problème.)
whuber
1
Oui! Il y a eu une erreur ponctuelle.
Zen