2016-06-22 18 views
0

を使用boost::random私は同じ範囲の乱数ジェネレータを使用して、異なる範囲の一様分布の整数のサンプルを試そうとしています。それぞれの範囲に対して、私は乱数を返す別の関数を定義しています。 しかし、各関数は同じ番号を返すようです。C++単一ジェネレータを使用して複数の範囲からランダムintをブースト

アプローチを示す例:

#include <boost/bind.hpp> 
#include <boost/function.hpp> 
#include <boost/random.hpp> 

struct RandomNumberGenerator { 
    boost::mt19937 generator; 

    RandomNumberGenerator(long seed) { 
    generator.seed(seed); 
    } 

    boost::function<int()> getRandomFunctionInt(int min, int max) { 
    boost::uniform_int<> uni_dist(min, max); 
    boost::variate_generator<boost::mt19937&, boost::uniform_int<> > uni(generator, uni_dist); 

    boost::function<int()> f; 
    f = boost::bind(uni_dist, generator); 
    return f; 
    } 
}; 

int main (int argc, char* argv[]) { 
    RandomNumberGenerator rng(1729); 
    boost::function<int()> runif1 = rng.getRandomFunctionInt(0, 1000); 
    boost::function<int()> runif2 = rng.getRandomFunctionInt(0, 10000); 

    for (int i=0; i<10; ++i) { 
    std::cout << runif1() << ", " << runif2() << std::endl; 
    } 
} 

出力をした

212, 2121 
623, 6226 
259, 2590 
[...] 

は非相関関数にする方法はありますか?私の実験の再現性のために、私は単一のシードで作業したいと思っています。

答えて

0
f = boost::bind(uni_dist, generator); 

ジェネレータへの参照を渡す必要があります。今は、ジェネレータのコピーを渡しています。つまり、各fオブジェクトには初期状態のジェネレータのコピーがあります。

f = boost::bind(uni_dist, boost::ref(generator)); 

ラムダを使用して、異なるバージョンの曖昧さをより可視(及び/決意を検出しやすい)になるだろう:

f = [uni_dist, this] {return uni_dist(generator);}; 

はまた、++ 11cはすべて同じを提供<random>ヘッダを導入しました機能など、ブーストのrandomヘッダーが提供されているので、ブーストバージョンを使用し続ける理由はもうありません。

+0

私のルーキーミスを指摘してくれてありがとう...答えが受け入れられ、感謝!標準の ''ヘッダに切り替えることも良いアドバイスです。ラムダ関数を使用するソリューションの場合は+1ですが、C++の11個のメンバ変数( 'generator'など)を直接取得することはできません。ローカル変数を使用してその変数を取得してください。 ' boost: :mt19937&g = generator' – mrhd

+0

@mrhdあなたが 'this'をキャプチャすると、メンバ変数を取得できると思います。私はそれを説明する答えを改訂しました。 – Xirema

+0

更新いただきありがとうございます。あなたのソリューションはより簡潔です。 'uni_dist(ジェネレータ)'で参照渡しする必要がないので、コピーが実際にboost :: bind()だったことが分かりました。 – mrhd

関連する問題