C言語のrand関数は乱数としての性能が良くないということで、C++の乱数ライブラリを使うことにした。
しかし、これがややこしくて難しい。ということで、自分用にメモ。
乱数のときに良く聞くメルセンヌ・ツイスタは
std::mt19937 mt(0x1234); cout << mt() << endl;
で利用できる。引数は初期シード値。これだと初期シードが同じなので毎回同じ乱数となる。省略しても同じ。得られる値は32ビットの符号なし整数。
std::random_device rnd; std::mt19937 mt(rnd());
実行するたびに変わるようにするには、初期シード値に非決定的な乱数生成器で生成した値を指定する。
std::random_deviceはハードの状態や時刻を使うものらしい。これを使って乱数を取得しても良いのだが、動作が重いので、std::mt19937のような決定的な乱数生成器を使う。
乱数の範囲を指定したい場合は、整数の場合は std::uniform_int_distribution, 浮動小数点数の場合は std::uniform_real_distribution を使う。
実際に試してみたコードがこちら。
#include <iostream> #include <random> using namespace std; int main(void){ std::random_device rd; std::mt19937 mt(rd()); std::uniform_int_distribution<> dist_int(1,6); std::uniform_real_distribution<> dist_float(-1.f,1.f); for(int i=0; i<10; i++) { cout << mt() << endl; cout << dist_int(mt) << endl; cout << dist_float(mt) << endl; } }
とりあえず、一応使えるようにはなったけど、もっと正しいやり方とかあるのかもしれない。乱数は奥が深くて大変。