疑似乱数, モンテカルロ法によるシミュレーション

Slides:



Advertisements
Similar presentations
プログラミング演習( 2 組) 第 9 回
Advertisements

情報処理演習 (9)グラフィックス システム科学領域 日浦 慎作.
プログラミング演習(1組) 第7回
プログラミング論 数値積分
解答 1 複素数を構造体として定義し、二つの複素数の積(結果は複素数)を返す 関数 を定義せよ。
解析的には解が得られない 方程式を数値的に求める。 例:3次方程式
基礎プログラミングおよび演習 第9回
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
第2回ネットワークプログラミング 中村 修.
P129 モンテカルロ シミュレーション 乱数を使ったシミュレーション.
C言語講座 第4回 ポインタ.
第5回C言語講座 ~ポインタと配列.
関数 関数とスタック.
精密工学科プログラミング基礎Ⅱ 第3回資料 今回の授業で習得してほしいこと: 2次元配列の使い方 (前回の1次元配列の復習もします.)
構造体 構造体, 構造体とポインタの組み合わせ,.
第7回 条件による繰り返し.
C言語講座 第3回 ポインタ、配列.
プログラミング演習 バージョン1 担当教員:綴木 馴.
岩村雅一 知能情報工学演習I 第11回(後半第5回) 岩村雅一
繰り返し計算 while文, for文.
関数と配列とポインタ 1次元配列 2次元配列 配列を使って結果を返す 演習問題
Cプログラミング演習.
数値積分.
関数の定義.
Cプログラミング演習 第7回 メモリ内でのデータの配置.
第10章 これはかなり大変な事項!! ~ポインタ~
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
高度プログラミング演習 (03).
知能情報工学演習I 第12回(後半第6回) 課題の回答
今までの練習問題の復習.
前回の練習問題.
第7回 条件による繰り返し.
岩村雅一 知能情報工学演習I 第10回(後半第4回) 岩村雅一
四則演算,変数 入力文,出力文,代入文, ライブラリ関数
復習 2次元配列 4列 j = 0 j = 1 j = 2 j = 3 i = 0 i = 1 i = 2 3行
C言語講座第二回 2017 分岐とループと乱数.
岩村雅一 知能情報工学演習I 第11回(後半第5回) 岩村雅一
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
2分法のプログラム作成方法 2分法のプログラム(全体構成) プログラム作成要領 2分法のメイン関数(変数宣言)
整数データと浮動小数データ.
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
ソフトウェア制作論 平成30年10月10日.
メモリとメモリアドレス, ポインタ変数,関数へのポインタ渡し
C言語 はじめに 2016年 吉田研究室.
プログラミング序論演習.
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
プログラミング序論演習.
IF文 START もしも宝くじが当たったら 就職活動する 就職活動しない YES END NO.
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
ファイルの読み込み, ファイルからのデータの取り出し, ファイルの書き出し
11.1 標準ライブラリ関数 11.2 関数呼び出しのオーバーヘッド 11.3 大域変数 11.4 プロトタイプ宣言 11.5 関数引数
高度プログラミング演習 (11).
プログラミング基礎演習 第4回.
cp-15. 疑似乱数とシミュレーション (C プログラミング演習,Visual Studio 2019 対応)
cp-3. 計算 (C プログラミング演習,Visual Studio 2019 対応)
Cプログラミング演習 ニュートン法による方程式の求解.
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
岩村雅一 知能情報工学演習I 第10回(後半第4回) 岩村雅一
第7章 そろそろ int 以外も使ってみよう! ~データ型 double , bool~
四則演算,変数 入力文,出力文,代入文, ライブラリ関数
プログラミング入門2 第3回 条件分岐(2) 繰り返し文 篠埜 功.
第2章 数値の入力と変数 scanfと変数をやります.
知能情報工学演習I 第9回(後半第3回) 課題の回答
計算技術研究会 第5回 C言語勉強会 関数(function)を使う
C言語講座第5回 2017 構造体.
C言語講座 四則演算  if ,  switch 制御文.
分岐(If-Else, Else if, Switch) ループ(While, For, Do-while)
プログラミング演習I 補講用課題
第13章 構造体 講習最後だよ!.
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
Presentation transcript:

