Diharapkan nomor saya akan aktif setelah menggambar kartu sampai saya mendapatkan kartu as, 2, 3, dan sebagainya

12

Saya mengalami beberapa masalah dalam menyelesaikan yang berikut ini.

Anda mengambil kartu dari tumpukan kartu 52 kartu standar tanpa penggantian sampai Anda mendapatkan kartu As. Anda menarik dari apa yang tersisa sampai Anda mendapatkan 2. Anda melanjutkan dengan 3. Berapa angka yang diharapkan Anda akan berada setelah seluruh dek habis?

Wajar membiarkannya

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

Jadi masalah pada dasarnya sama dengan mencari tahu probabilitas bahwa Anda akan berada di ketika dek habis, yaitu:k

Pr(T1<<TkUk+1<Tk)

Saya bisa melihatnya

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

tetapi tidak bisa melangkah lebih jauh ...

tagihan
sumber
1
Apa yang terjadi jika Anda sudah menggambar semua s pada saat Anda menggambar kartu as pertama Anda? 2
gung - Reinstate Monica
Apakah angka "yang diharapkan" benar-benar berarti angka "yang paling mungkin"?
whuber
Ini adalah masalah yang menarik, tetapi saya tidak yakin tentang matematika yang Anda tulis setelah "masalah dasarnya berjumlah". Dalam pernyataan pertama maksud Anda menulis daripada ? Meski begitu, bagaimanapun, saya tidak yakin pernyataan itu benar. Pertimbangkan urutan awal . Kami memiliki dan jadi , tetapi jika saya memahami deskripsi teks Anda dengan benar, kami masih dapat memilih Ace di posisi kedua dan kemudian 2 di posisi kelima? Dan karena itu bukan syarat yang perlu? T 1 = 2 , T 2 = 1 T 1 > T 2 T 1 < T 22AAA2T1=2,T2=1T1>T2T1<T2
TooTone
@ToTone Oh, maksudku seperti yang Anda katakan, dan Anda benar; bukan syarat yang diperlukan ...T 1 < T 2T1<T2
tagihan
@ Gung Dalam hal itu, dek Anda akan habis dan Anda masih akan berada di 2.
tagihan

Jawaban:

0

mengikuti ide @ gung, saya percaya nilai yang diharapkan adalah 5,84? dan dari interpretasi saya tentang komentar, saya berasumsi "A" adalah nilai yang hampir mustahil (kecuali empat kartu terakhir di geladak adalah kartu As). berikut adalah hasil dari iterasi 100.000 simulasi 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 

dan inilah kode R jika Anda ingin bermain dengannya ..

# 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
sumber
Kenapa tidak Amungkin? Pertimbangkan urutan 48 kartu yang diikuti oleh AAAAmisalnya.
TooTone
Anda benar .. ini salah satu dari 270725 - atau dengan kode R1/prod( 48:1 / 52:5 )
Anthony Damico
1
Jawaban ini salah. Pertimbangkan hitung untuk "2": karena ini hanya dapat terjadi ketika semua 2 ditemukan sebelum salah satu dari 1, probabilitasnya adalah satu di setiap dan karena itu harapannya dalam simulasi Anda adalah dengan kesalahan standar . Output lebih dari enam kesalahan standar terlalu tinggi, sehingga hampir pasti salah. Nilai akurat untuk rata-rata (berdasarkan simulasi berbeda dengan iterasi ) adalah . 105/ ( 8(84)=7037.516601065.833±0.004105/(84)1428.637.516601065.833±0.004
whuber
1
Sayangnya kode Anda yang banyak didokumentasikan beberapa kali lebih lama dan lebih lambat dari yang seharusnya. Saya menunjukkan hasilnya salah; walaupun saya berharap saya punya waktu untuk men-debug kode Anda saya tidak dan itu bukan tugas saya untuk melakukan itu. Argumen saya adalah ini: Anda masih akan mengerjakan "2" pada akhirnya jika dan hanya jika semua "2" mendahului semua "A". Di antara cara yang mungkin sama untuk mengatur empat "2" dan empat "A", salah satunya memenuhi kriteria ini. Karena itu nilai Anda di bawah judul "2" harus mendekati , tetapi tidak. 105/70=1429(4+44)=70results105/70=1429
whuber
1
Bahkan moderator tidak dapat menghapus suara orang lain :-). Tes chi-squared sekarang menunjukkan hasil Anda setuju dengan milik saya, tetapi akan menyenangkan untuk mengetahui bagaimana Anda menguji simulasi Anda, karena itu akan meningkatkan kepercayaan diri dalam jawaban Anda. Bahkan, menurut hasil edit yang Anda buat pada paragraf pertama dalam jawaban Anda, sekarang kedua hasil kami salah: karena saya telah menginterpretasikan pertanyaan Anda, tidak mungkin untuk mengerjakan kartu as ketika semua kartu habis.
whuber
7

