2009-12-04 13 views
10

メインの.cppブースト::ランダム

#include  "stdafx.h" 
#include  "random_generator.h" 


     int 
main (int argc, char *argv[]) 
{ 
     cout.setf(ios::fixed); 
     base_generator_type base_generator; 
     int max = pow(10, 2); 
     distribution_type dist(1, max); 

     boost::variate_generator<base_generator_type&, 
distribution_type > uni(base_generator, dist); 
     for (int i=0; i<10; i++) { 
       //cout << random_number(2) << endl; 
       cout << uni() << endl; 
     } 

     return EXIT_SUCCESS; 

}        /* ---------- end of function main ---------- */ 

random_gemerator.h

#include  "stdafx.h" 

#include  <boost/random.hpp> 
#include  <boost/generator_iterator.hpp> 

typedef boost::mt19937 base_generator_type; 
typedef boost::lagged_fibonacci19937 fibo_generator_type; 
typedef boost::uniform_int<> distribution_type; 
typedef boost::variate_generator<fibo_generator_type&, 
distribution_type> gen_type; 

     int 
random_number (int bits) 
{ 
     fibo_generator_type fibo_generator; 
     int max = pow(10, bits); 
     distribution_type dist(1, max); 

     gen_type uni(fibo_generator, dist); 
     return uni(); 

}    /* ----- end of function random_number ----- */ 

stdafx.hを

#include <iostream> 
#include <cstdlib> 
#include <cmath> 

using namespace std; 

私はそれを実行するたびに、それをすべて同じ番号シーケンスを生成する

のように77,33,5,22、...

使用方法ブースト:ランダム正しくですか?


それです。それはそれはdoesnのように、あなたはあなたの乱数ジェネレータをシードする必要が同じ乱数

int get_random() {get_seed();return generate_random();} for (;;) {cout << get_random() <<endl;} // output the same random number yet 

答えて

6

をgenereate

get_seed(); for (;;) {cout << generate_random() << endl; } // is ok 

を鳴らすようだ

:多分、次のような小さな問題を、持っています毎回同じ場所から始める。

数字を使って何をしているかによって、シード値の選択方法を考える必要があります。高品質な乱数が必要な場合(暗号鍵を生成し、それをかなり安全にしたい場合)には、シード値が必要です。これがPosixなら、私は/ dev/randomを提案しますが、あなたはWindowsを使っているように見えるので、どのような良いソースがあるのか​​分かりません。

しかし、予測可能なシード(ゲーム、シミュレーションなど)を気にしない場合は、time()によって返される現在のタイムスタンプが素早く汚れた種となります。

+0

雅右。シードが同じ場合、ジェネレータは同じ乱数で始まり、毎回 – A9S6

+0

となります。次のように少し問題があるかもしれません: それは音のようです get_seed(); for(;;){cout << generate_random()<< endl; } // OKです。 同じ乱数を生成します。 int get_random(){get_seed();}();} // get_random()<< endl; //出力同じ乱数はまだ – mono

+0

は、関数が呼び出されるたびにシードを生成します。同じ種子を使用する毎回同じ種子を使用する ? なぜ私は前の方法で同じ乱数シーケンスを取得する – mono

13

あなたは乱数列は、あなたのプログラムを実行するたびに変更したい場合、あなたは、あなたが例thereを見つけるインスタンス

の現在の時間でそれを初期化することにより、抜粋をランダムシードを変更する必要があります。

/* 
* Change seed to something else. 
* 
* Caveat: std::time(0) is not a very good truly-random seed. When 
* called in rapid succession, it could return the same values, and 
* thus the same random number sequences could ensue. If not the same 
* values are returned, the values differ only slightly in the 
* lowest bits. A linear congruential generator with a small factor 
* wrapped in a uniform_smallint (see experiment) will produce the same 
* values for the first few iterations. This is because uniform_smallint 
* takes only the highest bits of the generator, and the generator itself 
* needs a few iterations to spread the initial entropy from the lowest bits 
* to the whole state. 
*/ 
generator.seed(static_cast<unsigned int>(std::time(0))); 
+0

です。次のように少し問題があるかもしれません: それは音のようです get_seed(); for(;;){cout << generate_random()<< endl; } // OKです。 同じ乱数を生成します。 int get_random(){get_seed();}();} // get_random()<< endl; //出力同じ乱数はまだ – mono

+8

です。私はPRNGを 'std :: time(NULL)+ getpid()'に初期化する方が好きです。これにより、バイナリが急速に連続して実行され、PRNGが異なる方法で初期化されるようになります。 – user1202136

+1

「セキュリティ」を追加するには、/ dev/random(または[Windows](https://en.wikipedia.org/wiki/Entropy_(コンピューティング)#Windows)の下で同等のものを使用してPRNGを初期化するのが正しい方法です。 ) – Avio

5

'nixシステムで実行している場合は、このようなことをいつでも試すことができます。

int getSeed() 
{ 
    ifstream rand("/dev/urandom"); 
    char tmp[sizeof(int)]; 
    rand.read(tmp,sizeof(int)); 
    rand.close(); 
    int* number = reinterpret_cast<int*>(tmp); 
    return (*number); 
} 

私はこの方法では、単純にすべてのあなたの乱数のニーズに/dev/urandom(または/dev/random)を読み出すよりも高速である乱数ジェネレータをシード推測しています。

+0

これは正しい考えです。 Boostの新しいバージョンでは、少なくともこれはすべて 'random_device'によって抽象化されています。ボーナスとして、 'random_device'もWindows上に実装する必要があります。 BSD/dev/urandomは実際には非決定論的ではないので、残念ながら、私が正しく理解すれば、BSDで実装されていません。したがって、LinuxとWindowsの相互運用性が必要な場合は、 'random_device'を使用することができます。また、LinuxとBSDの相互運用性が必要な場合は、/ dev/urandomからの明示的な読み取りを使用できます。あなたが相互運用性の他の組み合わせを望むなら、私はあなた自身でいると思います! – Chinasaur

2

クラスをそのまま使用することも、他のジェネレータをシードすることもできます。あなたはシンプルで、それのうちの一回限りの乱数を得ることができます

 
boost::random::random_device()() 

+0

「unsigned int」型の結果を返すかのように見えます(私は疑問に思っていましたので、それを見なければなりませんでした)。 –