Số dự kiến ​​tôi sẽ có sau khi rút thẻ cho đến khi tôi nhận được ace, 2, 3, v.v.


12

Tôi đang gặp một số khó khăn để giải quyết sau đây.

Bạn rút thẻ từ bộ bài 52 lá tiêu chuẩn mà không cần thay thế cho đến khi bạn có được một con át chủ bài. Bạn rút ra từ những gì còn lại cho đến khi bạn nhận được 2. Bạn tiếp tục với 3. Số lượng dự kiến ​​bạn sẽ có sau khi toàn bộ bộ bài hết?

Đó là tự nhiên để cho

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

Vì vậy, vấn đề cơ bản là để tìm ra xác suất bạn sẽ ở khi hết bài, cụ thể là:k

Pr(T1<<TkUk+1<Tk)

tôi có thể thấy rằng

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

nhưng không thể có thêm ...


1
Điều gì xảy ra nếu bạn đã rút hết giây trước khi bạn rút được con át chủ bài đầu tiên? 2
gung - Phục hồi Monica

Số "dự kiến" có thực sự có nghĩa là số "rất có thể" không?
whuber

Đây là một vấn đề thú vị, nhưng tôi không chắc về toán học bạn viết sau "vấn đề cơ bản lên tới". Trong câu lệnh đầu tiên, bạn muốn viết chứ không phải ? Mặc dù vậy, tuy nhiên, tôi không chắc tuyên bố này là chính xác. Hãy xem xét một chuỗi bắt đầu . Chúng tôi có và vì vậy , nhưng nếu tôi hiểu đúng mô tả văn bản của bạn, chúng tôi vẫn có thể chọn Ace ở vị trí thứ hai và sau đó là 2 ở vị trí thứ năm? Và do đó không phải là điều kiện cần thiết? 2AAA2T1=2,T2=1T1>T2T1<T2
TooTone

@TooTone Ồ, ý tôi là như bạn đã nói, và bạn đã đúng; không phải là điều kiện cần thiết ...T1<T2
hóa đơn

@gung Trong trường hợp đó, bộ bài của bạn sẽ hết và bạn vẫn sẽ ở trên 2.
hóa đơn

Câu trả lời:


0

Theo ý tưởng của @ gung, tôi tin rằng giá trị mong đợi sẽ là 5,84? và theo cách giải thích của tôi về các bình luận, tôi cho rằng "A" là một giá trị gần như không thể (trừ khi bốn thẻ cuối cùng trong bộ bài đều là con át chủ bài). đây là kết quả của một mô phỏng monte carlo 100.000 lần lặp

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 

và đây là mã R trong trường hợp bạn muốn chơi với nó ..

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

Tại sao là Akhông thể? Hãy xem xét chuỗi 48 thẻ theo sau là AAAAví dụ.
TooTone

bạn nói đúng .. đó là một trong số 270725 - hoặc với mã R1/prod( 48:1 / 52:5 )
Anthony Damico