Untuk simulasi, sangat penting untuk menjadi benar dan cepat. Kedua tujuan ini menyarankan penulisan kode yang menargetkan kemampuan inti dari lingkungan pemrograman serta kode yang sesingkat dan sesederhana mungkin, karena kesederhanaan memberikan kejelasan dan kejelasan mempromosikan kebenaran. Inilah usaha saya untuk mencapai keduanya di 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
}

Menerapkan ini dengan cara yang dapat direproduksi dapat dilakukan dengan replicatefungsi setelah mengatur seed number acak, seperti pada

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

Itu lambat, tetapi cukup cepat untuk melakukan simulasi yang cukup panjang (dan karenanya tepat) berulang kali tanpa menunggu. Ada beberapa cara untuk menunjukkan hasilnya. Mari kita mulai dengan artinya:

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

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

Yang terakhir adalah kesalahan standar: kami berharap rata-rata yang disimulasikan berada dalam dua atau tiga SE dari nilai sebenarnya. Itu menempatkan harapan sebenarnya di suatu tempat antara dan5.8535.8175.853 .

Kami juga mungkin ingin melihat tabulasi frekuensi (dan mereka kesalahan standar). Kode berikut sedikit memberi sedikit tabulasi:

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)

Berikut hasilnya:

                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

Bagaimana kita tahu simulasi itu benar? Salah satu caranya adalah mengujinya secara mendalam untuk masalah yang lebih kecil. Untuk alasan itu kode ini ditulis untuk menyerang generalisasi kecil dari masalah, mengganti kartu yang berbeda dengan dan kartu dengan . Namun, untuk pengujian penting untuk dapat memberi makan kode dek dalam urutan yang telah ditentukan. Mari kita tulis antarmuka yang sedikit berbeda dengan algoritma yang sama: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)
}

(Dimungkinkan untuk digunakan drawdi simmana - mana, tetapi kerja ekstra yang dilakukan di awal drawmembuatnya dua kali lebih lambat sim.)

Kita dapat menggunakan ini dengan menerapkannya pada setiap pengocokan berbeda dari dek yang diberikan. Karena tujuan di sini hanya beberapa tes satu kali, efisiensi dalam menghasilkan shuffles tidak penting. Berikut ini cara kasar yang cepat:

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

Sekarang dadalah bingkai data yang barisnya berisi semua shuffles. Terapkan drawke setiap baris dan hitung hasilnya:

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

Output (yang akan kita gunakan dalam tes formal sebentar lagi) adalah

   2    3    4 
 420  784 1316 