疑似乱数, モンテカルロ法によるシミュレーション 疑似乱数とシミュレーション 疑似乱数, モンテカルロ法によるシミュレーション

本日の内容 例題1.疑似乱数 例題2.ランダムウオーク 例題3.じゃんけんゲーム 例題4.モンテカルロ法による数値積分

今日の到達目標 疑似乱数を使ったプログラムを理解する 疑似乱数を使ったシミュレーションを理解する

例題1.疑似乱数 疑似乱数を表示するプログラムを作る. 疑似乱数の表示を,10回繰り返すこと 疑似乱数を発生させるために,srand 関数と rand 関数を使うこと.

疑似乱数のシード の設定 疑似乱数の発生 #include <stdio.h> #include <stdlib.h> #include <time.h> int main() { int i; int x; srand( (unsigned int) time(NULL) ); for ( i = 0; i < 10; i++ ) { x = ( (double)rand() / (RAND_MAX+1) ) * 10; printf( "x=%d\n", x ); } return 0; 疑似乱数のシード の設定 疑似乱数の発生

実行結果例 x=3 x=1 x=8 x=4 x=6

疑似乱数 i = 0 i < 10 i++ srand( (unsigned int) time(NULL) ); Yes No x = ( (double)rand() / (RAND_MAX+1) ) * 10; printf( "x=%d\n", x ); i++

プログラムとデータ メモリ ② ① x 疑似乱数の発生 printf( "x=%d\n", x ); 表示 X = ( (double)rand() / (RAND_MAX+1) ) * 10; 疑似乱数の発生 printf( "x=%d\n", x ); 表示

疑似乱数 rand 関数は疑似乱数(pseudo-random number)を発生させるためのライブラリ関数. 発生される数は,0からRAND_MAXの間の値をとる. RAND_MAX は,rand 関数で発生する疑似乱数(pseudo-random number)の最大値を表す

疑似乱数のシード(seed) srand 関数は,rand 関数で発生させる疑似乱数(pseudo-random number)の系列を設定するためのライブラリ関数. 疑似乱数の系列は,srand 関数の引数 seed によって変化する. rand 関数は,シードの設定を行わないと,同じ系列の疑似乱数を返す.

疑似乱数のまとめ srand 関数,rand 関数の使用では, #include <stdlib.h> が必要 疑似乱数の範囲: 0からRAND_MAX 疑似乱数の型:  整数データ rand関数を実行するたびに,新しい疑似乱数が返される srand 関数 rand 関数は,ある決められた初期値(「シード」という)から,疑似乱数を計算する プログラムの実行のたびに,シードを変えて,違う疑似乱数を発生させるために,srand 関数を用いる

例題2.ランダムウオーク ランダムウオークのプログラムを作る. 「酔っ払い」が歩いている 「酔っ払い」には記憶がない 「酔っ払い」は確率0.5で右に,確率0.5で左に歩く 道の幅は11メートル,1歩は1メートルとし,最初,酔っ払いは道の中央にいる.道幅を超えたら終わり

疑似乱数のシード の設定 疑似乱数の発生 #include <stdio.h> #include <stdlib.h> #include <time.h> void print( int n ) { int i; for ( i = 0; i < n; i++ ) { printf( " " ); } printf( "*\n" ); int main() int n = 5; srand( (unsigned int) time(NULL) ); while ( ( n >= 0 ) && ( n <= 10 ) ) { print( n ); if ( ( (double)rand() / (RAND_MAX+1) ) < 0.5 ) { n++; } else { n--; return 0; 疑似乱数のシード の設定 疑似乱数の発生

実行結果例 *

0 1 2 3 4 5 6 7 8 9 10 道幅11メートル

課題1.ランダムウオーク結果集計 例題2の「ランダムウオーク」を1000回繰り返して,「平均で何歩歩いたかを求めるプログラム」を作りなさい 「小数付きのデータ」を扱うために、浮動小数(double)を使うこと 各繰り返しにおいて 「n = 5;」を実行すること

例題3.じゃんけんゲーム じゃんけんを行うプログラム 0: パー 1: グー 2: チョキ 0: パー 1: グー 2: チョキ じゃんけんの勝負の判定のために,2次元配列を用いる