1
Câu trả lời này không chính xác. Hãy xem xét số đếm cho "2": bởi vì điều này chỉ có thể xảy ra khi tất cả các số 2 gặp phải trước bất kỳ số 1 nào, xác suất của nó là một trong mỗi và do đó, kỳ vọng của nó trong mô phỏng của bạn là với sai số chuẩn là . Sản lượng của bạn vượt quá sáu lỗi tiêu chuẩn quá cao, khiến nó gần như chắc chắn bị lỗi. Giá trị chính xác cho giá trị trung bình (dựa trên một mô phỏng khác với lần lặp) là . 105/ ( 8(84)=7037,516601065,833±0,004105/(84)1428.637.516601065.833±0.004
whuber

1
Rất tiếc, mã tài liệu nặng nề của bạn dài hơn nhiều lần và chậm hơn so với yêu cầu. Tôi đã chứng minh đầu ra của nó là không chính xác; mặc dù tôi ước tôi có thời gian để gỡ lỗi mã của bạn nhưng tôi không có nhiệm vụ phải làm điều đó. Đối số của tôi là thế này: bạn vẫn sẽ làm việc với "2" ở cuối nếu và chỉ khi tất cả các "2" đứng trước tất cả các "A". Trong số cách sắp xếp bằng nhau có thể sắp xếp bốn "2" và bốn "A", chính xác một trong số chúng thỏa mãn tiêu chí này. Do đó, giá trị của bạn dưới tiêu đề "2" phải gần bằng , nhưng thực tế không phải vậy. 105/70=1429(4+44)=70results105/70=1429
whuber

1
Ngay cả người điều hành cũng không thể xóa phiếu bầu của người khác :-). Một bài kiểm tra chi bình phương hiện cho thấy kết quả của bạn đồng ý với tôi, nhưng thật tuyệt khi biết bạn đã kiểm tra mô phỏng của mình như thế nào, bởi vì điều đó sẽ cải thiện sự tự tin trong câu trả lời của bạn. Trên thực tế, theo một chỉnh sửa mà bạn đã thực hiện cho đoạn đầu tiên trong câu trả lời của bạn, bây giờ cả hai kết quả của chúng tôi đều sai: như tôi đã giải thích câu hỏi của bạn, không bao giờ có thể làm việc trên ace khi tất cả các thẻ đã hết.
whuber

7

Đối với một mô phỏng, điều quan trọng là phải chính xác cũng như nhanh chóng. Cả hai mục tiêu này đều đề xuất viết mã nhắm vào các khả năng cốt lõi của môi trường lập trình cũng như mã ngắn và đơn giản nhất có thể, bởi vì sự đơn giản cho phép sự rõ ràng và rõ ràng thúc đẩy tính chính xác. Đây là nỗ lực của tôi để đạt được cả hai trong 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
}

Áp dụng điều này theo cách có thể lặp lại có thể được thực hiện với replicatehàm sau khi đặt hạt giống số ngẫu nhiên, như trong

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

Điều đó chậm, nhưng đủ nhanh để thực hiện các mô phỏng khá dài (và do đó chính xác) liên tục mà không phải chờ đợi. Có một số cách chúng ta có thể trưng bày kết quả. Hãy bắt đầu với ý nghĩa của nó:

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

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

Cái sau là lỗi tiêu chuẩn: chúng tôi hy vọng giá trị trung bình mô phỏng sẽ nằm trong hai hoặc ba SE của giá trị thực. Điều đó đặt kỳ vọng thực sự ở đâu đó giữa và5,8535.8175.853 .

Chúng tôi cũng có thể muốn xem bảng tổng hợp các tần số (và các lỗi tiêu chuẩn của chúng ). Đoạn mã sau đây sắp xếp lại bảng một chút:

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)

Đây là đầu ra:

                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

Làm thế nào chúng ta có thể biết mô phỏng là chính xác? Một cách là kiểm tra nó một cách triệt để cho các vấn đề nhỏ hơn. Vì lý do đó, mã này được viết để tấn công một sự khái quát nhỏ của vấn đề, thay thế thẻ khác biệt bằng và bộ quần áo bằng . Tuy nhiên, đối với thử nghiệm, điều quan trọng là có thể cung cấp mã cho một bộ bài theo thứ tự được xác định trước. Chúng ta hãy viết một giao diện hơi khác với cùng một thuật toán:13n4k

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

(Có thể sử dụng drawthay thế cho simmọi nơi, nhưng công việc bổ sung được thực hiện khi bắt đầu drawlàm cho nó chậm gấp đôi sim.)

Chúng ta có thể sử dụng điều này bằng cách áp dụng nó cho mỗi lần xáo trộn riêng biệt của một cỗ bài nhất định. Vì mục đích ở đây chỉ là một vài thử nghiệm một lần, nên hiệu quả trong việc tạo ra các xáo trộn đó là không quan trọng. Đây là một cách nhanh chóng:

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

Bây giờ dlà một khung dữ liệu có các hàng chứa tất cả các xáo trộn. Áp dụng drawcho mỗi hàng và đếm kết quả:

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

