各面が3回現れるまでダイスを振る回数


15

各サイドが3回出現するまでダイスを振る必要があると予想される回数はいくつですか?

この質問はニュージーランドの小学校で尋ねられ、シミュレーションを使用して解決されました。この問題の分析ソリューションは何ですか?


6
ロールの結果はランダムであるため、必要なロールの数を事前に知ることはできません。たとえば、質問が各サイドが3回現れる前に予想されるロールの数を探している場合、それを明示的に指定する必要があります。その場合、stats.stackexchange.com / tags / self-study / infoが適用されます。
たJuho Kokkala

3
ニュージーランドの子供たちに、ノーマンL.ジョンソン、サミュエルコッツ、N。バラクリシュナン「離散多変量分布」wiley.com/WileyCDA/WileyTitle/productCd-0471128449.htmlを読むように伝えます。
マークL.ストーン

回答:


28

すべてのd=6辺に等しいチャンスがあると仮定します。サイド1n1回現れ、サイド2n2回現れ、...サイドdnd回現れるまで、必要なロールの予想数を一般化して見つけましょう。側面のアイデンティティーは重要ではないので(それらはすべて等しいチャンスを持っています)、この目的の説明は凝縮することができます:i0側面はまったく現れる必要がなく、側面のi1が現れる必要があると仮定しましょう一度だけ、...、そしてin辺の出現する必要があります =n=max(n1,n2,,nd)回。してみましょう

i=(i0,i1,,in)
このような状況と書き込み指定する
e(i)
のロール数の期待値のため。質問はを要求e(0,0,0,6)i3=6 は、6つの側面すべてをそれぞれ3回見る必要があることを示します。

簡単な繰り返しが利用可能です。 次のロールのいずれかに対応して表示された側のijいずれか、である私たちはそれを参照してくださいする必要はありませんでした、または我々は、一度それを見るために必要な、...、または我々はそれを見るために必要な:n以上回。jは、それを見るのに必要な回数です。

  • ときj=0、我々はそれと何も変更を確認する必要はありませんでした。これは、確率発生しi0/dます。

  • ときj>0その後、我々はこの辺を参照してくださいする必要がありました。これで、j回見る必要がある側が1つ少なくなり、j1回見る必要がある側がもう1つあります。したがって、ijij1なり、ij1ij+1ます。この操作は、構成要素にしてみましょうiに指定されijように、

    ij=(i0,,ij2,ij1+1,ij1,ij+1,,in).

    これは、確率発生しij/dます。

このサイコロを数えるだけで、再帰を使用してさらに多くのロールが予想されることを知ることができます。 期待と総確率の法則により、

e(i)=1+i0de(i)+j=1nijde(ij)

i j = 0のときはいつでも理解しましょうij=0場合、合計の対応する項はゼロである。)

場合、処理は完了し、e i= 0です。それ以外の場合、e i)を解いて、望ましい再帰式を与えることができますi0=de(i)=0e(i)

(1)e(i)=d+i1e(i1)++ine(in)di0.

そのお知らせは、表示したいイベントの総数です。操作jは任意のための1つによりその量を低減J > 0設けI 、J > 0常にそうです。したがって、この再帰は正確に|の深さで終了します| 3 6 )に等しい=

|i|=0(i0)+1(i1)++n(in)
jj>0ij>0|i|3(6)=18質問で)。さらに、この質問の各再帰深度での可能性の数は(確認するのが難しくないように)小さい(を超えない)。したがって、これは少なくとも組み合わせの可能性が多すぎず、中間結果をメモする場合に効率的な方法です(したがって、eの値は8e複数回計算さです。

私は計算

e(0,0,0,6)=22868786045088836998400000000032.677.

それは私にはひどく小さいように思えたので、シミュレーションを実行しました(を使用R)。300万回以上のサイコロを振った後、このゲームは平均長さで100,000回以上プレイされていました。その推定値の標準誤差は0.027です。この平均値と理論値の差はわずかであり、理論値の精度が確認されています。32.6690.027

長さの分布が興味深い場合があります。(明らかに、6面すべてを3回収集するために必要なロールの最小数であるから開始する必要があります。)18

Figure

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

実装

の再帰的な計算は簡単ですが、一部のコンピューティング環境ではいくつかの課題があります。これらの中で最も重要なのは、e i)の値を計算時に保存することです。これは不可欠です。それ以外の場合、各値は非常に多くの回数(冗長に)計算されます。ただし、iによってインデックス付けされた配列に必要なストレージは膨大な量になる可能性があります。理想的には、計算中に実際に遭遇するiの値のみを保存する必要があります。これには、一種の連想配列が必要です。ee(i)ii

