我需要生成具有以下属性的随机数。
最低应为200
最大值应为20000
平均值(均值)为500。
可选:第75百分位为5000
绝对不是均匀分布,也不是高斯分布。我需要给出一些左偏斜。
答案 0 :(得分:12)
Java Random可能无法正常工作,因为它只能为您提供普通(高斯)分布。
您可能正在寻找的是f分发(见下文)。您可以使用distlib库here并选择f distribution。您可以使用random方法获取随机数。
答案 1 :(得分:8)
说X
是你的目标变量,让我们通过Y=(X-200)/(20000-200)
来规范化范围。因此,现在您需要一些Y
随机变量,其中[0,1]
的值为(500-200)/(20000-200)=1/66
。
你有很多选择,最自然的选择Beta distribution,Y ~ Beta(a,b)
a/(a+b) = 1/66
- 你有一个额外的自由度,你可以选择适合最后四分位数要求。
之后,您只需将X作为Y*(20000-200)+200
要生成Beta随机变量,您可以使用Apache Commons或查看here。
答案 2 :(得分:4)
这可能不是您正在寻找的答案,但具有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百分位,有机会在75-100。
感谢@Stas - 我正在使用他的“包容性随机”功能。
是的,我意识到我的数字是错误的,因为这种方法适用于离散数字,我的计算是连续的。如果有人可以纠正我的边境案件,那将是件好事。
答案 3 :(得分:3)
你可以在[0; 1]上使用函数f,例如
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))
就在你身边!
答案 4 :(得分:0)
PERT distribution(或 beta-PERT发行版)旨在采用最小值和最大值以及估算模式。它是一个平滑的"三角分布的版本,并从该分布生成随机数可以如下实现:
startpt + (endpt - startpt) *
BetaDist(1.0 + (midpt - startpt) * shape / (endpt - startpt),
1.0 + (endpt - midpt) * shape / (endpt - startpt))
其中 -
startpt
是最低要求,midpt
是模式(不一定是平均值或均值),endpt
是最大值,shape
是0或更大的数字,但通常是4和BetaDist(X, Y)
会返回包含参数X
和Y
的测试版分布中的随机数。给定已知均值(mean
),midpt
可以通过以下方式计算:
3 * mean / 2 - (startpt + endpt) / 4