Існує точна відповідь (у вигляді матричного добутку, представленого в пункті 4 нижче). Досить ефективний алгоритм для його обчислення, що випливає з цих спостережень:
Випадкове переміщення карт може бути згенеровано випадковим переміщенням карт, а потім випадковим чином перетинання решти карт у них.N kN+kNk
Перетасовуючи лише тузи, а потім (застосовуючи перше спостереження) перетинаючи двійки, потім трійки тощо, цю проблему можна розглядати як ланцюжок із тринадцяти кроків.
Нам потрібно відслідковувати більше, ніж вартість картки, яку ми шукаємо. При цьому, однак, нам не потрібно враховувати положення знака відносно всіх карт, а лише його положення щодо карт однакового або меншого значення.
Уявіть, що ви поставите позначку на першому тузі, а потім позначте перші два знайдені після нього тощо. (Якщо на будь-якому етапі колода закінчиться, не показуючи карту, яку ми зараз шукаємо, ми залишимо всі картки без позначення.) Нехай "місце" кожної марки (коли вона існує) буде кількістю карток, рівних або менших значень, були розібрані, коли марка була зроблена (включаючи саму марковану карту). Місця містять усю необхідну інформацію.
Місце після позначки є випадковим числом. Для даної колоди послідовність цих місць утворює стохастичний процес. Фактично це процес Маркова (зі змінною матрицею переходу). Точна відповідь може бути обчислена з дванадцяти матричних множень.ith
Використовуючи ці ідеї, ця машина отримує значення (обчислення з плаваючою точкою подвійної точності) за секунди. Це наближення точного значення є точним для всіх показаних цифр.1 / 9 19826005792658947850269453319689390235225425695.83258855290199651/9
1982600579265894785026945331968939023522542569339917784579447928182134345929899510000000000
У решті цього допису розміщені деталі, представлена робоча реалізація (в R
) та завершується деякими коментарями щодо питання та ефективності рішення.
Генерування випадкових переміщень колоди
Насправді зрозуміліше концептуально і не складніше математично вважати "колоду" (він же мультисетом ) карт, в яких є найнижчого номіналу, наступного найнижчого і так далі . (Поставлене запитання стосується колоди, визначеної вектором .)k 1 k 2 13 ( 4 , 4 , … , 4 )N=k1+k2+⋯+kmk1k213(4,4,…,4)
"Випадкове переміщення" з карт - це одна перестановка, взята рівномірно та випадково з перестановка карт. Ці перетасовки потрапляють у групи еквівалентних конфігурацій, оскільки перестановка "тузів" між собою нічого не змінює, перестановка "двійки" між собою також нічого не змінює тощо. Тому кожна група перестановок, які виглядають однаково при ігноруванні карт, міститьперестановки. Ці групи, число яких тому задано коефіцієнтом багаточленуNN!=N×(N−1)×⋯×2×1Nk1k2k1!×k2!×⋯×km!
(Nk1,k2,…,km)=N!k1!k2!⋯km!,
називаються "комбінаціями" колоди.
Є ще один спосіб підрахунку комбінацій. Перші картки можуть утворювати лише комбінація. Вони залишають "прорізи" між ними та навколо них, в яких можна розмістити наступні карти. Ми можемо вказати це на діаграмі, де " " позначає одну з карт, а " " позначає слот, який може містити від до додаткових карт:k1k1!/k1!=1k1+1k2∗k1_0k2
_∗_∗_⋯_∗_k1 stars
Коли додаткові картки перетинаються, візерунок зірок та нових карток розділяє карти на два підмножини. Кількість відмінних таких підмножин - .k2k1+k2(k1+k2k1,k2)=(k1+k2)!k1!k2!
Повторивши цю процедуру з "трійками", ми виявимо, що є способи їх серед перших карток. Тому загальна кількість різних способів розташування перших карток таким чином дорівнює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!.
Закінчивши останні карт і продовжуючи примножувати ці телескопічні дроби, ми виявляємо, що кількість отриманих чітких комбінацій дорівнює загальній кількості комбінацій, як раніше підраховували, . Тому ми не помітили комбінацій. Це означає, що цей послідовний процес перетасування карт правильно фіксує ймовірності кожної комбінації, припускаючи, що на кожному етапі кожен можливий чіткий спосіб перетинання нових карт серед старих приймається з однаковою ймовірністю.kn(Nk1,k2,…,km)
Місце процес
Спочатку є тузи і, очевидно, відзначається найперший. На пізніх етапах є карт, місце (якщо є позначена карта) дорівнює (деяке значення від до ), і ми збираємося перерізати карт навколо них. Ми можемо візуалізувати це за допомогою такої діаграмиk1n=k1+k2+⋯+kj−1p1nk=kj
_∗_∗_⋯_∗_p−1 stars⊙_∗_⋯_∗_n−p stars
де " " позначає позначений в даний час символ. Залежно від цього значення місця , ми хочемо знайти ймовірність того, що наступне місце буде рівним (деяке значення від до ; за правилами гри наступне місце повинно бути після , звідки ). Якщо ми зможемо знайти скільки способів перекреслити нових карток у пробіли, щоб наступне місце дорівнювало , то ми можемо розділити на загальну кількість способів перекреслення цих карт (рівних , як ми бачили) для отримання⊙pq1n+kpq≥p+1kq(n+kk)ймовірність переходу, що місце змінюється від до . (Існує також ймовірність переходу місця, коли воно зовсім зникне, коли жодна з нових карт не буде розміщена за маркованою картою, але немає необхідності чітко обчислювати це.)pq
Оновімо схему, щоб відобразити цю ситуацію:
_∗_∗_⋯_∗_p−1 stars⊙∗∗⋯∗s stars | _∗_⋯_∗_n−p−s stars
Вертикальна смуга « » показує , де відбувається перше нової карти після зазначеної карти: НЕ нові карти не можуть , отже , з'являється між і (і , отже , немає слота не показані на цьому інтервалі). Ми не знаємо, скільки зірок у цьому інтервалі, тому я щойно назвав це (що може бути нульовим). Невідомі зникнуть, як тільки ми знайдемо зв’язок між ним та .|⊙|ssq
Припустимо, тоді ми перекреслюємо нові картки навколо зірок перед а потім - незалежно від цього - ми перемішуємо інші нові карти навколо зірок після . Існуєj⊙k−j−1|
τn,k(s,p)=((p−1)+jj)((n−p−s)+(k−j)−1k−j−1)
способи це зробити. Зауважте, проте - це найскладніша частина аналізу - що місце дорівнює оскільки|p+s+j+1
- На місці або перед позначкою є "старі" картки.p
- Є старі карти після знака , але перед .s|
- Перед позначкою є нові картки.j
- Є нова карта, представлена самим .|
Таким чином, дає нам інформацію про перехід від місця до місця . Коли ми ретельно відстежуємо цю інформацію для всіх можливих значень і підсумовуємо всі ці (непересічні) можливості, отримуємо умовну ймовірність розміщення після місця ,τn,k(s,p)pq=p+s+j+1sqp
Prn,k(q|p)=(∑j(p−1+jj)(n+k−qk−j−1))/(n+kk)
де сума починається від і закінчується при . (Змінна довжина цієї суми дозволяє припустити, що існує навряд чи це буде закритою формулою для неї як функції і , за винятком особливих випадків.)j=max(0,q−(n+1))j=min(k−1,q−(p+1)n,k,q,p
Алгоритм
Спочатку існує ймовірність що місце буде а ймовірність матиме будь-яке інше можливе значення у . Це можна представити вектором .1102,3,…,k1p1=(1,0,…,0)
Після перекреслення наступних карт вектор оновлюється до шляхом множення його (зліва) на матрицю переходу . Це повторюється, поки не будуть розміщені всі картки . На кожному етапі сума записів у векторі ймовірності - це ймовірність, що якась картка була позначена. Все , що залишається зробити значення , рівне , тому ймовірність того, що немає карти не залишаються помітними після крокуk2p1p2(Prk1,k2(q|p),1≤p≤k1,1≤q≤k2)k1+k2+⋯+kmjpj1j. Отже, послідовні відмінності в цих значеннях дають нам ймовірність того, що ми не змогли знайти карту типу для позначення: це розподіл ймовірності значення карти, яку ми шукали, коли колода закінчується в кінці гри .j
Впровадження
Наступний R
код реалізує алгоритм. Він паралельний попередній дискусії. По-перше, обчислення ймовірностей переходу виконується за допомогою t.matrix
(без нормалізації з поділом на , що полегшує відстеження обчислень при тестуванні коду):(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))
}
Це використовується transition
для оновлення до . Він обчислює матрицю переходу і виконує множення. Він також піклується про обчислення початкового вектора якщо аргумент порожній вектор: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)
}
Тепер ми можемо легко обчислити ймовірності без позначення на кожному етапі для будь-якої колоди:
#
# `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)
}
Ось вони для стандартної колоди:
k <- rep(4, 13)
names(k) <- c("A", 2:9, "T", "J", "Q", "K")
(g <- game(k))
Вихід є
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
Згідно з правилами, якщо короля було позначено, ми б не шукали жодних подальших карток: це означає, що значення повинно бути збільшено до . Виконуючи це, різниці дають розподіл "числа, на якому ви будете працювати, коли палуба закінчується":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
(Порівняйте це з результатами, про які я повідомляю, в окремій відповіді, що описує моделювання Монте-Карло: вони здаються однаковими, аж до очікуваної кількості випадкових змін.)
Очікуване значення негайне:
> sum(diff(g) * 2:13)
[1] 5.832589
Все, що було сказано, для цього було потрібно лише десяток рядків або близько того виконуваного коду. Я перевірив це в ручних обчисленнях для малих значень (до ). Таким чином, якщо виявиться якась невідповідність між кодом та попереднім аналізом проблеми, довіряйте коду (оскільки аналіз може мати друкарські помилки).k3
Зауваження
Взаємини з іншими послідовностями
Коли є одна з кожної картки, розподіл - це послідовність зворотних записів цілих чисел:
> 1/diff(game(rep(1,10)))
[1] 2 3 8 30 144 840 5760 45360 403200
Значення в місці - це(починаючи з місця ). Це послідовність A001048 в Інтернет-енциклопедії цілих послідовностей. Відповідно, ми можемо сподіватися на закриту формулу для колод з постійною ("підходящою" колодою), яка б узагальнила цю послідовність, яка сама має деякі глибокі значення. (Наприклад, він підраховує розміри найбільших класів кон'югації в групах перестановки, а також пов'язаний з тричленними коефіцієнтами .) (На жаль, зворотні в узагальненні для зазвичай не є цілими числами.)ii!+(i−1)!i=1kik>1
Гра як стохастичний процес
Наш аналіз дає зрозуміти, що початкові коефіцієнти векторів , є постійними. Наприклад, давайте відстежимо результат роботи, коли вона обробляє кожну групу карт: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
Наприклад, друге значення кінцевого вектора (описуючи результати з повною колодою з 52 карт) вже з'явилося після обробки другої групи (і дорівнює ). Таким чином, якщо ви хочете отримати інформацію лише про позначки вгору через значення картки , вам потрібно виконати обчислення лише для колоди карт .1/(84)=1/70jthk1+k2+⋯+kj
Оскільки шанс не позначити карту значення швидко наближається до оскільки збільшується, після типів карт у чотирьох костюмах ми майже досягли граничного значення для очікування. Дійсно, обмежувальне значення становить приблизно (обчислюється для колоди з карт, коли точка похибки округлення подвійної точності запобігає подальшому проходженню).j1j135.8333554×32
Хронометраж
Дивлячись на алгоритм, застосований до вектора , ми бачимо, що його терміни повинні бути пропорційними і - використовуючи сиру верхню межу - не гірші, ніж пропорційні . Тимчасом усіх обчислень для до та до та аналізуючи лише ті, що займають відносно тривалий час ( секунди чи довше), я вважаю, що час обчислення становить приблизно , що підтримує цю верхню оцінку.( до , до , ... , K ) K 2 м 3 K = 1 7 п = 10 30 1 / 2 O ( K 2 н 2.9 )m(k,k,…,k)k2m3k=17n=10301/2O(k2n2.9)
Одним із застосувань цих асимптотиків є прогнозування часу розрахунку на більші проблеми. Наприклад, бачачи, що випадок займає приблизно секунди, ми вважаємо, що (дуже цікавий) випадок займе приблизно секунди. (Насправді це займає секунди.)1,31 до = 1 , п = 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