疑似乱数のシード の設定 疑似乱数の発生 #include <stdio.h> #include <stdlib.h> #include <time.h> int main() { int x; int y; int hantei[3][3] = { {0, 1, -1}, {-1, 0, 1}, {1, -1, 0}}; char jk[3][20] ={ "パー", "グー", "チョキ" }; srand( (unsigned int) time(NULL) ); do { y = ( (double) rand() / (RAND_MAX+1) ) * 3; printf( "\n" ); printf( "じゃんけん (0:%s,1:%s,2:%s,3:やめる)\n", jk[0], jk[1], jk[2] ); scanf( "%d", &x ); switch ( hantei[x][y] ) { case 1: printf( "あなた: %s, 私: %s, あなたの勝ち!うう悔しい\n", jk[x], jk[y] ); break; case 0: printf( "あなた: %s, 私: %s, ひきわけ.もう1度勝負!\n", jk[x], jk[y] ); case -1: printf( "あなた: %s, 私: %s, 私の勝ち!やったあ\n", jk[x], jk[y] ); } } while ( x!= 3 ); return 0; 疑似乱数のシード の設定 疑似乱数の発生

課題2.じゃんけん結果集計 例題3の「じゃんけんプログラム」について,入力されたパー,グー,チョキの回数に関する情報を表示するプログラムを作りなさい パーの次にパー パーの次にグー パーの次にチョキ グーの次にパー グーの次にグー グーの次にチョキ チョキの次にパー チョキの次にグー チョキの次にチョキ

例題4.モンテカルロ法による 数値積分 モンテカルロ法による数値積分を行うプログラムを書く 次の値を読み込むこと 積分区間[a,b] 疑似乱数の発生回数 数値積分を行うべき f(x) は,指数関数 exp(-x) とする (プログラム中に書く)

モンテカルロ法とは モンテカルロ法は,疑似乱数を用いて積分近似値を求める 積分区間[a,b]で f(x) の値が0以上で,かつある値Ymax以下であることが分かっているとき(下図), 1.ランダムな座標の発生(疑似乱数を利用)   a≦x≦b,0≦y≦Ymaxの範囲内でランダムな座標(x,y)を発生 2.関数 f(x) 以下であるのかの判定 関数f(x)以下である座標が総数に占める割合を求める 以上で,矩形の面積(b-a)*Ymaxに乗じることで積分近似値を求める a b x y Ymax f(x)

#include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> double f(double x) { return exp(-x*x); }

積分区間 a, b の読み込み 疑似乱数の発生回数 の読み込み main() { double Ymax = 1.0; double a, b, x, y, S; int i, N, seed, count; printf("積分区間(a~b) : "); printf("a= ? "); scanf("%lf", &a); printf("b= ? "); scanf("%lf", &b); printf("疑似乱数の発生回数 N : "); printf("N= ? "); scanf("%d", &N); 積分区間 a, b の読み込み 疑似乱数の発生回数 の読み込み

ランダムな座標値 (x, y) の発生 積分値の計算 count = 0; for(i = 0 ; i < N ; i++){ srand( (unsigned int) time(NULL) ); count = 0; for(i = 0 ; i < N ; i++){ x = (double)rand() / (RAND_MAX+1) * (b - a) + a; y = (double)rand() / (RAND_MAX+1) * Ymax; if(y < f(x)) { count++; } S = (b - a) * Ymax * count / N; printf("面積 = %lf\n",S); ランダムな座標値 (x, y) の発生 関数 f(x) 以下であるのかの判定 積分値の計算

実行結果の例 f(x) = exp(-x ) 積分範囲(a~b) : 0 1 乱数の個数 : 1000 乱数の種 : 0 2 積分範囲(a~b) : 0 1 乱数の個数 : 1000 乱数の種 : 0 面積 = 0.761000 乱数の個数 : 1000000 面積 = 0.747537 積分範囲(a~b) : 0 1 乱数の個数 : 1000000000 乱数の種 : 0 面積 = 0.746825

課題3.円周率の計算 モンテカルロ法を用いて,円周率を求めなさい

課題3のヒント ① ランダムな座標値 (x, y) をこの正方形内 で発生させる ② 発生させた座標値 がこの円内かどうかを 判定する ① ランダムな座標値 (x, y) をこの正方形内 で発生させる 1 ② 発生させた座標値 がこの円内かどうかを 判定する (円内である確率は,  π/4) 1