Szybsza pseudolosowość

0

Witam.
Piszę w C++ pewien algorytm randomizowany, który w bardzo krótkich odstępach czasu potrzebuje nowych liczb pseudolosowych. I tutaj pojawia się problem - otóż funkcja

rand()

przy tak krótkich odstępach czasu zwraca bardzo bliskie sobie wartości. Jak można zwiększyć ową pseudolosowość?

Gwoli ścisłości: dokładnie raz w main() wywołuję

srand(time(NULL));

, więc błąd tutaj nie polega na tym, że robiłbym to za każdym razem przed losowaniem kolejnej liczby.

Być może ma znaczenie również to, że potrzebuję liczb z przedziału [0; 1), więc instrukcja losowania nowej liczby wygląda u mnie tak:

x = double(rand()) / RAND_MAX;
0

Bo LCG jest dość cienki. Użyj MT lub innego dość mocnego i dającego lepszy szum.

0

@up - LCG ma różne wady, ale zwracanie przy krótkich odstępach bardzo bliskie sobie wartości do nich nie należy.

@patry93 - Jesteś pewien że sranda używasz tylko raz? Jesteś pewien że problem leży w tym że rand zwraca bliskie sobie wartości? Jaki kompilator/środowisko i system?

0

W C++ właśnie po to jest <random>. Zapoznaj się z tym: http://en.cppreference.com/w/cpp/numeric/random

Oczywiście jeszcze kompilator musi to obsługiwać.

1

Jedno jest pewne - w przypadku rand czas nie ma nic do gadania.

0

jeżeli piszesz pod linuksem, to możesz czytać pseudolosowe dane z plików /dev/random i /dev/urandom

1

Czas, tak jak pisze adf88, w przypadku generatorów liczb losowych nie ma znaczenia.
Jeśli masz problemy czasowe to znaczy, że "srand(time(NULL));" umieściłeś wewnątrz pętli.

Standardowy generator jest kiepski. Kolejne pary liczb wykazują pewną korelację, ale nie jest to korelacja na zasadzie, że liczby są sobie bliskie.
Przykładowo wypełniając jedynkami kwadratową szachownicę o rozmiarze RAND_MAX+1, w ten sposób, że nieskończona pętlą ustawia jedynkę dla współrzędnych (rand(), rand()), nigdy nie uzyskasz pełnego wypełnienia. W takim wypadku zobaczysz wzorek, jedynki będą się układać wzdłuż równoległych bliskich sobie prostych. Taka natura tego generatora pseudolosowego!
Z tego powodu ten generator nie jest najlepszy do poważnych obliczeń Monte Carlo, poszukaj alternatywnych generatorów liczb pseudolosowych (patrz na sugestię winerfresh).

0

Standardowy rand() jest słaby i chyba do tego wolny, bo używa dzielenia, a to jest dość kosztowna operacja.
Wystarczy mnożenie, dodawanie, xor, itp.

np. taki prosty generator spełnia wszystkie standardowe kryteria dla generatorów i będzie pewnie znacznie szybszy:

uint xor128(void) {

  uint t = x ^ (x << 11);

  x = y; y = z; z = w;
  return w = w ^ (w >> 19) ^ (t ^ (t >> 8));

}

cztery zmienne statyczne: x,y,z,w, należy wcześniej ustawić.

1

Do dziś pamiętam moje zdziwko kiedy do wykonania jakiegoś testu użyłam użyłem bibliotecznego rand. Jakoś sumowałem liczby losowe, po 256 sztuk czy podobnie, wszystkie wyniki były identyczne...

3
adf88 napisał(a):

Do dziś pamiętam moje zdziwko kiedy do wykonania jakiegoś testu użyłam bibliotecznego rand. Jakoś sumowałem liczby losowe, po 256 sztuk czy podobnie, wszystkie wyniki były identyczne...

Eeee?

1 użytkowników online, w tym zalogowanych: 0, gości: 1