モンテカルロ法シミュレーター
モンテカルロ法は、乱数で試行を繰り返し、条件を満たした割合から答えを近似する方法です。 正方形に点を打ち、円の内側に入った割合から円周率が求まっていく様子を確認できます。
動きを1ステップずつ確認する
- 円の内側
- 円の外側
- いま打った点(枠つき)
パソコンではキーボードでも操作できます:→ 次へ / ← 前へ / スペース 再生・一時停止
実行ログを見る(ここまでの処理)
ALGORITHM
モンテカルロ法とは何をしているか
モンテカルロ法は、乱数を使った試行をたくさん繰り返し、その結果の割合から答えを見積もる方法です。 数式で正確に解くのが難しい問題でも、「たくさん試して数える」だけで答えに近い値が得られます。 名前はカジノで有名なモナコの地区名から来ています。
円周率を求める例では、次の3つを繰り返すだけです。
- 乱数で点を1つ作る(x と y をそれぞれ 0以上1未満の乱数にする)
- 円の内側かどうか判定する(
x × x + y × y <= 1なら内側) - 内側なら数える(inside を1増やす)
なぜ4倍すると円周率になるのか
1辺が1の正方形の面積は 1 です。その正方形に収まる半径1の四分円(円の4分の1)の面積は π ÷ 4 です。点が正方形全体にまんべんなく散らばるなら、 円の内側に入る点の割合は、面積の比 π/4 に近づくはずです。
つまり inside ÷ trial ≒ π ÷ 4 なので、両辺を4倍して
π ≒ 4 × inside ÷ trial となります。これがコードの最後の式です。
シミュレーターの「いまの近似値」は、この式をその時点までの結果で計算したものです。
平方根を使わない判定
本来、原点から点までの距離は √(x² + y²) です。「距離が1以下」を確かめるには平方根が必要に見えますが、
両辺を2乗しても大小関係は変わらないため、x × x + y × y <= 1 と書けます。
計算が簡単になるうえ、平方根の関数を使わずに済みます。この書き換えはよく問われます。
試行回数を増やすとどうなるか
シミュレーターは20回までは1試行ずつ、それより多いときはまとめて進みます。試行回数を 10 → 100 → 1000 と切り替えてみてください。 回数が少ないうちは近似値が 2.8 や 3.6 のように大きくぶれますが、回数を増やすと 3.14 前後に落ち着いていくことが分かります。
ここで使う「乱数」とは
乱数とは、次にどの値が出るか決まっていない数のことです。ただしコンピュータが作る乱数は、 実際には計算式で作られた「擬似乱数」で、見かけ上ばらばらに見えるだけです。 そのため「同じ出発点(シード)を与えれば同じ並びが再現できる」という性質を持ちます。
情報Ⅰでは「0以上1未満の乱数」という書き方がよく出ます。ここで1が含まれない点が大切です。
たとえばサイコロを作るなら 整数部分(乱数 × 6) + 1 と書きます。
1が含まれてしまうと 7 が出る可能性が生まれるため、範囲の指定は必ず確認してください。
試行回数と精度の目安
実際にどのくらいの精度になるのか、目安を持っておくと問題文の判断が速くなります。
| 試行回数 | よくある結果の範囲 | 小数第何位まで信頼できるか |
|---|---|---|
| 10 回 | 2.0 〜 4.0 | 整数の桁すら怪しい |
| 100 回 | 2.9 〜 3.4 | おおよそ「3」と分かる程度 |
| 1,000 回 | 3.05 〜 3.25 | 小数第1位(3.1)くらい |
| 100,000 回 | 3.135 〜 3.150 | 小数第2位(3.14)くらい |
10倍にしても1桁ぶんの精度は増えません。 誤差が試行回数の平方根に反比例するため、1桁増やすには回数を100倍にする必要があります。 シミュレーターで10回と1000回を交互に試すと、この差を実感できます。
他にどんなことに使えるか
面積や体積の見積もり、待ち時間の予測、ゲームの勝率の見積もりなど、「実際に何度も試してみないと分からない」問題全般に使えます。 共通テストでは、円周率のほかに複雑な図形の面積を求める題材で出題されることがあります。 考え方は同じで、「図形を囲む長方形に点を打ち、図形の内側に入った割合 × 長方形の面積」で求められます。
CODE
3つの書き方で見るモンテカルロ法
inside = 0 trial = 1000 i を 1 から trial まで 1 ずつ増やしながら繰り返す: |x = 0以上1未満の乱数 |y = 0以上1未満の乱数 |もし x × x + y × y <= 1 ならば: ⎿⎿ inside = inside + 1 pi = 4 × inside ÷ trial 表示する(pi)
import random
inside = 0
trial = 1000
for i in range(trial):
x = random.random()
y = random.random()
if x * x + y * y <= 1:
inside = inside + 1
pi = 4 * inside / trial
print(pi)
let inside = 0;
const trial = 1000;
for (let i = 0; i < trial; i++) {
const x = Math.random();
const y = Math.random();
if (x * x + y * y <= 1) {
inside = inside + 1;
}
}
const pi = (4 * inside) / trial;
console.log(pi);
÷ は整数どうしだと切り捨てになる場合があります。
円周率のように小数で答えを出したいときは、4 × inside のように先に掛けてから割る、
または小数として計算することを明示します。Python では /(小数の割り算)と //(切り捨て)が別なので、
/ を使う点に注意してください。
EXAM POINT
共通テスト「情報Ⅰ」での出題ポイント
- 判定の条件式:
x × x + y × y <= 1の空欄。平方根を使わない形に書き換えられている点が要点です。 - 最後の式:
pi = 4 × inside ÷ trialの「4」がどこから来たのか。面積の比 π/4 から説明できるようにします。 - 近似であること:「この方法の特徴として正しいものを選べ」という形。厳密解ではなく近似、実行のたびに結果が変わるが答えになります。
- 試行回数と精度:「回数を増やすとどうなるか」。真の値に近づきやすくなるが、必ず近づくとは限らない点に注意します。
- 他の図形への応用:正方形以外の範囲に点を打つ場合の式。「割合 × 全体の面積」で求めます。
MISTAKES
よくある間違い
| 間違い | 何が起きるか | 正しくは |
|---|---|---|
| 4 を掛け忘れる | 0.785 前後(π/4)になる | 面積比が π/4 なので4倍する |
| inside の初期化を忘れる | 数え始めの値が定まらない | 繰り返しの前に inside = 0 とする |
| 条件を < 1 と書く | ちょうど円周上の点を外側と数える | <= 1(境界を含む)にする |
| 毎回同じ答えになると思う | 「近似」という性質を答えられない | 乱数なので実行のたびに変わる |
| 回数を増やせば必ず正確になると思う | 「必ず」を含む選択肢を選んでしまう | 近づきやすくなるだけで保証はない |
CHECK
理解度チェック
Q1. 1000回試行して、円の内側に入った点が 785 個でした。円周率の近似値はいくつですか。
4 × 785 ÷ 1000 = 3.14 です。割合 0.785 がそのまま π/4 に対応しているので、4倍すると π の近似値になります。
Q2. 同じプログラムを2回実行すると、同じ結果になりますか。
Q3. 判定を x × x + y × y <= 1 ではなく x + y <= 1 にすると、何を求めることになりますか。
x + y <= 1 は直線より下の領域、つまり直角二等辺三角形の内側を表します。
その面積は 0.5 なので、割合は 0.5 に近づきます。条件式を変えると調べる図形が変わるという点が要点です。