จำนวนที่คาดว่าฉันจะอยู่หลังจากวาดการ์ดจนกว่าฉันจะได้รับเอซ 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
จะเกิดอะไรขึ้นถ้าคุณวาด s ไปแล้วเมื่อคุณวาดเอซตัวแรก? 2
gung - Reinstate Monica

หมายเลข "คาดหวัง" หมายถึงหมายเลข "น่าจะ" จริง ๆ หรือไม่
whuber

นี่เป็นปัญหาที่น่าสนใจ แต่ฉันไม่แน่ใจเกี่ยวกับคณิตศาสตร์ที่คุณเขียนหลังจาก "ปัญหานี้มีค่าเป็น" ในข้อความแรกคุณหมายถึงเขียนมากกว่าใช่ไหม อย่างไรก็ตามถึงกระนั้นฉันก็ไม่แน่ใจว่าคำสั่งนั้นถูกต้อง พิจารณาการเริ่มต้นลำดับ เรามีและดังนั้นแต่ถ้าฉันเข้าใจคำอธิบายข้อความของคุณอย่างถูกต้องเรายังสามารถเลือก Ace ที่ตำแหน่งที่สองแล้วอันดับที่สองที่ตำแหน่งที่สองคืออะไร? ดังนั้นไม่ใช่เงื่อนไขที่จำเป็นใช่ไหม T 1 = 2 , T 2 = 1 T 1 > T 2 T 1 < T 22AAA2T1=2,T2=1T1>T2T1<T2
TooTone

@ เสียงแตกโอ้ฉันหมายถึงเหมือนที่คุณพูดและคุณพูดถูก; ไม่ใช่เงื่อนไขที่จำเป็น ...T 1 < T 2T1<T2
เรียกเก็บเงิน

@gung ในกรณีนี้เด็คของคุณจะหมดและคุณจะยังคงอยู่ในวันที่ 2
เรียกเก็บเงิน

คำตอบ:


0

ตามความคิดของ @ gung ฉันเชื่อว่าค่าที่คาดหวังจะเป็น 5.84 และจากการตีความความคิดเห็นของฉันฉันถือว่า "A" เป็นค่าที่เกือบเป็นไปไม่ได้ (ยกเว้นว่าไพ่สี่ใบสุดท้ายในสำรับเป็นเอซทั้งหมด) นี่คือผลลัพธ์ของการจำลองมอนเตคาร์โล 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 )
Anthony Damico

1
คำตอบนี้ไม่ถูกต้อง พิจารณาการนับสำหรับ "2": เนื่องจากสิ่งนี้สามารถเกิดขึ้นได้เมื่อ 2 ทั้งหมดถูกพบก่อน 1 ใดความน่าจะเป็นของมันคือหนึ่งในทุก ๆดังนั้นความคาดหวังในการจำลองของคุณคือกับข้อผิดพลาดมาตรฐาน37.5ผลลัพธ์ของคุณในปีมีข้อผิดพลาดมาตรฐานมากกว่าหกข้อสูงเกินไป ค่าที่ถูกต้องสำหรับค่าเฉลี่ย (ขึ้นอยู่กับแบบจำลองที่แตกต่างกันด้วยซ้ำ) เป็น0.004 105/ ( 8)(84)=7037.516601065.833±0.004105/(84)1428.637.516601065.833±0.004
whuber

1
รหัสหนักของคุณน่าเสียดายที่นานกว่าและช้ากว่าที่ควรจะเป็นหลายเท่า ฉันแสดงว่าเอาต์พุตไม่ถูกต้อง แม้ว่าฉันจะหวังว่าฉันจะมีเวลาในการแก้ปัญหารหัสของคุณฉันไม่ได้และมันไม่ใช่งานของฉันที่จะทำเช่นนั้น อาร์กิวเมนต์ของฉันคือ: คุณจะยังคงทำงานกับ "2" ในตอนท้ายถ้าหาก "2" นำหน้า "A" ทั้งหมด ในบรรดาวิธีที่เป็นไปได้อย่างเท่าเทียมกันในการจัดเรียง "2" และสี่ "A" สี่วิธีหนึ่งในนั้นเป็นไปตามเกณฑ์นี้ ดังนั้นค่าของคุณภายใต้หัวข้อ "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

