web-dev-qa-db-ja.com

C ++のループで異なる乱数を生成する方法は?

ループが実行されるたびに、異なる乱数を生成することは可能ですか?たとえば、私は持っています:

for (int t=0;t<10;t++)
{
    int random_x;
    srand ( time(NULL) );
    random_x = Rand() % 100;
    cout<<"\nRandom X = "<<random_x;
} 

しかし問題は、毎回同じ乱数を生成することです。ループが実行されるたびに異なる乱数を生成することは可能ですか?

乱数の初期化もリセットする可能性はありますか?

19
bijlikamasla

ループ内でsrandを使用しないでください。一度だけ使用してください。 main()の先頭。 srand()は、まさにこれをリセットする方法です。

26
etarion

ループ内にシードを設定しているため、毎回同じ乱数を取得しています。 time()を使用している場合でも、1秒に1回しか変更されないため、ループが1秒で完了すると(おそらくそうなります)、毎回同じシード値を取得し、同じ初期乱数。

srand()呼び出しをループの外側に移動し(アプリの開始時に1回だけ呼び出します)、ランダムな「ランダムな」番号を取得する必要があります。

16
payne

Donotuse Rand();新しいC++ 11機能を使用します(例(_std::mt19937__std::uniform_int_distribution_など))代わりに。

次のようなコードを使用できます( live on Ideone ):

_#include <iostream>
#include <random>
using namespace std;

int main()
{
    // Random seed
    random_device rd;

    // Initialize Mersenne Twister pseudo-random number generator
    mt19937 gen(rd());

    // Generate pseudo-random numbers
    // uniformly distributed in range (1, 100)
    uniform_int_distribution<> dis(1, 100);

    // Generate ten pseudo-random numbers
    for (int i = 0; i < 10; i++)
    {
        int randomX = dis(gen);
        cout << "\nRandom X = " << randomX;
    }
}
_

PS

Rand()関連の問題の詳細については、Going Native 2013カンファレンスの次のビデオをご覧ください。

Rand()は有害と見なされます

8
Mr.C64

シードsrandをループの外に移動してみてください:

srand ( time(NULL) );
for (int t=0;t<10;t++)
{
    int random_x;
    random_x = Rand() % 100;
    cout<< "\nRandom X = "<<random_x;
} 

Mark Ransomがコメントで述べているように、ループの外側にシードを移動することは、ループが数回呼び出している関数に存在しない場合にのみ役立ちます。

3
Tommy Andersen

私は何日も同じ問題を抱えていました。 srand()をループから外すことは+です。また、Rand()%100を変数に割り当てないでください。ループ内でRand()%100を単純に計算します。これを試して:

    srand (time(NULL));
    (int t=0;t<10;t++)
    {
    cout << Rand() % 100 << endl;
    } 
1
user3000012
/*this code is written in Turbo C++
 For Visual Studio, code is in comment*/

int a[10],ct=0,x=10,y=10;    //x,y can be any value, but within the range of 
                             //array declared
randomize();                 //there is no need to use this Visual Studio
for(int i=0;i<10;i++)
{   a[i]=random(10);         //use a[i]=Rand()%10 for Visual Studio
}
cout<<"\n\n";
do
{   ct=0;
    for(i=0;i<x;i++)
    {   for(int j=0;j<y;j++)
        {   if(a[i]==a[j]&&i!=j)
            {   a[j]=random(10);    //use a[i]=Rand()%10 for Visual Studio
            }
            else
            {   ct++;
            }
        }
    }
}while(!(ct==(x*y)));

まあ、私はC++のプロではありませんが、学校でそれを学びました。私は過去1年間このアルゴリズムを使用して、1D配列にさまざまなランダム値を保存していますが、これはいくつかの変更後に2D配列でも機能します。コードに関する提案は歓迎します。

0
Sarthik Garg

プログラムの早い段階でランダムがある場合、ループ変数に時間を掛けることで、より良い分布を得ることができます。例えば

for (int t = 0; t < 10; t++){
        srand(time(NULL)*t);
        random =  Rand() % GetScreenWidth();

}
0
JH95

ジェネレーターのシードを毎回停止します。ループからスンダ呼び出しを引き出します

0
Erix

関数Rand()の動作方法は、呼び出すたびに乱数を生成することです。コードでは、一度呼び出して変数random_xに保存しました。目的の乱数を変数に保存する代わりに取得するには、次のように関数を呼び出します。

for (int t=0;t<10;t++)
{
    cout << "\nRandom X = " << Rand() % 100;
}
0
Joseph Yu

srand呼び出しをプログラムの先頭に移動します。現在のように、2つの連続した呼び出しの間で時間が同じになる可能性があるため、乱数発生器は同じ場所で再び開始されます。

0
Mark Ransom

For()ループからtime()の初期化を抽出する必要があります。

以下は、Windowsコンソールで期待される(ahah)乱数を出力する例です。

#include <iostream>
#include <windows.h>
#include "time.h"
int main(int argc, char*argv[])
{
    srand ( time(NULL) );
    for (int t = 0; t < 10; t++)
    {
        int random_x;

        random_x = Rand() % 100;
        std::cout << "\nRandom X = " << random_x << std::endl;
    }
    Sleep(50000);
    return 0;
}
0
Xavier V.

Time関数は、ループの各反復中におそらく同じ値を返します。

ループの前にランダムシードを初期化してみてください。

0
djp

srandを同じシードで呼び出しているため(timeの呼び出しは頻繁に行われるため)、反復ごとに擬似乱数のシーケンスをリセットしています。別のシードを使用するか、ループに入る前にsrandonceを呼び出します。

0
Marlon