Boost.Random
Chapter 21. Boost.Random - 1.51.0
様々な分布の乱数の生成できる。
C言語標準のrand, srandはグローバル関数となっているが、
Boost Randomでは乱数計算はvariate_generatorオブジェクトでまとまっていている。
C+11で、randomが使えるようになったが、Boost Randomとは少し違う部分がある(variate_generatorがないとか)。
Boost Randomは大別すると、
variate_generator
乱数生成エンジン、
分布、
randomm_number_generator
で形成されているみたい
乱数生成エンジン
ほとんどがテンプレートクラスだけど、通常typedefしたものを使えばいい。
毎回同じ値を出したければ、seedを指定せず、引数なしのコンストラクタを使えばいい。
生成乱数の最大値、最小値はメンバ関数min(), max()を使えば良い。
メモリ使用量は少ないが、遅め.
rand48は、64bit演算を利用して、周期を長くしている
-
- minstd_rand0
- minstd_rand
- rand48
- ecuyer1988
2種類の乱数生成エンジンの差をとる擬似乱数生成エンジン(seedは2つ)。
-
- ecuyer1988
- kreutzer1986
ベースの乱数生成エンジンの出力をランダムシャッフルして疑似乱数を生成するらしい
-
- kreutzer19386
- 逆数合同法
すごく...遅いらしいです...
-
- hellekalek1995
- Ranlux法
周期はだけど、あんま速くないみたいです。
-
- ranlux64_3
- ranlux64_4
- Lagged Fibonacci法
速くて、周期が長いです(短いので, 長いので)。
そのかわりメモリ使用量は多いです。
BSD系のrandomで使われてる方法なんだって。
-
- legged_fibonacci607
- legged_fibonacci1279
- legged_fibonacci2281
- legged_fibonacci3217
- legged_fibonacci4423
- legged_fibonacci9689
- legged_fibonacci19937
- legged_fibonacci23209
- legged_fibonacci44497
- メルセンヌツイスター法
周期ははそこそこ長く( or )、高速。
メルセンヌツイスターってよく聞くけど、日本人が発明したのか...
-
- mt11213b
- mt19937
- 非決定的乱数生成エンジン
boost/notdet_random.hppをインクルードする必要がある。
linux系だと"/dev/urandom"をみて、ハードウェア上のノイズなどから乱数生成してるらしい。
※libboost_random.aをリンクしとく
-
- random_device
とりあえず、困ったらmt19937を使えば良さそう。
seedを入れたいときはrandom_deviceを使えばいいじゃないかな
めんどくさけりゃrandom_deviceだけでもいい気もする。
分布
- 一様分布
min以上、max以下の数を当確率で発生させる.
uniform_smallint<class IntType = int>( IntType min = 0, IntType max = 9 ) //result_type = IntType uniform_int<class IntType = int>( IntType min = 0, IntType max = 9 ) //result_type = IntType uniform_real<class RealType = double>( RealType min = 0, RealType max = 1 ) //result_type = RealTypeType
- ベルヌーイ分布
確率pでtrue, 確率(1-p)でfalseを発生させる
bernoulli_distribution<class RealType = double>( RealType p = 0.5) //result_type = bool
- 二項分布
の整数xを確率で発生させる。
binomial_distribution<class IntType = int, class RealType = double>(IntType t = 1, RealType p = 0.5 ) //result_type = IntType
- 幾何分布
確率で整数xを発生させるらしい. 名前ぐらいしか聞いたことない.
geometric_distribution<class IntType = int, class RealType =double>(RealType p = 0.5) //result_type = IntType
- 三角分布
最小値a, 中心値b, 最大値cの三角分布
triangle_distribution<class RealType = double>(RealType a = 0.0, RealType b = 0.5, RealType c = 1.0) //result_type = RealType
- 指数分布
多分
exponetial_distribution<class RealType = double>(RealType lamdba = 1.0) //result_type = RealType
- ガンマ分布
ガンマ分布 - Wikipediaを読んだ。なるほど、わからん。
gamma_distribution<class RealType = double>(RealType alpha = 1) //result_type = RealType
- ポアソン分布
,
平均すなわちを指定する。
二項分布でとしたやつだっけ?
poisson_distribution<class IntType = int, class RealType = double>( RealType mean = 1 ) //result_type = IntType
normal_distribution<class RealType = double>(RealType mean = 0.0, RealType sigma = 1.0) // result_type = RealType lognormal_distribution<class RealType = double>(RealType mean = 0.0, RealType sigma = 1.0) // result_type = RealType
- コーシー分布
コーシー分布 - Wikipedia
´_ゝ`)フーン
中央値medianとスケールパラメータsigmaを指定するんだってさ。
cauchy_distribution<class RealType = double>(RealType median = 0, RealType sigma = 1) // result_type = RealType
- 単位球面上一様分布
ちょっと他のと違って、dim次元の単位球面上に一様分布したdim次元のデータを返す。
uniform_on_sphere<class RealType = double, class Cont = std::vector<RealType> >(int dim = 2) //result_type = Cont
variate_generator
乱数生成エンジンと分布をあわせたクラス。
コンストラクタ
variate_generator(Engine e, Distribution d)
でエンジンと分布を設定して、operator()で乱数を生成する。
また、生成する値の最大値、最小値を求めるメンバ関数もある。
result_type variate_generator::min() const; result_type variate_generator::max() const;
Boost Randomテスト
こんな感じで使う。
boost::random_device myseed; //boost::mt19937 gen(static_cast<unsigned>(time(nullptr))); boost::mt19937 gen(static_cast<unsigned>(myseed()); boost::triangle_distribution<> dst(MIN, MID, MAX); boost::variate_generator<boost::mt19937, boost::triangle_distribution<> > r(gen, dst); REP(i, LOOP) std::cout << r(); std::cout << std::endl << gen.min() << " " << gen.max() << std::endl << r.min() << " " << r.max() << std::endl;
乱数発生させて、gnuplotとかでヒストグラムや、散布図を書いてみると、ちゃんと指定した分布になって面白い。http://t16web.lanl.gov/Kawano/gnuplot/index.html
random_number_generator
指定したエンジンで、0以上、引数未満の整数をランダムに出力する関数オブジェクト。
呼び出すときに、上限値変更したいなら、boost::uniform_intで範囲制限するよりこっちの方が便利かもね。
別の用途として、std::random_shuffleの引数にも使える。
class Random{ public: Random(){ srand( static_cast<unsigned>( time(nullptr) ) ); } unsigned operator()(unsigned max){ return rand() % max; } }; int main(){ std::vector<int> v; REP(i, 10) v.push_back( i ); std::vector<int> v2(v); //旧標準ライブラリだけでやる場合 Random r; std::random_shuffle( v.begin(), v.end(), r ); REP(i, 10) std::cout << v[i] << " "; std::cout << std::endl; //random_number_generatorを使う場合 boost::random_device gen; //libboost_randomライブラリをリンクする必要あり std::random_shuffle( v2.begin(), v2.end(), boost::random_number_generator<boost::random_device>(gen) ); REP(i, 10) std::cout << v2[i] << " "; std::cout << std::endl; boost::random_number_generator<boost::random_device> generator(gen); REP(i,10) std::cout << generator(101) << " "; std::cout << std::endl; return 0; }