2009-07-13 23 views
7

私は擬似乱数を生成するプログラムを書くという本の演習をしています。私は簡単に始めました。C++でrand()関数を使用する正しい方法は何ですか?

#include "std_lib_facilities.h" 

int randint() 
{ 
    int random = 0; 
    random = rand(); 
    return random; 
} 

int main() 
{ 
    char input = 0; 
    cout << "Press any character and enter to generate a random number." << endl; 
    while (cin >> input) 
    cout << randint() << endl; 
    keep_window_open(); 
} 

私は、プログラムが実行されるたびに同じ「ランダム」出力が存在することに気付きました。だから私は乱数発生器を調べ、randint()にこれを最初に含めてシードしようと決めました。

だけで何度も同じ番号を生成し
srand(5355); 

(私はそれを実現するために、今愚かな感じ。)

だから、私は賢いことと、このように種子を実装しようと思いました。

srand(rand()); 

プログラムとしてこの基本的には同じでしたが、最初の場所でなかったが、数の異なるセット出力(RAND(によって生成された第1の数ので理にかなっている)は、常に41である)

私はこれよりランダムにあることを確認するために考えることができる唯一の事:

  1. は、ユーザの入力に番号を持っており、シードとして(実装するのは簡単だろうが、これは最後の手段である)という設定 OR
  2. 何とかして、シードをコンピュータ時計やその他の絶えず変化する番号に設定する必要があります。

私は頭の中で私は今停止する必要がありますか?オプション2は実装が難しいですか?他のアイデア?

ありがとうございます。

答えて

27

オプション2は、ここであなたが行く、難しいことではありません。

srand(time(NULL)); 

あなたはtime()ためsrand()ためstdlib.htime.hを含める必要があります。

+8

+1これは標準的な方法です。 – SingleNegationElimination

+0

* nix環境にいる場合は、/ dev/randomでも読み込むことができます。私はTokenに同意しますが、これはsrandをtime関数で設定する標準的な方法です。 – Suroot

+2

また、一度呼び出すだけなので、上部のメインのsrand()を呼び出してください。新しい番号を生成するたびに呼び出さないでください。 – MahlerFive

6

乱数ジェネレータに現在時刻を設定するのが一般的です。試してください:

srand(時間(NULL));

8

にsrand()一度だけ使用する必要があります。

int randint() 
{ 
    int random = rand(); 
    return random; 
} 

int main() 
{ 
    // To get a unique sequence the random number generator should only be 
    // seeded once during the life of the application. 
    // As long as you don't try and start the application mulitple times a second 
    // you can use time() to get a ever changing seed point that only repeats every 
    // 60 or so years (assuming 32 bit clock). 
    srand(time(NULL)); 
    // Comment the above line out if you need to debug with deterministic behavior. 

    char input = 0; 
    cout << "Press any character and enter to generate a random number." << endl; 

    while (cin >> input) 
    { 
     cout << randint() << endl; 
    } 
    keep_window_open(); 
} 
+0

これを必ず実行します。 – trikker

4

問題は、発電機をシードしていない場合、それは(srand(0)が呼ばれたかのように)0で自身をシードするということです。 PRNGは同じシーケンスを生成するように設計されています(PNRGは実際にはランダムではないため、決定論的なアルゴリズムであり、テストには非常に便利なので多分です)。

あなたが実際にやっている

srand(rand()); 

を使用して乱数でそれをシードしようとしているとき:FigBug mentionedとして

srand(0); 
x = rand(); // x will always be the same. 
srand(x); 

を、発電機をシードする時間を使用することが一般的です中古。

+0

実際には、最初のシード値は1です: '' srand'の呼び出しが行われる前に 'rand()'が呼び出された場合、シード値が1の 'srand'が最初に呼び出された時と同じシーケンスが生成されます。 " http://www.opengroup.org/onlinepubs/000095399/functions/srand.html –

0

私は、これらの記事のポイントは、効果的に種を蒔く方法ではなく、rand()にあるアルゴリズムを実装することだと思います。

(疑似)乱数を生成することは簡単ではなく、それらを生成するさまざまな手法を検討する価値があります。私は単にrand()を使っているだけで、作者が気にしたことではないと思います。

関連する問題