[[20180203210605]] 『サイコロの確率の出し方』(たなか) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『サイコロの確率の出し方』(たなか)

エクセルの式というより、数学要素が強いのですが、
どなたか分かる方、またはこのサイトで計算できるよ、このサイトで聞く方がいいよ、等をご存じの方がいらっしゃいましたら、
お教えいただけましたら幸いです。

・6面体のサイコロ
・10個
・6面体にはあたりとはずれの2つの絵柄があり、10個それぞれあたりの数とはずれの数が違う

例えば、
・6面体のうち、5面が当たりのサイコロ 4個
・6面体のうち、4面が当たりのサイコロ 3個
・6面体のうち、1面が当たりのサイコロ 3個

10個のサイコロを同時にふり、
あたりが0個〜10個でるそれぞれの確率
をエクセル表でまとめたいと思っています。

サイコロの数自体や、それぞれのサイコロのあたりの面の数を変えた場合の動きもまとめたいと思っており、
こう計算するといいが分かる方がいらっしゃいましたら、
ご教授賜れましたら幸いです。

よろしくお願い致します。

< 使用 Excel:Excel2010、使用 OS:Windows7 >


宿題か何かだったらご自分でやったほうがよいと思います。 
(γ) 2018/02/03(土) 22:04

宿題やどこかに提出するものではなく、自身で必要なものです。
実際に必要な内容を記載のものに置き換えて噛み砕いて書いていますので、
お分かりになる方いらっしゃいましたらお教えください。

確率なので、学生の時に習ってると思うのですが、
エクセル計算でだせる方法を探しております。
(たなか) 2018/02/03(土) 23:34


一つのサイコロを複数回振ったときに当たりが出る回数は、
二項分布に従います。
それぞれのサイコロに当たりが出る回数の確率変数をそれぞれX,Y,Zとすると、
求めるものは、X+Y+Zという確率変数となります。
二項分布に従う3つの確率変数の和の分布を求めるという問題です。
 
(1)
二項分布については、ワークシート関数があります。
BINOM.DIST です。
 
(2)
確率変数XとYの和については、
その和 が k となる確率は、それぞれの確率変数の確率密度を使って
   Σ (PrX(j) * PrY(k - j) ) (Σはjを動かしたもの)
で求めることができます。
 
(3)
最初にX+Yの分布を求めたうえで、
もう一度それにZを加えるという二段階に分ければ考えれば良いでしょう。
 
"噛み砕いて"説明してみましたが、これでお分かりでしょうか?
 
# 質問するときに、噛み砕いて書きましたなどと上から目線で言うものでしょうか。
# それならこちらも上から目線で行きます。

(γ) 2018/02/04(日) 06:43


「噛み砕いて」というのは確かに誤解を生む表現ですが、
現実の案件をシンプルなモデルに置き換えたという意味ですよね。
実際、質問するときに、案件をそのまま提示せずにシンプルなモデルに
置き換えるということはよくあることなので、
私自身は上から目線とは感じませんでした。

yさんの回答は、高尚すぎて私にはさっばり理解できませんでしたので、
自分でも分かるレベルで回答します。

まず、サイコロ10個だと組み合わせが大きくなりすぎるので、
4個の場合で考えてみます。

・6面体のうち、5面が当たりのサイコロ 2個
・6面体のうち、4面が当たりのサイコロ 1個
・6面体のうち、1面が当たりのサイコロ 1個

とします。当たりとはずれの2通りですので、
4個の場合の組み合わせは、下記の16通り(2^4)ですね。
(0 がはずれ、1が当たり)
0 0 0 0
0 0 0 1
0 0 1 0
0 0 1 1
0 1 0 0
0 1 0 1
0 1 1 0
0 1 1 1
1 0 0 0
1 0 0 1
1 0 1 0
1 0 1 1
1 1 0 0
1 1 0 1
1 1 1 0
1 1 1 1

