Générateur de nombres aléatoires de départ en C++

Mohd Mohtashim Nawaz 11 décembre 2023
  1. Concept de graine dans le générateur de nombres aléatoires en C++
  2. Utilisez la fonction srand() pour amorcer un générateur de nombres aléatoires en C++
  3. Utilisez la fonction time() pour amorcer un générateur de nombres aléatoires en C++
  4. Semer les erreurs de générateur aléatoire à éviter
  5. Conclusion
Générateur de nombres aléatoires de départ en C++

Les langages de programmation tels que C++ ne génèrent pas de nombres vraiment aléatoires. Au lieu de cela, l’ordinateur génère des nombres pseudo-aléatoires à l’aide d’une fonction mathématique.

Cet article traite du concept de graine dans la génération de nombres aléatoires et de la méthode pour fournir une graine à la fonction utilisée pour générer des nombres aléatoires en C++.

Concept de graine dans le générateur de nombres aléatoires en C++

C++ génère des séquences de nombres aléatoires à l’aide d’un algorithme déterministe. Par conséquent, la séquence de nombres est pseudo-aléatoire plutôt que purement probabiliste.

Dans ce cas, la graine sert de point de départ à l’algorithme. Vous ne devriez pas y penser comme si le premier nombre généré serait la graine.

Au lieu de cela, l’algorithme sélectionne des nombres au hasard à partir d’une distribution définie par la graine. Si vous fournissez la même graine à l’algorithme, il générera la même séquence de nombres pseudo-aléatoires.

Cependant, vous devrez peut-être générer une séquence différente de nombres pseudo-aléatoires pour chaque exécution la plupart du temps. Dans ce cas, vous devez fournir une graine différente à l’algorithme à chaque exécution.

Utilisez la fonction srand() pour amorcer un générateur de nombres aléatoires en C++

La fonction srand() accepte un entier non signé comme argument. Il utilise l’argument pour amorcer l’algorithme qui génère les nombres pseudo-aléatoires.

Syntaxe:

void srand(unsigned int seed);

Si vous fournissez 1 comme argument à la fonction srand(), elle initialise le générateur de nombres pseudo-aléatoires à sa valeur initiale. Le générateur produit les mêmes résultats que le dernier appel à la fonction rand().

Voyons un exemple qui initialise le générateur de nombres pseudo-aléatoires avec un nombre arbitraire pris de l’utilisateur comme entrée.

Exemple de code :

#include <iostream>

using namespace std;

int main() {
  unsigned int seed;
  cout << "Enter seed value:\n";
  cin >> seed;
  srand(seed);
  cout << "Successfully seeded the generator\n";
  return 0;
}

Production:

mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ g++ seed_example.cc
mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ ./a.out
Enter seed value:
12
Successfully seeded the generator

Utilisez la fonction time() pour amorcer un générateur de nombres aléatoires en C++

Le problème avec l’approche précédente est qu’un utilisateur peut entrer le même nombre plus d’une fois. Si vous devez vous assurer que l’algorithme reçoit une graine différente à chaque exécution, utilisez la fonction time() pour fournir une graine au générateur de nombres pseudo-aléatoires.

La fonction time() en C++ renvoie l’horodatage UNIX actuel, le nombre de secondes écoulées depuis 00:00 le 1er janvier 1970, UTC.

Syntaxe:

time_t time(time_t* timer);

La fonction prend un argument comme pointeur de type time_t. Si vous fournissez une référence non nulle à la fonction en tant que paramètre, elle définit un objet de type time_t sur le paramètre qui contient l’horodatage actuel.

Le type time_t est un alias de type arithmétique et peut contenir la valeur d’horodatage UNIX actuelle. Il s’agit en fait d’une valeur entière non signée.

Exemple de code :

#include <iostream>

using namespace std;

int main() {
  srand(time(NULL));
  cout << "Successfully seeded the generator\n";
  return 0;
}

Notez que le code passe NULL comme argument à la fonction time(). Selon le code, vous n’avez pas besoin de l’objet de type time_t pour quelque raison que ce soit.

Production:

mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ g++ seed_example.cc
mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ ./a.out
Successfully seeded the generator

Semer les erreurs de générateur aléatoire à éviter

Généralement, vous générez une séquence de nombres pseudo-aléatoires dans une boucle de votre code. La plupart des gens commettent une erreur courante en initiant le générateur à chaque exécution de la boucle.

Vous obtenez probablement des nombres répétés dans un tel cas, car le générateur crée la même séquence de nombres chaque fois que vous l’ensemencez avec le même nombre.

Cela peut être vrai même si vous utilisez la fonction time() pour amorcer le générateur aléatoire puisque la fonction time() renvoie le nombre de secondes écoulées depuis une date fixe dans le passé.

D’un autre côté, la boucle s’exécutera beaucoup plus rapidement, et donc chaque appel à la fonction time() retournera la même valeur jusqu’à ce qu’une seconde soit passée. De cette façon, vous finirez par donner la même valeur au générateur.

Exemple de code :

#include <iostream>

using namespace std;

int main() {
  for (int i = 1; i <= 10; i++) {
    srand(time(NULL));
    cout << rand() << " ";
  }
  cout << endl;
  return 0;
}

Production:

mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ g++ seed_example.cc
mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ ./a.out
1524491454 1524491454 1524491454 1524491454 1524491454 1524491454 1524491454 1524491454 1524491454 1524491454

Le code place le générateur aléatoire dans la boucle et l’exécution donne dix fois le même nombre. Vous devez toujours amorcer le générateur de nombres aléatoires avant la boucle pour éviter cet écueil.

Voyons l’exemple où le code place le générateur aléatoire en dehors de la boucle.

Exemple de code :

#include <iostream>

using namespace std;

int main() {
  srand(time(NULL));
  for (int i = 1; i <= 10; i++) {
    cout << rand() << " ";
  }
  cout << endl;
  return 0;
}

Production:

mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ g++ seed_example.cc
mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ ./a.out
213462937 1076978976 1207347426 8310730 1551061902 266528745 944000672 871831053 1678325834 868781842

Observez que le code donne une séquence différente de nombres.

Conclusion

Vous pouvez fournir la graine au générateur pseudo-aléatoire qui sert de point de départ à l’algorithme, mais vous devez faire attention à éviter l’écueil, comme indiqué dans l’article. Sinon, cela peut entraîner des résultats indésirables.

Vous pouvez en savoir plus sur la fonction rand() qui génère la séquence de nombres pseudo-aléatoires après l’ensemencement ici.

Article connexe - C++ Random