Đầu ra (mà chúng ta sẽ sử dụng trong một thử nghiệm chính thức trong giây lát) là

   2    3    4 
 420  784 1316 

(Nhân tiện, giá trị của rất dễ hiểu: chúng tôi vẫn sẽ làm việc trên thẻ khi và chỉ khi tất cả các twos đi trước tất cả các con át chủ bài. Cơ hội xảy ra (với hai bộ quần áo) là . Trong số xáo trộn riêng biệt, có thuộc tính này.)42021/(2+22)=1/625202520/6=420

Chúng ta có thể kiểm tra đầu ra bằng một phép thử chi bình phương. Cuối cùng, tôi áp dụng lần cho trường hợp thẻ khác nhau trong bộ quần áo:sim 10,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

Vì quá cao, chúng tôi thấy không có sự khác biệt đáng kể giữa những gì nói và các giá trị được tính bằng phép liệt kê toàn diện. Lặp lại bài tập này cho một số giá trị (nhỏ) khác của và tạo ra kết quả tương đương, cho chúng tôi nhiều lý do để tin tưởng khi áp dụng cho và .n k n = 13 k = 4psimnksimn=13k=4

Cuối cùng, một bài kiểm tra chi bình phương hai mẫu sẽ so sánh đầu ra của simđầu ra được báo cáo trong một câu trả lời khác:

>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

Thống kê chi bình phương khổng lồ tạo ra giá trị p về cơ bản bằng không: không nghi ngờ gì, simkhông đồng ý với câu trả lời khác. Có hai cách giải quyết có thể có sự bất đồng: một (hoặc cả hai!) Của những câu trả lời này là không chính xác hoặc chúng thực hiện các cách hiểu khác nhau của câu hỏi. Chẳng hạn, tôi đã hiểu "sau khi hết cỗ" có nghĩa là sau khi quan sát thẻ cuối cùng và, nếu được phép, cập nhật "số bạn sẽ ở trên" trước khi chấm dứt thủ tục. Có thể hiểu rằng bước cuối cùng không có nghĩa là được thực hiện. Có lẽ một số khác biệt tinh tế của giải thích sẽ giải thích sự bất đồng, tại thời điểm đó chúng ta có thể sửa đổi câu hỏi để làm cho nó rõ ràng hơn những gì đang được hỏi.


4

Có một câu trả lời chính xác (dưới dạng một sản phẩm ma trận, được trình bày ở điểm 4 bên dưới). Một thuật toán hợp lý hiệu quả để tính toán nó tồn tại, xuất phát từ những quan sát sau:

  1. Việc xáo trộn ngẫu nhiên các thẻ có thể được tạo ra bằng cách xáo trộn ngẫu nhiên các thẻ N và sau đó xen kẽ ngẫu nhiên các thẻ k còn lại trong chúng.N+kNk

  2. Bằng cách xáo trộn chỉ những con át chủ bài, và sau đó (áp dụng quan sát đầu tiên) xen kẽ các twos, sau đó là ba, v.v., vấn đề này có thể được xem như một chuỗi mười ba bước.

  3. Chúng tôi cần theo dõi nhiều hơn giá trị của thẻ mà chúng tôi đang tìm kiếm. Tuy nhiên, khi làm điều này, chúng ta không cần tính đến vị trí của nhãn hiệu so với tất cả các thẻ, mà chỉ vị trí của nó so với các thẻ có giá trị bằng hoặc nhỏ hơn.

    Hãy tưởng tượng đặt một dấu trên ace đầu tiên, và sau đó đánh dấu hai cái đầu tiên được tìm thấy sau nó, v.v. (Nếu ở bất kỳ giai đoạn nào bộ bài hết mà không hiển thị thẻ mà chúng tôi hiện đang tìm kiếm, chúng tôi sẽ để lại tất cả các thẻ không được đánh dấu.) Đặt "vị trí" của mỗi dấu (khi nó tồn tại) là số lượng thẻ có giá trị bằng hoặc thấp hơn đã được xử lý khi nhãn hiệu được thực hiện (bao gồm cả thẻ được đánh dấu). Những nơi chứa tất cả các thông tin cần thiết.

  4. Vị trí sau dấu thứ được tạo là một số ngẫu nhiên. Đối với một bộ bài nhất định, trình tự của những nơi này tạo thành một quá trình ngẫu nhiên. Thực tế nó là một quá trình Markov (với ma trận chuyển tiếp biến). Do đó, một câu trả lời chính xác có thể được tính từ mười hai phép nhân ma trận.ith

