随机性#

随机数生成器 (RNGs) 经常用于生成、绘制和计算网络属性或操纵网络。NetworkX 提供了使用两种标准 RNG 之一的函数:NumPy 的包 numpy.random 或 Python 的内置包 random。它们都提供了相同的数字生成算法(梅森旋转算法)。它们的接口相似(非常相似),但又有所区别。它们各自提供一个全局默认的生成器实例,该实例由单个会话中的所有程序共享。大多数情况下,您可以按 NetworkX 的设置方式使用 RNG,您将获得合理的伪随机结果(统计学上随机,但以确定性方式创建的结果)。

有时您需要对数字生成方式进行更多控制。特别是,您需要设置生成器的 seed 以使您的结果可重现——无论是用于科学出版还是用于调试。这两个 RNG 包都有简单的函数可以将 seed 设置为任意整数,从而确定后续生成的数值。由于此包(和许多其他包)同时使用这两个 RNG,您可能需要设置两个 RNG 的 seed。即使我们严格只使用其中一个 RNG,您可能会发现自己使用了另一个使用另一个 RNG 的包。设置两个全局 RNG 的状态就像将每个 RNG 的 seed 设置为任意整数一样简单。

>>> import random
>>> random.seed(246)        # or any integer
>>> import numpy
>>> numpy.random.seed(4812)

许多用户会对这种程度的控制感到满意。

对于需要更多控制的人,我们在使用 RNG 的函数中包含了一个可选参数。此参数名为 seed,但它决定的不仅仅是 RNG 的 seed。它告诉函数要使用哪个 RNG 包,以及是使用全局 RNG 还是局部 RNG。

>>> from networkx import path_graph, random_layout
>>> G = path_graph(9)
>>> pos = random_layout(G, seed=None)  # use (either) global default RNG
>>> pos = random_layout(G, seed=42)  # local RNG just for this call
>>> pos = random_layout(G, seed=numpy.random)  # use numpy global RNG
>>> random_state = numpy.random.RandomState(42)
>>> pos = random_layout(G, seed=random_state)  # use/reuse your own RNG

NetworkX 中使用 RNG 的每个函数在编写时都考虑到了一个 RNG 包。它默认使用 randomnumpy.random。但有些用户只想为所有代码使用一个单独的 RNG。这个 seed 参数提供了一种机制,使得任何函数都可以使用 numpy.random RNG,即使函数是为 random 编写的。它的工作方式如下。

默认行为(当 seed=None 时)是使用函数的首选包的全局 RNG。如果 seed 被设置为整数值,则会创建一个具有指定 seed 值的局部 RNG,并在该函数(包括对其他函数的任何调用)的持续时间内使用,然后被丢弃。或者,您可以指定 seed=numpy.random,以确保无论函数是否期望,都使用全局 numpy RNG。最后,您可以提供一个 numpy RNG 供函数使用。该 RNG 随后可在其他函数甚至其他包(如 sklearn)中使用。通过这种方式,您可以为项目中的所有随机数使用一个单独的 RNG。

虽然可以将 seed 赋值为一个 random 风格的 RNG,用于为 random 包 API 编写的 NetworkX 函数,但 numpy RNG 接口有太多出色的特性,我们无法确保 random 风格的 RNG 适用于所有函数。实际上,您仅使用 random RNGs 就可以完成大多数事情(如果 numpy 不可用时很有用)。但如果 numpy 可用,您的体验将更丰富。

总而言之,您可以轻松忽略 seed 参数并使用全局 RNGs。您可以通过 seed=numpy.random 指定仅使用 numpy 全局 RNG。您可以通过提供整数 seed 值来使用局部 RNG。并且您可以提供您自己的 numpy RNG,并在所有函数中重复使用它。如果您想要一个单独的 RNG,使用 numpy RNGs 更容易。