Numeri casuali su C ++


12

Di recente mi sono abituato alle lingue moderne che includono un buon generatore casuale, che di solito è il Mersenne Twister; ora che sono tornato al C ++ devo decidere cosa usare.

Ho cercato le implementazioni di Mersenne Twister e ho notato che ce ne sono così tante: ce n'è una che è più usata e diffusa, o dovrei sceglierne una supponendo che siano tutte ugualmente buone?


1
Mi piace la tua separazione tra C ++ e linguaggi moderni.
jcora,

2
Forse dire "livello superiore" era più appropriato.
o0 '.

Penso che questa domanda appartenga a StackOverflow
TravisG

5
Su SO darei una risposta diversa perché non saprei che fosse per un motore di gioco al contrario, per esempio, delle simulazioni Monte Carlo per le terapie mediche, nel qual caso non avere 624 dimensioni di casualità può essere mortale.

Risposte:


19

C ++ 11 include un generatore Mersenne Twister di default come parte della sua nuova <random>interfaccia. Ad esempio, per generare numeri interi uniformemente tra [-10, 10] usando MT:

std::mt19937 eng; // This is the Mersenne Twister
std:::uniform_int_distribution<int> dist(-10, 10)
for (int i = 0; i < 10; ++i)
    std::cout << dist(eng) << std::endl;

Gran parte di questo è disponibile anche in qualsiasi compilatore che offre TR1 sebbene i nomi siano leggermente diversi; std::tr1::mt19937e std::tr1::uniform_int<int>.

Di solito avverto la gente di non usare Mersenne Twister. È un algoritmo ok ma molta della sua popolarità è solo il marketing. 624 dimensioni della casualità sono più di quanto la maggior parte delle persone abbia bisogno e MT ha requisiti di stato relativamente pesanti e quando esegue un ricalcolo completo della tabella può far saltare la cache. Sono personalmente parziale di xorshift che offre periodi eccellenti e distribuzioni ragionevoli per tutto ciò di cui un gioco ha bisogno, con minuscoli requisiti di memoria e CPU.

Ho scritto un generatore xorshift (principalmente?) Conforme a C ++ 11 - xorshift.hpp , xorshift.cpp - e l'ho messo di dominio pubblico. Puoi collegarlo a qualsiasi funzione di randomizzazione C ++ 11, come sopra:

xorshift eng;
std:::uniform_int_distribution<int> dist(-10, 10)
for (int i = 0; i < 10; ++i)
    std::cout << dist(eng) << std::endl;

5
Sì, questo è il tipo di risposta che stavo cercando, ecco perché ho pubblicato qui su gamedev:)
o0 '.

1
Volevo solo notare che nulla nei file che hai collegato indica che sono di dominio pubblico. Per come funziona la legge sul copyright, è necessario che ci sia una nota chiara al riguardo, dato che la legge presuppone "tutti i diritti riservati" per impostazione predefinita. In realtà è ancora più sicuro usare qualcosa come la licenza MIT o BSD a 2 clausole, dal momento che alcune giurisdizioni fondamentalmente non riconoscono che "questo è di dominio pubblico" come legalmente vincolante. Se sei interessato a vedere le persone usare il tuo codice, potrebbe valere la pena occupartene.
Sean Middleditch,

1
@seanmiddleditch: sono chiaro su questo proprio qui. Se lo desideri con una licenza in stile MIT, seguirò l'esempio di SQLite e te lo darò per soli $ 1000.

La mancanza di un'intestazione nel codice che dichiari qualcosa (cosa che fa SQLite, iirc) è il problema principale. Se non ti interessa, va bene. Ti stavo solo dando un suggerimento amichevole.
Sean Middleditch

1

Un altro RNG che ho usato prima per scopi di gioco è il "piccolo" RNG di Bob Jenkins, descritto qui .

(Ha anche un RNG di forza crittografica chiamato ISAAC, ma è più grande e più lento, e i giochi non hanno bisogno di quel livello di forza.)


1
Sembra più costoso di xorshift (4 xors e 3 turni rispetto a 4 aggiunte, 6 turni, 2 ors e xor), ha un periodo peggiore e corre il rischio di cicli molto brevi con determinate inizializzazioni. Sembra veloce ma non più veloce; periodo ok ma da nessuna parte ottimale; stesse qualità di distribuzione di base di xorshift; Non vedo alcun motivo per usarlo.

Giusto. Non ne so abbastanza dell'analisi RNG per scavare nelle proprietà di distribuzione e ciclo.
Nathan Reed,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.