3753817_s

C++でモンテカルロ法を使って円周率を求めるプログラムを作ったので概要と実装を忘備録として残します。


モンテカルロ法とは


モンテカルロ法とは乱数を用いてシミュレーションや数値計算を行う方法の一つです。

少し前には将棋や囲碁のAIでモンテカルロ法を使うのがブームになりました。

今回はモンテカルロ法を使った例題としてポピュラーな円周率の近似値を求めるという問題を解いていきます。



円周率を求める手順


①正方形内にランダムに点を打つ。今回は正方形の大きさを1×1として(x, y)座標のx, yを0~1の範囲で乱数を使って点を打っていきます。

②生成した点が円の内側にあるか、外側にあるか判定する。内側にある場合はポイントを加算する。

キャプチャ

点が上記の図の青色の範囲内ならポイントを加算するということです。

③上記の①と②の行為をn回繰り返す。試行回数が多いほど円周率が正しい値へと近づいていきます。

④円周率の近似値をもとめる。円周率の近似値は以下の式で求めることができます。

π = 4 × ポイント






実装


#include <iostream>
#include <ctime>
#include <cstdlib>

int main(void){
    int n = 0;
    std::cout << "試行回数を入力してください" << std::endl;
    std::cin >> n;

    // 試行回数が0以下ならエラー
    if (n <= 0){
        return -1;
    }

    // 試行回数分ランダムに点を描画
    std::srand(time(NULL));
    int point = 0;
    double x = 0;
    double y = 0;
    for(int i=0i<n; ++i){
        // ①x, yは0~1の範囲
        x = (double)rand() / 32767;
        y = (double)rand() / 32767;
        // ②
        if (x*x+y*y < 1.0){
            // 円内に点が打たれた場合
            point++;
        }
    }

    // ④円周率を求める
    float pi = 4.0 * point / n;
    std::cout << "pi = " << pi << std::endl;
    
    return 0;
}




実行結果


1000
pi = 3.064

1000000
pi = 3.14275

試行回数が多いほど近似した値になっていることが分かりますね。