説明のために、ここに作業Rコードを示します。コメントは、中間結果を保存するための単純な「AA」(連想配列)クラスの作成を説明しています。ベクトルは文字列に変換され、すべての値を保持するリストにインデックスを付けるために使用されます。j個の操作は、次のように実装されています。iEij%.%

これらの予備により、数学的な表記法に対応する方法で、再帰関数をかなり簡単に定義できます。特に、ラインe

x <- (d + sum(sapply(1:n, function(i) j[i+1]*e.(j %.% i))))/(d - j[1])

上記の式と直接比較できます。すべてのインデックスが増加されていることに注意してください1ので開始はでその配列のインデックスを作成する1ではなく0(1)1R10

タイミングは、計算に秒かかることを示しています。その値は0.01e(c(0,0,0,6))

32.6771634160506

蓄積された浮動小数点丸めエラーが(あるべきで下二桁破壊した68というよりは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))

最後に、正確な答えを生成した元のMathematica実装を示します。メモ化は慣用表現を介して行われe[i_] := e[i] = ...ほとんどすべてのR予備作業が排除されます。ただし、内部的には、2つのプログラムは同じことを同じ方法で実行しています。

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

228687860450888369984000000000


5
+1この質問をされた学生にとって、表記法の一部を理解するのは難しいと思います(現時点で提案する具体的な代替案があるわけではありません)。一方、私は彼らがそのような質問で何をするつもりだったのだろうか。
Glen_b-モニカを

1
@Glen_b彼らは実際にサイコロを転がす(そして結果を集計する)ことで多くを学ぶことができた。先生が休んでいる間に30分間クラスを忙しくしておくのに良い方法のように思えます:-)。
whuber

12

この質問の元のバージョンは、次の質問から始まりました。

各面が3回現れるまでに必要なロール数

Of course, that is a question that does not have an answer as @JuhoKokkala commented above: the answer is a random variable with a distribution that needs to be found. The question was then modified to ask: "What is the expected number of rolls." The answer below seeks to answer the original question posed: how to find the distribution of the number of rolls, without using simulation, and just using conceptually simple techniques any New Zealand student with a computer could implement Why not? The problem reduces to a 1-liner.

Distribution of the number of rolls required ... such that each side appears 3 times

We roll a die n times. Let Xi denote the number of times side i of the die appears, where i{1,,6}. Then, the joint pmf of (X1,X2,,X6) is Multinomial(n,16) i.e.:

P(X1=x1,,X6=x6)=n!x1!x6!16n subject to: i=16xi=n

Let: N=min{n:Xi3i}. Then the cdf of N is: P(Nn)=P(Xi3|n)

i.e. To find the cdf P(Nn), simply calculate for each value of n={18,19,20,}:

P(X13,,X63) where (X1,,X6)Multinomial(n,16)

Here, for example, is Mathematica code that does this, as n 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 n increases:

1814889875110199605761928290762544079842304203111983875176319369216211168408491253173748645888223283142988125507799783342082361483465418375609359740010496

Here is a plot of the cdf P(Nn), as a function of n:

enter image description here

To derive the pmf P(N=n), simply first difference the cdf:

enter image description here

Of course, the distribution has no upper bound, but we can readily solve here for as many values as practically required. The approach is general and should work just as well for any desired combination of sides required.

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.