(Nilai mudah dimengerti, ngomong-ngomong: kita masih akan mengerjakan kartu jika dan hanya jika semua pasangan mendahului semua kartu As. Peluang terjadinya ini (dengan dua setelan) adalah . Dari berbeda, miliki properti ini.)2 1 / ( 2 + 2420225202520/6=4201/(2+22)=1/625202520/6=420

Kami dapat menguji output dengan uji chi-squared. Untuk tujuan ini saya menerapkan kali untuk kasus ini kartu berbeda dalam :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

Karena sangat tinggi, kami tidak menemukan perbedaan yang signifikan antara apa yang dikatakan dan nilai-nilai yang dihitung oleh enumerasi lengkap. Mengulangi latihan ini untuk beberapa nilai dan lainnya (kecil) menghasilkan hasil yang sebanding, memberi kami banyak alasan untuk percaya ketika diterapkan pada dan .n k n = 13 k = 4psimnksimn=13k=4

Akhirnya, uji chi-kuadrat dua sampel akan membandingkan keluaran simke keluaran yang dilaporkan dalam jawaban lain:

>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

Statistik chi-squared yang sangat besar menghasilkan nilai-p yang pada dasarnya nol: tanpa keraguan, simtidak setuju dengan jawaban lainnya. Ada dua kemungkinan resolusi perselisihan: satu (atau keduanya!) Jawaban ini salah atau mereka menerapkan interpretasi yang berbeda dari pertanyaan tersebut. Sebagai contoh, saya telah menafsirkan "setelah dek habis" berarti setelah mengamati kartu terakhir dan, jika diperbolehkan, memperbarui "nomor Anda akan berada di" sebelum mengakhiri prosedur. Dapat dibayangkan bahwa langkah terakhir tidak dimaksudkan untuk diambil. Mungkin beberapa perbedaan penafsiran yang halus seperti itu akan menjelaskan ketidaksepakatan, pada titik mana kita dapat memodifikasi pertanyaan untuk memperjelas apa yang ditanyakan.

whuber
sumber
4

Ada jawaban yang tepat (dalam bentuk produk matriks, disajikan pada poin 4 di bawah). Algoritma yang cukup efisien untuk menghitungnya ada, berasal dari pengamatan ini:

  1. Acak acak kartu dapat dihasilkan dengan mengocok kartu secara acak dan kemudian secara acak memotong kartu tersisa di dalamnya.N kN+kNk

  2. Dengan hanya mengocok kartu As, dan kemudian (menerapkan pengamatan pertama) menyelingi keduanya, lalu bertiga, dan seterusnya, masalah ini dapat dilihat sebagai rantai dari tiga belas langkah.

  3. Kita perlu melacak lebih dari nilai kartu yang kita cari. Ketika melakukan ini, kita tidak perlu memperhitungkan posisi tanda relatif terhadap semua kartu, tetapi hanya posisinya relatif terhadap kartu yang nilainya sama atau lebih kecil.

    Bayangkan menempatkan tanda pada kartu as pertama, dan kemudian menandai dua yang pertama ditemukan setelahnya, dan seterusnya. (Jika pada suatu tahap dek habis tanpa menampilkan kartu yang sedang kami cari, kami akan membiarkan semua kartu tidak ditandai.) Biarkan "tempat" dari setiap tanda (bila ada) adalah jumlah kartu dengan nilai yang sama atau lebih rendah yang dibagikan ketika tanda dibuat (termasuk kartu yang ditandai itu sendiri). Tempat-tempat berisi semua informasi penting.

  4. Tempat setelah tanda dibuat adalah angka acak. Untuk dek tertentu, urutan tempat-tempat ini membentuk proses stokastik. Ini sebenarnya adalah proses Markov (dengan matriks transisi variabel). Karena itu jawaban yang tepat dapat dihitung dari dua belas perkalian matriks.ith

Menggunakan ide-ide ini, mesin ini memperoleh nilai (komputasi dalam floating point presisi ganda) dalam detik. Perkiraan nilai persis ini akurat untuk semua digit yang ditampilkan.1 / 9 19826005792658947850269453319689390235225425695.83258855290199651/9

1982600579265894785026945331968939023522542569339917784579447928182134345929899510000000000

Sisa dari posting ini memberikan perincian, menyajikan implementasi kerja (dalam R), dan diakhiri dengan beberapa komentar tentang pertanyaan dan efisiensi solusi.


Menghasilkan serutan acak dari sebuah geladak

Sebenarnya lebih jelas secara konseptual dan tidak lebih rumit secara matematis untuk mempertimbangkan "dek" (alias multiset ) dari kartu yang ada dari denominasi terendah, dari terendah berikutnya, dan seterusnya . (Pertanyaan yang diajukan menyangkut dek yang ditentukan oleh vektor- .)N=k1+k2++kmk1k213(4,4,,4)

A "acak acak" kartu adalah satu permutasi diambil secara seragam dan acak dari permutasi kartuShuffles ini jatuh ke dalam kelompok konfigurasi yang setara karena "ace" antara mereka sendiri tidak mengubah apa pun, "dua" antara mereka sendiri juga tidak mengubah apa pun, dan sebagainya. Oleh karena itu setiap kelompok permutasi yang terlihat identik ketika kartu-kartu tersebut diabaikan berisipermutasi. Kelompok-kelompok ini, yang jumlahnya diberikan oleh koefisien multinomialNN!=N×(N1)××2×1Nk1k2k1!×k2!××km!

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

disebut "kombinasi" dari dek.

Ada cara lain untuk menghitung kombinasi. Kartu pertama dapat membentuk kombinasi. Mereka meninggalkan "slot" di antara dan di sekelilingnya tempat kartu berikutnya dapat ditempatkan. Kami dapat menunjukkan ini dengan diagram di mana " " menunjuk salah satu kartu dan " " menunjuk sebuah slot yang dapat menampung antara dan kartu tambahan:k1k1!/k1!=1k1+1k2k1_0k2

_____k1 stars

Ketika kartu tambahan diselingi, pola bintang dan kartu baru kartu menjadi dua subset. Jumlah himpunan bagian yang berbeda adalah .k2k1+k2(k1+k2k1,k2)=(k1+k2)!k1!k2!

Mengulangi prosedur ini dengan "bertiga," kami menemukan ada cara untuk menyelinginya di antara kartu pertama . Karenanya jumlah total cara berbeda untuk mengatur kartu dengan cara ini sama dengank3((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!.

Setelah menyelesaikan kartu terakhir dan terus melipatgandakan fraksi teleskop ini, kami menemukan bahwa jumlah kombinasi berbeda yang diperoleh sama dengan jumlah total kombinasi yang dihitung sebelumnya, . Karenanya, kami tidak mengabaikan kombinasi. Itu berarti proses berurutan mengocok kartu dengan benar menangkap probabilitas setiap kombinasi, dengan asumsi bahwa pada setiap tahap, setiap cara yang mungkin berbeda untuk menyelingi kartu-kartu baru di antara kartu yang lama diambil dengan probabilitas yang sama merata.kn(Nk1,k2,,km)

Proses tempat

Awalnya, ada ace dan jelas yang pertama ditandai. Pada tahap selanjutnya ada , tempatnya (jika kartu yang ditandai ada) sama dengan (beberapa nilai dari hingga ), dan kami akan menyelingi kartu sekitar mereka. Kita dapat memvisualisasikan ini dengan diagram sepertik1n=k1+k2++kj1p1nk=kj

_____p1 stars____np stars

di mana " " menunjukkan simbol yang saat ini ditandai. Bersyarat pada nilai tempat , kami ingin menemukan probabilitas bahwa tempat berikutnya akan sama dengan (beberapa nilai dari hingga ; menurut aturan permainan, tempat berikutnya harus datang setelah , dari mana ). Jika kita dapat menemukan berapa banyak cara yang ada untuk menyelingi kartu baru di tempat kosong sehingga tempat berikutnya sama dengan , maka kita dapat membagi dengan jumlah total cara untuk menyelingi kartu-kartu ini (sama dengan , seperti yang telah kita lihat) untuk mendapatkanpq1n+kpqp+1kq(n+kk)probabilitas transisi bahwa tempat berubah dari ke . (Akan ada juga kemungkinan transisi untuk tempat tersebut hilang sama sekali ketika tidak ada kartu baru yang mengikuti kartu yang ditandai, tetapi tidak perlu menghitung ini secara eksplisit.)pq

Mari kita perbarui diagram untuk mencerminkan situasi ini:

_____p1 starss stars | ____nps stars

Bilah vertikal " " menunjukkan di mana kartu baru pertama muncul setelah kartu yang ditandai: karena itu tidak ada kartu baru yang muncul di antara dan (dan karenanya tidak ada slot yang ditampilkan dalam interval itu). Kita tidak tahu berapa banyak bintang dalam interval ini, jadi saya baru saja menyebutnya (yang mungkin nol) tidak diketahui akan hilang begitu kita menemukan hubungan antara itu dan .||ssq

Misalkan, kemudian, kami menyelingi kartu baru di sekitar bintang sebelum dan then-- secara independen dari yang --Kami menyelingi sisa kartu baru di sekitar bintang setelah . Adajkj1|

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

cara untuk melakukan ini. Perhatikan, meskipun - ini adalah bagian tersulit dari analisis - bahwa tempat sama dengan karena|p+s+j+1

  • Ada kartu "lama" di atau sebelum tanda.p
  • Ada kartu lama setelah tanda tapi sebelum .s|
  • Ada kartu baru sebelum tanda.j
  • Ada kartu baru yang diwakili oleh itu sendiri.|

Dengan demikian, memberi kami informasi tentang transisi dari tempat ke tempat . Ketika kami melacak informasi ini dengan cermat untuk semua nilai yang mungkin dari , dan menjumlahkan semua kemungkinan (terpisah) ini, kami memperoleh probabilitas bersyarat tempat berikut tempat ,τn,k(s,p)pq=p+s+j+1sqp

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

di mana jumlah dimulai pada dan berakhir pada . (Panjang variabel dari jumlah ini menunjukkan ada tidak mungkin menjadi formula tertutup untuk itu sebagai fungsi dari dan , kecuali dalam kasus khusus.)j=max(0,q(n+1))j=min(k1,q(p+1)n,k,q,p

Algoritma

Awalnya ada probabilitas bahwa tempat itu akan menjadi dan probabilitas itu akan memiliki nilai lain yang mungkin dalam . Ini dapat diwakili oleh vektor .1102,3,,k1p1=(1,0,,0)

Setelah kartu berikutnya , vektor diperbarui ke dengan mengalikannya (di sebelah kiri) dengan matriks transisi . Ini diulangi sampai semua telah ditempatkan. Pada setiap tahap , jumlah entri dalam vektor probabilitas adalah kemungkinan beberapa kartu telah ditandai. Apa pun yang tersisa untuk membuat nilai sama dengan oleh karena itu adalah kesempatan bahwa tidak ada kartu yang ditandai setelah langkahk2p1p2(Prk1,k2(q|p),1pk1,1qk2)k1+k2++kmjpj1j. Perbedaan berturut-turut dalam nilai-nilai ini karena itu memberi kita probabilitas bahwa kita tidak dapat menemukan kartu tipe untuk ditandai: yaitu distribusi probabilitas dari nilai kartu yang kita cari ketika tumpukan kartu habis di akhir permainan. .j


Penerapan

RKode berikut mengimplementasikan algoritma. Ini sejajar dengan diskusi sebelumnya. Pertama, perhitungan probabilitas transisi dilakukan oleh t.matrix(tanpa normalisasi dengan pembagian dengan , membuatnya lebih mudah untuk melacak perhitungan saat menguji kode):(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))
}

Ini digunakan transitionuntuk memperbarui ke . Ini menghitung matriks transisi dan melakukan perkalian. Ia juga menangani perhitungan vektor awal jika argumennya adalah vektor kosong: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)
}

