După cum sugerează și titlul, am încercat să găsesc o modalitate de generare de numere aleatoare folosind noul C++11 `
std::default_random_engine generator;
std::uniform_real_distribution<double> uniform_distance(1, 10.001);
Problema cu codul am este că de fiecare dată când compilați și rulați-l, se generează întotdeauna aceleași numere. Deci, întrebarea mea este ce alte funcții din întâmplare library poate realiza acest lucru în timp ce a fi cu adevărat aleatoriu?
Pentru caz particular de folosire, am fost încercarea de a obține o valoare din intervalul [1, 10]
Ștefan T. Lavavej (stl) de la Microsoft a făcut-o discuție la O Nativi despre cum să folosiți noul C++11 funcții aleatoare și de ce să nu folosim rand()`. În ea, el a inclus un diapozitiv care, practic, rezolvă întrebarea ta. Am'am copiat codul de la acel diapozitiv de mai jos.
Puteți vedea plin vorbim aici: 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";
}
Folosim random_device
o dată la semințe de generatorul de numere aleatorii numit mt
. random_device()
este mai lent decât `mt19937, dar ea nu are nevoie să fie însămânțate pentru că cererile aleatoare de date din sistemul de operare (care va fi sursa din diverse locații, cum ar fi RdRand de exemplu).
În căutarea la această întrebare / răspuns](https://stackoverflow.com/questions/16224446/stduniform-real-distribution-inclusive-range), se pare că uniform_real_distribution
returnează un număr în intervalul [a, b)
, unde[a, b]. Pentru a face asta, ne
uniform_real_distibution` ar trebui să arate ca de fapt:
std::uniform_real_distribution<double> dist(1, std::nextafter(10, DBL_MAX));
Mi 'aleatorie' biblioteca oferă o mare convenabil înveliș în jurul valorii de C++11 clase aleatoare. Poti face aproape toate lucrurile cu un simplu 'ia' metoda.
Exemple:
auto val = Random::get(-10, 10); // număr Întreg auto val = Random::ia(10.f, -10.f); // Float punct
auto val = Random::ia
auto val = Random::ia( { 1, 3, 5, 7, 9 } ); // val = 1 sau 3 sau...
auto = Random::get( vec.begin(), vec.end() ); // a = random iterator auto = Random::get( vec ); // întoarce aleatoare iterator
Și chiar și mai multe lucruri ! Check out pagina github:
Aici's ceva ce am scris de-a lungul acestor linii::
#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;
}
~
Aici este o resursă puteți citi despre pseudo-generator de numere aleatorii.
https://en.wikipedia.org/wiki/Pseudorandom_number_generator
Practic, numere aleatoare în computer nevoie de o sămânță (acest număr poate fi sistemul actual de timp).
Înlocuiți
std::default_random_engine generator;
De
std::default_random_engine generator(<some seed number>);
Te'am două situații comune. Primul este că vrei numere aleatoare și nu't prea fussed despre calitatea sau viteza de executie. În acest caz, utilizați următoarele macro
#define uniform() (rand()/(RAND_MAX + 1.0))
asta îți dă p în intervalul de la 0 la 1 - epsilon (cu excepția cazului în RAND_MAX este mai mare decât precizia de dublu, dar vă faceți griji despre asta când vii la el).
int x = (int) (uniformă() * N);
Acum dă un număr întreg aleator la 0 la N -1.
Dacă aveți nevoie de alte distribuții, trebuie să se transforme p. Sau uneori se's ușor pentru a apela uniformă() de mai multe ori.
Dacă doriți repetabile comportament, semințe cu o constantă, în caz contrar semințele cu un apel în timp().
Acum, dacă sunteți deranjat despre calitate sau de timp a alerga de performanță, rescrie uniformă(). Dar altfel nu - 't atinge codul. Păstrați întotdeauna uniform pe() 0 la 1 minus epsilon. Acum puteți încheia C++ număr aleator biblioteca pentru a crea o mai bună uniformă(), dar care's un fel de nivel mediu opțiune. Dacă sunteți deranjat despre caracteristicile de RNG, apoi se's, de asemenea, în valoare de a investi un pic de timp pentru a înțelege cum stau la baza metodelor de muncă, atunci oferi unul. Deci'ai control complet din cod, și vă pot garanta că cu aceeași sămânță, secvența va fi întotdeauna exact același, indiferent de platforma sau ce versiune de C++ care faci trimitere.