9.6. random — 生成伪随机数 — Python 文档

来自菜鸟教程
Python/docs/2.7/library/random
跳转至:导航、​搜索

9.6. 随机的 — 生成伪随机数

源代码: :source:`Lib/random.py`



该模块为各种分布实现了伪随机数生成器。

对于整数,从一个范围中统一选择。 对于序列,随机元素的统一选择,就地生成列表随机排列的函数,以及无需替换的随机采样函数。

在实线上,有一些函数可以计算均匀分布、正态分布(高斯分布)、对数正态分布、负指数分布、伽马分布和 beta 分布。 对于生成角度分布,可以使用 von Mises 分布。

几乎所有的模块函数都依赖于基本函数random(),它在半开区间[0.0, 1.0)内均匀地产生一个随机浮点数。 Python 使用 Mersenne Twister 作为核心生成器。 它产生 53 位精度浮点数,周期为 2**19937-1。 C 中的底层实现既快速又线程安全。 Mersenne Twister 是目前测试最广泛的随机数生成器之一。 但是,由于完全确定性,它并不适合所有用途,并且完全不适合加密用途。

该模块提供的函数实际上是 random.Random 类的隐藏实例的绑定方法。 您可以实例化自己的 Random 实例以获得不共享状态的生成器。 这对于多线程程序特别有用,为每个线程创建 Random 的不同实例,并使用 jumpahead() 方法使每个线程看到的生成序列可能不要重叠。

如果您想使用自己设计的不同基本生成器,类 Random 也可以被子类化:在这种情况下,覆盖 random()seed()getstate() ]、setstate()jumpahead() 方法。 或者,新的生成器可以提供 getrandbits() 方法——这允许 randrange() 在任意大范围内生成选择。

2.4 新功能:getrandbits() 方法。


作为子类化的一个例子,random 模块提供了 WichmannHill 类,它在纯 Python 中实现了一个替代生成器。 该类提供了一种向后兼容的方式来重现早期 Python 版本的结果,该版本使用 Wichmann-Hill 算法作为核心生成器。 请注意,不再推荐这种 Wichmann-Hill 生成器:按照当代标准,它的周期太短,并且已知生成的序列无法通过一些严格的随机性测试。 有关修复这些缺陷的最新变体,请参阅下面的参考资料。

2.3 版更改: MersenneTwister 取代 Wichmann-Hill 作为默认生成器。


random 模块还提供了 SystemRandom 类,该类使用系统函数 os.urandom() 从操作系统提供的源生成随机数。

警告

该模块的伪随机生成器不应用于安全目的。 如果您需要加密安全的伪随机数生成器,请使用 os.urandom()SystemRandom


簿记功能:

random.seed(a=None)

初始化随机数生成器的内部状态。

None 或没有参数种子来自当前时间或来自操作系统特定的随机源(如果可用)(有关可用性的详细信息,请参阅 os.urandom() 函数)。

如果 a 不是 Noneintlong,则使用 hash(a)。 请注意,当启用 PYTHONHASHSEED 时,某些类型的哈希值是不确定的。

2.4 版本变更:原先不使用操作系统资源。

random.getstate()

返回一个捕获生成器当前内部状态的对象。 这个对象可以传递给 setstate() 来恢复状态。

2.1 版中的新功能。

2.6 版更改:Python 2.6 中生成的状态值无法加载到早期版本中。

random.setstate(state)

state 应该是从之前对 getstate() 的调用中获得的,并且 setstate() 将生成器的内部状态恢复到当时的状态getstate() 被调用。

2.1 版中的新功能。

random.jumpahead(n)

将内部状态更改为与当前状态不同且可能远离当前状态的状态。 n 是一个非负整数,用于对当前状态向量进行加扰。 这在多线程程序中最有用,结合 Random 类的多个实例: setstate()seed() 可用于强制所有实例进入相同的内部状态,然后 jumpahead() 可用于强制实例的状态远离。

2.1 版中的新功能。

2.3版本改动: 不是跳转到特定状态,而是n向前一步,jumpahead(n)跳转到另一个可能相隔很多步的状态。

random.getrandbits(k)

返回带有 k 随机位的 python long int。 此方法随 MersenneTwister 生成器提供,其他一些生成器也可以将其作为 API 的可选部分提供。 当可用时,getrandbits() 使 randrange() 能够处理任意大的范围。

2.4 版中的新功能。

整数函数:

random.randrange(stop)
random.randrange(start, stop[, step])

range(start, stop, step) 中返回一个随机选择的元素。 这等效于 choice(range(start, stop, step)),但实际上并不构建范围对象。

1.5.2 版中的新功能。

random.randint(a, b)
返回一个随机整数 N,使得 a <= N <= b

序列函数:

random.choice(seq)
从非空序列 seq 中返回一个随机元素。 如果 seq 为空,则引发 IndexError
random.shuffle(x[, random])

将序列 x 打乱到位。 可选参数 random 是一个 0 参数函数,返回 [0.0, 1.0) 中的随机浮点数; 默认情况下,这是函数 random()

请注意,即使是相当小的 len(x)x 的排列总数也大于大多数随机数生成器的周期; 这意味着无法生成长序列的大多数排列。

random.sample(population, k)

返回从种群序列中选择的唯一元素的 k 长度列表。 用于不放回的随机抽样。

