Java中的替换加权采样

时间:2013-12-31 22:02:03

标签: java matlab random random-sample

Java中是否有函数,或者像Apache Commons Math这样的库中有一个函数,它等同于MATLAB函数randsample? 更具体地说,我想找到一个函数randSample,它根据我指定的概率分布返回独立和同分布随机变量的向量。 例如:

int[] a = randSample(new int[]{0, 1, 2}, 5, new double[]{0.2, 0.3, 0.5})
//        { 0 w.p. 0.2
// a[i] = { 1 w.p. 0.3
//        { 2 w.p. 0.5

输出与MATLAB代码randsample([0 1 2], 5, true, [0.2 0.3 0.5])相同,其中true表示替换采样。

如果这样的功能不存在,我该怎么写呢?

注意:我知道Stack Overflow上已经询问similar question,但遗憾的是它没有得到答复。

1 个答案:

答案 0 :(得分:3)

我很确定一个不存在,但很容易制作一个可以产生这样的样本的函数。首先,Java确实附带了一个随机数生成器,特别是一个带有函数Random.nextDouble()的生成器,它可以产生0.0到1.0之间的随机双精度数。

import java.util.Random;

double someRandomDouble = Random.nextDouble();
     // This will be a uniformly distributed
     // random variable between 0.0 and 1.0.

如果您使用替换进行采样,如果将作为输入的pdf转换为cdf,则可以使用Java提供的随机双精度通过查看cdf的哪个部分来创建随机数据集。首先,您需要将pdf转换为cdf。

int [] randsample(int[] values, int numsamples, 
        boolean withReplacement, double [] pdf) {

    if(withReplacement) {
        double[] cdf = new double[pdf.length];
        cdf[0] = pdf[0];
        for(int i=1; i<pdf.length; i++) {
            cdf[i] = cdf[i-1] + pdf[i];
        }

然后,您可以使用正确大小的整数数组来存储结果并开始查找随机结果:

        int[] results = new int[numsamples];
        for(int i=0; i<numsamples; i++) {
            int currentPosition = 0;

            while(randomValue > cdf[currentPosition] && currentPosition < cdf.length) {
                currentPosition++; //Check the next one.
            }

            if(currentPosition < cdf.length) { //It worked!
                results[i] = values[currentPosition];
            } else { //It didn't work.. let's fail gracefully I guess.
                results[i] = values[cdf.length-1]; 
                     // And assign it the last value.
            }
        }

        //Now we're done and can return the results!
        return results;
    } else { //Without replacement.
        throw new Exception("This is unimplemented!");
    }
}

有一些错误检查(确保值数组和pdf数组的大小相同)以及一些其他功能,您可以通过重载它来提供其他功能,但希望这足以让您启动。干杯!