Generate random values with fixed sum in C++ [clos

2020-05-29 06:47发布

问题:

I saw tons of answers to this question on the web but, can you believe me? I still don't get the solution of this problem. I have an array of values. The size of this array is "n". I have also the defined value "sum". What I want is to generate "n" random values in such a way that their sum is equals to "sum", preferably uniformly distributed, otherwise (for example) having the first random number equals to "sum" and the rest equals to zero is not that nice. I need two algorithms which accomplish this task. One with positive Integers and one with positive Floats. Thanks a lot in advance!

回答1:

First generate n random variables. Then sum them up: randomSum. Calculate coefficient sum/randomSum. Then multiply all random variables with that coefficient.

Integers would pose a problem... Rounding too (probably)



回答2:

You can generate n numbers with a normal distribution then normalize them to your sum



回答3:

You can generate n values defined by this : ((Sum - sumOfGeneratedValues) / n - (numberOfGeneatedValue)) -+X (With X maximal deviance)

Example :

SUM = 100 N = 5 +- 10


Rand between 100 - 0 / 5 - 0 --> 20 +-10 (So bewteen 10 and 30)

Value1 = 17;

Rand between 100 - 17 / 5 - 1 ---> 21 +-10 (So between 11 and 31)

... etc

Deviance would make your random uniform :)



回答4:

you have a loop, where the number of iterations is equal to the number of random numbers you want minus 1. for the first iteration, you find a random number between 0 and the sum. you then subtract that random number from the sum, and on the next iteration you get another random number and subtract that from the sub sum minus the last iteration

its probably more easy in psuedocode

int sum = 10;
int n = 5; // 5 random numbers summed to equal sum
int subSum = sum;
int[] randomNumbers = new int[n];

for(int i = 0; i < n - 2; i++)
{
    randomNumbers[i] = rand(0, subSum); // get random number between 0 and subSum 
    subSum -= randomNumbers[i];
}

randomNumbers[n - 1] = subSum; // leftovers go to the last random number


回答5:

My C++ is very (very very) rusty. So let's assume you already know how to get a random number between x and y with the function random(x,y). Then here is some psuedocode in some other c derived language:

int n = ....; // your input
int sum = ....; // your input
int[] answer = new int[n];
int tmpsum = 0;
for (int i=0; i < n; i++) {
    int exactpart = sum/n;
    int random = (exactpart/2) + random(0,exactpart);
    int[i] = tmpsum + random > sum ? sum - tmpsum : random;
    tmpsum += int[i];
}
int[n-1] += sum - tmpsum;