すべてはずれ(0 0 0 0)の場合、
5面が当たりのサイコロがはずれの確率は 1/6
4面が当たりのサイコロがはずれの確率は 2/6
1面が当たりのサイコロがはずれの確率は 5/6
同時に4個のサイコロを振りますので、
同時に複数の事象が発生する場合は、それぞれの確率をかけますので、
1/6*1/6*2/6*5/6 = 0.007716049

 の確率になります。

当たりが1回の場合は、下記の4通り

(0 0 0 1)の場合、1/6*1/6*2/6*1/6 = 0.00154321
(0 0 1 0)の場合、1/6*1/6*4/6*5/6 = 0.015432099
(0 1 0 0)の場合、1/6*5/6*2/6*5/6 = 0.038580247
(1 0 0 0)の場合、5/6*1/6*2/6*5/6 = 0.038580247

それぞれの事象は同時に発生するものでないので、それぞれの確率を加算します。
すると 0.094135802 となりますのて、これが、1回当たりが出る場合の確率。

当たり2回、3回、4回の場合の確率も同様に計算します。

考え方としてはこのようになると思います。
数学的な確率の考え方としてはあってますよね(大昔に習ったことなので自信なし)。

これをVBAに翻訳すればいいことになります。
(hatena) 2018/02/05(月) 00:38


とりあえず、すべての組み合わせをシートに書き出す処理を書いてみました。

シートに下記のようにサイコロ個数と当たり数を入力しておきます。

  A        B   C   D   E
1 サイコロ個数   4
2 当たり数     5   5   4   1

A4 から組み合わせを出力します。

Public Sub AllCases()

    Dim i As Long, a() As Long, r As Range
    Dim SaiCount As Long

    SaiCount = Range("B1")

    Set r = Range("A4")
    For i = 0 To 2 ^ SaiCount - 1
        a = ToBinArray(i, 4)
        r.Resize(, 4) = ToBinArray(i, 4)
        Set r = r.Offset(1)
    Next

End Sub

Function ToBinArray(ByVal a As Long, dig As Long) As Long()

    Dim p As Long, buf() As Long

    ReDim buf(dig)

    For p = dig - 1 To 0 Step -1
        buf(p) = (a Mod 2)
        a = a \ 2
    Next

    ToBinArray = buf
End Function

