Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How exactly does one make random numbers add up to a declared sum?

Tags:

c#

random

I'm confused as to how exactly I would make 9 random numbers add to whatever number the user may input. Let's say the user inputs "200" as the number, how do I make it so that I could get 9 random numbers add up exactly to 200?

Obviously, the code below doesn't work the way I want it to because it's literally just 9 random numbers that don't add up to a specific number. I just have no idea how to get this built properly.

public static void RandomStats()
{
    Random RandomClass = new Random();

    int[] intRandomStats = {
        RandomClass.Next(0, 101), 
        RandomClass.Next(0, 101), 
        RandomClass.Next(0, 101), 
        RandomClass.Next(0, 101), 
        RandomClass.Next(0, 101), 
        RandomClass.Next(0, 101), 
        RandomClass.Next(0, 101), 
        RandomClass.Next(0, 101), 
        RandomClass.Next(0, 101)
    };

    // ...
}
like image 463
kayobi Avatar asked Sep 05 '25 03:09

kayobi


2 Answers

I think your question is more of math question than a code question.

It sounds like what you are looking for is a multinomial distribution. A very naive way of generating a distribution like that would be to think of it like throwing dice. Imagine that you have 200 dice with 9 sides each. Roll all of them. Count all the ones that ended up with the 1 side up, that would be your first number. Then count the ones that ended up with the 2 side up, that would be your second number. Continue until all dice are counted. There are 200 dice, so the sum of the counts will be 200. Each count would have the same probability distribution.

The above pseudo-algorithm would not be so efficient, basically looping over each die. Maybe efficiency is not so important in your case, (and 200 is a small number, so it does not matter) so feel free to write this algorithm.

If efficiency matters, try to find an existing implementation in a library. Maybe the MathNet library would work for you? See the Sample method if you are interested. At the very least, now that you know the term "multinomial distribution" it should be a bit easier to google for inspiration.

like image 96
DrPhil Avatar answered Sep 08 '25 00:09

DrPhil


Imagine you have a bag of 200 coins. You need to divvy those coins into 9 random piles. A pile can have all the coins in the bag, some of the coins in the bag, or no coins.

Each time you allocate coins for a pile, the number of coins in the bag gets smaller (unless you grabbed 0 coins in which case it stays the same). This new count is referenced for the next pile allocation.

var rand = new Random();
var amount = 200;
var targetOutputValueCount = 9;
var outputValues = new List<int>();
for (int i = 1; i < targetOutputValueCount; i++) // 1 less than all groups
{
    var groupAmount = rand.Next(0, amount);
    amount -= groupAmount;
    outputValues.Add(groupAmount);
}

// for the last group, it's whatever is left over
outputValues.Add(amount);

foreach (var outputValue in outputValues)
{
    Console.WriteLine(outputValue);
}

An example output would be

148
28
0
2
12
2
1
6
1

The advantage of this approach is that you are always guaranteed to have positive output numbers.

like image 39
gunr2171 Avatar answered Sep 07 '25 22:09

gunr2171