ข้อผิดพลาดหลังคือข้อผิดพลาดมาตรฐาน: เราคาดว่าค่าเฉลี่ยที่จำลองไว้จะอยู่ภายในสองหรือสาม SEs ของค่าจริง ว่าสถานที่บางแห่งความคาดหวังที่แท้จริงระหว่างและ5.8535.8175.853 5.853

นอกจากนี้เรายังอาจต้องการที่จะเห็นการจัดระเบียบของความถี่ (และพวกเขามีข้อผิดพลาดมาตรฐาน) รหัสต่อไปนี้ prettifies การจัดระเบียบเล็กน้อย:

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)

เราสามารถใช้นี้โดยนำไปใช้กับทุกสับเปลี่ยนที่แตกต่างกันของดาดฟ้าที่กำหนด เนื่องจากจุดประสงค์ที่นี่เป็นเพียงการทดสอบแบบครั้งเดียวไม่กี่ครั้งประสิทธิภาพในการสร้าง shuffles เหล่านี้จึงไม่สำคัญ นี่คือวิธีที่ดุร้ายกำลังอย่างรวดเร็ว:

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เป็นกรอบข้อมูลที่มีแถวมี shuffles ทั้งหมด ใช้drawกับแต่ละแถวและนับผลลัพธ์:

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

เอาท์พุท (ซึ่งเราจะใช้ในการทดสอบอย่างเป็นทางการในไม่ช้า) คือ

   2    3    4 
 420  784 1316 

(ค่าของนั้นง่ายต่อการเข้าใจโดยวิธี: เราจะยังคงทำงานบนการ์ดถ้าหากทั้งสองนำหน้าเอซทั้งหมดโอกาสของเหตุการณ์นี้ (มีสองชุด) คือ . จากจำนวนสับที่แตกต่างกัน ,มีคุณสมบัตินี้)2 1 / ( 2 + 2)420225202520/6=4201/(2+22)=1/625202520/6=420

เราสามารถทดสอบผลลัพธ์ด้วยการทดสอบไคสแควร์ ด้วยเหตุนี้ฉันจึงใช้ครั้งกับกรณีนี้ของไพ่ที่แตกต่างในชุด: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

เนื่องจากมีค่าสูงมากเราจึงไม่พบความแตกต่างอย่างมีนัยสำคัญระหว่างสิ่งที่พูดกับค่าที่คำนวณโดยการแจงนับอย่างละเอียด การทำซ้ำการออกกำลังกายนี้สำหรับบางคนอื่น ๆ (เล็ก) ค่าของและก่อให้เกิดผลลัพธ์เทียบเคียงให้เรามีเหตุผลเพียงพอที่จะไว้วางใจเมื่อนำไปใช้และ 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

สถิติแบบไคสแควร์ขนาดมหึมาก่อให้เกิดค่า p ซึ่งเป็นศูนย์: โดยไม่ต้องสงสัยเลยsimไม่เห็นด้วยกับคำตอบอื่น มีวิธีแก้ปัญหาความขัดแย้งที่อาจเกิดขึ้นได้สองประการ: หนึ่ง (หรือทั้งสอง!) ของคำตอบเหล่านี้ไม่ถูกต้องหรือพวกเขาใช้การตีความที่แตกต่างกันของคำถาม ตัวอย่างเช่นฉันตีความ "หลังจากเด็คหมด" เพื่อหมายถึงหลังจากดูการ์ดใบสุดท้ายและหากอนุญาตให้อัปเดต "หมายเลขที่คุณจะอยู่" ก่อนที่จะยุติกระบวนการ น่าจะเป็นไปได้ว่าขั้นตอนสุดท้ายนั้นไม่ได้เกิดขึ้น บางทีการตีความที่แตกต่างกันเล็กน้อยเช่นนี้อาจอธิบายถึงความไม่เห็นด้วยซึ่งตอนนี้เราสามารถแก้ไขคำถามเพื่อให้ชัดเจนยิ่งขึ้นในสิ่งที่ถูกถาม


