位发生器#
产生的随机值Generator
源自 BitGenerator。 BitGenerators 不直接提供随机数,仅包含用于播种、获取或设置状态、跳转或推进状态的方法,以及用于访问低级包装器以供可有效访问所提供函数的代码使用的方法,例如numba。
支持的 BitGenerators #
包含的 BitGenerators 是:
PCG-64 - 默认值。可以任意前进的快速生成器。请参阅 的文档
advance
。 PCG-64 的周期为\(2^{128}\)。有关此类 PRNG 的更多详细信息,请参阅PCG 作者页面。PCG-64 DXSM - PCG-64 的升级版本,在并行环境中具有更好的统计特性。有关这些改进的更多信息,请参阅使用 PCG64DXSM 升级 PCG64 。
MT19937 - 标准 Python BitGenerator。添加一个
MT19937.jumped
函数,返回一个状态为 as if 的新生成器\(2^{128}\)抽签已经进行。Philox - 一种基于计数器的生成器,能够前进任意数量的步骤或生成独立的流。有关此类位生成器的更多详细信息,请参阅 Random123页面。
SFC64 - 基于随机可逆映射的快速生成器。通常是四个生成器中最快的。有关(一点)更多详细信息,请参阅SFC 作者页面。
|
通用 BitGenerators 的基类,提供基于不同算法的随机位流。 |
播种和熵#
BitGenerator 提供随机值流。为了生成可重现的流,BitGenerators 支持通过种子设置其初始状态。所有提供的 BitGenerators 都将采用任意大小的非负整数或此类整数的列表作为种子。 BitGenerator 需要获取这些输入并将其处理为 BitGenerator 的高质量内部状态。 numpy 中的所有 BitGenerator 都将该任务委托给
SeedSequence
,它使用哈希技术来确保即使是低质量的种子也能生成高质量的初始状态。
from numpy.random import PCG64
bg = PCG64(12345678903141592653589793)
SeedSequence
旨在方便实施最佳实践。我们建议随机程序默认使用操作系统中的熵,以便每次运行都是不同的。程序应该打印出或记录该熵。为了重现过go的值,程序应该允许用户通过某种机制提供该值,命令行参数很常见,以便用户可以重新输入该熵来重现结果。
SeedSequence
可以处理除了与用户沟通之外的所有事情,这取决于你。
from numpy.random import PCG64, SeedSequence
# Get the user's seed somehow, maybe through `argparse`.
# If the user did not provide a seed, it should return `None`.
seed = get_user_seed()
ss = SeedSequence(seed)
print('seed = {}'.format(ss.entropy))
bg = PCG64(ss)
我们默认使用 128 位整数,并使用从操作系统收集的熵。这是初始化 numpy 中所有生成器的大量熵。我们不建议将低于 32 位的小种子用于一般用途。仅使用一小组种子来实例化更大的状态空间意味着有些初始状态是不可能达到的。如果每个人都使用这样的价值观,就会产生一些偏见。
结果本身不会有任何问题;由于处理的原因,即使是 0 的种子也完全没问题SeedSequence
。如果您只需要一些固定值进行单元测试或调试,请随意使用您喜欢的任何种子。但如果您想从结果中进行推论或发布它们,从更大的种子集中提取是一个很好的做法。
如果您需要“离线”生成一个好的种子,那么SeedSequence().entropy
或者使用secrets.randbits(128)
标准库都是方便的方法。
如果您需要并行运行多个随机模拟,最佳实践是为每个模拟构建一个随机生成器实例。为了确保随机流具有不同的初始状态,您可以使用的spawnSeedSequence
方法。例如,这里我们构造一个包含 12 个实例的列表:
from numpy.random import PCG64, SeedSequence
# High quality initial entropy
entropy = 0x87351080e25cb0fad77a44a3be03b491
base_seq = SeedSequence(entropy)
child_seqs = base_seq.spawn(12) # a list of 12 SeedSequences
generators = [PCG64(seq) for seq in child_seqs]
如果您已经有一个初始随机生成器实例,您可以使用以下spawn
方法缩短上述内容:
from numpy.random import PCG64, SeedSequence
# High quality initial entropy
entropy = 0x87351080e25cb0fad77a44a3be03b491
base_bitgen = PCG64(entropy)
generators = base_bitgen.spawn(12)
SeedSequence
另一种方法是利用 a可以由元素元组初始化的事实。这里我们使用一个基本熵值和一个整数
worker_id
from numpy.random import PCG64, SeedSequence
# High quality initial entropy
entropy = 0x87351080e25cb0fad77a44a3be03b491
sequences = [SeedSequence((entropy, worker_id)) for worker_id in range(12)]
generators = [PCG64(seq) for seq in sequences]
请注意,后一种方法生成的序列将与通过 构造的序列不同spawn
。
|
SeedSequence 以可重现的方式混合熵源,为独立且很可能不重叠的 BitGenerators 设置初始状态。 |