サンプルプログラム1−4
・モンテカルロ法とは、乱数を使って統計的に解を求める手法である。ここでは、円周率(π)求めるプログラムを説明する。
・原点を中心として半径1の円を考える。平面上の点(x,y)をランダムに求め、座標が円の内にある個数(count_in)と外にある個数(count_out)をカウントします。
・求めた座標の中で内にあった個数から円周率(π)を求めます。円内にある確率は、π/4となります。
π≒ 4 * count_in / (count_in + count_out )
・点の数が少ないと誤差が大きいですが、発生数を多くすると正しい値に近づきます。
■この問題は「オイラーの贈物」(吉田武著、2010年、東海大学出版会)の中にあった、
例題(BASICで解法ある)をCで書いてみました。
1)srand・・・乱数の種を設定する。
void srand(unsigned seed);
使用例
time_t t;
srand((unsigned) time(&t));
2)rand・・・(0 〜 RAND_MAX) の範囲で乱数を発生させる。
(RAND_MAX は,stdlib.h で定義されています)
使用例
int rand(void);
@sample_104.c
// -------------------------------------------------
// モンテカルロ法によるπの計算
// 2023/08/22 Kimio Nakamura
// -1.0 〜 1.0で 座標(x , y) をランダムに出し、
// X^2 + y^2 ≦ 1 の確率計算を行う。
// -------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main( void )
{
time_t t;
long i , max;
double x, y;
long count_in , count_out;
while(1){
count_in = 0L;
count_out = 0L;
fprintf(stdout ,"回数を入力してください(終了=99):");
scanf( "%ld", &max );
if(max == 99) break;
srand((unsigned int) time(&t));
for( i = 0L ; i < max ; i++){
x = (double) rand() / ( (double) RAND_MAX / 2 ) - 1.0;
y = (double) rand() / ( (double) RAND_MAX / 2 ) - 1.0;
if((x*x+y*y) < 1.0) count_in++;
else count_out++;
}
fprintf(stdout ,"max =%ld in = %ld out = %ld pi = %lf \n\n",
max , count_in , count_out ,
4*(double)count_in/ (double)(count_in+count_out));
}
return 0;
}
Aコンパイル結果

B実行結果
回数を様々入力して、πの試算を行っています。徐々に近づきますが、なかなか正確な値にはなりません。


|