Pourquoi rand
est une mauvaise idée
La plupart des réponses que vous avez obtenues ici utilisent l'expression rand
et l'opérateur de module. Cette méthode peut ne pas générer les nombres de manière uniforme (cela dépend de la plage et de la valeur de l'option RAND_MAX
), et est donc déconseillé.
C++11 et génération sur une gamme
Avec C++11, de multiples autres options sont apparues. L'une d'entre elles répond très bien à votre besoin de générer un nombre aléatoire dans un intervalle : std::uniform_int_distribution
. Voici un exemple :
const int range_from = 0;
const int range_to = 10;
std::random_device rand_dev;
std::mt19937 generator(rand_dev());
std::uniform_int_distribution<int> distr(range_from, range_to);
std::cout << distr(generator) << '\n';
Et aquí C'est l'exemple à suivre.
La fonction de modèle peut aider certains :
template<typename T>
T random(T range_from, T range_to) {
std::random_device rand_dev;
std::mt19937 generator(rand_dev());
std::uniform_int_distribution<T> distr(range_from, range_to);
return distr(generator);
}
Autres générateurs aléatoires
El <random>
en-tête propose d'innombrables autres générateurs de nombres aléatoires avec différents types de distributions, notamment Bernoulli, Poisson et normale.
Comment puis-je mélanger un conteneur ?
La norme prévoit std::shuffle
qui peut être utilisé comme suit :
std::vector<int> vec = {4, 8, 15, 16, 23, 42};
std::random_device random_dev;
std::mt19937 generator(random_dev());
std::shuffle(vec.begin(), vec.end(), generator);
L'algorithme réordonnera les éléments de manière aléatoire, avec une complexité linéaire.
Boost.Random
Une autre alternative, dans le cas où vous n'avez pas accès à un compilateur C++11+, est d'utiliser Boost.Random . Son interface est très similaire à celle du C++11.
4 votes
Construire un Dice-O-Matic : gamesbyemail.com/News/DiceOMatic
1 votes
Je ne savais pas que le C++
rand()
était uniforme. Quelle bibliothèque utilisez-vous ?cstdlib.h
'srand()
n'est PAS uniforme : cplusplus.com/reference/cstdlib/rand3 votes
Non, rand() est uniforme (sauf dans certaines implémentations précoces et boguées). Ce qui n'est pas uniforme, c'est l'utilisation de l'opérateur modulo '%' pour restreindre la plage. Voir stackoverflow.com/questions/2999075/ pour une solution appropriée, ou si vous disposez de 'arc4random_uniform', vous pouvez également l'utiliser directement.
0 votes
@Alien01 : Pourriez-vous envisager de changer la réponse acceptée à celle de "Shoe" ("Why rand is a bad idea" etc..) ? Ma réponse est vraiment dépassée et à chaque fois que je reçois un upvote pour elle, j'ai l'impression que quelqu'un court dans la mauvaise allée.
0 votes
Nice livre blanc à propos de random dans c++11.