前提・実現したいこと
chianerのチュートリアルに取り組んでいます。
webで調べても回答解説がでてこないため、質問させていただきます。
以下の問題はどのようにとけばよいのでしょうか
問6.4 (ベイズの定理)
一様な確率で1から6までの数が出るサイコロがあります。 サイコロを何回か連続で振る試行を考えます。サイコロを振った後、直前に出た数より大きい数が出たときに「ラッキーである」と呼ぶことにします。 例えばサイコロを5回振って 2,5,3,4,4 と順に出た場合、2回目と4回目はラッキーですが、それ以外はラッキーではありません。
いま、サイコロを 10 回振って一度もラッキーではなかったとします。このとき、次にサイコロを振ってラッキーになる確率はいくらになるでしょうか。プログラムを使って分析してみて下さい。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
2時間弱計算にかかりました。
もっと効率的な方法がありそうです。
python3
1import time 2startTime = time.time() 3 4kaisu = 11 5ten_unlucky = 0 6saigo_lucky = 0 7deme =[0]*kaisu 8 9for i in range(6**kaisu): 10 temp = i 11 for j in range(kaisu): 12 deme[j] = temp % 6 + 1#1投目の数1~6 13 if 0<j<kaisu -1 and deme[j]>deme[j-1]:#ラッキーが途中で出たらストップ 14 break 15 temp = int(temp/6) 16 17 if j == kaisu -1:#10回ラッキーが出なかった場合 18 #print(deme) 19 ten_unlucky = ten_unlucky+1 20 if deme[j]>deme[j-1]:#最後がラッキー 21 saigo_lucky = saigo_lucky+1 22 23print("Time={}".format(time.time()-startTime)) 24print(saigo_lucky / (ten_unlucky))
投稿2020/06/18 11:06
総合スコア46
0
解答例がないのであくまで個人の解釈になりますが、考え方だけ。
この問題はベイズの問題というよりは条件付確率の問題のような...
まずサイコロを2回振ってラッキーがでる確率を考えます。1回目の目が1なら2回目が(2,3,4,5,6)ならラッキー、1回目の目が2なら(3,4,5,6)がラッキー、すなわちサイコロの目をd1,d2とすると、d1 > d2
の場合ラッキーとなる式が成り立ちます。逆にラッキーでない場合はd1 <= d2
です。ラッキーとなる確率は
(5+4+3+2+1)/6**2 = 15/36
になります。逆にラッキーでない確率は(1+2+3+4+5+6)/6**2 = 21/36
です。
次にサイコロをN回振った場合を考えます。全てのサイコロ試行において、d(N-1) <= d(N)
が成り立つ場合のみ、「一度もラッキーしていない」と認められます。全試行の組み合わせ数から上記式が成り立つ組み合わせを求めれば「10回振って一度もラッキーしていない」確率が求められます。これを手計算で行うのは厳しいのでプログラムを使って求めようということです。(全試行数は6**10≒6000万)
さて、この課題で求めるのは、上記の状態が前提で次の試行でラッキーとなる確率です。ラッキーになる確率は1つ前のサイコロの目で変わってきますが、事前に組み合わせを全部洗いだしていればひとつ前の目(10投目)が何であるかは容易に集計できます。10投目が1~6それぞれの場合において、
10投目が1である確率11投目でラッキーになる確率
+10投目が2である確率11投目でラッキーになる確率
...
を計算すれば、最終的に求める確率が計算できます。
以上の考え方が正しいなら、回答は25/33になるはずです。
追記
全然質問者から反応ないけど回答を実装したソースです。まだ質問を見てくれている方へ。
python
1from collections import defaultdict 2# ラッキー判定 3def lucky(p,c): 4 return p < c 5 6# 探索関数。引数はそれまでのサイコロの出目のリスト 7def search(l): 8 global cnt 9 p = l[-1] # リストの一番最後の出目 10 # 10投して全部ノーラッキーだったら総数にカウントする 11 # リストの要素数が10だったら条件成立 12 if len(l) == N: 13 # 14 cnt += 1 15 cnt_d[p] += 1 16 return 17 # それ以外の場合は次のサイコロ試行。1~6 18 for c in range(1,7): 19 # ラッキーだったらそこで探索終了 20 if lucky(p,c): 21 pass 22 else: 23 # ノーラッキーだったら引数のリストに今の出目を加えて次の試行へ 24 search(l + [c]) 25 26cnt = 0 # ノーラッキー総数 27cnt_d = defaultdict(int) # 最後の出目別ノーラッキー数 28N = 10 # サイコロ投擲回数 29total = 6**N # 10回のサイコロ投擲総組み合わせ数 30 31# 第1投目を初期値として与えて探索開始 32for i in range(1,7): 33 search([i]) 34 35#10回振って一度もラッキーしない確率 36print(cnt,'/',total) 37# うち最後の目別のカウント 38print(cnt_d) 39 40# 分母は10投ノーラッキー数ごとに11投目の出目数の乗算 41fb = cnt*6 42# 分子はラッキー総数 43fi = 0 44# ラッキー数計算 45for i in range(1,7): 46 fi += (cnt_d[i])*(6-i) 47 48# 10投目までノーラッキーのとき、11投目にラッキーが出る確率 49print(fi/fb) 50print(fi,'/',fb) 51from fractions import Fraction 52print(Fraction(fi,fb)) 53 54''' >> 出力 55# 10回振って一度もラッキーしない確率 563003 / 60466176 57# うち最後の目別のカウント 58defaultdict(<class 'int'>, {1: 2002, 2: 715, 3: 220, 4: 55, 5: 10, 6: 1}) 59# 10投目までノーラッキーのとき、11投目にラッキーが出る確率 600.7575757575757576 61# 分数にすると 6213650 / 18018 63# 約分すると 6425/33 65 66CPU times: user 10 ms, sys: 0 ns, total: 10 ms 67Wall time: 9.72 ms 68'''
投稿2020/06/05 10:18
編集2020/06/18 12:13総合スコア4447
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。