web-dev-qa-db-fra.com

Générer des nombres aléatoires à l'aide de la bibliothèque aléatoire C ++ 11

Comme le titre l'indique, j'essaie de trouver un moyen de générer des nombres aléatoires à l'aide de la nouvelle bibliothèque C++ 11 <random>. Je l'ai essayé avec ce code:

std::default_random_engine generator;
std::uniform_real_distribution<double> uniform_distance(1, 10.001);

Le problème avec le code que j'ai est que chaque fois que je compile et l'exécute, il génère toujours les mêmes nombres. Ma question est donc de savoir quelles autres fonctions de la bibliothèque aléatoire peuvent accomplir cela tout en étant réellement aléatoires.

Pour mon cas d'utilisation particulier, j'essayais d'obtenir une valeur comprise dans la plage [1, 10]

125
smac89

Stephan T. Lavavej (stl) de Microsoft a expliqué à Going Native comment utiliser les nouvelles fonctions aléatoires C++ 11 et pourquoi ne pas utiliser Rand(). Il y a inclus une diapositive qui résout fondamentalement votre question. J'ai copié le code de la diapositive ci-dessous.

Vous pouvez voir son exposé complet ici: http://channel9.msdn.com/Events/GoingNative/2013/Rand-Considered-Harmful

#include <random>
#include <iostream>

int main() {
    std::random_device rd;
    std::mt19937 mt(rd());
    std::uniform_real_distribution<double> dist(1.0, 10.0);

    for (int i=0; i<16; ++i)
        std::cout << dist(mt) << "\n";
}

Nous utilisons une fois random_device pour créer le générateur de nombres aléatoires nommé mt. random_device() est plus lent que mt19937, mais il n'est pas nécessaire de l'ensemencer car il demande des données aléatoires à votre système d'exploitation (qui se source à différents endroits, comme RdRand par exemple ).


En regardant cette question/réponse , il apparaît que uniform_real_distribution renvoie un nombre compris dans la plage [a, b), où vous voulez [a, b]. Pour ce faire, notre uniform_real_distibution devrait en réalité ressembler à:

std::uniform_real_distribution<double> dist(1, std::nextafter(10, DBL_MAX));
178
Bill Lynch

Ma bibliothèque 'random' fournit un wrapper très pratique autour des classes aléatoires C++ 11. Vous pouvez faire presque toutes les choses avec une simple méthode "get".

Exemples:

  1. Nombre aléatoire dans une plage

    auto val = Random::get(-10, 10); // Integer
    auto val = Random::get(10.f, -10.f); // Float point
    
  2. Booléen aléatoire

    auto val = Random::get<bool>( ) // 50% to generate true
    auto val = Random::get<bool>( 0.7 ) // 70% to generate true
    
  3. Valeur aléatoire d'un std :: initilizer_list

    auto val = Random::get( { 1, 3, 5, 7, 9 } ); // val = 1 or 3 or...
    
  4. Itérateur aléatoire de la gamme d'itérateurs ou de tous les conteneurs

    auto it = Random::get( vec.begin(), vec.end() ); // it = random iterator
    auto it = Random::get( vec ); // return random iterator
    

Et encore plus de choses! Consultez la page github:

https://github.com/effolkronium/random

21
Ilya Polishchuk

Voici quelque chose que je viens d'écrire dans ce sens:

#include <random>
#include <chrono>
#include <thread>

using namespace std;

//==============================================================
// RANDOM BACKOFF TIME
//==============================================================
class backoff_time_t {
  public:
    random_device                      rd;
    mt19937                            mt;
    uniform_real_distribution<double>  dist;

    backoff_time_t() : rd{}, mt{rd()}, dist{0.5, 1.5} {}

    double Rand() {
      return dist(mt);
    }
};

thread_local backoff_time_t backoff_time;


int main(int argc, char** argv) {
   double x1 = backoff_time.Rand();
   double x2 = backoff_time.Rand();
   double x3 = backoff_time.Rand();
   double x4 = backoff_time.Rand();
   return 0;
}

~

2
Bill Moore

Voici quelques ressources que vous pouvez lire sur le générateur de nombres pseudo-aléatoires.

https://en.wikipedia.org/wiki/Pseudorandom_number_generator

Fondamentalement, les nombres aléatoires dans l'ordinateur ont besoin d'une graine (ce nombre peut être l'heure système actuelle).

Remplacer

std::default_random_engine generator;

Par

std::default_random_engine generator(<some seed number>);