从一个范围中挑选一个随机数时,我正在rand(0..100)
。这一切都很好,但我希望它支持范围的低端。
因此,根据一些加权比例,选择0
的概率最高,挑选概率100
(以及之间的所有内容)的概率最低。
我如何在Ruby中实现它?
答案 0 :(得分:2)
您可以尝试使用两个随机数中的较低者。这将有利于较小的数字。
[rand(0..100), rand(0..100)].min
如果您的第一个数字是5,那么第二个数字较低(和替换)的可能性仅为4中的4个。
如果您的第一个号码是95,那么您的第二个号码降低的可能性是94分(满分100分),因此它可能会被较低的号码替换。
答案 1 :(得分:1)
我的回答主要是从基础概率分布中产生随机变量,而不仅仅是那些给较小随机变量赋予更大权重的分布。
您需要识别具有所需形状的(概率)密度函数f
。然后构造它的(累积)分布函数F
和后者的反函数G
(分位数),意味着所有G(F(x)) = x
的{{1}}样本空间。 x
可以是连续的或离散的。
例如,f
和f
可以是(负)指数密度和分布函数,它们对较小的值赋予较高的权重,如下所示(来源:Wiki for Exponential Distribution)。
指数PDF 指数CDF
这些函数分别由f(x)=λe-λx和F(x)= 1 - e -λx给出,其中F
是自然对数的基础。 e
是形状参数。
要为此分布生成随机变量,我们将绘制一个介于0和1之间的(伪)随机数,在CDF图的垂直轴上标记该伪随机数并从该点绘制一条水平线。随机变量是水平轴上CDF与水平线相交的点。如果y是0到1之间的随机数,我们有
λ
解决y = 1 − e**(−λx)
,
x
因此反向CDF被视为
x = -log(1 - y)/λ
以下是g(y) = -log(1 - y)/λ
的一些随机变量。
λ = 1
大多数CDF没有封闭形式的反函数,但如果CDF是连续的,则可以执行二进制搜索来计算随机变量(图上的def g(y)
-Math.log(1 - y)
end
5.times { y = rand; puts "y = #{y.round(2)}, x = #{g(y).round(2)}" }
y = 0.09, x = 0.10
y = 0.67, x = 1.09
y = 0.35, x = 0.43
y = 0.55, x = 0.79
y = 0.19, x = 0.21
)的任意近似近似值。给定x
。
Weibull Distribution是为数不多的具有闭式反函数的连续分布(除了均匀和三角形之外)。有两个参数,它提供了比单参数指数分布更大的范围,用于建模所需的形状。
对于离散CDF,可以使用y = rand
语句(或者更好的是case语句)来计算给定if
的随机变量。
答案 2 :(得分:0)
我会做这样的事情:
weighted_range
这将给出:
weighted_range
数组中出现100次,weighted_range
数组中出现99次,weighted_range
数组中出现一次,并且low_end_of_range
数组中出现两次,如果您不需要采样大小的任何灵活性(即high_end_of_range
/ (1..100).map { |i| (101 - i).times.map { i } }.flatten.sample
),您可以在一个漂亮的单行中进行:
wait_time