のんびりしているエンジニアの日記

ソフトウェアなどのエンジニア的な何かを書きます。

C++ 乱数生成(rand関数・実際の分布はどうなのか)

Sponsored Links

皆さんこんにちは
お元気ですか?私は絵を描く練習をしようかなって考えてたり

さて、本日は乱数生成について

プログラム組む時、乱数を生成する機会は沢山あると思います。
C++の乱数を見て行きましょう。

C++の乱数実行は?

あまり使わないほうがいいとの評判が高いrandを使っています。
線形合同法と呼ばれるアルゴリズムを利用しており、なんか分布が一様でないらしいです。

#include <stdlib.h>
#include <iostream>

using namespace std;

int main(void){
	srand(10);
	for(int i = 0; i < 100; i++){
		cout << rand() << endl;
	}
}

srandで乱数のシードを初期化し、ランダムを生成する関数を呼び出します。
逆に言い換えるとsrandで初期化しないと一様なのでプログラムのチェックには利用できます。

ところで巷では線形合同法では一様ではないと流れていますが本当でしょうか

いやね。ほらやってみたくなるでしょう。

実際にやってみよう(本当に一様ではないのか)

実験

実験内容

0〜999までの乱数を生成し、ヒストグラムを組む。
10000000回の乱数生成を行った

ソースコード

#include <stdlib.h>
#include <iostream>

using namespace std;

int main(void){
	srand(10);
	int array[1000] = {0};
	for(int i = 0; i < 100000000; i++){
		array[0 + (int)( rand() * (999 - 0 + 1.0) / (1.0 + RAND_MAX))]++;
	}

	for(int i = 0; i < 1000; i++){
		cout << i << " " << array[i] << endl;
	}
	return 0;
}

結果

kenf:id:tereka:20140614200114p:plain

評価

評価には大変困るのですが
一様と言うほど、一様と言い切れない…。誤差といえば誤差の範囲という気がするが…。
厳密なものと比較することが今後必要かもしれない。

参考文献

乱数