4

มีคำตอบที่แน่นอน (ในรูปแบบของผลิตภัณฑ์เมทริกซ์, นำเสนอในจุดที่ 4 ด้านล่าง) อัลกอริธึมที่มีประสิทธิภาพพอสมควรในการคำนวณมันเกิดขึ้นจากการสังเกตเหล่านี้:

  1. การสุ่มแบบสุ่มของการ์ดสามารถสร้างขึ้นได้โดยการสุ่มไพ่แบบแล้วทำการสุ่มแยกไพ่ที่เหลือภายในสุ่มN kN+kNk

  2. ด้วยการสับเอซเพียงอย่างเดียวจากนั้น (ใช้การสังเกตครั้งแรก) สลับกับ twos จากนั้นทั้งสามและต่อ ๆ ไปปัญหานี้สามารถมองได้ว่าเป็นโซ่สิบสามขั้น

  3. เราจำเป็นต้องติดตามมากกว่ามูลค่าของการ์ดที่เรากำลังค้นหา อย่างไรก็ตามในการทำเช่นนี้เราไม่จำเป็นต้องคำนึงถึงตำแหน่งของเครื่องหมายที่สัมพันธ์กับการ์ดทั้งหมดแต่จะมีเฉพาะตำแหน่งที่สัมพันธ์กับการ์ดที่มีค่าเท่ากันหรือเล็กกว่า

    ลองนึกภาพวางเครื่องหมายบนเอซตัวแรกแล้วทำเครื่องหมายสองอันแรกที่พบหลังจากนั้นเป็นต้น (หากในขั้นตอนใด ๆ ที่เด็คหมดโดยไม่ต้องแสดงการ์ดที่เรากำลังค้นหาเราจะปล่อยการ์ดทั้งหมดที่ไม่มีเครื่องหมาย) ให้ "สถานที่" ของเครื่องหมายแต่ละอัน (เมื่อมีอยู่) เป็นจำนวนไพ่ที่มีค่าเท่ากันหรือต่ำกว่า ถูกแจกเมื่อทำเครื่องหมาย (รวมถึงการ์ดที่ทำเครื่องหมายด้วยตัวเอง) สถานที่มีข้อมูลที่จำเป็นทั้งหมด

  4. สถานที่หลังเครื่องหมายถูกสร้างขึ้นเป็นหมายเลขสุ่ม สำหรับสำรับที่กำหนดลำดับของสถานที่เหล่านี้ในรูปแบบกระบวนการสุ่ม อันที่จริงแล้วมันเป็นกระบวนการของมาร์คอฟ (พร้อมเมทริกซ์การเปลี่ยนแปลงตัวแปร) คำตอบที่แน่นอนสามารถคำนวณได้จากการคูณเมทริกซ์ที่สิบสองith

การใช้แนวคิดเหล่านี้เครื่องนี้จะได้รับค่า (คำนวณในทศนิยมความแม่นยำสองเท่า) ในวินาที การประมาณค่าที่แน่นอนนี้ตัวเลขทุกตัวที่แสดงนั้นถูกต้อง1 / 9 19826005792658947850269453319689390235225425695.83258855290199651/9

1982600579265894785026945331968939023522542569339917784579447928182134345929899510000000000

ส่วนที่เหลือของโพสต์นี้ให้รายละเอียดนำเสนอการดำเนินงาน (ในR) และสรุปความคิดเห็นเกี่ยวกับคำถามและประสิทธิภาพของการแก้ปัญหา


การสร้างสับแบบสุ่มของสำรับ

จริง ๆ แล้วมันเป็นแนวคิดที่ชัดเจนและไม่มีความซับซ้อนทางคณิตศาสตร์มากนักในการพิจารณา "เด็ค" (aka multiset ) ของการ์ดซึ่งมีของนิกายที่ต่ำที่สุดของที่ต่ำที่สุดถัดไปและอื่น ๆ . (คำถามที่ถามเป็นความกังวลดาดฟ้ากำหนดโดยเวกเตอร์ .)k 1 k 2 13 ( 4 , 4 , , 4 )N=k1+k2++kmk1k213(4,4,,4)

