ustawia losowe ziarno programowo w Pythonie

83

Mam dość duży program, w którym używam funkcji z randommodułu w różnych plikach. Chciałbym móc raz ustawić losowe ziarno w jednym miejscu, aby program zawsze zwracał te same wyniki. Czy można to w ogóle osiągnąć python?

Mischa Obrecht
źródło

Odpowiedzi:

121

Główny moduł Pythona, który jest uruchamiany, powinien import randomi powinien zostać wywołany random.seed(n)- jest to współdzielone między wszystkimi innymi importami, o randomile gdzieś indziej nie resetuje ziarna.

Jon Clements
źródło
3
czy mogę gdzieś zresetować ziarno, nie wiedząc o tym? bo umieszczenie nasionka raz w głównym pliku nie załatwia sprawy
Mischa Obrecht
1
@MischaObrecht Myślę, że tak - ziarno jest inicjowane tylko przy pierwszym imporcie modułu losowego - jeśli zostanie zaimportowane więcej niż raz, nie przeprowadzi inicjalizacji i nie zresetuje ziarna - więc gdzieś w kodzie musi być wyraźne wywołanie
Jon Clements
3
Jeśli wywołujesz metody z randomkodu poziomu modułu, który importujesz w main, zanim dojdziesz do random.seed(n)in main, wtedy te wywołania zostaną wykonane przed ziarnem, a więc będą rozłożone w czasie i skutecznie niemożliwe do odtworzenia losowy.
Russell Borogove
13
Jeśli okaże się, że jakiś kod innej firmy ponownie zasiewa RNG (mało prawdopodobne, ale możliwe), zauważ, że możesz utworzyć dodatkowe generatory liczb losowych z niezależnym stanem za pośrednictwem random.Random()konstruktora i używać tych, gdy ważna jest ścisła odtwarzalność.
Russell Borogove
To nie działa dla mnie. Nie mam powtarzalnego kodu. Zgaduję, że będę musiał sprawdzić dokumentację wszystkich zaimportowanych bibliotek ... (patrz stackoverflow.com/questions/37886997/ ...
B Furtado
36

Komentarz zss powinien być wyróżniony jako faktyczna odpowiedź:

Kolejna rzecz, na którą ludzie powinni uważać: jeśli używasz numpy.random, musisz użyć, numpy.random.seed()aby ustawić ziarno. Użycie random.seed()nie ustawi ziarna dla liczb losowych wygenerowanych z numpy.random. To mnie przez chwilę zdezorientowało. -zss

Sida Zhou
źródło
Absolutnie prawda, jeśli gdzieś w swojej aplikacji używasz liczb losowych z random module, powiedzmy, funkcji, random.choices()a następnie w innym miejscu z numpygeneratora liczb losowych, powiedzmy, np.random.normal()że musisz ustawić ziarno dla obu modułów. Co mogę zrobić, to zazwyczaj mają kilka linii w moim main.pyLike random.seed(my_seed)a np.random.seed(my_seed). Kudos to zss
Aenaon
Sage ma podobny problem, ponieważ jego PRNG różni się od Pythona i Numpy. Użyj set_random_seed()dla szałwii.
Brent Baccala
8

Na początku swojej aplikacji zadzwoń, random.seed(x)upewniając się, że x jest zawsze takie samo. Zapewni to, że sekwencja liczb pseudolosowych będzie taka sama podczas każdego uruchomienia aplikacji.

Chimera
źródło
3

Jon Clements właściwie odpowiada na moje pytanie. Jednak to nie był prawdziwy problem: okazuje się, że przyczyną losowości mojego kodu był numpy.linalg SVD, ponieważ nie zawsze daje takie same wyniki dla źle uwarunkowanych macierzy !!

Więc pamiętaj, aby sprawdzić to w swoim kodzie, jeśli masz te same problemy!

Mischa Obrecht
źródło
23
Kolejna rzecz, na którą ludzie powinni uważać: jeśli używasz numpy.random, musisz użyć numpy.random.seed (), aby ustawić ziarno. Użycie random.seed () nie ustawi ziarna dla liczb losowych generowanych z numpy.random. To mnie przez chwilę zdezorientowało.
zss
1

Opierając się na poprzednich odpowiedziach: pamiętaj, że wiele konstrukcji może różnić się ścieżkami wykonania, nawet jeśli wszystkie nasiona są kontrolowane.

Pomyślałem " dobrze, ustawiłem swoje seedy, aby były zawsze takie same i nie mam żadnych zmieniających się / zewnętrznych zależności, dlatego ścieżka wykonania mojego kodu powinna być zawsze taka sama ”, ale to źle.

Przykładem, który mnie ugryzł, było to list(set(...)), że otrzymana kolejność może się różnić.

JBSnorro
źródło
Słuszna uwaga, to mnie wcześniej paliło. Również takie rzeczy, jak uzyskiwanie wyników z bazy danych, te wracają poza kolejnością (losowo), chyba że określono inaczej
Justin Furuness
0

Ważnym zastrzeżeniem jest to, że w wersjach Pythona starszych niż 3.7 klucze słownika nie są deterministyczne. Może to prowadzić do losowości w programie lub nawet do innej kolejności, w jakiej generowane są liczby losowe, a tym samym do niedeterministycznych liczb losowych. Wniosek aktualizacja Pythona.

Davoud Taghawi-Nejad
źródło
-14

Możesz to dość łatwo zagwarantować, używając własnego generatora liczb losowych.

Po prostu wybierz trzy duże liczby pierwsze (zakładając, że nie jest to aplikacja kryptograficzna) i podłącz je do a, b i c: a = ((a * b)% c) To daje system sprzężenia zwrotnego, który generuje całkiem przypadkowe dane. Zwróć uwagę, że nie wszystkie liczby pierwsze działają równie dobrze, ale jeśli wykonujesz tylko symulację, nie powinno to mieć znaczenia - wszystko, czego naprawdę potrzebujesz do większości symulacji, to mieszanina liczb ze wzorem (pseudolosowym, pamiętaj) na tyle złożonym, że w jakiś sposób nie pasuje do Twojej aplikacji.

Knuth o tym mówi.

user1277476
źródło
10
Zmiana własnego jest niepotrzebna, ponieważ Python ma doskonałe funkcje liczb losowych w swojej standardowej bibliotece i bardzo łatwo jest stworzyć naprawdę zły generator, jeśli nie wiesz, co robisz.
Russell Borogove
6
Zgadzam się, że to całkiem złe rozwiązanie: w symulacjach Monte Carlo (którym jest mój program), gdzie zwykle zbiera się miliony próbek, skorelowane liczby losowe (pochodzące ze złego generatora) mogą łatwo zepsuć wyniki !!
Mischa Obrecht
Masz na myśli, że Knuth cały czas o tym mówi? Nawet teraz?
oznacza-znaczenie