deftwister(self): # 梅森旋转 for i inrange(self.n): y = (self.iv[i] & 0x80000000) + (self.iv[(i + 1) % self.n] & 0x7fffffff) if y % 2: y >>= 1 y ^= self.a else: y >>= 1 self.iv[i] = self.iv[(i + self.m) % self.n] ^ y
获取随机数
在获取随机数时用到了大量的常数项:
首先在梅森链中选取 state 位置的 word,赋值给
x,然后通过下面的方式获取最终的随机数。
在获取完随机数后,state+1。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12
defgenerate(self): if self.state == 0: self.twister()
y = self.iv[self.state] y = y ^ (y >> self.u) & self.d y = y ^ (y << self.s) & self.b y = y ^ (y << self.t) & self.c y = y ^ (y >> self.l)
deftwister(self): # 梅森旋转 for i inrange(self.n): y = (self.iv[i] & 0x80000000) + (self.iv[(i + 1) % self.n] & 0x7fffffff) if y % 2: y >>= 1 y ^= self.a else: y >>= 1 self.iv[i] = self.iv[(i + self.m) % self.n] ^ y
defgenerate(self): if self.state == 0: self.twister()
y = self.iv[self.state] y = y ^ (y >> self.u) & self.d y = y ^ (y << self.s) & self.b y = y ^ (y << self.t) & self.c y = y ^ (y >> self.l)
self.state = (self.state + 1) % self.n return y
def__call__(self): return self.generate()
if __name__ == "__main__": mt = MT19937() tank = set() kLen = 100000 odd = 0 for _ inrange(kLen): t = mt() odd += 1if t % 2else0 tank.add(t) print(t) print(odd / kLen) print(f"set: {len(tank)}") print(f"kLen: {kLen}")
a = 0xb5026f5aa96619e9 u, d = 29, 0x5555555555555555 s, b = 17, 0x71d67fffeda60000 t, c = 37, 0xfff7eee000000000 l = 43 f = 6364136223846793005 upperMask = 0xFFFFFFFF80000000 lowerMask = 0x7FFFFFFF
deftwister(self): # 梅森旋转 for i inrange(self.n): y = (self.iv[i] & 0x80000000) + (self.iv[(i + 1) % self.n] & 0x7fffffff) if y % 2: y >>= 1 y ^= self.a else: y >>= 1 self.iv[i] = self.iv[(i + self.m) % self.n] ^ y
defgenerate(self): if self.state == 0: self.twister()
y = self.iv[self.state] y = y ^ (y >> self.u) & self.d y = y ^ (y << self.s) & self.b y = y ^ (y << self.t) & self.c y = y ^ (y >> self.l)
self.state = (self.state + 1) % self.n
return y
def__call__(self): return self.generate()
if __name__ == "__main__": mt = MT19937x64() tank = set() kLen = 100000 odd = 0 for _ inrange(kLen): t = mt() odd += 1if t % 2else0 tank.add(t) print(t) print(odd / kLen) print(f"set: {len(tank)}") print(f"kLen: {kLen}")
deftwister(self): # 梅森旋转 i = self.state y = (self.iv[i] & 0x80000000) + (self.iv[(i + 1) % self.n] & 0x7fffffff) if y % 2: y >>= 1 y ^= self.a else: y >>= 1 self.iv[i] = self.iv[(i + self.m) % self.n] ^ y
defgenerate(self): self.twister() y = self.iv[self.state] y = y ^ (y >> self.u) & self.d y = y ^ (y << self.s) & self.b y = y ^ (y << self.t) & self.c y = y ^ (y >> self.l)