"สุ่มสุ่ม" ของการ์ดคือการเปลี่ยนรูปแบบหนึ่งครั้งที่สม่ำเสมอและสุ่มจากการเรียงสับเปลี่ยนของการ์ดshuffles เหล่านี้จัดอยู่ในกลุ่มของการกำหนดค่าที่เทียบเท่ากันเพราะการ "เอซ" ในหมู่พวกเขาไม่มีอะไรเปลี่ยนแปลงการ "twos" ในหมู่พวกเขาเองก็ไม่มีอะไรเปลี่ยนแปลงเช่นกัน ดังนั้นการเรียงสับเปลี่ยนแต่ละกลุ่มที่มีลักษณะเหมือนกันเมื่อชุดไพ่ถูกละเว้นจะมีพีชคณิต กลุ่มเหล่านี้ที่มีจำนวนจึงถูกกำหนดโดยสัมประสิทธิ์พหุนามNN!=N×(N1)××2×1Nk1k2k1!×k2!××km!

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

เรียกว่า "ชุด" ของสำรับ

มีอีกวิธีในการนับชุดค่าผสม การ์ดแรกสามารถสร้างได้เพียงชุดค่าผสม พวกเขาปล่อยให้ "ช่อง" ระหว่างและรอบ ๆ พวกเขาซึ่งสามารถวางการ์ดถัดไปได้ เราสามารถระบุสิ่งนี้ด้วยแผนภาพที่ " " กำหนดหนึ่งในการ์ดและ " " กำหนดช่องที่สามารถเก็บการ์ดได้ระหว่างและการ์ดเพิ่มเติม:k1k1!/k1!=1k1+1k2k1_0k2

_____k1 stars

เมื่อการ์ดเพิ่มเติมสลับกันรูปแบบของดาวและการ์ดใหม่จะแบ่งพาร์ติชันการ์ดออกเป็นสองชุดย่อย จำนวนย่อยดังกล่าวที่แตกต่างกันคือk_2!}k2k1+k2(k1+k2k1,k2)=(k1+k2)!k1!k2!

ทำซ้ำขั้นตอนนี้ด้วย "threes" เราพบว่าวิธีในการสลับกันระหว่างการ์ดแรก ดังนั้นจำนวนวิธีที่แตกต่างในการจัดเรียงในลักษณะนี้เท่ากับ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!.

หลังจากเสร็จสิ้นการสุดท้ายบัตรและต่อเนื่องในการคูณเศษส่วนเหลื่อมเหล่านี้เราพบว่าจำนวนของชุดที่แตกต่างกันได้เท่ากับจำนวนรวมของการรวมกันนับเป็นก่อนหน้านี้k_m} ดังนั้นเราไม่ได้มองข้ามชุดค่าผสม นั่นหมายถึงกระบวนการเรียงลำดับของการสับไพ่อย่างถูกต้องจะตรวจจับความน่าจะเป็นของแต่ละชุดรวมกันโดยสมมติว่าในแต่ละขั้นตอนแต่ละวิธีที่เป็นไปได้ที่แตกต่างกันในการสลับไพ่ใหม่ในกลุ่มเก่านั้นkn(Nk1,k2,,km)

กระบวนการสถานที่

เริ่มแรกมีเอซและเห็นได้ชัดว่ามีการทำเครื่องหมายครั้งแรก ในระยะต่อมาจะมีสถานที่ (หากมีการ์ดที่ทำเครื่องหมายไว้) เท่ากับ (ค่าบางส่วนจากถึง ) และเรากำลังจะกระจายไพ่รอบตัว เราสามารถเห็นภาพนี้ด้วยแผนภาพดังนี้k1n=k1+k2++kj1p1nk=kj

_____p1 stars____np stars

