8

C ++で乱数を生成する根拠は何ですか?

その背後にある論理や原則はありますか?

生成された数字は完全にランダムですか?

このプログラムを実行していると仮定します。

#include <iostream.h>
#include <stdlib.h>
#include <time.h>

int main()
{
    /*
    Declare variable to hold seconds on clock.
    */
    time_t seconds;
    /*
    Get value from system clock and
    place in seconds variable.
    */
    time(&seconds);
    /*
    Convert seconds to a unsigned
    integer.
    */
    srand((unsigned int) seconds);
    /*
    Output random values.
    */
    cout<< rand() << endl;
    cout<< rand() << endl;
    cout<< rand() << endl;
    return 0;
}

表示内容:http: //img14.imageshack.us/img14/1538/98271820.png

205を2回表示しました。

4

2 に答える 2

6

質問は基本的にコメントと別の回答で答えられましたが、私はそれを一箇所にまとめます。

C ++rand()関数は、真にランダムな数列ではなく、疑似乱数列を生成します。これは、基本的には「ランダム」であるがどこかで固定されている事前定義された数列であることを意味します(実際には、それよりも複雑ですが、これは理解を深めるための簡略化です)。整数の長いリストと考えてください。

関数を呼び出すたびにrand()、現在の番号がプルされ、「現在の「乱数」番号」へのポインタが次の番号に移動します。

srand()関数が行うことは、基本的に、リスト内のある場所へのポインターを設定することです。起動のたびに関数を呼び出さない場合srand()、または固定パラメーター(シード)を使用して関数を呼び出さない場合は、プログラムの起動ごとに同じ番号のシーケンスが使用されます。

秒からシードを設定しているときに、その秒内にプログラムを2回起動すると、シードは同じになります。したがって、同じ結果が得られます。

次のコードを試してください。

#include <windows.h>
// << other code >>
for (int i=0; i<50; i++) {
    time(&seconds);
    srand(seconds);
    cout<< seconds<<" "<<rand()<<endl;
    Sleep(100);
}

各「秒」の値は、関数の固定された「最初の」値に対応していることに気付くでしょうrand()

于 2013-03-03T17:32:28.373 に答える
2

2番目の質問から始めます:

生成された数字は完全にランダムですか?

いいえ、それがコンピュータで発生する可能性はほとんどありません。それらは「疑似乱数」であり、ランダムな方法で時間の経過とともに範囲が変化する一連の数値です。ただし、同じ「シード」から始めると、毎回同じシーケンスが得られます。この予測可能性は、同じ実験を同じ結果で数回繰り返すことができるため、非常に役立つ場合があります。シードを変更すると、同様の実行で異なる結果が得られます。

この関数srandはシードを設定します。一部のシステムには、と呼ばれる機能がありますがrandomize、それ自体は標準の一部ではありません。存在する場合は、シードをコードに不明なもの(ミリ秒単位の現在の時刻など)に設定します。

その背後にある論理や原則はありますか?

はい。疑似ランダム番号を生成する方法はいくつかあります。単純なものは、通常intまたはlong型を使用して1行または2行のCコードで記述でき、「現在の値」+定数を取り、大きな数を掛けて、他の大きな数を法とするだけで構成されます。

より複雑なものには、数十行のかなり複雑な数学が含まれます。たとえば、メルセンヌツイスターは最近の作品で、少し検索するとソースコードとして利用できます。

于 2013-03-03T17:18:09.477 に答える