- ベストアンサー
モンテカルロ法の面積近似
- 線形合同法を使った乱数発生方法が誤っているため、面積の近似がうまくいきません。
- 領域a = {(x,y)|x≧1,y≧2,(x-1)^2 + (y-2)^2 ≦1}の面積を計算するプログラムを作成し、n=10000の場合の面積と円周率πの近似値を求めたい。
- 乱数を発生させる関数random_gの乱数発生方法が間違っています。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
正しいかどうかよくわからないのですが、こんな感じなのでしょうか。 求める面積は(1, 2)を中心とする半径1の円の4分の1ですから、 円周率の値は面積を4倍しなければなりません。 #include <stdio.h> #include <stdlib.h> #include <math.h> #define N (10000) #define Nx (1) #define Ny (2) /*乱数を発生させる関数*/ unsigned long random_g(unsigned long x0, unsigned long a, unsigned long c); int main(void) { unsigned long x0, a, c; double x, y, s; int n, count_in; printf("x0: "); scanf("%d", &x0); a = 61; c = 49; for (count_in = n = 0; n < N; n++) { /*乱数を発生*/ x0 = random_g(x0, a, c); x = x0 / (double) 4294967296 + Nx; x0 = random_g(x0, a, c); y = x0 / (double) 4294967296 + Ny; if (x >= Nx && y >= Ny && (x-Nx) * (x-Nx) + (y-Ny) * (y-Ny) <= 1) count_in++; } s = (double) count_in / n; printf("s = %f\n", s); printf("pi = %f\n", 4 * s); return 0; } unsigned long random_g(unsigned long x0, unsigned long a, unsigned long c) { return a * x0 + c; } (注)インデントのため、全角空白を使っています。
その他の回答 (3)
- asuncion
- ベストアンサー率33% (2127/6289)
> unsigned long random_g > としているので、乱数はrandom_g内で発生させたい random_g()の中で、前回発生させた乱数(x0)をもとに、 所定のパラメータ(a, c)を用いて新しい乱数(returnする値)を 発生させています。
お礼
そうですねっっ!! 勘違いしてたみたいです。。 ありがとうございました(^_^)
- asuncion
- ベストアンサー率33% (2127/6289)
> 領域a = {(x,y)|x≧1,y≧2,(x-1)^2 + (y-2)^2 ≦1} この定義と > if(x >= 1 && y >= 1 && pow(x-1, 2) + pow(y-2, 2) <= 1) このif文とが一致していませんが、よいのでしょうか? また、このif文の真偽によってcount_inかcount_outの いずれか一方だけをインクリメントするのですから、 count_inとcount_outの和は試行回数nと一致しますよね。 よって、count_outは特に必要ないと思います。
補足
確かにそうですね(^_^;)
- rabbit_cat
- ベストアンサー率40% (829/2062)
まずは、random_gの中でせっかく計算した、x0を覚えておくようにしないといけません。 そうですね。 1 x0をグローバル変数にする。 2 x = (random_g(x0, 4*a*n+1, c) / (double)4294967296)*Nx + 1; を x = (random_g(x0, a, c) / (double)4294967296)*Nx + 1; に変更する。 yについても同様に、4*a*n+1をaに変更する。 とどうでしょうかね。 2で指摘した4*a*n+1ていうのは、apple_cubeさんが何を考えてそうなっていたのか意図をつかみかねているので、もしかしたら、方向違いの回答になっているかもしれません。
お礼
ありがとうございます!! 4*a*n+1は乱数の数が近くてどうすれば全然関係なくなるのか 考えて色々試していた残骸です…(^_^;) それで、x0をグローバルか変数にしたのですが、答えがやはり2と4になってしまいました(>_<)
お礼
ありがとうございます! 参考になりました!! でも、 /*乱数を発生させる関数*/ unsigned long random_g としているので、乱数はrandom_g内で発生させたいのですが、 それは無理ですか??(T_T)