โดยที่ " " กำหนดสัญลักษณ์ที่ทำเครื่องหมายไว้ในปัจจุบัน ตามเงื่อนไขเกี่ยวกับค่าของตำแหน่งเราต้องการค้นหาความน่าจะเป็นที่ที่ถัดไปจะเท่ากับ (ค่าบางส่วนจากถึง ; ตามกฎของเกมสถานที่ถัดไปจะต้องมาหลังดังนั้น ) ถ้าเราสามารถหาวิธีการหลายวิธีมีการกระจายบัตรใหม่ในช่องว่างเพื่อให้สถานที่ถัดไปเท่ากับ ,แล้วเราสามารถหารด้วยจำนวนรวมของวิธีการที่จะกระจายบัตรเหล่านี้ (เท่ากับตามที่เราได้เห็น) เพื่อให้ได้pq1n+kpqp+1kq(n+kk)ความน่าจะเป็นการเปลี่ยนแปลงสถานที่ที่มีการเปลี่ยนแปลงจากไปยังคิว(นอกจากนี้ยังมีความเป็นไปได้ที่การเปลี่ยนสถานที่จะหายไปโดยสิ้นเชิงเมื่อไม่มีบัตรใหม่ตามหลังบัตรที่ทำเครื่องหมายไว้ แต่ไม่จำเป็นต้องคำนวณสิ่งนี้อย่างชัดเจน)pq

ลองปรับปรุงไดอะแกรมเพื่อสะท้อนสถานการณ์นี้:

_____p1 starss stars | ____nps stars

แถบแนวตั้ง " " แสดงตำแหน่งที่มีการ์ดใหม่ใบแรกเกิดขึ้นหลังจากการ์ดที่ถูกทำเครื่องหมาย: จึงไม่มีการ์ดใหม่ปรากฏขึ้นระหว่างและ (ดังนั้นจึงไม่มีช่องแสดงในช่วงเวลานั้น) เราไม่ทราบว่าหลายดาวที่มีอยู่ในช่วงเวลานี้ดังนั้นฉันได้เพียงแค่เรียกมัน (ซึ่งอาจจะเป็นศูนย์) ไม่ทราบจะหายไปเมื่อเราพบความสัมพันธ์ระหว่างมันและQ||ssq

สมมติว่าแล้วเรากระจายบัตรใหม่รอบดาวก่อนและ then-- เป็นอิสระจากที่ --we กระจายส่วนที่เหลืออีกบัตรใหม่รอบดาวฤกษ์หลังจากที่\มีjkj1|

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

วิธีในการทำเช่นนี้ โปรดสังเกตว่า - นี่คือส่วนที่ยากที่สุดของการวิเคราะห์ - ที่ของเท่ากับเพราะ|p+s+j+1

  • มีไพ่ "เก่า" ที่ก่อนหรือเครื่องหมายp
  • มีบัตรเก่าหลังจากทำเครื่องหมาย แต่ก่อน\s|
  • มีบัตรใหม่ก่อนทำเครื่องหมายj
  • มีบัตรใหม่ที่แสดงโดยตัวเอง|

ดังนั้นทำให้เรามีข้อมูลเกี่ยวกับการเปลี่ยนแปลงจากสถานที่ที่ไปยังสถานที่ 1 เมื่อเราติดตามข้อมูลนี้อย่างละเอียดสำหรับค่าที่เป็นไปได้ทั้งหมดของและสรุปผลมากกว่าทุกเหล่านี้ (ไม่เป็นสมาชิกร่วม) เป็นไปได้ที่เราได้รับความน่าจะเป็นเงื่อนไขของสถานที่ต่อไปที่ ,τn,k(s,p)pq=p+s+j+1sqp

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