(hatena) 2018/02/05(月) 01:32


 確率変数X,Y,Zを以下とします。
 X・・・6面体のうち、5面が当たりのサイコロ を4回振ったときのあたりの回数 
 Y・・・6面体のうち、4面が当たりのサイコロ を3回振ったときのあたりの回数 
 Z・・・6面体のうち、1面が当たりのサイコロ を3回振ったときのあたりの回数
 このとき、X+Y+Z という確率変数の分布を求めることが課題と言い換えられます。
 (同じ種類の4個のサイコロを同時に振るのも、
   一つのサイコロを4回繰り返すのも同じことです)

 (1)
 Xは、成功確率が5/6(失敗は1/6)の試行を4回繰り返す時の成功回数ですから、
 その確率は、二項分布に従います。

 つまり、成功回数が k回 である確率は、
    (4個からk個を取る組み合わせの数)× ((5/6)^k) × ((1-(5/6))^(4-k)) 
 で表されます。二項分布については例えば
 https://ja.wikipedia.org/wiki/%E4%BA%8C%E9%A0%85%E5%88%86%E5%B8%83
 を参照。

 Excelのワークシート関数を使えば
     For k = 0 To 4
         probX(k) = WorksheetFunction.Binom_Dist(k, 4, (5 / 6), False)
     Next
 として求められます。
 Y,Zも同様です。

 (2)
 X+Y は、0から7までに値をとる確率変数ですが、
 その確率convo1(k)としますと、
     For k = 0 To 7
         For j = 0 To 4
             If (k - j) >= 0 And (k - j) <= 3 Then
                 convo1(k) = convo1(k) + probX(j) * probY(k - j)
             End If
         Next
     Next
 などと計算できます。
 (convoは X,Yの畳み込み(convolution)の意味です)

 (3)
 その結果を、今度はZとの和をとればよいですから、
 同様にして、
     ' (X + Y) + Z の確率分布
     For k = 0 To 10
         For j = 0 To 7
             If (k - j) >= 0 And (k - j) <= 3 Then
                 convo2(k) = convo2(k) + convo1(j) * probZ(k - j)
             End If
         Next
     Next
 として得られる convo2(k)が求める確率分布です。

 (4)
 纏めると以下のとおりです。
 Sub test()

     Dim probX(0 To 4) As Double
     Dim probY(0 To 3) As Double
     Dim probZ(0 To 3) As Double
     Dim convo1(0 To 7) As Double
     Dim convo2(0 To 10) As Double
     Dim k As Long

     For k = 0 To 4
         probX(k) = WorksheetFunction.Binom_Dist(k, 4, (5 / 6), False)
     Next

     For k = 0 To 3
         probY(k) = WorksheetFunction.Binom_Dist(k, 3, (4 / 6), False)
     Next

     For k = 0 To 3
         probZ(k) = WorksheetFunction.Binom_Dist(k, 3, (1 / 6), False)
     Next

     ' X + Y の確率分布
     For k = 0 To 7
         For j = 0 To 4
             If (k - j) >= 0 And (k - j) <= 3 Then
                 convo1(k) = convo1(k) + probX(j) * probY(k - j)
             End If
         Next
     Next

     ' (X + Y) + Z の確率分布
     For k = 0 To 10
         For j = 0 To 7
             If (k - j) >= 0 And (k - j) <= 3 Then
                 convo2(k) = convo2(k) + convo1(j) * probZ(k - j)
             End If
         Next
     Next

     '結果を書き出します    
     Sheet1.Range("A1").Resize(11, 1).Value = Application.Transpose(convo2)

 End Sub

 あとは、上記のパラメータを可変にすればよいでしょう。
 3種類のサイコロの成功確率とか、それぞれの試行回数ですね。
 場合によっては、サイコロの種類も増やすのでしょうか?
 原理的には同じです。

(γ) 2018/02/05(月) 06:16


たくさんのご教授ありがとうございます!

>hatenaさま

ご教授ありがとうございます!
「すべての組み合わせをシートに書き出す処理」を10個バージョンで作成することはできました!
ありがとうございます。

そこからの確率の出し方が見いだせずだったので、改めて研究してみます。

10個のサイコロをふるので、
パターンは「6の10乗」で60466176通り、
全てがはずれで0点の確率は、0.002%
全てが当たりで10点の確率は、0.066%
かなと思ったのですが、1〜9点の計算方法が分からず、
且つ0点と10点の確率も違う場合は根本から出し方を考え直してみます。

>γさま

「宿題や課題ではないです、必要なものをサイコロに置き換えて書いてます」を伝えたかっただけなのですが、
お気を悪くされてしまったようでしたらすみません。
hatenaさまが書いてくださっている通り「シンプルにしました」と書くべきでした、すみません。

ご回答ありがとうございます。
元々VBAやプログラミングに全く知識がないため、
参考書と見比べながら実行してみたのですが、
答えを見つけ出すことができませんでした。
丁寧にお教えいただいたのにすみません。
一週間後にまた改めてチャレンジしてみます。

>みなさま

一週間ほどパソコンが触れない環境になるため、また一週間後に教えていただいたものを
ひとつひとつ解読できるようひもといてみます。

hatenaさまが書いてくださった「すべての組み合わせをシートに書き出す処理」まではできたので、
ここから確率を導き出す方法がありましたらお教えいただけましたら幸いです。

エクセルの縦軸にサイコロの名前「サイコロA〜サイコロJ」、その横にそれぞれのサイコロのあたりの面数「5555444111」
横軸に合計当たりの数「0点〜10点」
と記載し、12×11のマス目から計算できないか、当たりの面数を書き換えることで、それぞれの点数がどう動くかを見れないだろうか、と模索していたのですが、
1点〜9点までの組み合わせが複数あるので、行き詰った次第です。
説明が稚拙ですみません。

