今回はSNSで話題になっていた
直感に反する数学の問題を解く
プログラムに関してです。



解説動画はこちら 



今回の問題は、とある数学者の考案した
「一見シンプルだが直感に反する確率パズル」
というものです。


問題

100個のボールが入ったつぼがあります。
そのうちn個が赤で、100-n個が緑です。
ただし、nは0~100の間で一様分布しています。

つぼからボールをランダムに1つ取り出したところ、赤でした。
それを捨ててから、残り99個からボールを選ぶとき
次に引くボールの色は赤と緑どちらが多いでしょうか?

1.赤
2.緑
3.赤と緑が同じ



さてこの問題を考えてみてください。





解説

こちらの詳細な解説は
ながーいので、割愛します。

動画の中では 3:53 くらいから解説しています。



シミュレーションコード

こちらの確率をもとめるコードは
こんな感じになります。

1.ランダムに赤いボールの個数を決める
2.赤を引いたら、次のボールを引く
3.二回目のボール、赤と緑どちらを引いたか集計する

import numpy as np

# シミュレーションの設定
num_trials = 100000  # 試行回数
n_balls = 100  # ボールの総数
data = []

# 結果を記録するための変数
red_first_count = 0
red_second_count = 0
green_second_count = 0

# シミュレーション
for _ in range(num_trials):
    n_red = np.random.randint(0, n_balls + 1)  # 0から100までのランダムな赤いボールの数
    n_green = n_balls - n_red  # 緑のボールの数

    # 最初のボールをランダムに引く(赤または緑)
    first_draw = np.random.choice(['red'] * n_red + ['green'] * n_green)

    if first_draw == 'red':
        # 最初に赤を引いたので、赤を1つ減らす
        red_first_count += 1
        n_red -= 1

        # 次のボールを引く
        second_draw = np.random.choice(['red'] * n_red + ['green'] * n_green)

        # 次のボールの数を集計
        if second_draw == 'red':
            red_second_count += 1
        else:
            green_second_count += 1
        tmp = [red_first_count,red_second_count,red_second_count/red_first_count,n_red]
        data.append(tmp)

# 結果の計算
total_first_red = red_first_count
total_second_red = red_second_count

# 確率の計算
if total_first_red > 0:
    p_second_red_given_first_red = total_second_red / total_first_red
    print(f"P(second red | first red) = {p_second_red_given_first_red:.4f}")
else:
    print("No trials with the first ball red.")



google colab などで試してみてください。

ベイズの定理などを用いて
机上でかなり大変な計算をしないと
求めることは困難ですが

プログラムであれば
簡単にシミュレーションして
擬似値をもとめる事ができます。

ぜひ色々試してみてください。

それでは。