rand () génère le même nombre – même avec srand (time (NULL)) dans mon main!

J’essaie donc de créer un vecteur aléatoire (pensez à la géomésortinge, pas à un tableau extensible) et chaque fois que j’appelle ma fonction de vecteur aléatoire, j’obtiens la même valeur x, bien que y et z soient différents.

int main () { srand ( (unsigned)time(NULL)); Vector a; a.randvec(); cout << a << endl; return 0; } 

en utilisant la fonction

 //random Vector template  void Vector::randvec() { const int min=-10, max=10; int randx, randy, randz; const int bucket_size = RAND_MAX/(max-min); do randx = (rand()/bucket_size)+min; while (randx = max); x = randx; do randy = (rand()/bucket_size)+min; while (randy = max); y = randy; do randz = (rand()/bucket_size)+min; while (randz = max); z = randz; } 

Pour une raison quelconque, randx retournera systématiquement 8, alors que les autres nombres semblent suivre parfaitement le (pseudo) caractère aléatoire. Cependant, si je mets l’appel pour définir, disons, randy avant randx, randy retournera toujours 8.

Pourquoi mon premier nombre aléatoire est-il toujours 8? Est-ce que je sème mal?

Le problème est que le générateur de nombres aléatoires est ensemencé avec des valeurs très proches les unes des autres – chaque exécution du programme modifie uniquement la valeur renvoyée de time () par une petite quantité – peut-être 1 seconde, voire aucune! Le générateur de nombres aléatoires standard plutôt médiocre utilise ensuite ces valeurs de départ similaires pour générer des nombres aléatoires initiaux apparemment identiques. En gros, vous avez besoin d’un meilleur générateur de semences initial que time () et d’un meilleur générateur de nombres aléatoires que rand ().

Je pense que l’algorithme de bouclage utilisé est basé sur C ++ accéléré et est destiné à produire un meilleur étalement des nombres sur la plage requirejse que ne le ferait le cas de l’opérateur mod. Mais cela ne peut compenser le fait de toujours recevoir (effectivement) la même graine.

Je ne vois pas de problème avec votre srand() , et lorsque j’ai essayé d’exécuter un code extrêmement similaire, je n’ai pas obtenu le même numéro à plusieurs resockets avec le premier rand() . Cependant, j’ai remarqué un autre problème possible.

 do randx = (rand()/bucket_size)+min; while (randx <= min && randx >= max); 

Cette ligne ne fait probablement pas ce que vous vouliez. Tant que min < max (et cela devrait toujours l'être), il est impossible que randx soit inférieur ou égal à min et supérieur ou égal à max . De plus, vous n'avez pas du tout besoin de faire une boucle. Au lieu de cela, vous pouvez obtenir une valeur entre min et max en utilisant:

 randx = rand() % (max - min) + min; 

De plus, vous pouvez même vous débarrasser de cette étrange variable bucket_size et utiliser la méthode suivante pour générer des nombres de a à b inclusivement:

 srand ((unsigned)time(NULL)); const int a = -1; const int b = 1; int x = rand() % ((b - a) + 1) + a; int y = rand() % ((b - a) + 1) + a; int z = rand() % ((b - a) + 1) + a; 

Une solution simple consiste à appeler rand plusieurs fois après le semis.

 int main () { srand ( (unsigned)time(NULL)); rand(); rand(); rand(); Vector a; a.randvec(); cout << a << endl; return 0; } 

Juste pour mieux expliquer, le premier appel à rand () dans quatre exécutions séquentielles d'un programme de test a donné le résultat suivant:

 27592 27595 27598 27602 

Notez à quel point ils sont similaires Par exemple, si vous divisez rand() par 100, vous obtiendrez le même nombre 3 fois de suite. Examinons maintenant le deuxième résultat de rand () en quatre exécutions séquentielles:

 11520 22268 248 10997 

Cela a l'air beaucoup mieux, n'est-ce pas? Je ne vois vraiment aucune raison pour les votes négatifs.

J’ai eu exactement le même problème. Je l’ai corrigé en déplaçant l’appel srand () afin qu’il ne soit appelé qu’une seule fois dans mon programme (auparavant, je l’avais semé en haut d’un appel de fonction). Je ne comprends pas vraiment les détails techniques, mais le problème était résolu.

Votre mise en œuvre, par division d’entier, ignore le plus petit des 4 à 5 bits du nombre aléatoire. Etant donné que votre RNG est paramétré avec l’heure système, la première valeur que vous en retirerez ne changera que (en moyenne) toutes les 20 secondes.

Cela devrait fonctionner:

 randx = (min) + (int) ((max - min) * rand() / (RAND_MAX + 1.0)); 

 rand() / (RAND_MAX + 1.0) 

est une valeur double aléatoire dans [0, 1) et le rest ne fait que la déplacer.