web-dev-qa-db-fra.com

Comment générer différents nombres aléatoires dans une boucle en C++?

Est-il possible de générer un nombre aléatoire différent à chaque exécution de boucle? Par exemple, j'ai:

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

Mais le problème est qu'il génère le même nombre aléatoire à chaque fois. Est-il possible de générer différents nombres aléatoires à chaque exécution de boucle?

Est-il possible de réinitialiser l'initialisation de nombres aléatoires?

19
bijlikamasla

N'utilisez pas srand dans la boucle, utilisez-la une seule fois, par exemple. au début de main(). Et srand() est exactement ce que vous réinitialisez.

24
etarion

Vous obtenez le même nombre aléatoire à chaque fois, car vous établissez une graine dans la boucle. Même si vous utilisez time(), il ne change qu'une fois par seconde. Ainsi, si votre boucle se termine en une seconde (ce qui sera probablement le cas), vous obtiendrez la même valeur de départ à chaque fois et le même nombre aléatoire initial.

Déplacez l'appel srand() en dehors de la boucle (et appelez-le une seule fois, au début de votre application) et vous obtiendrez des nombres aléatoires "aléatoires".

16
payne

Ne pas utilisez Rand(); utilisez plutôt les nouvelles fonctionnalités C++ 11 (par exemple, std::mt19937, std::uniform_int_distribution, etc.).

Vous pouvez utiliser un code comme celui-ci ( live ici sur 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;
    }
}

P.S.

Regardez cette vidéo de la conférence Going Native 2013 pour plus de détails sur les problèmes liés à Rand()-:

Rand () considéré comme nuisible

8
Mr.C64

Essayez de déplacer la graine srand en dehors de la boucle comme ceci:

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

Comme le dit Mark Ransom dans le commentaire, déplacer la valeur de départ en dehors de la boucle ne sera utile que si la boucle ne réside pas dans une fonction que vous appelez plusieurs fois.

3
Tommy Andersen

J'ai eu ce même problème pendant des jours. Garder srand () hors de la boucle est un +. En outre, n'affectez pas Rand ()% 100 à une variable. Il suffit de cout Rand ()% 100 dans la boucle. Essaye ça:

    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)));

Eh bien, je ne suis pas un pro en C++, mais je l'ai appris à l'école. J'utilise cet algo depuis un an pour stocker différentes valeurs aléatoires dans un tableau 1D, mais cela fonctionnera également dans un tableau 2D après quelques modifications . Toute suggestion concernant le code est la bienvenue.

0
Sarthik Garg

Si vous avez des aléas au début du programme, vous pouvez multiplier la variable de boucle par la suite pour améliorer la répartition. Par exemple

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

}
0
JH95

Arrêtez d'ensemencer le générateur à chaque fois . Tirez l'appel srand de la boucle.

0
Erix

Déplacez l'appel srand au début du programme. Comme vous l'avez maintenant, le temps peut être le même entre deux appels consécutifs, ainsi le générateur de nombres aléatoires va redémarrer au même endroit.

0
Mark Ransom

Vous devez extraire l'initialisation de time () de la boucle for.

Voici un exemple qui produira dans la console Windows un nombre aléatoire attendu (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.

La fonction time renvoie probablement la même valeur à chaque itération de la boucle.

Essayez d’initialiser la graine aléatoire avant la boucle.

0
djp

À chaque itération, vous réinitialisez la séquence de nombres pseudo-aléatoires parce que vous appelez srand avec la même graine (car l'appel à time est si fréquent). Utilisez une autre graine ou appelez srand une fois avant d'entrer dans la boucle.

0
Marlon