C言語関係掲示板

過去ログ

No.134.モンテカルロ法で正規分布のグラフを描く


No.848

誰かおしえてください。
投稿者---リカ(2002/01/16 17:59:00)


学校の課題で次の3つの問題がでたのですが、さっぱりわかりません。できればプログラムの解説(説明)を一行ずつつけてもらえるととても助かります。お願いします。C言語でお願いします。

(1)
乱数を利用する(モンテカルロ計算)
x、yをともに[0,1]区の一様乱数であるとし、乱数の組(x、y)を多数発生させるとこれらの点は一辺の長さが1の正方形内に一様に分布するはずである.このことを利用して、直系の1の円の面積を計算するプログラムを作りなさい。(ヒント:円内に含まれる点の個数と点の総数との比は、円と正方形の面積の比に等しいはずである。)

(2)乱数を利用する(モンテカルロ計算)
平均0、標準偏差1の正規分布に従う乱数を発生するプログラムを書き、実際に1000個の乱数を発生させて、区間[−4、+4]の範囲で度数分布を描け.分布の刻みは0.1にせよ。なおm、標準偏差sの正規分布に従う乱数zは、区間[0,1]の12個の一様乱数x1、x2、x3、・・・・・・、x12を用いて、次のように発生させることができる。
      z=s*(x1+x2+x3+・・・+x12−6)−m

(3)微分方程式の数値解
次の微分方程式を、オイラー法およびルンゲクッタ法により数値積分し、結果を比較せよ。積分のきざみ幅は0.05にせよ。初期値が1.0と5.0の2つの場合について調べ、結果をグラフにせよ。尚、4周期ぐらいは時間の範囲をとること。
     dx/dt=−sinx+sint





No.849

Re:誰かおしえてください。
投稿者---ともじ(2002/01/16 20:26:41)


こんばんは。

>(1)
>乱数を利用する(モンテカルロ計算)
>x、yをともに[0,1]区の一様乱数であるとし、乱数の組(x、y)を多数発生させるとこれらの点は一辺の長さが1の正方形内に一様に分布するはずである.このことを利用して、直系の1の円の面積を計算するプログラムを作りなさい。(ヒント:円内に含まれる点の個数と点の総数との比は、円と正方形の面積の比に等しいはずである。)

過去ログで、「半径1の球の体積(モンテカルロ法)」というのはありますが、
参考になるのでは。


No.850

Re:誰かおしえてください。
投稿者---リカ(2002/01/16 20:38:13)


わかりました。明日学校で試してみます。ありがとうございます。
できれば、あとの2問もお願いいたします。
すいません、無理いっちゃって。

No.860

Re:誰かおしえてください。
投稿者---B.Smith(2002/01/17 19:27:06)


ちょっと言葉が悪いかもしれませんが、決して悪意で言っているのではありませんから、そこの所をご理解ください。

私は数学に弱いので、回答をすることはできませんが、数学のアルゴリズムをプログラムにすることは容易いはずです。このような問題が出題される、ということは、貴方にはそれだけの知識がある、ということのはずです。
よりプログラミングに近い部分で悩んでいる、というのであればお力になれるかもしれませんが、問題理解とプログラミング、そしてステップ毎の説明をする…問題を全部解いて欲しい、と言っていますよね?
回答してくださる方がいるかもしれませんが、ご自分でプログラムを作成された方が良いと思いますよ?恐らく、これらの問題は数学アルゴリズムを理解していることを前提に、プログラミングをする、ということを求めているはずですから、プログラミング自体は簡単なはずです。

これだけで終わると申し訳ないので、浮動小数点演算で1点だけ注意しておきたいことがあります。値の比較をする際、演算結果は必ずイコールになるとは思わないでください。
例.
#include <math.h>

#define MINIMUM        0.00001 /* ゼロと見なせる値 */
    ・
    ・
    ・
    double    A,B;
    ・
    ・
    ・
    if (A == B)                  ×

    if (fabs(A-B) <= MINIMUM)    ○



No.863

Re:誰かおしえてください。
投稿者---taku(2002/01/17 21:10:55)


>一応、自分なりには考えたんですけどわからないのです。
問題をすべてといてもらおうとは思っていません。
なにか解くヒントになるようなアドバイスをいただけたらなっと思っています。
人にたよることはあまりよくないことはわかったいますが、なにかアドバイスをお願いします。


No.862

Re:誰かおしえてください。
投稿者---ともじ(2002/01/17 20:01:40)


こんにちは。

>(2)乱数を利用する(モンテカルロ計算)
>平均0、標準偏差1の正規分布に従う乱数を発生するプログラムを書き、実際に1000個の乱数を発生させて、区間[−4、+4]の範囲で度数分布を描け.分布の刻みは0.1にせよ。なおm、標準偏差sの正規分布に従う乱数zは、区間[0,1]の12個の一様乱数x1、x2、x3、・・・・・・、x12を用いて、次のように発生させることができる。
>      z=s*(x1+x2+x3+・・・+x12−6)−m

上記の指示をそのまま以下のようにプログラムすると、
10個の乱数が発生できるようです。
あとは、これを1000個発生させるようにし、[−4、+4]で刻みは0.1
とのことですので、大きさ81のint型の配列に振り分け、
発生した乱数の個数をカウントし、グラフにすればよいのではないでしょうか。

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
	double z,s=1,m=0,x;
	int i,j;
	
	for (i=1; i<=10; i++) {
		x = 0;
		for (j=1; j<=12; j++) {
			x += (double)(rand()%1000)/1000;
		}
		z = s * (x - 6) - m;
		printf("%f ",z);
	}		
	
	return(0);
}



No.864

Re:誰かおしえてください。
投稿者---taku(2002/01/17 21:12:37)


ともじさんどうもありがとうございます。
無理な質問をしてしまってすいません。

No.866

ちょっと訂正
投稿者---ともじ(2002/01/18 00:00:31)


> x += (double)(rand()%1000)/1000;

ここは、

x += (double)rand()/RAND_MAX;

の方がいいですね。


No.870

ちょっと補足
投稿者---kikk(2002/01/18 11:06:30)


ども。


もし、非標準関数のdrand()ないしdrand48()という関数が使えるならば、

>x += (double)rand()/RAND_MAX;

の右辺はそれでおきかえてもいいかも。ただし、この関数は、[0,1]ではなく
[0,1)のdoubleの乱数を返すので、厳密にはちょっと元と違っちゃいますが。。


なお、学校で習う程度の数値解析のおはなしはサーチエンジンで検索すれば
(たぶんソースコード込みで)みつかります。


では。

戻る


「初心者のためのポイント学習C言語」 Last modified:2002.02.03
Copyright(c) 2000-2002 TOMOJI All Rights Reserved