Supponiamo di voler utilizzare le funzionalità C ++ <random>
in un programma pratico (per alcune definizioni di "pratico" - i vincoli qui fanno parte di questa domanda). Il codice è approssimativamente simile a questo:
int main(int argc, char **argv) {
int seed = get_user_provided_seed_value(argc, argv);
if (seed == 0) seed = std::random_device()();
ENGINE g(seed); // TODO: proper seeding?
go_on_and_use(g);
}
La mia domanda è: per quale tipo dovresti usare ENGINE
?
Lo dicevo sempre
std::mt19937
perché era veloce digitare e aveva il riconoscimento del nome. Ma in questi giorni sembra che tutti stiano dicendo che il Mersenne Twister è molto pesante e ostile alla cache e non supera nemmeno tutti i test statistici che altri fanno.Vorrei dire
std::default_random_engine
perché è l'ovvio "default". Ma non so se varia da piattaforma a piattaforma e non so se sia statisticamente utile.Dal momento che ognuno è su una piattaforma a 64-bit in questi giorni, dovremmo almeno essere utilizzando
std::mt19937_64
overstd::mt19937
?Vorrei dirlo
pcg64
oxoroshiro128
perché sembrano rispettati e leggeri, ma non esistono<random>
affatto.Io non so niente di
minstd_rand
,minstd_rand0
,ranlux24
,knuth_b
, ecc - di certo si deve essere buono per qualcosa?
Ovviamente ci sono alcuni vincoli concorrenti qui.
Forza del motore (
<random>
non ha PRNG crittograficamente forti, ma alcuni di quelli standardizzati sono "più deboli" di altri, giusto?)sizeof
il motore.La sua velocità
operator()
.Facilità di semina.
mt19937
è notoriamente difficile seminare correttamente perché ha così tanto stato da inizializzare.Portabilità tra i fornitori di biblioteche. Se un fornitore
foo_engine
produce numeri diversi da quelli di un altro fornitorefoo_engine
, ciò non va bene per alcune applicazioni. (Speriamo che questo non escluda nulla tranne forsedefault_random_engine
.)
Pesando tutti questi vincoli nel miglior modo possibile, quale diresti sia la migliore risposta "best practice restando all'interno della libreria standard"? Devo continuare a usare std::mt19937
o cosa?