2009-03-16 2 views
5

Desidero fornire un numero e quindi ricevere un insieme di numeri casuali. Tuttavia, voglio che quei numeri siano gli stessi indipendentemente dal computer su cui lo eseguo (assumendo che io fornisca lo stesso seme).Corrispondenti numeri casuali deterministici in C++ STL

Fondamentalmente la mia domanda è: in C++, se faccio uso di rand(), ma fornisco srand() con un seme definito dall'utente anziché l'ora corrente, sarò in grado di generare lo stesso flusso di numeri casuali su qualsiasi computer?

risposta

5

srand() & rand() non sono parte del STL. In realtà fanno parte del runtime C. Sì, produrranno gli stessi risultati finché si tratta della stessa implementazione di srand()/rand().

A seconda delle esigenze, è possibile considerare l'utilizzo di Boost.Random. Fornisce diversi generatori di numeri casuali di alta qualità.

+0

Devo dire +1 su Boost.Random. Funziona alla grande e hanno persino specifiche classi deterministiche. – rlbond

4

Supponendo che le implementazioni di rand() siano uguali, sì.

Il modo più semplice per garantire ciò è includere un'implementazione nota di rand() con il programma, inclusa nel codice sorgente del progetto o nella forma di una libreria che è possibile gestire.

+0

"Ogni" è una parola GRANDE. Qualificare questo con "Most" invece di "Every" è necessario. Gli RNG più moderni sono progettati per funzionare in modo coerente su gran parte delle famiglie di hardware a 32 bit. Ma questo non dice nulla sulle macchine a 64 bit o sul raro hardware particolare. –

+0

Ecco perché ho detto che devi avere una copia di rand() che puoi controllare o almeno prevedere. – greyfade

+0

Abbastanza corretto :-) L'unica altra cosa da accertare è che è portatile in termini di tipi di dati per tutte le architetture di destinazione. –

0

Credo che se si fornisce a srand con lo stesso seme, si otterranno gli stessi risultati. Questa è praticamente la definizione di un seme in termini di generatori di numeri pseudo casuali.

7

Ci sono dozzine di PRNG s disponibili come librerie. Sceglierne uno. Tendo ad usare Mersenne Twister.

Utilizzando una libreria fornita esternamente, si evita il rischio di un'implementazione bizzarra o strana della libreria della propria lingua rand(). Finché le tue piattaforme sono tutte conformi alla stessa semantica matematica, otterrai risultati coerenti.

MT è uno dei miei preferiti perché sono un fisico e uso queste cose per Monte Carlo, dove è importante garantire la distribuzione equa delle dimensioni. Ma non utilizzare MT come PRNG crittografico!

+0

Per curiosità, perché non usare MT per crypto? Mente condividendo un link? (È una domanda onesta, non sto cercando di essere snarky :-) –

+0

È facilmente prevedibile da un piccolo numero di uscite conosciute. C'è un link nell'articolo di Wikipedia. – dmckee

+1

http://en.wikipedia.org/wiki/Mersenne_twister#Application –

0

Sì. Per un dato seme (valore iniziale), la sequenza di numeri che rand() restituisce sarà sempre la stessa.

+0

Si dovrebbe qualificare questo con "una data implementazione di rand()". Non è garantito che due PRNG producano la stessa sequenza. – greyfade

1

No, l'ANSI C standard di solo specifica che rand() deve produrre un flusso di interi casuali tra 0 e RAND_MAX, che deve essere di almeno 32767 (source). Questo flusso deve essere deterministico solo in quanto, per una determinata implementazione su una determinata macchina, deve produrre lo stesso flusso intero dato lo stesso seme.

Si desidera un PRNG portatile.Mersenne Twister (molte implementazioni collegate in basso) è piuttosto portatile, come lo è Ben Pfaff's homegrown C99-compliant PRNG. Boost.Random dovrebbe andare bene; mentre stai scrivendo il tuo codice in C++, usare Boost non limita molto la tua scelta di piattaforme (anche se alcuni compilatori "minori" (cioè non conformi) potrebbero avere problemi con il suo uso massiccio della metaprogrammazione del modello). Questo è solo un vero problema per le piattaforme embedded a basso volume e forse anche per le architetture di ricerca, quindi se per "qualsiasi computer" intendi "qualsiasi piattaforma x86/PPC/ARM/SPARC/Alpha/etc che GCC bersaglia", qualsiasi sopra dovrebbe fare bene.