Очікуване число я буду набирати після малювання карт, поки я не отримаю туза, 2, 3 тощо


12

У мене виникають проблеми з вирішенням наступного.

Ви малюєте карти зі стандартної колоди на 52 картки без заміни, поки не отримаєте туза. Ви отримуєте з того, що залишилося, поки не отримаєте 2. Ви продовжуєте роботу з 3. Яке очікуване число ви будете мати після закінчення всієї колоди?

Це було природно пускати

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

Таким чином, проблема по суті полягає в з'ясуванні ймовірності того, що ви будете на коли палуба закінчиться, а саме:k

Pr(T1<<TkUk+1<Tk)

я можу бачити це

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

але далі не міг дістатися ...


1
Що станеться, якщо ви вже намалювали всі с до моменту, коли ви намалюєте свій перший туз? 2
gung - Відновіть Моніку

Чи означає "очікуване" число насправді "найімовірніше" число?
whuber

Це цікава проблема, але я не впевнений у математиці, яку ви пишете після того, як "проблема по суті становить". У першому вислові ви мали намір написати а не ? Однак тоді я не впевнений, що твердження правильне. Розглянемо початок послідовності . У нас і так , але якщо я правильно зрозумів ваш опис тексту, ми все одно можемо вибрати туза на другій позиції, а потім 2 на п'ятій позиції? І тому не є необхідною умовою? T 1 = 2 , T 2 = 1 T 1 > T 2 T 1 < T 22AAA2T1=2,T2=1T1>T2T1<T2
TooTone

@TooTone О, я мав на увазі як ти сказав, і ти маєш рацію; не є необхідною умовою ...T 1 < T 2T1<T2
законопроект

@gung У цьому випадку ваша палуба закінчиться, і ви все одно будете 2
законопроект

Відповіді:


0

слідуючи ідеї @ gung, я вважаю, очікуване значення буде 5,84? і з моєї інтерпретації коментарів я припускаю, що "А" - це майже неможливе значення (якщо тільки останні чотири карти в колоді не є тузами). Ось результати 100 000 ітерації Монте Карло моделювання

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 

і ось код R на випадок, якщо ви хочете пограти з ним ..

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

Чому це Aнеможливо? Розглянемо послідовність 48 карток, яку слід, AAAAнаприклад.
TooTone

Ви маєте рацію .. це один із 270725 - або з кодом R1/prod( 48:1 / 52:5 )
Ентоні Даміко

1
Ця відповідь невірна. Розглянемо підрахунок "2": оскільки це може призвести лише тоді, коли всі 2 зустрічаються перед будь-яким із 1-х, його ймовірність одна в кожному і тому його очікування у вашому моделюванні становить зі стандартною помилкою . Вихід перевищує шість стандартних помилок занадто високий, що робить його майже напевно помилковим. Точне значення для середнього значення (засноване на іншому моделюванні з ітераціями) становить . (84)=7037,516601065,833±0,004105/(84)1428.637.516601065.833±0.004
whuber

1
На жаль, ваш сильно задокументований код, на жаль, у кілька разів довший і повільніший, ніж повинен бути. Я продемонстрував, що його результат неправильний; хоча я б хотів, щоб у мене був час налагодити ваш код, я цього не роблю, і це не моя задача зробити це. Мій аргумент такий: ви все одно будете працювати над "2" в кінці, якщо і лише тоді, коли всі "2" передують усім "А". Серед однаково вірогідних способів впорядкування чотирьох "2" s та чотирьох "A" s, саме один із них задовольняє цьому критерію. Тому ваше значення під заголовком "2" має бути близьким до , але це не так. 105/70=1429(4+44)=70results105/70=1429
whuber

1
Навіть модератори не можуть зняти голоси інших людей :-). Тест на квадратний чі тепер пропонує, що ваші результати погоджуються з моїми, але було б непогано знати, як ви перевірили своє моделювання, оскільки це поліпшить довіру до вашої відповіді. Насправді, згідно з редакцією, яку ви внесли до першого пункту у своїй відповіді, тепер обидва наші результати помилкові: як я інтерпретував ваше запитання, ніколи не можна працювати над тузом, коли всі картки вичерпані.
whuber

7

Для моделювання дуже важливо правильно та швидко. Обидві ці цілі передбачають написання коду, який орієнтований на основні можливості середовища програмування, а також на максимально короткий і простий код, оскільки простота надає чіткість і чіткість сприяє правильності. Ось моя спроба досягти обох в 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
}

Застосовуючи це відтворюваним способом, можна виконати replicateфункцію після встановлення насіння випадкових чисел, як у

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

Це повільно, але досить швидко, щоб проводити досить тривалі (і тому точні) симуляції повторно, не чекаючи. Є кілька способів проявити результат. Почнемо з його середнього:

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

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

