• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:モンテカルロ法の面積近似)

モンテカルロ法の面積近似

このQ&Aのポイント
  • 線形合同法を使った乱数発生方法が誤っているため、面積の近似がうまくいきません。
  • 領域a = {(x,y)|x≧1,y≧2,(x-1)^2 + (y-2)^2 ≦1}の面積を計算するプログラムを作成し、n=10000の場合の面積と円周率πの近似値を求めたい。
  • 乱数を発生させる関数random_gの乱数発生方法が間違っています。

質問者が選んだベストアンサー

  • ベストアンサー
  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.3

正しいかどうかよくわからないのですが、こんな感じなのでしょうか。 求める面積は(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; } (注)インデントのため、全角空白を使っています。

apple_cube
質問者

お礼

ありがとうございます! 参考になりました!! でも、 /*乱数を発生させる関数*/ unsigned long random_g としているので、乱数はrandom_g内で発生させたいのですが、 それは無理ですか??(T_T)

その他の回答 (3)

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.4

> unsigned long random_g > としているので、乱数はrandom_g内で発生させたい random_g()の中で、前回発生させた乱数(x0)をもとに、 所定のパラメータ(a, c)を用いて新しい乱数(returnする値)を 発生させています。

apple_cube
質問者

お礼

そうですねっっ!! 勘違いしてたみたいです。。 ありがとうございました(^_^)

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.2

> 領域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は特に必要ないと思います。

apple_cube
質問者

補足

確かにそうですね(^_^;)

  • rabbit_cat
  • ベストアンサー率40% (829/2062)
回答No.1

まずは、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さんが何を考えてそうなっていたのか意図をつかみかねているので、もしかしたら、方向違いの回答になっているかもしれません。

apple_cube
質問者

お礼

ありがとうございます!! 4*a*n+1は乱数の数が近くてどうすれば全然関係なくなるのか 考えて色々試していた残骸です…(^_^;) それで、x0をグローバルか変数にしたのですが、答えがやはり2と4になってしまいました(>_<)

関連するQ&A