W moim programie muszę uruchomić N osobnych wątków, każdy z własnym RNG, który służy do próbkowania dużego zestawu danych. Muszę być w stanie zaszczepić cały ten proces jedną wartością, aby móc odtwarzać wyniki.
Czy wystarczy po prostu sekwencyjnie zwiększać ziarno dla każdego indeksu?
Obecnie używam numpy
tych, RandomState
które korzystają z generatora liczb pseudolosowych Mersenne Twister.
Fragment kodu poniżej:
# If a random number generator seed exists
if self.random_generator_seed:
# Create a new random number generator for this instance based on its
# own index
self.random_generator_seed += instance_index
self.random_number_generator = RandomState(self.random_generator_seed)
Zasadniczo zaczynam od zarodka wprowadzonego przez użytkownika (jeśli istnieje) i dla każdej instancji / wątku kolejno dodaję indeks (od 0 do N-1) uruchomionej instancji. Nie wiem, czy to dobra praktyka, czy może jest na to lepszy sposób.
Odpowiedzi:
Z pewnością nie jest to świetna praktyka. Na przykład zastanów się, co się stanie, gdy wykonasz dwa przebiegi z nasionami root 12345 i 12346. Każdy bieg będzie miał
N-1
wspólne strumienie.Implementacje Mersenne Twister (w tym
numpy.random
irandom
) zwykle używają innego PRNG do rozszerzenia zarodka liczb całkowitych do dużego wektora stanu (624 32-bitowe liczby całkowite), którego używa MT; to jest tablica zRandomState.get_state()
. Dobrym sposobem na zrobienie tego, co chcesz, jest uruchomienie tego PRNG, zaszczepionego jednorazową liczbą całkowitą, i uzyskanie z niegoN*624
32-bitowych liczb całkowitych. Podziel strumień naN
wektory stanu i użyj,RandomState.set_state()
aby jawnie zainicjować każdąRandomState
instancję. Być może trzeba będzie konsultować źródła C onumpy.random
lub_random
z biblioteki standardowej, aby ta PRNG (są takie same). Nie jestem pewien, czy ktoś zaimplementował samodzielną wersję tego PRNG dla Pythona.źródło
RandomState
implementacji w rozwoju, która wykorzystuje algorytm z ustawialnymi strumieniami. Innymi słowy, inicjujesz każdąRandomState
instancję przy użyciu tego samego materiału źródłowego i różnych identyfikatorów strumienia (tylko zwiększenie jest w porządku) i masz zagwarantowane niezależne strumienie. pypi.python.org/pypi/randomstateRozwiązaniem stosowanym w przetwarzaniu równoległym jest użycie generatora losowegoΦ ( u ) , gdzie u jest twoim nasieniem, przez N. partie:
gdzieΦn( u ) = Φ (Φn - 1( u ) ) . W ten sposób używasz pojedynczego ziarna, a wszystkie sekwencje są jednolite i niezależne.
źródło
Istnieje teraz pakiet Python o nazwie RandomGen, który ma metody pozwalające to osiągnąć.
To wspiera niezależnych strumieni utworzonych z jednego materiału siewnego, a także protokołu narciarskie dla starszych generatorów liczb losowych, takich jak MT19937.
źródło
Niektóre osoby twierdzą, że istnieją korelacje w liczbach losowych generowanych przez sekwencyjne nasiona. /programming/10900852/near-seeds-in-random-number-generation-may-give-similar-random-numbers Nie jestem pewien, czy to prawda.
Jeśli się tym martwisz, dlaczego nie użyć jednego generatora liczb losowych, aby wybrać nasiona dla wszystkich innych generatorów?
źródło