・6面体であることには変化なし(8面体になったり、10面体になったりはしない)
・それぞれのサイコロの当たりの数は変動する(が、一旦例文のものの確率の導きだし方を知りたい)

という形です。よろしくお願い致します。

(たなか) 2018/02/05(月) 13:54


回答をプレビューしてしている間に、たなかさんの投稿があったようです。
投稿内容はまだ読んでませんが、とりあえず準備した回答を投稿します。

二項分布ですか。Wiki読んでみたけど難しいですね。統計学の範疇にはいるのでしょうか。

とりあえず、前回の回答の方針で作成してみました。
事前に Sheet1 に下記のように、サイコロの個数と、
それぞれのサイコロの当たり数を入力してから、
下記の Main を実行してください。

  A      B C D E F G H I J K
1 サイコロ個数 10
2 当たり数   5 5 5 5 4 4 4 3 3 3

Public Sub Main()

    Dim Dic As Object
    Dim i As Long, a() As Long
    Dim SaiCount As Long
    Dim HitCount() As Variant
    Dim K() As Double '当たり確率、はずれ確率の配列
    Dim ACnt As String

    Set Dic = CreateObject("Scripting.Dictionary")
    With Sheet1
        SaiCount = .Range("B1").Value  'さいころ個数
        HitCount = .Range("B2").Resize(, .Range("B1")).Value 'あたり数の配列
    End With

    ReDim K(LBound(HitCount, 2) To UBound(HitCount, 2), 1)
    For i = LBound(HitCount, 2) To UBound(HitCount, 2)
        K(i, 1) = HitCount(1, i) / 6 '当たり確率
        K(i, 0) = 1 - K(i, 1)        'はずれ確率
    Next

    For i = 0 To 2 ^ SaiCount - 1
        a = ToBinArray(i, SaiCount)
        ACnt = SumArray(a)
        Dic(ACnt) = Dic(ACnt) + Kakuritu(a, K)
    Next

    '結果を書き出し
    Sheet1.Range("A4").Resize(Dic.Count) = WorksheetFunction.Transpose(Dic.keys)
    Sheet1.Range("B4").Resize(Dic.Count) = WorksheetFunction.Transpose(Dic.items)
    Set Dic = Nothing
End Sub

'2進数変換を利用して、n番目の当たり/はずれの組み合わせを取得
Function ToBinArray(ByVal n As Long, dig As Long) As Long()

    Dim p As Long, buf() As Long

    ReDim buf(dig)
    For p = dig - 1 To 0 Step -1
        buf(p) = (n Mod 2)
        n = n \ 2
    Next
    ToBinArray = buf
End Function

Public Function Kakuritu(a() As Long, K() As Double) As Double

    Dim i As Long, rng As Range

    Kakuritu = K(1, a(0))
    For i = 2 To UBound(K, 1)
        Kakuritu = Kakuritu * K(i, a(i - 1))
    Next
End Function

Public Function SumArray(a) As Long

    Dim i As Long
    For i = LBound(a) To UBound(a)
       SumArray = SumArray + a(i)
    Next
End Function

結果は、Sheet1 の A4 から下記のように表示されます。

 0  0.0000165382 
 1  0.0004399154 
 2  0.0049237445 
 3  0.0301048970 
 4  0.1092817247 
 5  0.2398202923 
 6  0.3101466843 
 7  0.2192743262 
 8  0.0738859358 
 9  0.0114444148 
10  0.0006615269 

yさんのと同じ結果になったので、間違いはないと思います。

サイコロ個数と当たり数を書き換えれば、別の条件でも結果を得られます。
(hatena) 2018/02/05(月) 14:01


盛り下げるようなコメントですいません。

前提条件ですが、全部アタリとか全部ハズレのサイコロも考慮なのですかね? まぁ、計算方法はそのままで良いのですが。