Останнє - це стандартна помилка: ми очікуємо, що змодельоване середнє значення буде в межах двох або трьох СЕ від справжнього значення. Це відповідає справжньому очікуванню десь між і5.8535.8175.853 .

Ми також можемо побачити таблицю частот (та їх стандартних помилок). Наступний код трохи покращує табуляцію:

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)

Ось вихід:

                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

Як ми можемо знати, що моделювання навіть правильне? Один із способів - це вичерпно перевірити його на менші проблеми. З цієї причини цей код був написаний для нападу на невелике узагальнення проблеми, замінивши різних карт на та костюми на . Однак для тестування важливо вміти подавати коду в колоду в заздалегідь визначеному порядку. Давайте запишемо трохи інший інтерфейс до того ж алгоритму: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)
}

(Можна використовувати drawна місці simскрізь, але додаткова робота, зроблена на початку, drawробить це вдвічі повільніше, ніж sim.)

Ми можемо скористатися цим, застосувавши його до кожного чіткого переміщення даної колоди. Оскільки метою є лише кілька разових тестів, ефективність у створенні цих перебоїв є неважливою. Ось такий швидкий спосіб:

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

Тепер dце кадр даних, рядки якого містять усі перетасовки. Застосовуйте drawдо кожного рядка і підраховуйте результати:

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

Вихід (який ми ми використаємо у формальному тесті миттєво) є

   2    3    4 
 420  784 1316 

