给定最小值、最大值、平均值和标准差,使用 Java 从分布中生成随机值

Given a min, max, mean and standard deviation, generate a random value from a distribution using Java

鉴于最小值 = 0.00,最大值 = 1400.00,平均值 = 150.50,标准差 = 25.00,如何根据这些统计数据生成随机值?据我了解,该图是一个偏斜图,但我不太确定它是否是对数正态分布的。然而,根据我目前的理解,以下代码 returns 一个来自正态分布的值。

private static int generateValue(double mean, double stdDev) {
    return (rand.nextGaussian() * stdDev) + mean);
}

您可以使用 do while 或 just while 循环,然后您可以简单地使用 if 语句为您的数字设置参数并生成随机数!

import java.util.Random;
class GenerateRandom {
public static void main( String args[] ) {
  Random rand = new Random(); //instance of random class
  int upperbound = 25;
    //generate random values from 0-24
  int int_random = rand.nextInt(upperbound); 
  double double_random=rand.nextDouble();
  float float_random=rand.nextFloat();
  
  System.out.println("Random integer value from 0 to" + (upperbound-1)       + " : "+ int_random);
  System.out.println("Random float value between 0.0 and 1.0 :  "+float_random);
  System.out.println("Random double value between 0.0 and 1.0 : "+double_random);
}

实现此目的的一种方法是找到具有由两个参数表征的均值和方差的自然有界分布。这将问题从试图同时满足四个约束(最小值、最大值、平均值和 s.d.)减少到根据两个参数求解两个方程(对于平均值和 s.d.)。要输入的 beta distribution meets those needs. It's defined on the range [0, 1], but that can be easily adjusted to your problem by scaling results by 1400. I used the Wikipedia link provided above to refresh my memory on the formulae for mean and variance of a beta, and then headed over to the solver at Wolfram|Alpha 使用平均值 150.5/1400 和标准差 25/1400 输入公式。这产生了 α=32.237057 和 β=267.642543 的解,因此您可以通过使用导出的参数值生成值 X = 1400 * beta(α, β) 来满足您的要求。

我已经超过 15 年没有使用 Java 了,我的机器上也没有,所以我使用 python 测试了它以确认参数化:

from scipy.stats import beta
import math

a = 32.237057
b = 267.642543
n = 100_000_000

mean, var = beta.stats(a, b, moments='mv')
print( f"mean = {mean * 1400}, std dev = {math.sqrt(var) * 1400}" )

产生

mean = 150.50000000000003, std dev = 25.000000000000004

我想说这与您使用浮点运算的要求差不多。然后我尝试了实际生成:

r = beta.rvs(a, b, size=n) * 1400
print( f"For n={n} min and max are {min(r)} and {max(r)}, respectively")

输出:

For n=100000000 min and max are 45.22697720545599 and 327.87270125710194, respectively

您可能认为经验最大值较低,但请注意,1400 仅比平均值高出 50σ。 Chebyshev's inequality 给出了一个非常弱的非参数上限来获得这样一个值的概率——它小于 1/2500。在许多情况下,包括这一个,实际概率远小于切比雪夫界限。也就是说,接近1400的概率基本为零。

通过 Apache Commons 库快速 Google 搜索挖掘出 class BetaDistribution,因此将此方法映射到 Java 应该很简单。