そして、アタリ個数毎の確率計算は既にγ(ガンマ)さんがコーディングしてくれていますよね。これを理解すると良いでしょう。

しかし、個数毎の確率計算は良いですが、アタリ数を変えたときの変化って、最終的には10個まとめて振って、アタリが何個出るかの期待値1つで表現できるのではないかと思うのですが、いかがでしょう? 11個の確率を並べてグラフにでもして比較しても、真ん中は多くて、端は少ないよね〜、くらいの事しか判らなくて、役立たないように思います。

期待値だけで良いならば、(5*4+4*3+1*3)/(6*10)*10 = 5.8個 という簡単な式で終わってしまうので、個数毎の確率を計算した後はどうするのだろうなぁ?、等と考えてしまいました。
(???) 2018/02/05(月) 14:43


>hatenaさま

ご回答ありがとうございます!!!
求めていた通りのものを作成することができました!!
私の拙い文章から、全てを汲み取ってくださり、本当にありがとうございました!

一週間をまたずに解決することができ、とても助かりました!ありがとうございました!
またぜひよろしくお願い致します!

>???さま

>個数毎の確率を計算した後はどうするのだろうなぁ?、等と考えてしまいました。

「このパターンで固定したときに0点が何%でるか、1点が何%でるか」というそれぞれを知りたかったので、hatenaさまので解決することができました。

ご興味をお持ちいただき、読んでいただき、ありがとうございました。
またぜひよろしくお願い致します。

(たなか) 2018/02/05(月) 15:57


一応、コードの解説をしておきます。

ロジックは高校レベルの確率の知識で組み立ててます。

すべての組み合わせを生成する。
各組み合わせの確率は、各サイコロの確率を乗算する。
その確率を当たり数毎に加算する。
というシンプルなものです。
それを下記のようなコードで実現しています。

(1) 当たり=1 はずれ=0 としてすべての組み合わせを生成する。
4個なら、
0 0 0 0
0 0 0 1
0 0 1 0
0 0 1 1
0 1 0 0
・・・
となりますが、これは2進数と同じです。
そこで、数値を2進数に変換するロジックで
当たり/はずれの組合せの配列を生成します。
それが、ToBinArray関数です。

(2) 生成した一つの組み合わせ配列から、当たり数(点数)と確率を計算する。
当たり数は、SumArray関数で計算します。
確率は、Kakuritu関数で計算します。
各要素の当たり確率、はずれ確率をかけて得られます。
各サイコロの当たり確率、はずれ確率は、配列K() に格納されていますので、それを利用します。

(3) Mainでの処理
上記で取得した一つの組み合わせの当たり数と確率を、順にDictionaryに格納します。
当たり数をkeyにして、同じkeyに対応する確率をItemに加算していきます。

これで、当たり数に対応する確率の合計がDictionaryに格納されますので、
そのキー配列(keys)とアイテム配列(Items)をシートに書き出す。

以上です。
(hatena) 2018/02/05(月) 17:02


質問者さんへ
 
>答えを見つけ出すことができませんでした。
Sheet1のA1:A11に当たり回数0〜10の確率が書き出されていますけど。
不思議ですね。
 
確率というものが理解できていないと、
実際のものをこういう形に置き換えて考えること自体が
できないんじゃないかと思いますけどねえ。
いずれにせよ、単に計算だけではなく、それらの持つ意味を
よく理解されることをお薦めします。
 
なお、私が言及した内容(二項分布だとか、確率変数の和など)は、
一昔前ですが高校で教えられていたことがあるようです。
https://ja.wikibooks.org/wiki/%E9%AB%98%E7%AD%89%E5%AD%A6%E6%A0%A1%E6%95%B0%E5%AD%A6C/%E7%A2%BA%E7%8E%87%E5%88%86%E5%B8%83#確率変数の和と積
確率・統計などでは比較的基本的な話のはずで、
Excelのワークシート関数にあるくらいですから、
結構一般的なものかと思っていました。
(γ) 2018/02/05(月) 23:40

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.