我想生成没有任何上界的随机自然数。
例如,我可以使用random.randint(1, 1000)
生成随机自然数,但我不想指定上限。我怎样才能做到这一点?
这里的主要问题甚至不是计算机可以保持的最大整数(包括在生成如此大的随机数时暂时保持的整数(。假设PO同意在获得非常大的数字时牺牲精度,并同意将其保留为float
这里的根本问题实际上是这个自然数的分布。random.randint(1, 1000)
从均匀分布返回一个随机整数。如果没有上界,这种分布就不可能存在,因为概率质量函数(pmf(将只返回零。从-∞到+∞的pmf积分必须等于1,这在没有上界的均匀分布中是不可能的,因为它不向右收敛
然而,还有其他自然数的离散分布,虽然不限于右侧,但整数越大,概率就越低。但在Python中生成它们的包通常使用numpy
数据类型(非常有限,如C,与常规Python和Wolfram不同,受整数大小的限制(,所以在Python中,无论如何都有一个固有的界限。
from scipy.stats import nbinom
print(nbinom.rvs(1e10, 0.5, size=1) + 1)
可以尝试用正则Python编写一个数值算法,从0.0到1.0的连续均匀分布产生的随机数中生成负二项式+1随机变量,每次在正则Python中计算前者的pmf的积分(并将其反转为分位数函数(,但这将是非常低效的。
不可能选择从0到无穷大的数字。但是,您可以使用sys.maxsize
作为上限,这是支持的最大数字。不要忘记导入sys模块。
import sys
如果我们注意到p(n(画出数字n的概率,即使p(n(可能不会降到零,p(n。所以p(n(的下降速度必须足够快。
一种可能性是采用指数分布。分布的参数决定了随机数的有限平均值。
天真地,分布返回一个浮点数,所以我们必须使用int()
转换函数。
像这样,目标是平均值20:
$ python3
Python 3.10.6 (main, Aug 2 2022, 00:00:00) [GCC 12.1.1 20220507 (Red Hat 12.1.1-1)] on linux
...
>>>
>>> import numpy as np
>>>
>>> ys = list(map(int, np.random.exponential(20, 10)))
>>>
>>> ys
[7, 5, 36, 4, 10, 3, 26, 45, 9, 17]
>>>
>>> ys2 = list(map(int, np.random.exponential(20, 100)))
>>>
>>> sum(ys2) / len(ys2)
18.89
>>>
>>> ys4 = list(map(int, np.random.exponential(20, 10000)))
>>>
>>> sum(ys4) / len(ys4)
19.5025
>>>
>>> min(ys4)
0
>>> max(ys4)
207
>>>
>>> quit()
$