Số lần dự kiến bạn phải lăn một con súc sắc cho đến khi mỗi bên xuất hiện 3 lần là bao nhiêu?
Câu hỏi này đã được hỏi ở trường tiểu học ở New Zealand và nó đã được giải quyết bằng cách sử dụng mô phỏng. Giải pháp phân tích cho vấn đề này là gì?
Số lần dự kiến bạn phải lăn một con súc sắc cho đến khi mỗi bên xuất hiện 3 lần là bao nhiêu?
Câu hỏi này đã được hỏi ở trường tiểu học ở New Zealand và nó đã được giải quyết bằng cách sử dụng mô phỏng. Giải pháp phân tích cho vấn đề này là gì?
Câu trả lời:
Giả sử tất cả bên có cơ hội như nhau. Hãy khái quát hóa và tìm số lượng cuộn dự kiến cần thiết cho đến khi mặt xuất hiện lần, mặt xuất hiện lần, ... và mặt đã xuất hiện lần. Bởi vì danh tính của các bên không quan trọng (tất cả chúng đều có cơ hội như nhau), nên mô tả về mục tiêu này có thể được cô đọng: chúng ta giả sử rằng bên không phải xuất hiện, trong số các bên cần phải xuất hiện chỉ một lần, ..., và của các bên phải xuất hiện lần. Đặt
Một sự tái phát dễ dàng có sẵn. Tại cuộn tới, phía xuất hiện tương ứng với một trong những : đó là, một trong hai chúng tôi không cần phải nhìn thấy nó, hoặc chúng tôi cần phải nhìn thấy nó một lần, ..., hoặc chúng tôi cần phải nhìn thấy nó n hơn lần j là số lần chúng ta cần để xem nó.
Khi , chúng tôi không cần nhìn thấy nó và không có gì thay đổi. Điều này xảy ra với xác suất i 0 / d .
Khi thì chúng ta cần nhìn thấy mặt này. Bây giờ có một mặt ít hơn cần nhìn thấy j lần và một mặt nữa cần được nhìn thấy j - 1 lần. Do đó, i j trở thành i j - 1 và i j - 1 trở thành i j + 1 . Đặt thao tác này trên các thành phần của i được chỉ định i ⋅ j , sao cho
Điều này xảy ra với xác suất .
Chúng tôi chỉ đơn giản là phải đếm cuộn chết này và sử dụng đệ quy để cho chúng tôi biết có bao nhiêu cuộn nữa được mong đợi. Theo quy luật kỳ vọng và tổng xác suất,
(Hãy hiểu rằng bất cứ khi nào , thuật ngữ tương ứng trong tổng bằng không.)
Nếu , chúng ta đã hoàn thành và e ( i ) = 0 . Nếu không, chúng tôi có thể giải quyết cho e ( i ) , đưa ra công thức đệ quy mong muốn
Lưu ý rằng là tổng số các sự kiện chúng ta muốn nhìn thấy. Thao tác ⋅ j giảm số lượng đó đi một lần cho bất kỳ j > 0 với điều kiện i j > 0 , luôn luôn như vậy. Do đó, đệ quy này chấm dứt ở độ sâu chính xác | tôi | (bằng 3 ( 6 ) =
Tôi tính rằng
Điều đó dường như rất nhỏ đối với tôi, vì vậy tôi đã chạy một mô phỏng (sử dụng R
). Sau hơn ba triệu con xúc xắc, trò chơi này đã được chơi đến mức hoàn thành hơn 100.000 lần, với chiều dài trung bình là . Sai số chuẩn của ước tính đó là 0,027 : chênh lệch giữa giá trị trung bình này và giá trị lý thuyết là không đáng kể, xác nhận tính chính xác của giá trị lý thuyết.
Việc phân phối độ dài có thể được quan tâm. (Rõ ràng là phải bắt đầu từ , số lượng cuộn tối thiểu cần thiết để thu thập tất cả sáu mặt ba lần mỗi cái.)
# Specify the problem
d <- 6 # Number of faces
k <- 3 # Number of times to see each
N <- 3.26772e6 # Number of rolls
# Simulate many rolls
set.seed(17)
x <- sample(1:d, N, replace=TRUE)
# Use these rolls to play the game repeatedly.
totals <- sapply(1:d, function(i) cumsum(x==i))
n <- 0
base <- rep(0, d)
i.last <- 0
n.list <- list()
for (i in 1:N) {
if (min(totals[i, ] - base) >= k) {
base <- totals[i, ]
n <- n+1
n.list[[n]] <- i - i.last
i.last <- i
}
}
# Summarize the results
sim <- unlist(n.list)
mean(sim)
sd(sim) / sqrt(length(sim))
length(sim)
hist(sim, main="Simulation results", xlab="Number of rolls", freq=FALSE, breaks=0:max(sim))
Mặc dù tính toán đệ quy của rất đơn giản, nhưng nó đưa ra một số thách thức trong một số môi trường máy tính. Trưởng trong số này là lưu trữ các giá trị của e ( i ) khi chúng được tính toán. Điều này rất cần thiết, vì nếu không, mỗi giá trị sẽ được tính toán (một cách dư thừa) một số lần rất lớn. Tuy nhiên, lưu trữ có khả năng cần thiết cho một mảng được lập chỉ mục bởi tôi có thể là rất lớn. Lý tưởng nhất, chỉ nên lưu trữ các giá trị của i thực sự gặp phải trong quá trình tính toán. Điều này gọi cho một loại mảng kết hợp.
Để minh họa, đây là R
mã làm việc . Các ý kiến mô tả việc tạo ra một lớp "AA" (mảng kết hợp) đơn giản để lưu trữ các kết quả trung gian. Các vectơ được chuyển đổi thành các chuỗi và chúng được sử dụng để lập chỉ mục thành một danh sách sẽ chứa tất cả các giá trị. Các i ⋅ j hoạt động được thực hiện như .E
%.%
Các sơ bộ này cho phép hàm đệ quy được định nghĩa khá đơn giản theo cách tương đồng với ký hiệu toán học. Đặc biệt, dòng
x <- (d + sum(sapply(1:n, function(i) j[i+1]*e.(j %.% i))))/(d - j[1])
có thể so sánh trực tiếp với công thức ở trên. Lưu ý rằng tất cả các chỉ mục đã được tăng thêm 1 vì bắt đầu lập chỉ mục các mảng của nó ở 1 thay vì 0 .R
Thời gian cho thấy phải mất giây để tính toán ; giá trị của nó làe(c(0,0,0,6))
32.6771634160506
Lỗi vòng tròn tích lũy điểm tích lũy đã phá hủy hai chữ số cuối (nên 68
thay vì 06
).
e <- function(i) {
#
# Create a data structure to "memoize" the values.
#
`[[<-.AA` <- function(x, i, value) {
class(x) <- NULL
x[[paste(i, collapse=",")]] <- value
class(x) <- "AA"
x
}
`[[.AA` <- function(x, i) {
class(x) <- NULL
x[[paste(i, collapse=",")]]
}
E <- list()
class(E) <- "AA"
#
# Define the "." operation.
#
`%.%` <- function(i, j) {
i[j+1] <- i[j+1]-1
i[j] <- i[j] + 1
return(i)
}
#
# Define a recursive version of this function.
#
e. <- function(j) {
#
# Detect initial conditions and return initial values.
#
if (min(j) < 0 || sum(j[-1])==0) return(0)
#
# Look up the value (if it has already been computed).
#
x <- E[[j]]
if (!is.null(x)) return(x)
#
# Compute the value (for the first and only time).
#
d <- sum(j)
n <- length(j) - 1
x <- (d + sum(sapply(1:n, function(i) j[i+1]*e.(j %.% i))))/(d - j[1])
#
# Store the value for later re-use.
#
E[[j]] <<- x
return(x)
}
#
# Do the calculation.
#
e.(i)
}
e(c(0,0,0,6))
Cuối cùng, đây là cách triển khai Mathicala ban đầu tạo ra câu trả lời chính xác. Việc ghi nhớ được thực hiện thông quae[i_] := e[i] = ...
biểu thức thành ngữ , loại bỏ gần như tất cả các R
sơ bộ. Trong nội bộ, mặc dù, hai chương trình đang làm những điều tương tự theo cùng một cách.
shift[j_, x_List] /; Length[x] >= j >= 2 := Module[{i = x},
i[[j - 1]] = i[[j - 1]] + 1;
i[[j]] = i[[j]] - 1;
i];
e[i_] := e[i] = With[{i0 = First@i, d = Plus @@ i},
(d + Sum[If[i[[k]] > 0, i[[k]] e[shift[k, i]], 0], {k, 2, Length[i]}])/(d - i0)];
e[{x_, y__}] /; Plus[y] == 0 := e[{x, y}] = 0
e[{0, 0, 0, 6}]
Phiên bản gốc của câu hỏi này bắt đầu cuộc sống bằng cách hỏi:
Cần bao nhiêu cuộn cho đến khi mỗi bên xuất hiện 3 lần
Tất nhiên, đó là một câu hỏi không có câu trả lời như @JuhoKokkala đã nhận xét ở trên: câu trả lời là một biến ngẫu nhiên có phân phối cần được tìm thấy. Câu hỏi sau đó đã được sửa đổi để hỏi: "Số lượng cuộn dự kiến là bao nhiêu". Câu trả lời dưới đây tìm cách trả lời câu hỏi ban đầu được đặt ra: làm thế nào để tìm phân phối số lượng cuộn , không sử dụng mô phỏng và chỉ sử dụng các kỹ thuật đơn giản về mặt khái niệm mà bất kỳ sinh viên New Zealand nào có máy tính đều có thể thực hiệnTại sao không? Vấn đề giảm xuống 1 lớp lót.
Phân phối số lượng cuộn cần thiết ... sao cho mỗi bên xuất hiện 3 lần
Chúng tôi lăn một cái chết lần Để cho biểu thị số lần bên của cái chết xuất hiện, nơi . Then, the joint pmf of is i.e.:
Let: Then the cdf of is:
i.e. To find the cdf , simply calculate for each value of :
Here, for example, is Mathematica code that does this, as increases from 18 to say 60. It is basically a one-liner:
cdf = ParallelTable[
Probability[x1 >= 3 && x2 >= 3 && x3 >= 3 && x4 >= 3 && x5 >= 3 && x6 >= 3,
{x1, x2, x3, x4, x5, x6} \[Distributed] MultinomialDistribution[n, Table[1/6, 6]]],
{n, 18, 60}]
... which yields the exact cdf as increases:
Here is a plot of the cdf , như là một chức năng của :
Để lấy được pmf , đơn giản là sự khác biệt đầu tiên của cdf:
Tất nhiên, phân phối không có giới hạn trên, nhưng chúng ta có thể dễ dàng giải quyết ở đây cho nhiều giá trị theo yêu cầu thực tế. Cách tiếp cận là chung và nên hoạt động tốt cho bất kỳ sự kết hợp mong muốn nào của các bên cần thiết.