โดยที่ผลรวมเริ่มต้นที่และสิ้นสุดที่ . (ความยาวตัวแปรของผลรวมนี้แสดงว่ามี ไม่น่าจะเป็นสูตรปิดสำหรับมันเป็นฟังก์ชันของและยกเว้นในกรณีพิเศษ)j = min ( k - 1 , q - ( p + 1 )j=max(0,q(n+1))j=min(k1,q(p+1)n,k,q,p

อัลกอริทึม

สมัยก่อนมีความน่าจะเป็นว่าสถานที่ที่จะเป็นและน่าจะเป็นมันจะมีค่าที่เป็นไปได้อื่น ๆ ในk_1 นี้สามารถแสดงโดยเวกเตอร์0)1102,3,,k1p1=(1,0,,0)

หลังจากสลับการ์ดถัดไปเวกเตอร์จะได้รับการอัปเดตเป็นโดยคูณ (ทางซ้าย) โดยเมทริกซ์การเปลี่ยนภาพk_2) สิ่งนี้จะทำซ้ำจนกว่าจะทั้งหมด ในขั้นตอนแต่ละผลรวมของรายการในความน่าจะเป็นเวกเตอร์เป็นโอกาสที่บางบัตรได้รับการทำเครื่องหมาย สิ่งที่ยังคงอยู่ที่จะทำให้ค่าเท่ากับดังนั้นจึงเป็นโอกาสที่ไม่มีบัตรถูกทำเครื่องหมายไว้หลังจากขั้นตอน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การอัปเดตการp_jมันคำนวณเมทริกซ์การเปลี่ยนแปลงและดำเนินการคูณ นอกจากนี้ยังดูแลการคำนวณเวกเตอร์เริ่มต้นหากอาร์กิวเมนต์เป็นเวกเตอร์เปล่า: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

ตามกฎถ้าเป็นพระมหากษัตริย์ที่ถูกทำเครื่องหมายแล้วเราจะไม่มองหาบัตรใด ๆ เพิ่มเติม: ที่นี้หมายถึงค่าของจะต้องมีการเพิ่มขึ้นถึง1เมื่อทำเช่นนั้นความแตกต่างจะให้การกระจายของ "หมายเลขที่คุณจะได้รับเมื่อเด็คหมด":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

(เปรียบเทียบสิ่งนี้กับผลลัพธ์ที่ฉันรายงานในคำตอบแยกต่างหากที่อธิบายถึงการจำลอง Monte-Carlo: พวกเขาดูเหมือนจะเหมือนกันมากถึงความคาดหวังของการเปลี่ยนแปลงแบบสุ่ม)

มูลค่าที่คาดว่าจะได้ทันที:

> 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ในสารานุกรมออนไลน์ของลำดับจำนวนเต็ม ดังนั้นเราอาจหวังว่าสูตรปิดสำหรับเด็คที่มีค่าคงที่ ( "เหมาะ") ที่จะพูดคุยลำดับนี้ซึ่งตัวมันเองมีความหมายที่ลึกซึ้งบางอย่าง (ยกตัวอย่างเช่นมันนับขนาดของชั้นเรียน conjugacy ที่ใหญ่ที่สุดในกลุ่มการเปลี่ยนแปลงและยังเกี่ยวข้องกับค่าสัมประสิทธิ์ Trinomial .) ( แต่น่าเสียดายที่ส่วนกลับในลักษณะทั่วไปสำหรับมักจะไม่จำนวนเต็ม.)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

การจับเวลา

เมื่อดูอัลกอริธึมที่ใช้กับ -vectorเราจะเห็นว่าจังหวะของมันควรจะเป็นสัดส่วนกับและ - โดยใช้ขอบเขตบนที่หยาบ - ไม่เลวร้ายยิ่งกว่า . โดยการจับเวลาการคำนวณทั้งหมดสำหรับถึงและถึงและวิเคราะห์เฉพาะที่ใช้เวลาค่อนข้างนาน (วินาทีหรือนานกว่า) ฉันประมาณเวลาการคำนวณประมาณสนับสนุนการประเมินบนขอบเขตนี้( k , k , ... , k ) k 2 ม. 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)

การใช้งานหนึ่งใน asymptotics เหล่านี้คือการคำนวณเวลาของโครงการสำหรับปัญหาที่ใหญ่กว่า ตัวอย่างเช่นเมื่อเห็นว่ากรณีใช้เวลาประมาณวินาทีเราจะประมาณว่ากรณี (น่าสนใจมาก)จะใช้เวลาประมาณวินาที (ใช้เวลาจริงวินาที)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


0

Hacked ง่าย Monte Carlo ใน Perl และพบว่าประมาณ5.83295.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
อ้อ! มีข้อผิดพลาดแบบปิดโดยหนึ่งคือ
เซน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.