random.seed (): Co to robi?


177

Nie wiem, co random.seed()robi się w Pythonie. Na przykład, dlaczego poniższe testy robią to, co robią (konsekwentnie)?

>>> import random
>>> random.seed(9001)
>>> random.randint(1, 10)
1
>>> random.randint(1, 10)
3
>>> random.randint(1, 10)
6
>>> random.randint(1, 10)
6
>>> random.randint(1, 10)
7

Nie mogłem znaleźć dobrej dokumentacji na ten temat.


30
Generowanie liczb losowych nie jest naprawdę „przypadkowe”. Jest deterministyczna, a sekwencja, którą generuje, jest podyktowana wartością ziarna, do której przechodzisz random.seed. Zwykle po prostu wywołujesz random.seed()i używa bieżącego czasu jako wartości początkowej, co oznacza, że ​​za każdym razem, gdy uruchamiasz skrypt, otrzymasz inną sekwencję wartości.
Asad Saeeduddin

3
Przekazanie tego samego ziarna losowo, a następnie wywołanie go da ci ten sam zestaw liczb. Działa to zgodnie z założeniami, a jeśli chcesz, aby wyniki były inne za każdym razem, będziesz musiał zasiać coś innego za każdym razem, gdy uruchomisz aplikację (na przykład wyjście z / dev / random lub time)
Tymoteusz Paul

5
Ziarno jest tym, co jest podawane do RNG w celu wygenerowania pierwszej liczby losowej. Po tym, RNG jest samowystarczalny. Z tego powodu nie widzisz konsekwentnie tej samej odpowiedzi. Jeśli uruchomisz ten skrypt ponownie, otrzymasz tę samą sekwencję „losowych” liczb. Ustawienie ziarna jest pomocne, jeśli chcesz odtworzyć wyniki, ponieważ wszystkie generowane liczby „losowe” będą zawsze takie same.
Blink

Warto wspomnieć: sekwencja pokazana w tym poście jest w Pythonie 2. Python 3 podaje inną sekwencję.
ggorlen

1
Użycie przez @Blink „liczby losowej” jest mylące. RNG ma stan wewnętrzny, który jest zasilany samodzielnie. Z tego stanu wewnętrznego wyprowadzane są dane wyjściowe dla randint (1,10) i innych wywołań. Jeśli RNG zasilałby się z wyjścia randint (1,10), sekwencja zwaliłaby się do 1 z co najwyżej 10 sekwencji i sekwencja powtórzyłaby się po co najwyżej 10 liczbach.
Joachim Wagner

Odpowiedzi:


213

Generatory liczb pseudolosowych działają, wykonując pewne operacje na wartości. Na ogół ta wartość jest poprzednią liczbą wygenerowaną przez generator. Jednak przy pierwszym użyciu generatora nie ma poprzedniej wartości.

Wypełnienie generatora liczb pseudolosowych daje mu pierwszą „poprzednią” wartość. Każda wartość początkowa będzie odpowiadać sekwencji generowanych wartości dla danego generatora liczb losowych. Oznacza to, że jeśli podasz dwa razy to samo ziarno, otrzymasz dwukrotnie tę samą sekwencję liczb.

Ogólnie rzecz biorąc, chcesz zapełnić generator liczb losowych jakąś wartością, która będzie zmieniać każde wykonanie programu. Na przykład, często używanym nasieniem jest aktualny czas. Powodem, dla którego nie dzieje się to automatycznie, jest to, że jeśli chcesz, możesz podać określone ziarno, aby uzyskać znaną sekwencję liczb.


39
Może warto wspomnieć, że czasami chcemy dać ziarno, aby ta sama losowa sekwencja była generowana przy każdym uruchomieniu programu. Czasami unika się przypadkowości w programie, aby zachować deterministyczne zachowanie programu i możliwość odtworzenia problemów / błędów.
ViFI

1
Zgodnie z tym, co powiedział @ViFI, utrzymanie deterministycznego zachowania programu (ze stałym nasieniem lub ustaloną sekwencją nasion) może również pozwolić ci lepiej ocenić, czy jakaś zmiana w twoim programie jest korzystna, czy nie.
shaneb,

czy zechciałbyś wyjaśnić coś z prawdziwego życia. Nie rozumiem przypadku użycia tego samego. Czy mamy coś podobnego do tego w innym języku programowania?
Shashank Vivek