(До речі, значення легко зрозуміти: ми все одно працювали над картою якщо і лише тоді, коли б всі двоє передували всім тузам. Шанс, що це станеться (з двома костюмами), становить . З різних перетасовок мають цю властивість.)2 1 / ( 2 + 2420225202520/6=4201/(2+22)=1/625202520/6=420

Ми можемо перевірити вихід за допомогою тесту чи-квадрата. З цією метою я застосовую до цього випадку разів різних карт у костюмах: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

Оскільки настільки високий, ми не знаходимо суттєвої різниці між сказаним та значеннями, обчисленими вичерпним перерахуванням. Повторення цієї вправи для деяких інших (малих) значень і дає порівнянні результати, що дає нам достатньо підстав для довіри, коли застосовуються до і .n k n = 13 k = 4psimnksimn=13k=4

Нарешті, тест з двома зразком чи-квадрата зіставить результат з результатом, про simякий повідомляється в іншій відповіді:

>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

Величезна статистика хі-квадратів дає р-значення, яке по суті є нульовим: без сумніву, simне погоджується з іншою відповіддю. Можливі два розв’язання розбіжностей: одне (або обидва!) Цих відповідей є неправильним або вони реалізують різні тлумачення питання. Наприклад, я інтерпретував "після закінчення колоди" означає після спостереження за останньою карткою і, якщо можливо, оновлення "номера, на якому ви будете", перш ніж припинити процедуру. Можливо, останній крок не передбачався робити. Можливо, якась така тонка різниця тлумачення пояснить незгоду, і в цей момент ми можемо змінити питання, щоб зрозуміти, що йому задають.


4

Існує точна відповідь (у вигляді матричного добутку, представленого в пункті 4 нижче). Досить ефективний алгоритм для його обчислення, що випливає з цих спостережень:

  1. Випадкове переміщення карт може бути згенеровано випадковим переміщенням карт, а потім випадковим чином перетинання решти карт у них.N kN+kNk

  2. Перетасовуючи лише тузи, а потім (застосовуючи перше спостереження) перетинаючи двійки, потім трійки тощо, цю проблему можна розглядати як ланцюжок із тринадцяти кроків.

  3. Нам потрібно відслідковувати більше, ніж вартість картки, яку ми шукаємо. При цьому, однак, нам не потрібно враховувати положення знака відносно всіх карт, а лише його положення щодо карт однакового або меншого значення.

    Уявіть, що ви поставите позначку на першому тузі, а потім позначте перші два знайдені після нього тощо. (Якщо на будь-якому етапі колода закінчиться, не показуючи карту, яку ми зараз шукаємо, ми залишимо всі картки без позначення.) Нехай "місце" кожної марки (коли вона існує) буде кількістю карток, рівних або менших значень, були розібрані, коли марка була зроблена (включаючи саму марковану карту). Місця містять усю необхідну інформацію.

  4. Місце після позначки є випадковим числом. Для даної колоди послідовність цих місць утворює стохастичний процес. Фактично це процес Маркова (зі змінною матрицею переходу). Точна відповідь може бути обчислена з дванадцяти матричних множень.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×(N1)××2×1Nk1k2k1!×k2!××km!

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

називаються "комбінаціями" колоди.

Є ще один спосіб підрахунку комбінацій. Перші картки можуть утворювати лише комбінація. Вони залишають "прорізи" між ними та навколо них, в яких можна розмістити наступні карти. Ми можемо вказати це на діаграмі, де " " позначає одну з карт, а " " позначає слот, який може містити від до додаткових карт:k1k1!/k1!=1k1+1k2k1_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++kj1p1nk=kj

_____p1 stars____np stars

де " " позначає позначений в даний час символ. Залежно від цього значення місця , ми хочемо знайти ймовірність того, що наступне місце буде рівним (деяке значення від до ; за правилами гри наступне місце повинно бути після , звідки ). Якщо ми зможемо знайти скільки способів перекреслити нових карток у пробіли, щоб наступне місце дорівнювало , то ми можемо розділити на загальну кількість способів перекреслення цих карт (рівних , як ми бачили) для отриманняpq1n+kpqp+1kq(n+kk)ймовірність переходу, що місце змінюється від до . (Існує також ймовірність переходу місця, коли воно зовсім зникне, коли жодна з нових карт не буде розміщена за маркованою картою, але немає необхідності чітко обчислювати це.)pq

Оновімо схему, щоб відобразити цю ситуацію:

_____p1 starss stars | ____nps stars

Вертикальна смуга « » показує , де відбувається перше нової карти після зазначеної карти: НЕ нові карти не можуть , отже , з'являється між і (і , отже , немає слота не показані на цьому інтервалі). Ми не знаємо, скільки зірок у цьому інтервалі, тому я щойно назвав це (що може бути нульовим). Невідомі зникнуть, як тільки ми знайдемо зв’язок між ним та .||ssq

Припустимо, тоді ми перекреслюємо нові картки навколо зірок перед а потім - незалежно від цього - ми перемішуємо інші нові карти навколо зірок після . Існуєjkj1|

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

способи це зробити. Зауважте, проте - це найскладніша частина аналізу - що місце дорівнює оскільки|p+s+j+1

  • На місці або перед позначкою є "старі" картки.p
  • Є старі карти після знака , але перед .s|
  • Перед позначкою є нові картки.j
  • Є нова карта, представлена ​​самим .|

Таким чином, дає нам інформацію про перехід від місця до місця . Коли ми ретельно відстежуємо цю інформацію для всіх можливих значень і підсумовуємо всі ці (непересічні) можливості, отримуємо умовну ймовірність розміщення після місця ,τn,k(s,p)pq=p+s+j+1sqp

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

де сума починається від і закінчується при . (Змінна довжина цієї суми дозволяє припустити, що існує навряд чи це буде закритою формулою для неї як функції і , за винятком особливих випадків.)j=max(0,q(n+1))j=min(k1,q(p+1)n,k,q,p

Алгоритм

Спочатку існує ймовірність що місце буде а ймовірність матиме будь-яке інше можливе значення у . Це можна представити вектором .1102,3,,k1p1=(1,0,,0)

Після перекреслення наступних карт вектор оновлюється до шляхом множення його (зліва) на матрицю переходу . Це повторюється, поки не будуть розміщені всі картки . На кожному етапі сума записів у векторі ймовірності - це ймовірність, що якась картка була позначена. Все , що залишається зробити значення , рівне , тому ймовірність того, що немає карти не залишаються помітними після крокуk2p1p2(Prk1,k2(q|p),1pk1,1qk2)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для оновлення до . Він обчислює матрицю переходу і виконує множення. Він також піклується про обчислення початкового вектора якщо аргумент порожній вектор: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)
}

Тепер ми можемо легко обчислити ймовірності без позначення на кожному етапі для будь-якої колоди:

#
# `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!+(i1)!i=1kik>1

Гра як стохастичний процес

Наш аналіз дає зрозуміти, що початкові коефіцієнти векторів , є постійними. Наприклад, давайте відстежимо результат роботи, коли вона обробляє кожну групу карт: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

Наприклад, друге значення кінцевого вектора (описуючи результати з повною колодою з 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,92,7 2,87k=4,n=301.31k=1,n=1001.31(1/4)2(100/30)2.92.72.87


0

Зламали простий Монте-Карло в і знайшли приблизно .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];
    }
}

Зважаючи на різку невідповідність цього та всіх попередніх відповідей, включаючи два моделювання та теоретичну (точну), я підозрюю, що ви трактуєте питання по-іншому. За відсутності будь-яких пояснень з вашого боку, ми просто повинні сприймати це як неправильне. (Я підозрюю, що ви можете порахувати один менший; у цьому випадку ваш 4,8 слід порівняти з 5,83258 ...; але навіть тоді ваші дві значущі цифри точності не дають додаткового розуміння цієї проблеми.)
whuber

1
Так! Була помилка по черзі.
Дзен
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.