Liczby losowe w C ++


12

Niedawno przyzwyczaiłem się do współczesnych języków, w tym dobrego generatora losowego, którym zwykle jest Twister Mersenne; teraz, gdy wróciłem do C ++, muszę zdecydować, którego użyć.

Szukałem implementacji Mersenne Twister i zauważyłem, że jest ich tak wiele: czy jest taka, która jest bardziej używana i rozpowszechniona, czy też mam wybrać jedną, zakładając, że wszystkie są równie dobre?


1
Podoba mi się twoje oddzielenie C ++ i języków współczesnych.
— jcora

2
Może powiedzenie „wyższy poziom” było bardziej odpowiednie.
— o0 ”.

Myślę, że to pytanie należy do stackoverflow
— TravisG,

5
W przypadku SO podam inną odpowiedź, ponieważ nie wiedziałbym, że dotyczy to silnika gry, w przeciwieństwie do, powiedzmy, symulacji Monte Carlo do terapii medycznych, w którym to przypadku brak 624 wymiarów losowości może być śmiertelny.

Odpowiedzi:


19

C ++ 11 domyślnie zawiera generator Mersenne Twister jako część nowego <random>interfejsu. Na przykład, aby równomiernie generować liczby całkowite między [-10, 10] przy użyciu 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;

Większość tego jest również dostępna w dowolnym kompilatorze oferującym TR1, chociaż nazwy są nieco inne; std::tr1::mt19937a std::tr1::uniform_int<int>.

Zazwyczaj ostrzegam ludzi przed używaniem Mersenne Twister. Algorytm jest w porządku, ale duża część jego popularności to tylko marketing. 624 wymiary losowości są więcej, niż potrzeba większości ludzi, a MT niesie ze sobą stosunkowo wysokie wymagania dotyczące stanu, a po ponownym przeliczeniu pełnej tabeli może zdmuchnąć pamięć podręczną. Osobiście jestem zwolennikiem xorshift, który zapewnia doskonałe okresy i rozsądną dystrybucję wszystkiego, czego potrzebuje gra, z niewielkimi wymaganiami dotyczącymi pamięci i procesora.

Napisałem (głównie?) Zgodny z C ++ 11 xorshift generator - xorshift.hpp , xorshift.cpp - i umieściłem go w domenie publicznej. Możesz podłączyć to do dowolnej funkcji randomizacji C ++ 11, jak wyżej:

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

5
Tak, takiej odpowiedzi szukałem, dlatego zamieściłem tutaj na gamedev
— :)

1
Chciałem tylko zauważyć, że nic w połączonych plikach nie wskazuje, że należą one do domeny publicznej. Sposób, w jaki działa prawo autorskie, naprawdę musi być wyraźnie zaznaczony, ponieważ prawo domyślnie zakłada „wszelkie prawa zastrzeżone”. Jeszcze bezpieczniej jest po prostu użyć czegoś takiego jak licencja 2-klauzulowa MIT lub BSD, ponieważ niektóre jurysdykcje zasadniczo nie uznają, że „jest to domena publiczna” jako prawnie wiążąca. Jeśli chcesz zobaczyć, jak ludzie używają Twojego kodu, warto się tym zająć.
— Sean Middleditch,

1
@seanmiddleditch: Mówię o tym właśnie tutaj. Jeśli chcesz na licencji MIT, pójdę za przykładem SQLite i dam ci to za jedyne 1000 $.

Głównym problemem jest brak nagłówka w kodzie deklarującym cokolwiek (co robi SQLite, iirc). Jeśli cię to nie obchodzi, to świetnie. Dałem ci tylko przyjazną sugestię.
— Sean Middleditch

1

Innym RNG, którego użyłem wcześniej do celów gamedev, jest opisany tutaj „mały” RNG Boba Jenkinsa .

(Ma również RNG o sile kryptograficznej o nazwie ISAAC, ale jest większy i wolniejszy, a gry nie potrzebują takiego poziomu siły).


1
To wygląda drożej niż xorshift (4 xors i 3 zmiany vs. 4 dodania, 6 zmian, 2 orki i xor), ma gorszy okres i wiąże się z ryzykiem bardzo krótkich cykli z pewnymi inicjalizacjami. Wygląda szybko, ale nie najszybciej; OK okres, ale nigdzie nie jest optymalny; te same podstawowe cechy dystrybucji, co xorshift; Nie widzę żadnego powodu, aby z niego korzystać.

Słusznie. Nie wiem wystarczająco dużo o analizie RNG, aby zagłębić się w właściwości rozkładu i cyklu.
— Nathan Reed
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.