获取带有偏差的范围内的随机数

时间:2019-06-16 17:23:58

标签: java random

您好,我正在尝试一种方法来生成一定范围内的随机数 可能会出现偏差,具体取决于偏差,从而使该数字更有可能更高/更低。

我目前正在使用此功能

 public int randIntWeightedLow(int max, int min, int rolls){

    int rValue = 100;

    for (int i = 0; i < rolls ; i++) {
        int rand = randInt(min, max);

        if (rand < rValue ){
            rValue = rand;
        }
    }

    return rValue;
}

通过给我一个范围内的数字可以正常工作,我添加的掷骰次数越多,这个数字可能就越低。但是我遇到的问题是3卷和4卷之间有很大的区别。

我希望有类似的东西 公共无效randomIntWithBias(int最小值,int最大值,浮点偏差){ }

如果给出负偏倚,则该数字会更频繁地降低,并且 正偏差会使数字更高,但仍将数字保持在最小值和最大值之间。

当前要生成我正在使用的随机数

 public int randInt(final int n1, final int n2) {
    if (n1 == n2) {
        return n1;
    }

    final int min = n1 > n2 ? n2 : n1;
    final int max = n1 > n2 ? n1 : n2;

    return rand.nextInt(max - min + 1) + min;
}

我是Java和编码的新手,所以对您的帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

好吧,这是一个简短的草图。

首先,我建议使用Apache commons java library,它具有整数采样 已经实现了不同的概率。我们需要Enumerated Integer Distribution

第二,两个参数使分布看起来呈线性,p0和增量。 对于第k个值,相对概率为p0 + k * delta。对于正增量 较大的数字将更有可能,因为负负较小的数字将是 更有可能的是,delta = 0等于统一采样。

代码(我的Java生锈了,请多多包涵)

import org.apache.commons.math3.distribution.EnumeratedIntegerDistribution;

public int randomIntWithBias(int min, int max, double p0, double delta){
    if (p0 < 0.0)
        throw new Exception("Negative initial probability");        
    int N = max - min + 1; // total number of items to sample

    double[] p = new double[N]; // probabilities
    int[] items = new int[N]; // items

    double sum = 0.0; // total probabilities summed
    for(int k = 0; k != N; ++k) { // fill arrays
        p[k] = p0 + k*delta;
        sum += p[k];
        items[k] = min + k;
    }

    if (delta < 0.0) { // when delta negative we could get negative probabilities
       if (p[N-1] < 0.0) // check only last probability
           throw new Exception("Negative probability");
    }

    for(int k = 0; k != N; ++k) { // Normalize probabilities
        p[k] /= sum;
    }

    EnumeratedIntegerDistribution rng = new EnumeratedIntegerDistribution(items, p);

    return rng.sample();
}

这就是主旨,可以(并且应该)优化和清理代码。

更新

当然,可以代替线性偏差函数,例如,平方函数。 一般的二次函数具有三个参数-传递它们,以类似的方式填充概率数组,归一化,采样