✏️Pythonで体験しよう モンテカルロ法

ここでは Pythonを使って モンテカルロ法を体験します。


ランダムに点を打ち その結果から円周率 π の近似値を求めてみましょう。

(π = 3.14159265359・・・)

円周率って昔習ったけど、どうやって求めるんだろう?

大体3.14ってのは知ってるけどね。

今回は、シミュレーションを使って求めましょう。

いろんな方法がありますが、今回は、モンテカルロ法を利用します。

プログラムの実行はGoogle Colabで行います。下記のリンクからGoogle Colabを開きましょう。

新しくノートブック「ip0408」を作成してください。

1. まずは考え方を確認しよう

まず、「円周率」とは何かを確認しましょう。

円周率ってどういう数値かは知っていますか?

円の直径を何倍すれば、円周の長さになるか。って値ですよね?

円周率を利用すれば、円周の長さだけでなく、円の面積も求められるんだよな。

その通りです。昔の人は、どうやって円周率を求めたんでしょうか?

この円周率を求めることは、昔からとても大変な問題でした。


約2000年前、アルキメデスという学者は、 円の中に多角形を描いて計算する方法で、ようやく「3.14」に近い値を求めました。


さらに約400年前、ルドルフという学者は、 角の数を何度も増やしながら計算を続け、 30年かけて35桁の円周率を求めました。


このように、円周率を正確に求めるには、 非常に多くの計算と長い時間が必要でした。


しかし、現在ではコンピュータの力によって、 円周率は300兆桁以上まで求められています。

人間の手では到底できないような計算も、 コンピュータなら短時間で行うことができます。


やっぱりコンピュータってとんでもないんだなぁ。

300兆って、想像もつかない。

1秒で2桁読み上げるとして、475万年かけて読み上げ終わる計算ですね。

読み上げている最中にさらに桁数が増えていそうですね。

では、難しい計算を使わずに、 円周率を求める方法はないのでしょうか。

そこで考えられたのが、 「ランダムに何度も試して結果から求める方法」です。

これが、モンテカルロ法です。


それでは、モンテカルロ法を利用した円周率の考え方を見てみましょう。

一辺が 2 の正方形の中に 半径 1 の円を入れることを考えます。

正方形の面積は、「縦 × 横」で求められるので、

2 × 2 = 4

となり、面積は4です。


次に、この正方形の中に、半径1の円を描きます。

円の面積は、


「半径 × 半径 × π」

で求められるので、


「1 × 1 × π = π」

となります。


ここで大切なのは、「正方形と円の大きさの関係」です。

正方形は4、円はπなので、


「正方形:円 = 4:π」

という関係になっています。


ここからがモンテカルロ法の考え方です。

正方形の中に、ランダムに点をたくさん打っていきます。

ランダムに点を打つというのは、「どこに点が落ちるかが決まっていない」ということです。

つまり、正方形の中のどの場所にも、同じくらいの確率で点が落ちることになります。

そのため、点は正方形の中にまんべんなく広がります。


もし円が正方形の半分の大きさだったら、点も半分くらいが円の中に入るはずです。

つまり、広さが大きいほど、その中に入る点の数も多くなると考えることができます。


ここで考えてみましょう。

正方形の中に100個の点を打ったとき、そのうち何個くらいが円の中に入るでしょうか。

円は正方形よりも小さいので、すべての点が入るわけではありません。

円の大きさは「正方形に対して π/4 くらい」なので、

円の中に入る点の数も、だいたい同じくらいになります。


つまり、


「正方形全体の点の数 : 円の中に入った点の数 = 正方形の面積 : 円の面積」

と同じように考えることができます。


この考え方を使うと

π ≒ 4 × (円の中に入った点の数 ÷ 全体の点の数)

として π を近似的に求めることができます。

ランダムに点を打つだけで「π」が分かるんですか?

ちょっと不思議だけど、割合を使うんだよね。

はい。たくさん試すことで、だんだん本当の値に近づいていきます。

2. ランダムな点を1つ作ってみよう

まずは正方形の中にランダムな点を1つ作ります。

