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]
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));
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:
Nombre aléatoire dans une plage
auto val = Random::get(-10, 10); // Integer
auto val = Random::get(10.f, -10.f); // Float point
Booléen aléatoire
auto val = Random::get<bool>( ) // 50% to generate true
auto val = Random::get<bool>( 0.7 ) // 70% to generate true
Valeur aléatoire d'un std :: initilizer_list
auto val = Random::get( { 1, 3, 5, 7, 9 } ); // val = 1 or 3 or...
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:
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;
}
~
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>);