1
Oto scenariusz z prawdziwego życia: stackoverflow.com/questions/5836335/… . Losowe nasiona są również powszechne w celu uzyskania powtarzalnych wyników badań. Na przykład, jeśli jesteś naukowcem zajmującym się danymi i chcesz opublikować swoje wyniki za pomocą jakiegoś modelu, który wykorzystuje losowość (np. Losowy las), będziesz chciał dołączyć ziarno do opublikowanego kodu, aby ludzie mogli upewnić się, że obliczenia są powtarzalne.
Galen Long

89

Wszystkie inne odpowiedzi nie wydają się wyjaśniać użycia random.seed (). Oto prosty przykład ( źródło ):

import random
random.seed( 3 )
print "Random number with seed 3 : ", random.random() #will generate a random number 
#if you want to use the same random number once again in your program
random.seed( 3 )
random.random()   # same random number as before

33
>>> random.seed(9001)   
>>> random.randint(1, 10)  
1     
>>> random.seed(9001)     
>>> random.randint(1, 10)    
1           
>>> random.seed(9001)          
>>> random.randint(1, 10)                 
1                  
>>> random.seed(9001)         
>>> random.randint(1, 10)          
1     
>>> random.seed(9002)                
>>> random.randint(1, 10)             
3

Spróbuj tego.

Powiedzmy, że „random.seed” podaje wartość do generatora wartości losowych („random.randint ()”), który generuje te wartości na podstawie tego ziarna. Jedną z koniecznych właściwości liczb losowych jest to, że powinny być odtwarzalne. Kiedy umieścisz to samo ziarno, otrzymasz ten sam wzór liczb losowych. W ten sposób generujesz je od samego początku. Dajesz inne ziarno - zaczyna się od innego inicjału (powyżej 3).

Biorąc pod uwagę ziarno, wygeneruje losowe liczby od 1 do 10 jedna po drugiej. Więc zakładasz jeden zestaw liczb dla jednej wartości początkowej.


15

Liczba losowa jest generowana przez jakąś operację na poprzedniej wartości.

Jeśli nie ma poprzedniej wartości, bieżący czas jest automatycznie poprzednią wartością. Możemy podać tę poprzednią wartość samodzielnie, używając random.seed(x)gdzie xmoże być dowolna liczba lub ciąg itp.

W związku z tym random.random()nie jest w rzeczywistości idealną liczbą losową, można ją przewidzieć za pomocą random.seed(x).

import random 
random.seed(45)            #seed=45  
random.random()            #1st rand value=0.2718754143840908
0.2718754143840908  
random.random()            #2nd rand value=0.48802820785090784
0.48802820785090784  
random.seed(45)            # again reasign seed=45  
random.random()
0.2718754143840908         #matching with 1st rand value  
random.random()
0.48802820785090784        #matching with 2nd rand value

Dlatego generowanie liczby losowej nie jest w rzeczywistości losowe, ponieważ działa na algorytmach. Algorytmy zawsze dają to samo wyjście w oparciu o to samo wejście. Oznacza to, że zależy to od wartości nasion. Tak więc, aby uczynić go bardziej losowym, czas jest automatycznie przypisywany seed().


11
Seed() can be used for later use ---

Example:
>>> import numpy as np
>>> np.random.seed(12)
>>> np.random.rand(4)
array([0.15416284, 0.7400497 , 0.26331502, 0.53373939])
>>>
>>>
>>> np.random.seed(10)
>>> np.random.rand(4)
array([0.77132064, 0.02075195, 0.63364823, 0.74880388])
>>>
>>>
>>> np.random.seed(12) # When you use same seed as before you will get same random output as before
>>> np.random.rand(4)
array([0.15416284, 0.7400497 , 0.26331502, 0.53373939])
>>>
>>>
>>> np.random.seed(10)
>>> np.random.rand(4)
array([0.77132064, 0.02075195, 0.63364823, 0.74880388])
>>>

11
# Simple Python program to understand random.seed() importance

import random

random.seed(10)

for i in range(5):    
    print(random.randint(1, 100))

Wykonaj powyższy program wiele razy ...

Pierwsza próba: wyświetla 5 losowych liczb całkowitych z zakresu 1 - 100

Druga próba: drukuje te same 5 losowych liczb, które pojawiły się w powyższym wykonaniu.

Trzecia próba: to samo

.....Wkrótce

Objaśnienie: Za każdym razem, gdy uruchamiamy powyższy program, ustawiamy ziarno na 10, a następnie generator losowy przyjmuje to jako zmienną odniesienia. Następnie, wykonując predefiniowaną formułę, generuje liczbę losową.

