【发布时间】:2021-06-30 15:14:48
【问题描述】:
我正在寻找一个类似 Python 的 random.randint() 的函数,它可以在 a 和 b 之间生成随机整数,但它更有可能生成数字更接近a,只有少数接近b。
有这样的功能吗?
【问题讨论】:
我正在寻找一个类似 Python 的 random.randint() 的函数,它可以在 a 和 b 之间生成随机整数,但它更有可能生成数字更接近a,只有少数接近b。
有这样的功能吗?
【问题讨论】:
您的问题含糊不清,因为有许多随机分布,其中较低的数字比较高的数字更有可能。此外,“在 a 和 b 之间”在这里同样含糊不清。这是许多示例之一,它以您要求的方式在闭区间 [a, b] 中生成一个随机整数:
min(random.randint(a, b), random.randint(a, b))
还有一个:
min(random.randint(a, b), random.randint(a, b), random.randint(a, b))
随着越来越多的random.randint(a, b),它们的最小值往往越来越集中在范围的下端。
用户“pjs”写了以下评论:
这两者都可以概括为相同的形式,即 k 阶统计的最小值,可以使用单个随机数生成,然后缩放到正确的范围:
int(math.floor(a + (b - a + 1) * (1.0 - random.random()**(1.0 / k))))。当k == 2具有三角形分布时,对于更高的k值,它变得越来越偏向a。如果您想在 Monte Carlo sims 中使用“减少方差”策略玩游戏,那么基于单个随机数也可以使该方法适用于常见随机数或对立随机数。
但是,这个公式存在问题。
random.random()**(1.0 / k) 在 1 附近是病态的,对于大的k 接近 1,因此在浮点算术中,从 1/2 到 1 比从0 到 1/2,“可能存在准确性问题”(Devroye,1986 年,非均匀随机变量生成,第 675 页)。min(random.randint(a, b) for i in k) 对于大于 0 的某个整数 k。【讨论】:
k 订单统计的最小值,可以使用单个随机数生成,然后缩放到正确的范围:int(math.floor(a + (b - a + 1) * (1.0 - random.random()**(1.0 / k))))。当k == 2 具有三角形分布时,对于k 的更高值,它变得越来越偏向a。如果您想在 Monte Carlo sims 中使用“减少方差”策略玩游戏,那么基于单个随机数也可以使该方法适用于常见随机数或对立随机数。
是的,有无数个函数可以做到这一点。成为合法离散概率分布的唯一要求是 p(x) ≥ 0 对于范围 [a, b] 中的所有 x,并且 sum(p(x)) = 1。因此,任何 g(x) 是在 [a, b] 范围内为非负且所有 a ≤ x ≤ b 的 g(x)
如上所述,选择任何在 x 中递减的函数 g(x)(有无数个函数可供您选择),按照描述进行缩放,并从生成的 p(x) 生成。一旦你有一个 p(x) 的表,例如discrete inversion 或Walker's alias method,有几种方法可以从离散分布生成。
【讨论】: