サンプル・プログラム:実行例
サンプル・プログラム
| montecarlo.php | サンプル・プログラム本体 |
| pahooInputData.php | データ入力に関わる関数群。 使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。 |
| バージョン | 更新日 | 内容 |
|---|---|---|
| 1.3.0 | 2026/04/05 | PHP8.5対応, pahooInputData.php導入 |
| 1.2.0 | 2023/01/08 | getRandomDot()改良--PHP8.2対応 |
| 1.1 | 2022/04/29 | PHP8対応,リファラ・チェック改良 |
| 1.0 | 2019/12/07 | 初版 |
| バージョン | 更新日 | 内容 |
|---|---|---|
| 2.0.1 | 2025/08/11 | getParam() bug-fix |
| 2.0.0 | 2025/08/11 | pahooLoadEnv() 追加 |
| 1.9.0 | 2025/07/26 | getParam() 引数に$trim追加 |
| 1.8.1 | 2025/03/15 | validRegexPattern() debug |
| 1.8.0 | 2024/11/12 | validRegexPattern() 追加 |
モンテカルロ法とは
中性子の運動を探るためにアメリカの数学者スタニスワフ・ウラムが考案し、コンピュータの父フォン・ノイマンが、カジノで有名なモナコ公国の地区の名前をとって命名した。
正方形の紙に円が描かれていたとする。ここで、正方形の中にランダムに点を打ち、円の中に入っているかどうかで場合分けるとする。
式3に式1,2を代入して変形すると、 $$ \displaystyle \begin{align*} \pi = \frac{4N_{in}}{N_{in} + N_{out}} \tag{4} \end{align*} $$
これをPHPプログラムで組んだのが "montecarlo.php" である。計算を簡単にするため、円を4分の1に切り取って行っている。打つ点の数を10万個以上にすると、だいぶ円周率に近くなってくる。
準備:初期値
montecarlo.php
51: // TrueTypeフォント・ファイル;各自の環境に合わせて要変更
52: define('FILE_FONT', '../../../../common/font/ipagp.ttf');
53:
54: // 初期値
55: define('COUNT', 100000); // 試行回数
56: define('WIDTH', 500); // 直径(ドット)
57: define('COLOR_IN', 'FF0000'); // 描画カラー:円周の内側
58: define('COLOR_OUT', '0000FF'); // 描画カラー:円周の外側
59: define('COLOR_STR', '00FF00'); // 描画カラー:円周率
60: define('SIZE_STR', 30); // 描画サイズ:円周率
FILE_FONT には、円周率の値を描画するために必要となるTrueTypeフォント・ファイルを、プログラムを配置したパスから見た相対パスで記述する。
描画カラーは、RGBの16進表記である。
ランダムな点座標
montecarlo.php
114: /**
115: * ランダムな点座標を1つ返す
116: * @param なし
117: * @return array(float, float) 座標
118: */
119: function getRandomDot() {
120: // PHP8.2以上はRandom\Randomizerを使う
121: if (isPHPversion(8, 2)) {
122: $n = 100000000;
123: $random = new Random\Randomizer();
124: $x = (float)$random->getInt(0, $n) / $n;
125: $y = (float)$random->getInt(0, $n) / $n;
126: $random = NULL;
127: // PHP8.2未満はmt_randを使う
128: } else {
129: $x = mt_rand() / mt_getrandmax();
130: $y = mt_rand() / mt_getrandmax();
131: }
132:
133: return array($x, $y);
134: }
なお、乱数ジェネレーター問題を解決したPHP8.2以上では、Random\Randomizer クラスを使って乱数を求めるようにした。
ポイントを返す
montecarlo.php
136: /**
137: * ポイントを返す
138: * @param $image = 画像リソースID(省略時はピクセル描画しない)
139: * @return int ポイント
140: */
141: function getPoint($image=NULL) {
142: list($x, $y) = getRandomDot();
143: $res = sqrt(($x * $x) + ($y * $y)) <= 1 ? 1 : 0;
144:
145: if ($image != NULL) {
146: $color = ($res == 1) ? COLOR_IN : COLOR_OUT;
147: $arr = color2rgb($color);
148: $color = imagecolorallocate($image, $arr[0], $arr[1], $arr[2]);
149: imagesetpixel($image, (int)($x * WIDTH), (int)(WIDTH - $y * WIDTH), $color);
150: }
151: return $res;
152: }
また、引数に画像リソースIDが指定されていれば、キャンパスに点を描画する。
ポイントを集計する
montecarlo.php
154: /**
155: * ポイントを集計する
156: * @param int $n 試行回数
157: * @param $image = 画像リソースID(省略時はピクセル描画しない)
158: * @return int 集計ポイント
159: */
160: function sumPoints($n, $image=NULL) {
161: $res = 0;
162: for ($i = 0; $i < $n; $i++) {
163: $res += getPoint($image);
164: }
165:
166: return $res;
167: }
メイン・プログラム
montecarlo.php
169: // メイン・プログラム ======================================================
170: $n = getParam('n', FALSE, COUNT); // 試行回数
171:
172: $image = @imagecreatetruecolor(WIDTH, WIDTH);
173: imagesavealpha($image, TRUE);
174:
175: // モンテカルロ法で円周率を求める
176: $res = sprintf('%.4f', 4 * sumPoints($n, $image) / $n);
177:
178: $arr = color2rgb(COLOR_STR);
179: $color = imagecolorallocate($image, $arr[0], $arr[1], $arr[2]);
180: $font = dirname(__FILE__) . '/' . FILE_FONT; // パスの通し方に注意
181: imagettftext($image, SIZE_STR, 0, 10, SIZE_STR + 10, $color, $font, $res);
182:
183: header('Content-type: image/png'); // MIMEはPNGで
184: imagepng($image); // ブラウザ表示
185: // PHP8.5:非推奨関数
186: if (PHP_VERSION_ID < 80500) {
187: imagedestroy($image); // 後処理
$res の値はキャンパスで描画するのだが、ここでフォント・ファイルへのパスの通し方に注意が必要だ。

(2026年4月5日)PHP8.5対応, pahooInputData.php導入