Stąd ustawienie ziarna na 10 w następnym wykonaniu ponownie ustawia numer referencyjny na 10 i znowu zaczyna się to samo zachowanie ...

Jak tylko zresetujemy wartość nasion, daje te same rośliny.

Uwaga: Zmień wartość ziarna i uruchom program, zobaczysz inną losową sekwencję niż poprzednia.


7

W tym przypadku losowe jest w rzeczywistości pseudolosowe. Biorąc pod uwagę ziarno, wygeneruje liczby o równym rozkładzie. Ale z tym samym ziarnem za każdym razem wygeneruje tę samą sekwencję liczb. Jeśli chcesz, aby to się zmieniło, musisz zmienić swoje ziarno. Wiele osób lubi generować ziarno na podstawie aktualnego czasu lub czegoś podobnego.


6

Imho, służy do generowania tego samego losowego wyniku kursu przy random.seed(samedigit)ponownym użyciu .

In [47]: random.randint(7,10)

Out[47]: 9


In [48]: random.randint(7,10)

Out[48]: 9


In [49]: random.randint(7,10)

Out[49]: 7


In [50]: random.randint(7,10)

Out[50]: 10


In [51]: random.seed(5)


In [52]: random.randint(7,10)

Out[52]: 9


In [53]: random.seed(5)


In [54]: random.randint(7,10)

Out[54]: 9

4

Ustaw seed(x)przed wygenerowaniem zestawu liczb losowych i użyj tego samego ziarna do wygenerowania tego samego zestawu liczb losowych. Przydatne w przypadku odtwarzania wydań.

>>> from random import *
>>> seed(20)
>>> randint(1,100)
93
>>> randint(1,100)
88
>>> randint(1,100)
99
>>> seed(20)
>>> randint(1,100)
93
>>> randint(1,100)
88
>>> randint(1,100)
99
>>> 

3

Oto moje zrozumienie. Za każdym razem, gdy ustawiamy wartość początkową, generowana jest „etykieta” lub „odniesienie”. Następne wywołanie random.function jest przypisane do tej „etykiety”, więc następnym razem, gdy wywołasz tę samą wartość początkową i random.function, da ci ten sam wynik.

np.random.seed( 3 )
print(np.random.randn()) # output: 1.7886284734303186

np.random.seed( 3 )
print(np.random.rand()) # different function. output: 0.5507979025745755

np.random.seed( 5 )
print(np.random.rand()) # different seed value. output: 0.22199317108973948

1

Oto mały test, który pokazuje, że podanie seed()metody tym samym argumentem spowoduje ten sam pseudolosowy wynik:

# testing random.seed()

import random

def equalityCheck(l):
    state=None
    x=l[0]
    for i in l:
        if i!=x:
            state=False
            break
        else:
            state=True
    return state


l=[]

for i in range(1000):
    random.seed(10)
    l.append(random.random())

print "All elements in l are equal?",equalityCheck(l)

4
Krótszy test równości:len(set(l))<=1
Oliver Ni

0

random.seed(a, version)w Pythonie służy do inicjalizacji generatora liczb pseudolosowych (PRNG) .

PRNG to algorytm, który generuje ciąg liczb przybliżających właściwości liczb losowych. Te liczby losowe można odtworzyć za pomocą wartości początkowej . Tak więc, jeśli podasz wartość początkową, PRNG rozpocznie się od dowolnego stanu początkowego przy użyciu ziarna.

Argumentem a jest wartość początkowa. Jeśli wartością jestNone , to domyślnie używany jest bieżący czas systemowy.

i versionjest liczbą całkowitą określającą sposób konwersji parametru a na liczbę całkowitą. Wartość domyślna to 2.

import random
random.seed(9001)
random.randint(1, 10) #this gives output of 1
# 1

Jeśli chcesz, aby ta sama liczba losowa została odtworzona, podaj ponownie to samo ziarno

random.seed(9001)
random.randint(1, 10) # this will give the same output of 1
# 1

Jeśli nie podasz ziarna, wygeneruje on inną liczbę, a nie 1, jak poprzednio

random.randint(1, 10) # this gives 7 without providing seed
# 7

Jeśli podasz inne ziarno niż poprzednio , otrzymasz inną liczbę losową

random.seed(9002)
random.randint(1, 10) # this gives you 5 not 1
# 5

Podsumowując, jeśli chcesz, aby ta sama liczba losowa została odtworzona, podaj ziarno. W szczególności to samo ziarno .

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.