Kita sekarang dapat dengan mudah menghitung probabilitas non-mark pada setiap tahap untuk setiap dek:

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

Ini untuk dek standar:

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

Outputnya adalah

         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

Menurut aturan, jika seorang raja ditandai maka kita tidak akan mencari kartu lebih lanjut: ini berarti nilai harus ditingkatkan menjadi . Setelah melakukan itu, perbedaannya memberikan distribusi "nomor Anda akan ketika dek habis":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

(Bandingkan ini dengan keluaran yang saya laporkan dalam jawaban terpisah yang menggambarkan simulasi Monte-Carlo: semuanya tampak sama, hingga jumlah variasi acak yang diharapkan.)

Nilai yang diharapkan segera:

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

Semua mengatakan, ini membutuhkan hanya selusin baris kode yang dapat dieksekusi. Saya telah memeriksanya dengan perhitungan tangan untuk nilai kecil (hingga ). Dengan demikian, jika ada perbedaan antara kode dan analisis masalah sebelumnya, percayakan kode tersebut (karena analisis tersebut mungkin memiliki kesalahan ketik).k3


Catatan

Hubungan dengan urutan lainnya

Ketika ada satu kartu masing-masing, distribusi adalah urutan kebalikan dari seluruh angka:

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

Nilai di tempat adalah(mulai dari tempat ). Ini adalah urutan A001048 dalam Ensiklopedia Online Urutan Bilangan Bulat. Dengan demikian, kita mungkin berharap untuk formula tertutup untuk deck dengan konstan (deck "cocok") yang akan menggeneralisasi urutan ini, yang dengan sendirinya memiliki beberapa makna mendalam. (Misalnya, ia menghitung ukuran kelas konjugasi terbesar dalam kelompok permutasi dan juga terkait dengan koefisien trinomial .) (Sayangnya, timbal balik dalam generalisasi untuk biasanya tidak bilangan bulat.)ii!+(i1)!i=1kik>1