Sử dụng những ý tưởng này, máy này có được một giá trị của (tính toán trong đôi điểm nổi chính xác) trong 1 / 9 giây. Giá trị gần đúng này của giá trị chính xác 19826005792658947850269453319689390235225425695.83258855290199651/9 chính xác với tất cả các chữ số được hiển thị.

1982600579265894785026945331968939023522542569339917784579447928182134345929899510000000000

Phần còn lại của bài viết này cung cấp chi tiết, trình bày một triển khai làm việc (trong R) và kết luận với một số ý kiến ​​về câu hỏi và hiệu quả của giải pháp.


Tạo ra sự xáo trộn ngẫu nhiên của một bộ bài

Đó là thực sự rõ ràng khái niệm và không phức tạp về mặt toán học để xem xét một "boong" (aka MultiSet ) của thẻ trong đó có k 1 của giáo phái thấp nhất, k 2 của tiếp theo thấp nhất, v.v. (Các câu hỏi như mối quan tâm hỏi những boong xác định bởi 13 -vector ( 4 , 4 , ... , 4 ) .)N=k1+k2++kmk1k213(4,4,,4)

Một "ngẫu nhiên ngẫu nhiên" của thẻ là một hoán vị được thực hiện thống nhất và ngẫu nhiên từ N ! = N × ( N - 1 ) × × 2 × 1 hoán vị của thẻ N. Các xáo trộn này rơi vào các nhóm có cấu hình tương đương vì việc hoán vị k 1 "aces" trong số chúng không thay đổi gì, cho phép k 2 "twos" trong số chúng cũng không thay đổi gì, v.v. Do đó, mỗi nhóm hoán vị trông giống hệt nhau khi bộ đồ của thẻ bị bỏ qua chứa k 1 !NN!=N×(N1)××2×1Nk1k2hoán vị. Các nhóm này, do đó số lượng được đưa ra bởihệ số đa thứck1!×k2!××km!

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

được gọi là "sự kết hợp" của bộ bài.

Có một cách khác để đếm các kết hợp. Thẻ đầu tiên chỉ có thể tạo thành k 1 ! / k 1 ! = 1 kết hợp. Chúng để lại k 1 + 1 "khe" giữa và xung quanh chúng, trong đó các thẻ k 2 tiếp theo có thể được đặt. Chúng ta có thể cho biết điều này với một sơ đồ nơi " * " chỉ định một trong những k 1 thẻ và " _ " chỉ định một khe cắm có thể chứa giữa 0k 2 thẻ bổ sung:k1k1!/k1!=1k1+1k2k1_0k2

_____k1 stars

