2024-04-26 01:27:43 发布
网友
我想生成一个随机数n,这样n在(a,b)或{}的范围内,其中a < b。在python中这是可能的吗?似乎唯一的选择是a + random.random()*(b-a),它包括[a,b)或者{},它包括范围{},所以都不能满足我的需要。在
n
(a,b)
a < b
a + random.random()*(b-a)
[a,b)
random.randint(a,b)似乎就是这样。https://docs.python.org/2/library/random.html
random.randint(a,b)
计算机生成“随机”数字是很棘手的,尤其是“随机”浮点数。你需要仔细考虑你真正想要什么。最后,您将需要在整数上构建一些东西,而不是直接从float中构建。在
实际上,在Python(以及其他所有使用Mersenne Twister源代码的语言)中,生成一个“随机”的IEEE-754 double(Python的基本random.random())实际上是通过生成一个随机的53位整数,然后除以2**53来实现的:
random.random()
randrange(2**53) / 9007199254740992.0
这就是为什么输出范围是[0.0, 1.0),但并非该范围内所有可表示的浮点都是相同的。只有那些可以用I/2**53形式表示的整数0 <= I < 2**53。例如,float 1.0 / 2**60永远不能返回。在
[0.0, 1.0)
I/2**53
0 <= I < 2**53
1.0 / 2**60
这里没有“实数”,只有可表示的二进制浮点数,所以要回答您的问题,首先需要您指定要从中选取的精确的一组。在
如果答案是你不想变得那么挑剔,那么开放和封闭的区别也太挑剔了。如果可以指定精确集,那么解决方案是生成映射到输出集的或多或少明显的随机整数。在
例如,如果你想从基数点后2位的[3.0,6.0]中选取“随机”浮点,有13个可能的输出。所以第一步是
然后映射到感兴趣的范围:
return 3.0 + i / 4.0
如注释中所述,可以从所有可表示的浮动中均匀地选取x,并带有{},但要在整个范围内均匀分布还远远不够。例如,在[0.5, 1.0)中有2**52可表示的浮动,2**52在{}中也有{}可表示的浮动,以及。。。在[2.0**-i, 2.0**(1-i))中增加{},直到当我们到达低于正常范围时,可表示的浮点数开始减少,当我们完全下溢到0时,最终下降到零。在
x
[0.5, 1.0)
2**52
[2.0**-i, 2.0**(1-i))
但是,作为位模式,它们非常简单:(0, 1)中可表示的IEEE-754双精度(几乎所有平台上的Python浮点数)集包括,当将位模式视为整数时,简单地
(0, 1)
range(1, 0x3ff0000000000000)
因此,一个生成每个具有相同可能性的函数很容易使用位技巧编写:
from struct import unpack from random import randrange def gen01(): i = randrange(1, 0x3ff0000000000000) as_bytes = i.to_bytes(8, "big") return unpack(">d", as_bytes)[0]
只需运行几次,看看为什么它是无用的-它非常严重地偏向0.0的范围的末端:
>>> for i in range(10): ... print(gen01()) 9.796357610869274e-104 4.125848254595866e-197 1.8114434720880952e-253 1.4937625148849258e-285 1.0537573744489343e-304 2.79008159472542e-58 4.718459887295062e-217 2.7996009087703915e-295 3.4129442284798105e-170 2.299402306630583e-115
对于(a, b],请执行b - random.random()*(b-a)。在
(a, b]
b - random.random()*(b-a)
random.randint(a,b)
似乎就是这样。https://docs.python.org/2/library/random.html计算机生成“随机”数字是很棘手的,尤其是“随机”浮点数。你需要仔细考虑你真正想要什么。最后,您将需要在整数上构建一些东西,而不是直接从float中构建。在
实际上,在Python(以及其他所有使用Mersenne Twister源代码的语言)中,生成一个“随机”的IEEE-754 double(Python的基本
random.random()
)实际上是通过生成一个随机的53位整数,然后除以2**53来实现的:这就是为什么输出范围是
[0.0, 1.0)
,但并非该范围内所有可表示的浮点都是相同的。只有那些可以用I/2**53
形式表示的整数0 <= I < 2**53
。例如,float1.0 / 2**60
永远不能返回。在这里没有“实数”,只有可表示的二进制浮点数,所以要回答您的问题,首先需要您指定要从中选取的精确的一组。在
如果答案是你不想变得那么挑剔,那么开放和封闭的区别也太挑剔了。如果可以指定精确集,那么解决方案是生成映射到输出集的或多或少明显的随机整数。在
例如,如果你想从基数点后2位的[3.0,6.0]中选取“随机”浮点,有13个可能的输出。所以第一步是
^{pr2}$然后映射到感兴趣的范围:
编辑:没用,但很有教育意义;-)
如注释中所述,可以从所有可表示的浮动中均匀地选取},但要在整个范围内均匀分布还远远不够。例如,在}中也有{}可表示的浮动,以及。。。在},直到当我们到达低于正常范围时,可表示的浮点数开始减少,当我们完全下溢到0时,最终下降到零。在
x
,并带有{[0.5, 1.0)
中有2**52
可表示的浮动,2**52
在{[2.0**-i, 2.0**(1-i))
中增加{但是,作为位模式,它们非常简单:
(0, 1)
中可表示的IEEE-754双精度(几乎所有平台上的Python浮点数)集包括,当将位模式视为整数时,简单地因此,一个生成每个具有相同可能性的函数很容易使用位技巧编写:
只需运行几次,看看为什么它是无用的-它非常严重地偏向0.0的范围的末端:
对于
(a, b]
,请执行b - random.random()*(b-a)
。在相关问题 更多 >
编程相关推荐