Permainan sebagai proses stokastik

Analisis kami memperjelas bahwa koefisien awal vektor , , adalah konstan. Misalnya, mari kita lacak output saat memproses setiap kelompok kartu: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

Sebagai contoh, nilai kedua dari vektor final (menggambarkan hasil dengan setumpuk penuh 52 kartu) sudah muncul setelah kelompok kedua diproses (dan sama dengan ). Dengan demikian, jika Anda menginginkan informasi hanya tentang tanda naik melalui nilai kartu , Anda hanya perlu melakukan perhitungan untuk setumpuk kartu .1/(84)=1/70jthk1+k2++kj

Karena peluang untuk tidak menandai kartu nilai semakin cepat mendekati ketika meningkat, setelah jenis kartu dalam empat setelan, kita hampir mencapai nilai pembatas untuk ekspektasi. Memang, nilai pembatas sekitar (dihitung untuk setumpuk kartu , di mana titik kesalahan pembulatan presisi ganda mencegah melangkah lebih jauh).j1j135.8333554×32

Pengaturan waktu

Melihat algoritma yang diterapkan pada vektor- , kami melihat waktunya harus proporsional dengan dan - menggunakan batas atas mentah - tidak lebih buruk daripada proporsional dengan . Dengan menghitung semua perhitungan untuk hingga dan hingga , dan menganalisis hanya mereka yang mengambil waktu yang relatif lama ( detik atau lebih lama), saya memperkirakan waktu perhitungan sekitar , mendukung penilaian batas atas ini.( 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)

Salah satu penggunaan asimptotik ini adalah memproyeksikan waktu perhitungan untuk masalah yang lebih besar. Sebagai contoh, melihat bahwa kasus membutuhkan waktu sekitar detik, kami akan memperkirakan bahwa kasus (sangat menarik) akan memakan waktu sekitar detik. (Sebenarnya butuh detik.)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
sumber
0

Meretas Monte Carlo sederhana di Perl dan menemukan sekitar .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
sumber
Mengingat perbedaan yang tajam antara ini dan semua jawaban sebelumnya, termasuk dua simulasi dan yang teoretis (tepat), saya menduga Anda menafsirkan pertanyaan dengan cara yang berbeda. Dengan tidak adanya penjelasan dari pihak Anda, kami hanya harus menganggapnya salah. (Saya menduga Anda mungkin menghitung satu lebih sedikit, dalam hal ini 4,8 Anda harus dibandingkan dengan 5,83258 ...; tetapi meskipun begitu, dua digit presisi Anda yang signifikan tidak memberikan wawasan tambahan tentang masalah ini.)
whuber
1
Ya! Ada kesalahan satu per satu.
Zen