有许多有趣的方法可以生成随机性,而无需诉诸随机(或 numpy)。例如,您可以使用内置的哈希函数:
def rand_generator(seed, N=10**6, a=0, b=10, integer = True):
'''For a given seed, this function returns N pseudo-random between a and b'''
rands =[]
if integer:
for i in range(N):
num = int(a+(b-a)*(abs(hash(str(hash(str(seed)+str(i+1)))))%10**13)/10**13)
rands.append(num)
return rands
else:
for i in range(N):
num = a+(b-a)*(abs(hash(str(hash(str(seed)+str(i+1)))))%10**13)/10**13
rands.append(num)
return rands
这将生成一个在 0 和 1 之间均匀分布的伪随机数列表。与 random 和 numpy 中的随机数生成器一样,对于给定的种子,序列是完全确定的。
Histogram of the function's output.
此算法在密码学上绝不是安全的,但它应该足以回答您的问题。
如果不希望存储整个列表,那么同样的想法可以采用生成器表达式的形式。如上所述设置 a、b、N 和种子的值后:
randnum = (int(a+(b-a)*(abs(hash(str(hash(str(seed)+str(j+1))))) % 10**13)/ 10**13) for i in range(N))
是一个迭代器,它通过
生成序列中的下一个数字
>>> next(randnum)
5
这可以更整洁如下:
def random(seed = None, a=0, b=10, N=10**12, integer=True):
'''Pass a seed to generate new sequence, otherwise next value is returned.'''
if seed:
print("Starting new sequence.")
global _rand_generator
if integer:
hash_plus = lambda j: int(a + (b-a)*(abs(hash(str(hash(str(seed) + str(j+1))))) % 10**13)/ 10**13)
else:
hash_plus = lambda j: a + (b-a)*(abs(hash(str(hash(str(seed) + str(j+1))))) % 10**13)/ 10**13
_rand_generator = (hash_plus(j) for j in range(N))
try:
return next(_rand_generator)
except:
print("Random seed required.")
要生成随机序列,请将种子传递给函数。
>>> random(42)
Starting new sequence.
8
在没有种子的情况下再次调用该函数以产生序列中的下一个随机数/整数。
>>> for i in range(10):
... print(random())
3
4
6
5
5
9
2
2
4
0
要开始一个新序列,只需使用新种子再次调用该函数。
>>> random(666)
Starting new sequence.
5