我需要生成具有以下属性的随机数:
最小值应为200
最大值应为20000
平均数(均值)为500。
可选:第75个百分位数为5000
它绝不是均匀分布,也不是高斯分布。我需要一些左偏斜度。
我需要生成具有以下属性的随机数:
最小值应为200
最大值应为20000
平均数(均值)为500。
可选:第75个百分位数为5000
它绝不是均匀分布,也不是高斯分布。我需要一些左偏斜度。
X
是您的目标变量,通过执行 Y=(X-200)/(20000-200)
来归一化范围。 现在您需要一些随机变量 Y
,它的值在区间 [0,1]
中,并且其平均值为 (500-200)/(20000-200)=1/66
。Y ~ Beta(a,b)
且 a/(a+b) = 1/66
- 您有一个额外的自由度,可以选择是否满足最后四分之一的要求。Y*(20000-200)+200
要生成 Beta 随机变量,您可以使用 Apache Commons 或参见此处。这可能不是你想要的答案,但针对三个均匀分布的特殊情况:
(忽略左侧的数字,但它是按比例缩放的!)
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 * 左高度 == 19500 * 右高度
,因此左高度 == 65 * 右高度
这给了我们1/66的机会选择正确的,以及65/66的机会选择左边。
然后我按照同样的方法计算第75个百分位数,但比率为500-5000 的机会 == 5000-20000 的机会 * 10 / 3
。同样,这意味着我们有10/13的机会处于50-75百分位数区间,以及3/13的机会处于75-100百分位数区间。
致敬@Stas - 我正在使用他的“包含随机”函数。
是的,我意识到我的数字是错误的,因为这种方法是适用于离散数字,并且我的计算是连续的。希望有人能够纠正我的边界情况。
Integral(f(x)dx) on [0;1] = 500
f(0) = 200
f(0.75) = 5000
f(1) = 20000
I guess a function of the form
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))
在编程中——
startpt
是最小值,midpt
是众数(不一定是平均数或者均值),endpt
是最大值,shape
是一个大于等于0的数字,但通常为4,且BetaDist(X, Y)
返回具有参数 X
和 Y
的beta分布的随机变量。已知均值(mean
),可以通过以下公式计算 midpt
:
3 * mean / 2 - (startpt + endpt) / 4