Khi thẻ bổ sung được xen kẽ, mô hình của các ngôi sao và thẻ mới phân chia các thẻ k 1 + k 2 thành hai tập con. Số lượng các tập con khác nhau như vậy là ( k 1 + k 2k2k1+k2.(k1+k2k1,k2)=(k1+k2)!k1!k2!

Lặp lại quy trình này với "threes", chúng tôi thấy có ( ( k 1 + k 2 ) + k 3k3cách để xen kẽ chúng trong số các thẻk1+k2đầu tiên. Do đó, tổng số cách khác nhau để sắp xếp các thẻk1+k2+k3đầu tiêntheo cách này bằng((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!.

Sau khi hoàn thành các thẻ cuối cùng và tiếp tục nhân các phân số kính thiên văn này, chúng tôi thấy rằng số lượng kết hợp riêng biệt thu được bằng tổng số kết hợp như đã tính trước đó, ( Nkn. Vì vậy, chúng tôi đã bỏ qua không có sự kết hợp. Điều đó có nghĩa làquá trình xáo trộn tuần tự các thẻ này nắm bắt chính xác xác suất của mỗi kết hợp,giả sử rằng ở mỗi giai đoạn, mỗi cách khác nhau có thể xen kẽ các thẻ mới giữa các thẻ cũ được thực hiện với xác suất đồng đều.(Nk1,k2,,km)

Quá trình diễn ra

Ban đầu, có aces và rõ ràng đầu tiên được đánh dấu. Ở các giai đoạn sau có n = k 1 + k 2 + + k j - 1 thẻ, địa điểm (nếu thẻ đánh dấu tồn tại) bằng p (một số giá trị từ 1 đến n ), và chúng tôi sắp đặt lộn nhau k = k thẻ j xung quanh họ. Chúng ta có thể hình dung điều này với một sơ đồ nhưk1n=k1+k2++kj1p1nk=kj

_____p1 stars____np stars

trong đó " " chỉ định biểu tượng hiện được đánh dấu. Có điều kiện về giá trị này của nơi p , chúng tôi mong muốn tìm ra xác suất mà địa điểm tiếp theo sẽ bằng q (một số giá trị từ 1 đến n + k ; bởi các quy tắc của trò chơi, địa điểm tiếp theo phải đến sau p , đâu q p + 1 ). Nếu chúng ta có thể tìm thấy có bao nhiêu cách để có vãi ra các k thẻ mới vào chỗ trống sao cho địa điểm tiếp theo bằng q , sau đó chúng ta có thể chia cho tổng số cách để vãi ra các thẻ (tương đương với (pq1n+kpqp+1kq , như chúng ta đã thấy) để có đượcxác suất chuyển tiếpmà địa điểm thay đổi từpsangq. (Cũng sẽ có xác suất chuyển tiếp cho địa điểm biến mất hoàn toàn khi không có thẻ mới nào theo thẻ được đánh dấu, nhưng không cần phải tính toán rõ ràng điều này.)(n+kk)pq

Hãy cập nhật sơ đồ để phản ánh tình huống này:

_____p1 starss stars | ____nps stars

Các thanh dọc " " show nơi thẻ mới đầu tiên xảy ra sau khi thẻ đánh dấu: không có thẻ mới có thể xuất hiện do đó giữa | (và do đó không có vị trí nào được hiển thị trong khoảng đó). Chúng tôi không biết có bao nhiêu ngôi sao có trong khoảng thời gian này, vì vậy tôi vừa gọi nó s (có thể không) Các chưa biết s sẽ biến mất khi chúng ta thấy mối quan hệ giữa nó và q .||ssq

Suppose, then, we intersperse j new cards around the stars before the and then--independently of that--we intersperse the remaining kj1 new cards around the stars after the |. There are

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

ways to do this. Notice, though--this is the trickiest part of the analysis--that the place of | equals p+s+j+1 because

  • There are p "old" cards at or before the mark.
  • There are s old cards after the mark but before |.
  • There are j new cards before the mark.
  • There is the new card represented by | itself.

Thus, τn,k(s,p) gives us information about the transition from place p to place q=p+s+j+1. When we track this information carefully for all possible values of s, and sum over all these (disjoint) possibilities, we obtain the conditional probability of place q following place p,

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

where the sum starts at j=max(0,q(n+1)) and ends at j=min(k1,q(p+1). (The variable length of this sum suggests there is unlikely to be a closed formula for it as a function of n,k,q, and p, except in special cases.)

The algorithm

Initially there is probability 1 that the place will be 1 and probability 0 it will have any other possible value in 2,3,,k1. This can be represented by a vector p1=(1,0,,0).

After interspersing the next k2 cards, the vector p1 is updated to p2 by multiplying it (on the left) by the transition matrix (Prk1,k2(q|p),1pk1,1qk2). This is repeated until all k1+k2++km cards have been placed. At each stage j, the sum of the entries in the probability vector pj is the chance that some card has been marked. Whatever remains to make the value equal to 1 therefore is the chance that no card is left marked after step j. The successive differences in these values therefore give us the probability that we could not find a card of type j to mark: that is the probability distribution of the value of the card we were looking for when the deck runs out at the end of the game.


Implementation

The following R code implements the algorithm. It parallels the preceding discussion. First, calculation of the transition probabilities is performed by t.matrix (without normalization with the division by (n+kk), making it easier to track the calculations when testing the code):

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

This is used by transition to update pj1 to pj. It calculates the transition matrix and performs the multiplication. It also takes care of computing the initial vector p1 if the argument p is an empty vector:

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

We can now easily compute the non-mark probabilities at each stage for any 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)
}

Here they are for the standard deck:

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

The output is

         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

According to the rules, if a king was marked then we would not look for any further cards: this means the value of 0.9994461 has to be increased to 1. Upon doing so, the differences give the distribution of the "number you will be on when the deck runs out":

> 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

(Compare this to the output I report in a separate answer describing a Monte-Carlo simulation: they appear to be the same, up to expected amounts of random variation.)

The expected value is immediate:

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

All told, this required only a dozen lines or so of executable code. I have checked it against hand calculations for small values of k (up to 3). Thus, if any discrepancy becomes apparent between the code and the preceding analysis of the problem, trust the code (because the analysis may have typographical errors).


Remarks

Relationships to other sequences

When there is one of each card, the distribution is a sequence of reciprocals of whole numbers:

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

The value at place i is i!+(i1)! (starting at place i=1). This is sequence A001048 in the Online Encyclopedia of Integer Sequences. Accordingly, we might hope for a closed formula for the decks with constant ki (the "suited" decks) that would generalize this sequence, which itself has some profound meanings. (For instance, it counts sizes of the largest conjugacy classes in permutation groups and is also related to trinomial coefficients.) (Unfortunately, the reciprocals in the generalization for k>1 are not usually integers.)

The game as a stochastic process

Our analysis makes it clear that the initial i coefficients of the vectors pj, ji, are constant. For example, let's track the output of game as it processes each group of cards:

> 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

For instance, the second value of the final vector (describing the results with a full deck of 52 cards) already appeared after the second group was processed (and equals 1/(84)=1/70). Thus, if you want information only about the marks up through the jth card value, you only have to perform the calculation for a deck of k1+k2++kj cards.

Because the chance of not marking a card of value j is getting quickly close to 1 as j increases, after 13 types of cards in four suits we have almost reached a limiting value for the expectation. Indeed, the limiting value is approximately 5.833355 (computed for a deck of 4×32 cards, at which point double precision rounding error prevents going any further).

Timing

Looking at the algorithm applied to the m-vector (k,k,,k), we see its timing should be proportional to k2 and--using a crude upper bound--not any worse than proportional to m3. By timing all calculations for k=1 through 7 and n=10 through 30, and analyzing only those taking relatively long times (1/2 second or longer), I estimate the computation time is approximately O(k2n2.9), supporting this upper-bound assessment.

One use of these asymptotics is to project calculation times for larger problems. For instance, seeing that the case k=4,n=30 takes about 1.31 seconds, we would estimate that the (very interesting) case k=1,n=100 would take about 1.31(1/4)2(100/30)2.92.7 seconds. (It actually takes 2.87 seconds.)


0

Hacked a simple Monte Carlo in Perl and found approximately 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];
    }
}

Given the sharp discrepancy between this and all the previous answers, including two simulations and a theoretical (exact) one, I suspect you are interpreting the question in a different way. In the absence of any explanation on your part, we just have to take it as being wrong. (I suspect you may be counting one less, in which case your 4.8 should be compared to 5.83258...; but even then, your two significant digits of precision provide no additional insight into this problem.)
whuber

1
Yep! There was an off-by-one mistake.
Zen
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.