第10回は乱数になります。
従来、乱数を使用する場合は
1: #include <iostream> 2: #include <cstdlib> 3: #include <ctime> 4: 5: using namespace std; 6: 7: int main() 8: { 9: //現在時刻に応じたシード値 10: srand((unsigned)time(nullptr)); 11: int cnt = 10; 12: while (cnt) 13: { 14: cout << rand() << endl; 15: cnt--; 16: } 17: 18: return 0; 19: }
srand()及びrand()を使用していましたが、あまり精度のいい乱数とは言えません。
また、int型の値を返すため他の種類に対応させる場合、少し手を加える必要があります。
C++11では乱数のライブラリが実装されており、複数の方法で扱うことが出来ます。
1: #include <iostream> 2: #include <random> 3: 4: using namespace std; 5: 6: int main() 7: { 8: random_device rd;//予測不能な乱数生成器 9: 10: for (int i = 0; i < 3; i++) 11: { 12: cout << rd() << endl; 13: } 14: 15: mt19937 mt(rd());//メルセンヌツイスター 16: 17: for (int i = 0; i < 3; i++) 18: { 19: cout << mt() << endl; 20: } 21: 22: //分布の指定も可能(一様分布) 23: uniform_int_distribution<int> dist1(1, 100);//整数 24: uniform_real_distribution<double> dist2(0.0, 1.0);//浮動小数点 25: 26: for (int i = 0; i < 3; i++) 27: { 28: cout << dist1(mt) << endl; 29: } 30: 31: for (int i = 0; i < 3; i++) 32: { 33: cout << dist2(mt) << endl; 34: } 35: 36: return 0; 37: }
少し書き方は複雑になりますが、覚えてしまえばそこまで大変じゃないです。
乱数の生成方法は
・線形合同法
・メルセンヌツイスター
・RANLUX法
・予測不能な乱数
があります。基本的に使用する場合は長い周期であるメルセンヌツイスターが処理も軽くていいと思います。
また、22行目から先の分布を見ると分かるように、乱数の生成の範囲を決めるときに型に応じて変えることが出来ます。
この分布方法も
・一様分布
・ベルヌーイ分布
・ポワソン分布
・正規分布
等の多用な種類があります。
この乱数生成は従来のrand()を利用したものよりも多用な手法が使え、乱数としての精度も優秀なのでこれから乱数を扱う時はこの<random>を使うようにしましょう。
以上でC++11での乱数についての説明を終わります。
前→C++11講座9回
次→C++11講座11回