我需要生成具有以下属性的随机数。
最小值应为 200
最大值应为 20000
平均值(平均值)为 500。
可选:第 75 个百分位为 5000
绝对不是均匀分布,也不是高斯分布。我需要给一些左偏度。
说X
是你的目标变量,让我们通过做来规范化范围Y=(X-200)/(20000-200)
。所以现在你想要一些随机变量,它用 meanY
取值。[0,1]
(500-200)/(20000-200)=1/66
你有很多选择,在我看来最自然的一个是Beta 分布, 你Y ~ Beta(a,b)
有a/(a+b) = 1/66
一个额外的自由度,你可以选择它来满足最后一个四分位数的要求。
之后,您只需将 X 返回为Y*(20000-200)+200
要生成 Beta 随机变量,您可以使用Apache Commons或查看此处。
这可能不是您要寻找的答案,而是具有 3 个均匀分布的特定情况:
(忽略左边的数字,但它是按比例计算的!)
public int generate() {
if(random(0, 65) == 0) {
// 50-100 percentile
if(random(1, 13) > 3) {
// 50-75 percentile
return random(500, 5000);
} else {
// 75-100 percentile
return random(5000, 20000);
}
} else {
// 0-50 percentile
return random(200, 500);
}
}
我是如何得到这些数字的
首先,曲线下面积等于 200-500 和 500-20000 之间。这意味着高度关系300 * leftHeight == 19500 * rightHeight
正在leftHeight == 65 * rightHeight
这给了我们 1/66 的机会选择右边,以及 65/66 的机会选择左边。
然后,我对第 75 个百分位数进行了相同的计算,但比率为500-5000 chance == 5000-20000 chance * 10 / 3
. 同样,这意味着我们有 10/13 的机会进入 50-75 个百分位数,有 3/13 的机会进入 75-100。
感谢@Stas - 我正在使用他的“包容性随机”功能。
是的,我意识到我的数字是错误的,因为这种方法适用于离散数字,而且我的计算是连续的。如果有人能纠正我的边境案件,那就太好了。
您可以让函数 f 在 [0;1] 上工作,例如
Integral(f(x)dx) on [0;1] = 500
f(0) = 200
f(0.75) = 5000
f(1) = 20000
我猜是表格的一个功能
f(x) = a*exp(x) + b*x + c
可能是一个解决方案,您只需要解决相关系统即可。
然后,你做到了,你就f(uniform_random(0,1))
在那里!
您的问题很模糊,因为有许多具有给定最小值、最大值和平均值的随机分布。
事实上,众多解决方案中的一种是max
用概率(mean-min)/(max-min)
或min
其他方式进行选择。也就是说,这个解决方案只生成两个数字之一——最小值和最大值。
以下是另一种解决方案。
PERT 分布(或beta-PERT 分布)旨在采用最小和最大和估计模式。这是三角分布的“平滑”版本,从该分布生成随机数可以实现如下:
startpt + (endpt - startpt) *
BetaDist(1.0 + (midpt - startpt) * shape / (endpt - startpt),
1.0 + (endpt - midpt) * shape / (endpt - startpt))
其中——</p>
startpt
是最小值,midpt
是众数(不一定是平均值或平均值),endpt
是最大值,shape
是一个 0 或更大的数字,但通常是 4,并且BetaDist(X, Y)
X
从带有参数和的 beta 分布中返回一个随机数Y
。给定一个已知的平均值 ( mean
),midpt
可以通过以下方式计算:
3 * mean / 2 - (startpt + endpt) / 4