2.3 版中的新功能。

返回一个包含来自总体的元素的新列表,同时保持原始总体不变。 结果列表按选择顺序排列,因此所有子切片也将是有效的随机样本。 这允许抽奖获胜者(样本)被划分为大奖和第二名获胜者(子片)。

总体成员不需要 可散列 或唯一。 如果总体包含重复,则每次出现都是样本中的一个可能选择。

要从整数范围中选择一个样本,请使用 xrange() 对象作为参数。 这对于从大量人口中采样尤其快速且节省空间:sample(xrange(10000000), 60)

以下函数生成特定的实值分布。 函数参数以分布方程中的相应变量命名,这在常见的数学实践中使用; 大多数这些方程可以在任何统计课本中找到。

random.random()
返回范围 [0.0, 1.0) 中的下一个随机浮点数。
random.uniform(a, b)

返回一个随机浮点数 N,使得 a <= ba <= N <= bb < ab <= N <= a

取决于等式a + (b-a) * random()中的浮点舍入,端点值b可能包括或不包括在范围内。

random.triangular(low, high, mode)

返回一个随机浮点数 N,使得 low <= N <= high 和指定的 mode 在这些边界之间。 lowhigh 边界默认为零和一。 mode 参数默认为边界之间的中点,给出对称分布。

2.6 版中的新功能。

random.betavariate(alpha, beta)
贝塔分布。 参数条件为 alpha > 0beta > 0。 返回值介于 0 和 1 之间。
random.expovariate(lambd)
指数分布。 lambd 是 1.0 除以所需的平均值。 它应该是非零的。 (该参数将被称为“lambda”,但这是 Python 中的保留字。)如果 lambd 为正,则返回值范围从 0 到正无穷大,如果 lambd,则从负无穷大到 0 为阴性。
random.gammavariate(alpha, beta)

伽马分布。 (不是伽马函数!)参数条件是alpha > 0beta > 0

概率分布函数为:

          x ** (alpha - 1) * math.exp(-x / beta)
pdf(x) =  --------------------------------------
            math.gamma(alpha) * beta ** alpha
random.gauss(mu, sigma)
高斯分布。 mu 是平均值,sigma 是标准偏差。 这比下面定义的 normalvariate() 函数稍快。
random.lognormvariate(mu, sigma)
对数正态分布。 如果采用此分布的自然对数,您将得到均值为 mu 和标准差为 sigma 的正态分布。 mu 可以是任意值,sigma 必须大于零。
random.normalvariate(mu, sigma)
正态分布。 mu 是平均值,sigma 是标准偏差。
random.vonmisesvariate(mu, kappa)
mu为平均角度,以弧度表示,0~2*pikappa为浓度参数,必须大于等于0 . 如果 kappa 等于 0,则该分布在 0 到 2*pi 范围内减少为均匀的随机角度。
random.paretovariate(alpha)
帕累托分布。 alpha 是形状参数。
random.weibullvariate(alpha, beta)
威布尔分布。 alpha 是尺度参数,beta 是形状参数。

替代发电机:

class random.WichmannHill([seed])
实现 Wichmann-Hill 算法作为核心生成器的类。 具有与 Random 相同的所有方法以及下面描述的 whseed() 方法。 因为这个类是用纯 Python 实现的,它不是线程安全的,可能需要在调用之间加锁。 生成器的周期是 6,953,607,871,644,它足够小,需要注意两个独立的随机序列不重叠。
random.whseed([x])
这是过时的,提供与 2.1 之前的 Python 版本的位级兼容性。 有关详细信息,请参阅 seed()whseed() 不保证不同的整数参数产生不同的内部状态,并且总共可以产生不超过大约 2**24 个不同的内部状态。
class random.SystemRandom([seed])

使用 os.urandom() 函数从操作系统提供的源生成随机数的类。 并非在所有系统上都可用。 不依赖软件状态,序列不可重现。 因此,seed()jumpahead() 方法没有效果并被忽略。 getstate()setstate() 方法在调用时会引发 NotImplementedError

2.4 版中的新功能。

基本用法示例:

>>> random.random()        # Random float x, 0.0 <= x < 1.0
0.37444887175646646
>>> random.uniform(1, 10)  # Random float x, 1.0 <= x < 10.0
1.1800146073117523
>>> random.randint(1, 10)  # Integer from 1 to 10, endpoints included
7
>>> random.randrange(0, 101, 2)  # Even integer from 0 to 100
26
>>> random.choice('abcdefghij')  # Choose a random element
'c'

>>> items = [1, 2, 3, 4, 5, 6, 7]
>>> random.shuffle(items)
>>> items
[7, 3, 2, 5, 6, 4, 1]

>>> random.sample([1, 2, 3, 4, 5],  3)  # Choose 3 elements
[4, 1, 5]

也可以看看

M。 松本和T。 Nishimura,“Mersenne Twister:一个 623 维均匀分布的均匀伪随机数发生器”,ACM 建模和计算机仿真交易卷。 8、没有。 1,1998 年 1 月第 3-30 页。

威克曼,B. 一种。 &希尔,我。 D.,“算法 AS 183:一种高效且便携的伪随机数生成器”,Applied Statistics 31 (1982) 188-190。

Complementary-Multiply-with-Carry recipe,用于具有长周期和相对简单更新操作的兼容替代随机数生成器。