Mersenne Twister è un turno -register basato PRNG (pseudo-generatore di numeri casuali) ed è quindi soggetto a cattive semi con lunghi tratti di 0 o 1 che portano a risultati relativamente prevedibili finché lo stato interno è mescolato abbastanza.
Tuttavia il costruttore che prende un singolo valore utilizza una funzione complessa su quel valore di seme che è progettato per minimizzare la probabilità di produrre tali stati 'cattivi'. C'è un secondo modo per inizializzare mt19937
in cui si imposta direttamente lo stato interno, tramite un oggetto conforme al concetto SeedSequence. È questo secondo metodo di inizializzazione in cui potrebbe essere necessario preoccuparsi della scelta di uno stato "buono" o del riscaldamento.
Lo standard include un oggetto conforme al concetto SeedSequence, chiamato seed_seq
. seed_seq
prende un numero arbitrario di valori di inizializzazione di ingresso, e poi esegue alcune operazioni su tali valori per produrre una sequenza di valori diversi adatti per impostare direttamente lo stato interno di un PRNG.
Ecco un esempio di caricamento di una sequenza di seme con dati casuali sufficienti per riempire l'intero stato std::mt19937
:
std::array<int, 624> seed_data;
std::random_device r;
std::generate_n(seed_data.data(), seed_data.size(), std::ref(r));
std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
std::mt19937 eng(seq);
Questo assicura che l'intero stato è randomizzato. Inoltre, ogni motore specifica la quantità di dati letti da seed_sequence in modo che tu possa leggere i documenti per trovare tali informazioni per qualsiasi motore tu usi.
Anche se qui carico completamente seed_seq da std::random_device
, seed_seq
è specificato in modo tale che solo alcuni numeri che non sono particolarmente casuali dovrebbero funzionare bene. Per esempio:
std::seed_seq seq{1, 2, 3, 4, 5};
std::mt19937 eng(seq);
nei commenti qui sotto Cubbi indica che seed_seq
opere di eseguire una sequenza di riscaldamento per voi.
Ecco quello che dovrebbe essere il tuo 'default' per la semina:
std::random_device r;
std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
std::mt19937 rng(seed);
Dove l'hai letto? Non ho mai sentito parlare, tutto quello che so è che essi dovrebbero essere testa di serie ... – PlasmaHH
Ad esempio, v'è una certa discussione in questo documento: http://www0.cs.ucl.ac.uk/staff/d. jones/GoodPracticeRNG.pdf – Brent
Per la maggior parte dei PRNG questo non ha assolutamente senso. La semina imposta lo stato interno e qualsiasi "riscaldamento" permuta lo stato interno, in quanto tale ha lo stesso identico effetto se questo nuovo stato fosse stato scelto come seme. – PlasmaHH