x座標とy座標を、0以上1以下の乱数で作れば 1辺が1の正方形の中の点を表せます。

今回は計算しやすいように、1/4円を使って考えます。

1/4円でも、その割合は同じです。

import random

x = random.random()
y = random.random()

print("x =", x)
print("y =", y)

実行するたびに、違う値が表示されることを確認しましょう。

x²+y²が1以下なら、円の中なんですね。

その通りです。数学の知識をプログラムに使っています。

数学とプログラミングがつながってきたね。

3. 円の内側かどうかを判定しよう

点 (x, y) が 半径1の1/4円の内側にあるかどうかは

x² + y² ≤ 1

で判定できます。

これは原点からの距離を使った判定です。

x = random.random()
y = random.random()

if x**2 + y**2 <= 1:
    print("円の内側です")
else:
    print("円の外側です")

4. これを何回も繰り返そう

モンテカルロ法では、1回だけではなく、たくさん試すことが大切です。

for文を使って、1000回くり返してみましょう。

最後に、点を打った状況が表示されます。

import matplotlib.pyplot as plt

count = 0
n = 1000

x_inside = []
y_inside = []
x_outside = []
y_outside = []

for i in range(n):
    x = random.random()
    y = random.random()

    if x**2 + y**2 <= 1:
        count += 1
        x_inside.append(x)
        y_inside.append(y)
    else:
        x_outside.append(x)
        y_outside.append(y)

print("円の内側に入った数 =", count)

# グラフ表示
plt.figure()
plt.scatter(x_inside, y_inside)
plt.scatter(x_outside, y_outside)

# 円の輪郭を描画(中心(0,0)、半径1の1/4円)
circle = plt.Circle((0, 0), 1, fill=False)
plt.gca().add_patch(circle)

plt.gca().set_aspect('equal', adjustable='box')
plt.title("Monte Carlo Simulation")
plt.xlim(0, 1)
plt.ylim(0, 1)

plt.show()

5. π を求めよう

1/4円の中に入った点の割合は だいたい π/4 に近づきます。

そこで 次の式で π を求めます。

π ≒ 4 × count ÷ n

count = 0
n = 1000

for i in range(n):
    x = random.random()
    y = random.random()

    if x**2 + y**2 <= 1:
        count += 1

pi = 4 * count / n
print("πの近似値 =", pi)

実行するたびに少しずつ違う値になることを確認しましょう。

6. 試行回数を変えてみよう

次に、試行回数「n」を変えて、結果を比べてみましょう。

たとえば、100回 1000回 10000回で比べます。

for n in [100, 1000, 10000]:
    count = 0

    for i in range(n):
        x = random.random()
        y = random.random()

        if x**2 + y**2 <= 1:
            count += 1

    pi = 4 * count / n
    print("試行回数", n, "回のときのπ =", pi)

(結果は意図的に隠しています)

試行回数が増えるほど「3.14」に近づきやすくなることを確認しましょう。

試行回数を増やしたら、本当に3.14に近づいてきました。

少ない回数だと、結構ばらつくんだね。

これが、モンテカルロ法で回数を重ねることが大切な理由です。

問題1

n=100の時のπの値を答えてください。

実行するたびに違う値が出ると思いますが、どの時のものでも構いません。

問題2

n=1000の時のπの値を答えてください。

実行するたびに違う値が出ると思いますが、どの時のものでも構いません。

問題3

n=10000の時のπの値を答えてください。

実行するたびに違う値が出ると思いますが、どの時のものでも構いません。

問題4

試行回数を増やすと どのような変化が見られましたか。その理由も考え、文章で説明してください。

最大 200 文字

モンテカルロ法では、ランダムな試行を何度も行い、その結果の割合から値を近似します。

今回の実習では、Pythonを使って点をたくさん打ち、円の内側に入る割合から π を求めました。

このように、数式だけでは求めにくい問題でも、コンピュータを使って近似的に調べることができます。

モンテカルロ法は、確率やシミュレーションの分野で広く活用されています。

※この再現版では提出は行いません(送信先は未接続です)

Well done!

次のステップに進みましょう!

次のステップに進む

← 前のステップにもどる