开发者

Independent instances of 'random'

The below code attempts to illustrate what I want. I basically want two instances of "random" that operate independently of each other. I want to seed "开发者_开发知识库random" within one class without affecting "random" in another class. How can I do that?

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


Class random.Random exists specifically to allow the behavior you want -- modules are intrinsically singletons, but classes are meant to be multiply instantiated, so both kinds of needs are covered.

Should you ever need an independent copy of a module (which you definitely don't in the case of random!), try using copy.deepcopy on it -- in many cases it will work. However, the need is very rare, because modules don't normally keep global mutable states except by keeping one privileged instance of a class they also offer for "outside consumption" (other examples besided random include fileinput).


For the seeded random numbers, make your own instance of random.Random. The random documentation explains this class, which the module depends on a single instance of when you use the functions directly within it.


Sadly, having two independent RNG's is can be less random than having a single RNG using an "offset" into the generated sequence.

Using an "offset" means you have to generate both complete sequences of samples, and then use them for your simulation. Something like this.

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 )

RNG's can only be proven to have desirable randomness properties for a single seed and a single sequence of numbers. Because two parallel sequences use the same constants for the multiplier and modulus, there's a chance that they can have a detectable correlation with each other.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