Java:具有非均匀分布的随机整数

2022-09-01 01:36:58

如何在Java中创建一个随机整数,介于“线性降序分布”之间,即 最有可能,不太可能,不太可能,...,最不可能,并且概率线性下降,如下所示:n1k123k

enter image description here

我知道这个话题已经有几十个线程了,我很抱歉做了一个新的线程,但我似乎无法从中创建我需要的东西。我知道使用,代码import java.util.*;

Random r=new Random();
int n=r.nextInt(k)+1;

在 和 之间创建一个随机整数,均匀分布。1k

普遍化:任何创建任意分布整数的提示,即 ,),也将不胜感激,例如:f(n)=some functionP(n)=f(n)/(f(1)+...+f(k))

enter image description here.


答案 1

这应该给你你需要的:

public static int getLinnearRandomNumber(int maxSize){
    //Get a linearly multiplied random number
    int randomMultiplier = maxSize * (maxSize + 1) / 2;
    Random r=new Random();
    int randomInt = r.nextInt(randomMultiplier);

    //Linearly iterate through the possible values to find the correct one
    int linearRandomNumber = 0;
    for(int i=maxSize; randomInt >= 0; i--){
        randomInt -= i;
        linearRandomNumber++;
    }

    return linearRandomNumber;
}

此外,以下是从开始索引到停止索引范围的正函数(负函数实际上没有意义)的一般解决方案:

public static int getYourPositiveFunctionRandomNumber(int startIndex, int stopIndex) {
    //Generate a random number whose value ranges from 0.0 to the sum of the values of yourFunction for all the possible integer return values from startIndex to stopIndex.
    double randomMultiplier = 0;
    for (int i = startIndex; i <= stopIndex; i++) {
        randomMultiplier += yourFunction(i);//yourFunction(startIndex) + yourFunction(startIndex + 1) + .. yourFunction(stopIndex -1) + yourFunction(stopIndex)
    }
    Random r = new Random();
    double randomDouble = r.nextDouble() * randomMultiplier;

    //For each possible integer return value, subtract yourFunction value for that possible return value till you get below 0.  Once you get below 0, return the current value.  
    int yourFunctionRandomNumber = startIndex;
    randomDouble = randomDouble - yourFunction(yourFunctionRandomNumber);
    while (randomDouble >= 0) {
        yourFunctionRandomNumber++;
        randomDouble = randomDouble - yourFunction(yourFunctionRandomNumber);
    }

    return yourFunctionRandomNumber;
}

注意:对于可能返回负值的函数,一种方法是获取该函数的绝对值,并将其应用于每个函数调用的上述解决方案。


答案 2

因此,我们需要以下分布,从最不可能到最有可能:

*
**
***
****
*****

等。

让我们尝试将均匀分布的整数随机变量映射到该分布:

1
2  3
4  5  6
7  8  9  10
11 12 13 14 15

等。

这样,如果我们生成一个均匀分布的随机整数,从1到15,在这种情况下,我们只需要弄清楚它适合哪个桶。棘手的部分是如何做到这一点。K = 5

请注意,右边的数字是三角形数字!这意味着对于随机生成的 from to ,我们只需要找到这样的 .幸运的是,有一个定义明确的公式可以找到给定数字的“三角形根”,我们可以将其用作从均匀分布到桶的映射的核心:X1T_nNT_(n-1) < X <= T_n

// Assume k is given, via parameter or otherwise
int k;

// Assume also that r has already been initialized as a valid Random instance
Random r = new Random();

// First, generate a number from 1 to T_k
int triangularK = k * (k + 1) / 2;

int x = r.nextInt(triangularK) + 1;

// Next, figure out which bucket x fits into, bounded by
// triangular numbers by taking the triangular root    
// We're dealing strictly with positive integers, so we can
// safely ignore the - part of the +/- in the triangular root equation
double triangularRoot = (Math.sqrt(8 * x + 1) - 1) / 2;

int bucket = (int) Math.ceil(triangularRoot);

// Buckets start at 1 as the least likely; we want k to be the least likely
int n = k - bucket + 1;

n现在应该具有指定的分布。


推荐