問題
- サイコロ5つをふる、そのうち6が出なかった目を全て振り直す。さらにもう一度6が出なかった目を全て振り直す。この時、全ての目が6になる確率を求めたい
実装
import math
y = 1/6
n = 5/6
def all_pattern():
all_patterns = []
for i in range(0,6):
for j in range(0, i+1):
all_patterns.append((i, j))
return all_patterns
def calc_prob(num, i):
"""
num: サイコロの個数
i: 6が出る回数
"""
return y**i * n**(num-i) * math.comb(num, i)
for i in range(1,6):
for j in range(0, i+1):
print(f"サイコロの個数: {i}, 6が出る回数: {j} = {calc_prob(i, j)}")
def calc_prob_reroll(pattern):
# 1回目に指定した個数の6が出る確率
num_six_1 = 5 - pattern[0]
prob_1 = calc_prob(5, num_six_1)
if pattern[0] == 0:
return prob_1
num_six_2 = pattern[0] - pattern[1]
prob_2 = calc_prob(pattern[0], num_six_2)
if pattern[1] == 0:
return prob_1 * prob_2
num_six_3 = pattern[1]
prob_3 = calc_prob(pattern[1], num_six_3)
return prob_1 * prob_2 * prob_3
for pattern in all_pattern():
print(f"{pattern}: {calc_prob_reroll(pattern)}")
print("確率の合計: ", sum(calc_prob_reroll(pattern) for pattern in all_pattern()))
実行結果
(0, 0): 0.00012860082304526745
(1, 0): 0.0005358367626886143
(1, 1): 0.0004465306355738454
(2, 0): 0.0008930612711476908
(2, 1): 0.0014884354519128181
(2, 2): 0.0006201814382970076
(3, 0): 0.0007442177259564091
(3, 1): 0.001860544314891023
(3, 2): 0.0015504535957425194
(3, 3): 0.000430681554372922
(4, 0): 0.0003100907191485037
(4, 1): 0.0010336357304950123
(4, 2): 0.0012920446631187658
(4, 3): 0.0007178025906215365
(4, 4): 0.00014954220637948678
(5, 0): 5.1681786524750625e-05
(5, 1): 0.00021534077718646097
(5, 2): 0.00035890129531076836
(5, 3): 0.00029908441275897367
(5, 4): 0.000124618505316239
(5, 5): 2.0769750886039836e-05
確率の合計: 0.013272056011374656
シミュレーションによる検算
-
疑似乱数を使って実際にたくさんサイコロを振れば、上記の計算が合っているかの検算ができる
-
なんとこれはchatgptがやってくれた!
- 書いてくれたコード
import numpy as np # サイコロを5つ振り、2回振り直すシミュレーション def roll_dice(): # 初回のサイコロを振る dice = np.random.randint(1, 7, 5) # 6が出ていない目を振り直し(1回目) dice[dice != 6] = np.random.randint(1, 7, np.sum(dice != 6)) # 再度、6が出ていない目を振り直し(2回目) dice[dice != 6] = np.random.randint(1, 7, np.sum(dice != 6)) # 全て6になっているかどうかを確認 return np.all(dice == 6) # シミュレーションを実行する回数 n_trials = 1000000 success_count = sum(roll_dice() for _ in range(n_trials)) # 全てのサイコロが6になる確率を求める probability = success_count / n_trials probability
- 実際答えが正しいことが確かめられた
数学的な計算をgptにさせられないか?
-
数学的に計算するんじゃなくて、シミュレーションで計算して確率を求める方向に(指示してないのに)もって言ってたのおもろい
-
その後、数学的な計算も実装されるよう指示したところ、2回目の試行で一部のサイコロが6になる可能性を考慮できていなかった。
-
しかし、そのことを指摘すると、正しいコードを実装して、数学的な計算で確率を求めることに成功していた!
-
会話のリンク
- https://chatgpt.com/share/6709125c-a26c-8011-bb47-f43f01415bb2
- chatはうまく表示されない場合がある。更新したりするといい。