86 votes

Nombre aléatoire c++ dans une certaine plage

Duplicata possible :
Générer des nombres aléatoires de façon uniforme sur toute la plage.

Je veux générer un nombre aléatoire en c++ dans une certaine fourchette, disons que je veux un nombre entre 25 et 63.

Comment puis-je avoir ça ?

0 votes

Cela fonctionne parfaitement même avec des boucles : sortie = min + (rand() % (int)(max - min + 1))

303voto

Cubbi Points 25339

Puisque personne n'a encore affiché l'approche moderne du C++,

#include <iostream>
#include <random>
int main()
{
    std::random_device rd; // obtain a random number from hardware
    std::mt19937 gen(rd()); // seed the generator
    std::uniform_int_distribution<> distr(25, 63); // define the range

    for(int n=0; n<40; ++n)
        std::cout << distr(gen) << ' '; // generate numbers
}

40 votes

Si vous vous demandez "ce que le hack est mt19937 type ?!" - A Mersenne Twister pseudo-random generator of 32-bit numbers with a state size of 19937 bits. Il s'agit d'un "wrapper" pour le modèle "mersenne_twister_engine" ( cplusplus.com/reference/random/mersenne_twister_engine ) avec des paramètres prédéfinis.

0 votes

J'ai créé une petite application de console d'entrée/sortie qui demande des informations et sort dynamiquement les nombres aléatoires en fonction de celles-ci. ideone.com/wk239Q *BTW : approche moderne du C++ - + ! *

0 votes

Downvote pour le moment, car std::random_device renvoie l'erreur /home/akiva/Programming/Tutorial/tutorial/main.cpp:21: error: 'random_device' is not a member of 'std' dans ma configuration ubuntu 14.10 avec qtcreator. Je ne sais pas si c'est une fonction dépréciée, qu'elle n'est pas incluse dans Linux, ou si je suis simplement incompétent.

41voto

K-ballo Points 44794

Vous pouvez utiliser la fonctionnalité aléatoire incluse dans les ajouts à la bibliothèque standard (TR1). Ou vous pouvez utiliser la même vieille technique qui fonctionne en C :

25 + ( std::rand() % ( 63 - 25 + 1 ) )

38 votes

Notez que cette réponse ne génère pas de nombres aussi probables ! La réponse ci-dessous est une meilleure approche.

0 votes

@GeorgeHilliard pourquoi ? je ne sais vraiment pas, comment l'algorithme pour générer des nombres aléatoires fonctionne

5 votes

@milanHrabos un exemple le fera facilement comprendre : std::rand() renvoie des nombres entiers répartis de manière égale entre 0 a RAND_MAX ( inclusivement ). Maintenant, en supposant que vous avez obtenu des nombres entiers dans la gamme de 0 a RAND_MAX - 1 (inclusivement) en utilisant std::rand() % RAND_MAX les chances d'obtenir un 0 serait maintenant doublé, puisqu'il sera le résultat lorsque std::rand() renvoie à soit 0 ou RAND_MAX . Tout autre numéro ne sera obtenu que s'il est renvoyé directement par std::rand() . Cela s'appliquera de manière similaire, pour tout modulo qui n'est pas un diviseur de . RAND_MAX + 1 .

26voto

Nawaz Points 148870
int random(int min, int max) //range : [min, max]
{
   static bool first = true;
   if (first) 
   {  
      srand( time(NULL) ); //seeding for the first time only!
      first = false;
   }
   return min + rand() % (( max + 1 ) - min);
}

0 votes

J'espère que l'édition ne vous dérange pas, je suis presque sûr que c'était votre intention.

3 votes

Pour que le maximum soit inclus, il faut utiliser max - min + 1.

2 votes

Comprend-elle une fourchette allant du négatif au positif ?

24voto

Benjamin Lindley Points 51005
int range = max - min + 1;
int num = rand() % range + min;

6 votes

Mauvais conseil. Cela ne donnera pas une distribution uniforme. Il s'agit toutefois d'une approche assez courante (mais fondamentalement erronée).

0 votes

Pourquoi cela est-il défectueux ? Si rand() % range est relativement uniforme, je m'attendrais à ce que l'ajout d'une constante préserve l'uniformité. Ou êtes-vous en train de dire que rand() lui-même n'est pas un excellent choix pour un nombre vraiment aléatoire ? C'est vrai, mais selon ce que le PO veut faire, rand() peut être suffisant.

0 votes

@Johannes : Je pense c'est assez uniforme pour la plupart des gens, à moins qu'ils ne mentionnent spécifiquement l'uniformité parfaite comme une exigence.

10voto

Kiley Naro Points 1221

Utilisez le rand fonction :

http://www.cplusplus.com/reference/clibrary/cstdlib/rand/

Citation :

A typical way to generate pseudo-random numbers in a determined range using rand is to use the modulo of the returned value by the range span and add the initial value of the range:

( value % 100 ) is in the range 0 to 99
( value % 100 + 1 ) is in the range 1 to 100
( value % 30 + 1985 ) is in the range 1985 to 2014

1 votes

@Tux-D C'était un extrait de code copié directement du site web de cplusplus, donc je suppose que j'ai pensé que c'était la façon standard de le faire. Je n'avais pas réalisé que c'était incorrect ou peu commun de le faire de cette façon, merci pour l'info. Parce que maintenant je suis curieux, quel est exactement le problème avec cette méthode ?

0 votes

Ver Benjamin Lindley réponse ci-dessus et mes commentaires associés pour l'approche pré-C++11. Mais mon commentaire ci-dessus était erroné (j'ai mal lu votre réponse). Je vais donc le supprimer. Le site cplusplus.com est un peu correct (et bon pour une référence rapide de temps en temps) mais je ne l'utiliserais PAS comme une source faisant autorité.

0 votes

Merci pour ces informations. J'ai lu les informations ci-dessus et j'ai l'impression de mieux comprendre. Je dirais que si ma réponse n'est pas la meilleure possible, elle n'est pas NON utile. Mais c'est votre décision et je vous remercie encore de m'avoir éclairé :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X