2

可能重复:
生成密度不均匀的随机数

我尝试识别/创建一个函数(在 Java 中),它给我一个非均匀分布的数字序列。如果我有一个函数说它function f(x), and x>0会给我一个从0to的随机数x

最适用于任何给定的功能x,下面这只是我想要的一个示例。

但是,如果我们说x=100该函数f(x)将返回 s nonunifrom 分布式。

我想例如说

0 to 20大约占所有情况的 20%。

21 to 50大约占所有情况的 50%。

51 to 70大约占所有情况的 20%。

71 to 100大约是所有情况的 10。

简而言之,这给了我一个像正态分布这样的数字,在这种情况下它x是30-40 100

http://en.wikipedia.org/wiki/Normal_distribution

(如果需要,我可以使用一个统一的随机生成作为分数,并且只有一个可以从统一结果转换为非统一结果的函数。)

编辑

我对这个问题的最终解决方案是:

/**
 * Return a value from [0,1] and mean as 0.3, It give 10% of it is lower
 * then 0.1. 5% is higher then 0.8 and 30% is in rang 0.25 to 0.45
 *
 * @return
 */
public double nextMyGaussian() {
    double d = -1000;
    while (d < -1.5) {
        // RANDOMis Java's normal Random() class.
        // The nextGaussian is normal give a value from -5 to +5?
        d = RANDOM.nextGaussian() * 1.5;
    }
    if (d > 3.5d) {
        return 1;
    }
    return ((d + 1.5) / 5);
}
4

5 回答 5

4

一个简单的解决方案是生成 0 到 9 之间的第一个随机数。

0 表示前 10 个百分比,1 表示后面的 10 个百分比,依此类推。

因此,如果你得到 0 或 1,你会生成第二个介于 0 和 20 之间的随机数。如果你得到 2、3、4、5 或 6,你会生成第二个介于 21 和 50 之间的随机数,依此类推。

于 2012-11-07T22:49:00.470 回答
2

你能写一个函数,将1-X范围内的随机数相加并取平均值吗?随着 n 的增加,这将趋于正态分布

看:

在 C/C++ 中按照正态分布生成随机数

我破解了以下内容:

class CrudeDistribution {

    final int TRIALS = 20;

    public int getAverageFromDistribution(int upperLimit) {
        return getAverageOfRandomTrials(TRIALS, upperLimit);
    }

    private int getAverageOfRandomTrials(int trials, int upperLimit) {
        double d = 0.0;
        for (int i=0; i<trials; i++) {
            d +=getRandom(upperLimit);
        }
        return (int) (d /= trials);
    }

    private int getRandom(int upperLimit) {
        return (int) (Math.random()*upperLimit)+1;
    }
}

Commons-Math 中有一些库可以根据均值和标准差(测量分布)生成分布。并在链接中执行此操作的一些算法。

可能是一个有趣的小时寻找相关的 2 班轮:

https://commons.apache.org/math/userguide/distribution.html

于 2012-11-07T23:04:25.827 回答
0

一种解决方案是做一个 1-100 之间的随机数,并根据结果在适当的范围内做另一个随机数。

1-20 -> 0-20

21-70 -> 21-50

71-90 -> 51-70

91-100 -> 71-100

希望这是有道理的。

于 2012-11-07T22:50:47.090 回答
0

您需要先创建 f(x)。

假设值 x 是等概率的,您的 f(x) 是

double f(x){
if(x<=20){
 return x;
}else if (x>20 && x<=70){
 return (x-20)/50*30+20;
} else if(...

ETC

于 2012-11-07T23:09:33.507 回答
0

只需生成一堆,例如至少 30 个,介于 0 和 x 之间的均匀随机数。然后取它们的平均值。根据中心极限定理,平均值将是来自以 x/2 为中心的正态分布的随机数。

于 2012-11-07T23:10:50.913 回答