2010-02-08 18 views
8

Poniższy kod próbuje zilustrować, co chcę. Zasadniczo chcę dwóch przypadków "losowych", które działają niezależnie od siebie. Chcę obsadzić "losowe" w ramach jednej klasy bez wpływu na "losowy" w innej klasie. Jak mogę to zrobić?Niezależne wystąpienia "losowego"

class RandomSeeded: 
    def __init__(self, seed): 
     import random as r1 
     self.random = r1 
     self.random.seed(seed) 
    def get(self): 
     print self.random.choice([4,5,6,7,8,9,2,3,4,5,6,7,]) 

class Random: 
    def __init__(self): 
     import random as r2 
     self.random = r2 
     self.random.seed() 
    def get(self): 
     print self.random.choice([4,5,6,7,8,9,2,3,4,5,6,7,]) 

if __name__ == '__main__': 
    t = RandomSeeded('asdf') 
    t.get()  # random is seeded within t 
    s = Random() 
    s.get()  
    t.get()  # random should still be seeded within t, but is no longer 

Odpowiedz

17

Klasa random.Random istnieje specjalnie w celu umożliwienia zachowania chcesz - moduły są nierozerwalnie singletons, ale zajęcia mają być wielokrotnie instancja, więc oba rodzaje potrzeb są objęte gwarancją.

Jeśli kiedykolwiek będziesz potrzebował niezależnej kopii modułu (czego na pewno nie potrzebujesz w przypadku random!), Spróbuj użyć na niej copy.deepcopy - w wielu przypadkach zadziała. Jednak potrzeba jest bardzo rzadka, ponieważ moduły zwykle nie zachowują globalnych stanów zmiennych, z wyjątkiem zachowywania jednej uprzywilejowanej instancji klasy, którą oferują również dla "zewnętrznego zużycia" (inne przykłady oprócz tego obejmują obejmują fileinput).

+0

Odpowiada na konkretny przypadek, a także na mój ogólny problem. Wielkie dzięki! – Lin

+3

Deepcopying modułu brzmi przerażająco. – FogleBird

+0

Trudno jest wymyślić przypadek, gdy wykonanie kopii modułu ma sens w ramach zdalnie uzasadnionego projektu. –

5

Dla zaszczepionych liczb losowych, należy utworzyć własną instancję z random.Random. W dokumencie random documentation objaśniono tę klasę, która jest zależna od pojedynczego wystąpienia podczas korzystania z funkcji bezpośrednio w nim.

3

Niestety, posiadanie dwóch niezależnych RNG może być mniej przypadkowe niż posiadanie pojedynczego RNG z wykorzystaniem "przesunięcia" w wygenerowanej sekwencji.

Użycie "przesunięcia" oznacza wygenerowanie obu kompletnych sekwencji próbek, a następnie użycie ich do symulacji. Coś takiego.

def makeSequences(sequences=2, size=1000000): 
    g = random.Random() 
    return [ [ g.random() for g in xrange(size) ] for s in xrange(sequences) ] ] 

t, s = makeSequences(2) 

Można udowodnić, że RNG ma pożądane właściwości losowości dla pojedynczego nasiona i pojedynczej sekwencji liczb. Ponieważ dwie równoległe sekwencje używają tych samych stałych dla mnożnika i modułu, istnieje szansa, że ​​mogą mieć wykrywalną korelację między sobą.