钻头发生器

所产生的随机值 Generator 源于位发生器。BitGenerator不直接提供随机数,只包含用于播种、获取或设置状态、跳跃或推进状态以及用于访问低级包装器的方法,以供能够有效访问所提供函数的代码使用,例如。, numba .

支持的位生成器

包含的位生成器包括:

  • PCG-64-默认值。一种支持多个并行流的快速生成器,可以按任意数量前进。有关详细信息,请参阅文档 advance . PCG-64的周期为 2^{{128}} . 见 PCG author's page 有关此类PRNG的更多详细信息。

  • MT19937-标准Python位生成器。添加 MT19937.jumped 函数返回一个新的生成器,其状态为 2^{{128}} 已经抽签了。

  • Philox-一个基于计数器的生成器,可以前进任意步数或生成独立的流。看到了吗 Random123 有关此类位生成器的详细信息,请参见第页。

  • SFC64-基于随机可逆映射的快速生成器。通常是四个发电机中最快的。看到了吗 SFC author's page 为了(多一点)细节。

BitGenerator \ [seed] )

通用位生成器的基类,它提供基于不同算法的随机位流。

种子与熵

位生成器提供随机值流。为了生成可再现的流,位生成器支持通过种子设置其初始状态。所有提供的位生成器都将采用任意大小的非负整数或此类整数的列表作为种子。位生成器需要获取这些输入并将其处理为位生成器的高质量内部状态。numpy中的所有位生成器都将该任务委托给 SeedSequence ,它使用散列技术来确保即使是低质量的种子也能生成高质量的初始状态。

from numpy.random import PCG64

bg = PCG64(12345678903141592653589793)

SeedSequence 旨在方便实施最佳实践。我们建议随机程序默认使用操作系统的熵,这样每次运行都是不同的。程序应该打印或记录这些信息。为了重现过去的值,程序应该允许用户通过某种机制提供该值,命令行参数是常见的,这样用户就可以重新输入熵来重现结果。 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 做。如果你只是需要 some 单元测试或调试的固定值,可以随意使用任何种子。但是,如果你想从结果中做出推论或发表它们,从更大的种子集合中提取是一个好的做法。

如果你需要“离线”生成一个好的种子,那么 SeedSequence().entropy 或使用 secrets.randbits(128) 这两种方法都很方便。

如果需要并行运行多个随机模拟,最佳实践是为每个模拟构造一个随机生成器实例。为了确保随机流具有不同的初始状态,可以使用 spawn 方法 SeedSequence . 例如,这里我们构建了一个包含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]

另一种方法是利用 SeedSequence 可以由元素元组初始化。这里我们使用一个基熵值和一个整数 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 \ [entropy, spawn_key, pool_size] )

SeedSequence以一种可复制的方式混合熵源,为独立且很可能不重叠的位生成器设置初始状态。