Независимые случаи «случайного» - PullRequest
12 голосов
/ 08 февраля 2010

Приведенный ниже код пытается проиллюстрировать то, что я хочу. Я в основном хочу два случая "случайных", которые работают независимо друг от друга. Я хочу посеять «случайный» в одном классе, не затрагивая «случайный» в другом классе. Как я могу это сделать?

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

Ответы [ 3 ]

19 голосов
/ 08 февраля 2010

Класс random.Random существует специально для того, чтобы разрешить желаемое поведение - модули по своей сути являются одиночными, но классы предназначены для множественной реализации, поэтому удовлетворяются оба вида потребностей.

Если вам когда-нибудь понадобится независимая копия модуля (чего вам точно не нужно в случае random!), Попробуйте использовать на нем copy.deepcopy - во многих случаях он будет работать. Тем не менее, необходимость очень редкая, поскольку модули обычно не поддерживают глобальные изменяемые состояния, за исключением сохранения одного привилегированного экземпляра класса, который они также предлагают для «внешнего потребления» (другие примеры, кроме random включают fileinput).

6 голосов
/ 08 февраля 2010

Для выбранных случайных чисел сделайте свой собственный экземпляр random.Random. random документация объясняет этот класс, от которого модуль зависит только от одного случая, когда вы используете функции непосредственно внутри него.

4 голосов
/ 08 февраля 2010

К сожалению, наличие двух независимых RNG может быть менее случайным, чем наличие одного RNG, использующего «смещение» в сгенерированной последовательности.

Использование «смещения» означает, что вы должны сгенерировать обе полные последовательности сэмплов, а затем использовать их для моделирования. Как то так.

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 )

Доказано, что ГСЧ обладают желаемыми свойствами случайности только для одного семени и одной последовательности чисел. Поскольку две параллельные последовательности используют одинаковые константы для множителя и модуля, есть вероятность, что они могут иметь обнаруживаемую корреляцию друг с другом.

...