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:
Acak acak kartu dapat dihasilkan dengan mengocok kartu secara acak dan kemudian secara acak memotong kartu tersisa di dalamnya.N kN+kNk
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.
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.
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×(N−1)×⋯×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+1k2∗k1_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+⋯+kj−1p1nk=kj
_∗_∗_⋯_∗_p−1 stars⊙_∗_⋯_∗_n−p 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 mendapatkan⊙pq1n+kpq≥p+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:
_∗_∗_⋯_∗_p−1 stars⊙∗∗⋯∗s stars | _∗_⋯_∗_n−p−s 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 . Adaj⊙k−j−1|
τn,k(s,p)=((p−1)+jj)((n−p−s)+(k−j)−1k−j−1)
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(p−1+jj)(n+k−qk−j−1))/(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(k−1,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),1≤p≤k1,1≤q≤k2)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
R
Kode 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 transition
untuk memperbarui ke . Ini menghitung matriks transisi dan melakukan perkalian. Ia juga menangani perhitungan vektor awal jika argumennya adalah vektor kosong:pj−1pjp1p
#
# `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!+(i−1)!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:ipjj≥igame
> 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,9 ≈ 2,7 2,87k=4,n=301.31k=1,n=1001.31(1/4)2(100/30)2.9≈2.72.87