C++11 に新たな乱数生成ライブラリ!?
Sponsored Links
皆さんこんにちは
お元気ですか。私は元気です。
さて、今日は乱数について
C++11では新たに乱数を生成するライブラリが追加されています。
一様分布を作るとき、以前まで線形合同法で作成されていたのが、このライブラリではメルセンヌ・ツイスターなど選択ができるようになっています。
一様分布の例
void uniform(){ random_device rd; mt19937 gen(rd()); std::uniform_int_distribution<> dis(1, 6); for(int n=0; n<10; ++n){ std::cout << dis(gen) << " "; } std::cout << endl; }
コード
3 3 5 6 4 6 1 4 5 2
解説
random_deviceは非決定的な乱数を生成するそうです。要は適当な乱数を作ってくれます。
これはseed(乱数生成の計算の変数)に入れる内容です。
std::mt19937 gen(rd()); らんだむに生成した値をseedとして利用しています。
(mtはメルセンヌ・ツイスター)
因みにここに何も入れずに生成すると毎回同じ順番で同じ値を生成します。
これを元にして乱数を生成する流れとなっています。
正規分布
コード
void normal_dist(){ //正規分布 random_device rd; mt19937 gen(rd()); normal_distribution<> d(5,2); //平均5,分散2 map<int, int> hist; for(int n=0; n<10000; ++n) { ++hist[round(d(gen))]; } for(auto p : hist) { cout << fixed << setprecision(1) << setw(2) << p.first << ' ' << string(p.second/200, '*') << '\n'; } }
出力
-3 -2 -1 0 1 * 2 *** 3 ****** 4 ******** 5 ********* 6 ******** 7 ***** 8 *** 9 * 10 11 12 13
ボアソン分布
コード
void poison(){ //ポアソン分布 random_device rd; mt19937 gen(rd()); poisson_distribution<> d(4); map<int, int> hist; for(int n=0; n<10000; ++n) { ++hist[d(gen)]; } for(auto p : hist) { cout << p.first << ' ' << string(p.second/100, '*') << '\n'; } }
出力
0 * 1 ******* 2 ************** 3 ******************* 4 ******************* 5 *************** 6 ********** 7 ****** 8 *** 9 * 10 11 12 13 14
ベルヌーイ分布
コード
void bernoulli(){ random_device rd; mt19937 gen(rd()); bernoulli_distribution d(0.25); //Trueが出る確率 map<bool, int> hist; for(int n=0; n<10000; ++n) { ++hist[d(gen)]; } for(auto p : hist) { cout << boolalpha << setw(5) << p.first << ' ' << string(p.second/500, '*') << '\n'; } }
出力
false *************** true ****
これらを見るとわかると思いますが、基本的な流れは
①random_deviceオブジェクトの生成
②乱数を作る
③乱数を元に表示させたい分布の乱数を生成する
です。