2009-03-16 18 views
5

Chcę podać liczbę, a następnie otrzymać zestaw liczb losowych. Jednak chcę, aby te liczby były takie same bez względu na komputer, na którym go uruchomiłem (zakładając, że dostarczam to samo nasiono).Deterministyczne strumienie liczb losowych w C++ STL

Zasadniczo moje pytanie brzmi: w C++, jeśli użyję rand(), ale dostarczę srand() z nasieniem zdefiniowanym przez użytkownika zamiast bieżącego czasu, czy będę w stanie wygenerować ten sam losowy strumień liczbowy na dowolnym komputerze?

Odpowiedz

5

srand() & rand() nie są częścią STL. W rzeczywistości są częścią środowiska wykonawczego C. Tak, będą one dawały takie same wyniki, o ile są zgodne z tą samą implementacją srand()/rand().

W zależności od potrzeb warto rozważyć użycie numeru Boost.Random. Zapewnia kilka wysokiej jakości generatorów liczb losowych.

+0

Będę musiał powiedzieć +1 przy Boost.Random. Działa świetnie i mają nawet określone klasy deterministyczne. – rlbond

4

Zakładając, że implementacje rand() są takie same, tak.

Najprostszym sposobem zapewnienia tego jest dołączenie znanej implementacji rand() do twojego programu - zawartej w kodzie źródłowym twojego projektu lub w formie biblioteki, którą możesz zarządzać.

+0

"Każdy" to WIELKIE słowo. Wymagane jest zakwalifikowanie tego za pomocą "Most" zamiast "Every". Większość nowoczesnych RNG zaprojektowano tak, aby działały konsekwentnie w większości rodzin 32-bitowego sprzętu. Ale to nie mówi nic o komputerach 64-bitowych lub rzadkim sprzęcie. –

+0

Dlatego powiedziałem, że potrzebujesz kopii Rand(), którą możesz kontrolować lub przynajmniej przewidzieć. – greyfade

+0

Wystarczająco uczciwe :-) Jedyną rzeczą, której należy się upewnić, jest to, że jest przenośny pod względem typów danych dla wszystkich architektur docelowych. –

0

Wierzę, że jeśli dostarczysz srand z tym samym materiałem siewnym, uzyskasz takie same wyniki. Taka jest definicja nasion w kategoriach generatorów liczb pseudolosowych.

7

Dostępne są dziesiątki PRNG s jako biblioteki. Wybierz jedno. Zwykle używam Mersenne Twister.

Korzystając z zewnętrznej biblioteki, ominiesz ryzyko dziwnej lub błędnej implementacji biblioteki Twojego języka rand(). Dopóki twoje platformy będą zgodne z tą samą matematyczną semantyką, uzyskasz spójne wyniki.

MT jest moim ulubionym, ponieważ jestem fizykiem i używam tych rzeczy w Monte Carlo, gdzie ważna jest gwarancja równego podziału na wysokie wymiary. Ale nie używają MT jako kryptograficznego PRNG!

+0

Z ciekawości, czemu nie skorzystać z MT dla krypto? Umysł udostępniający link? (To szczere pytanie, nie próbuję być chytry :-) –

+0

Łatwo to przewidzieć z niewielkiej liczby znanych wyników. W artykule wikipedia znajduje się link. – dmckee

+1

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

0

Tak. Dla danego materiału siewnego (wartość początkowa) sekwencja liczb zwracanych przez rand() zawsze będzie taka sama.

+0

Powinieneś zakwalifikować to za pomocą "danej implementacji rand()". Żadne dwa PRNG nie są w stanie wytworzyć tej samej sekwencji. – greyfade

1

Nie ANSI C Standard tylko określa, że ​​rand() musi wytwarzać strumień liczb całkowitych od 0 do RAND_MAX, która musi być co najmniej 32767 (source). Strumień ten musi być deterministyczny tylko w tym, że dla danej implementacji na danej maszynie musi generować ten sam strumień liczb całkowitych z tego samego materiału siewnego.

Potrzebujesz przenośnego PRNG.Mersenne Twister (wiele implementacji połączonych na dole) jest całkiem przenośne, podobnie jak Ben Pfaff's homegrown C99-compliant PRNG. Boost.Random też powinno być w porządku; kiedy piszesz swój kod w C++, użycie Boost nie ogranicza twojego wyboru wielu platform (chociaż niektórzy "mniejsi" (tzn. niespełniający wymagań) kompilatorzy mogą mieć kłopoty z intensywnym korzystaniem z metaprogramowania szablonów). Jest to naprawdę problem tylko dla wbudowanych platform o małej pojemności i być może nowatorskich architektur badawczych, więc jeśli przez "dowolny komputer" rozumie się "dowolną platformę x86/PPC/ARM/SPARC/Alpha/itp., Do której GCC jest kierowany", dowolny z powyżej powinien zrobić dobrze.