Je voudrais compléter les excellentes réponses de Angry Shoe et Peterchen par un bref aperçu de l'état de l'art en 2015:
Quelques bons choix
randutils
La randutils
bibliothèque (présentation) est une nouveauté intéressante, offrant une interface simple et des capacités aléatoires robustes (déclarées). Il présente l'inconvénient d'ajouter une dépendance à votre projet et, étant nouveau, il n'a pas été testé de manière approfondie. Quoi qu'il en soit, étant gratuit (licence MIT) et en-tête uniquement, je pense que cela vaut la peine d'essayer.
Échantillon minimal: un jet de dé
#include <iostream>
#include "randutils.hpp"
int main() {
randutils::mt19937_rng rng;
std::cout << rng.uniform(1,6) << "\n";
}
Même si l'on n'est pas intéressé par la bibliothèque, le site ( http://www.pcg-random.org/ ) propose de nombreux articles intéressants sur le thème de la génération de nombres aléatoires en général et de la bibliothèque C ++ en particulier.
Boost.Random
Boost.Random
(documentation) est la bibliothèque qui a inspiré C++11
les <random>
, avec qui partage une grande partie de l'interface. Tout en étant théoriquement une dépendance externe, elle Boost
a désormais le statut de bibliothèque «quasi-standard», et son Random
module pourrait être considéré comme le choix classique pour la génération de nombres aléatoires de bonne qualité. Il présente deux avantages par rapport à la C++11
solution:
- il est plus portable, nécessitant juste le support du compilateur pour C ++ 03
- il
random_device
utilise des méthodes spécifiques au système pour offrir un semis de bonne qualité
Le seul petit défaut est que l'offre de module random_device
n'est pas uniquement en-tête, il faut compiler et lier boost_random
.
Échantillon minimal: un jet de dé
#include <iostream>
#include <boost/random.hpp>
#include <boost/nondet_random.hpp>
int main() {
boost::random::random_device rand_dev;
boost::random::mt19937 generator(rand_dev());
boost::random::uniform_int_distribution<> distr(1, 6);
std::cout << distr(generator) << '\n';
}
Bien que l'échantillon minimal fasse bien son travail, les vrais programmes devraient utiliser une paire d'améliorations:
- faire
mt19937
un thread_local
: le générateur est assez dodu (> 2 Ko) et vaut mieux ne pas être alloué sur la pile
- graine
mt19937
avec plus d'un entier: le Mersenne Twister a un grand état et peut bénéficier de plus d'entropie lors de l'initialisation
Quelques choix pas si bons
La bibliothèque C ++ 11
Tout en étant la solution la plus idiomatique, la <random>
bibliothèque n'offre pas grand-chose en échange de la complexité de son interface même pour les besoins de base. Le défaut est là std::random_device
: le Standard n'impose aucune qualité minimale pour sa sortie (tant que les entropy()
retours 0
) et, à partir de 2015, MinGW (pas le compilateur le plus utilisé, mais pas un choix ésotérique) imprimera toujours 4
sur l'échantillon minimal.
Échantillon minimal: un jet de dé
#include <iostream>
#include <random>
int main() {
std::random_device rand_dev;
std::mt19937 generator(rand_dev());
std::uniform_int_distribution<int> distr(1, 6);
std::cout << distr(generator) << '\n';
}
Si l'implémentation n'est pas pourrie, cette solution devrait être équivalente à celle de Boost, et les mêmes suggestions s'appliquent.
La solution de Godot
Échantillon minimal: un jet de dé
#include <iostream>
#include <random>
int main() {
std::cout << std::randint(1,6);
}
C'est une solution simple, efficace et soignée. Seul défaut, la compilation prendra un certain temps - environ deux ans, à condition que C ++ 17 soit publié à temps et que la randint
fonction expérimentale soit approuvée dans le nouveau Standard. Peut-être que d'ici là aussi les garanties sur la qualité des semis s'amélioreront.
Échantillon minimal: un jet de dé
#include <cstdlib>
#include <ctime>
#include <iostream>
int main() {
std::srand(std::time(nullptr));
std::cout << (std::rand() % 6 + 1);
}
L'ancienne solution C est considérée comme nuisible, et pour de bonnes raisons (voir les autres réponses ici ou cette analyse détaillée ). Pourtant, il a ses avantages: c'est simple, portable, rapide et honnête, dans le sens où on sait que les nombres aléatoires que l'on obtient ne sont guère décents, et donc on n'est pas tenté de les utiliser à des fins sérieuses.
La solution de troll comptable
Échantillon minimal: un jet de dé
#include <iostream>
int main() {
std::cout << 9; // http://dilbert.com/strip/2001-10-25
}
Bien que 9 soit un résultat quelque peu inhabituel pour un jet de dé régulier, il faut admirer l'excellente combinaison de bonnes qualités de cette solution, qui parvient à être la plus rapide, la plus simple, la plus conviviale et la plus portable. En remplaçant 9 par 4, on obtient un générateur parfait pour tout type de dé Donjons et Dragons, tout en évitant les valeurs chargées de symboles 1, 2 et 3. Le seul petit défaut est que, à cause de la mauvaise humeur des trolls comptables de Dilbert, ce programme engendre en fait un comportement indéfini.