I'm trying to code (JavaScript or VB.NET) an algorithm to generate x random numbers. Each random number has to be within a certain range and the total sum of all the numbers has to be equal to a constant. I don't particularly need the exact code (if I do, I can always ask when I start getting into debugging), but just the logic behind the whole thing.
In my particular case: I need to generate 4 random numbers, each between 0 and 10, and the total sum of the randomly generated numbers needs to be 24.
If you need any more information: please ask. Thanks in advance for trying to solve this with me 🙂.
EDIT: I should have added what I tried already (the code is in VB.NET but not that hard so ...) Based on this StackOverflow answer, this is what I tried already (it does not work though):
Dim intAverageNumberMark As Integer = 24 / 4
Dim intOverMark As Integer = 0
Dim intGeneratedRandomNumber As Integer = 0
Dim intCurrentSumOfRandomNumbers = 0
For intCounter = 0 To intNumberOfTowers - 1
intGeneratedRandomNumber = RandomNumber(0 + intGeneratedRandomNumber, 10)
intOverMark = If(intGeneratedRandomNumber > intAverageNumberMark, intGeneratedRandomNumber - intAverageNumberMark, 0)
If intCounter = intNumberOfTowers - 1 Then
intNumbers(intCounter) = 24 - intCurrentSumOfRandomNumbers
End If
intNumbers(intCounter) = intGeneratedRandomNumber
intCurrentSumOfRandomNumbers += intGeneratedRandomNumber
Debug.Print(intGeneratedRandomNumber)
Next
intNumbers() is an array of declared with Dim intNumbers(7) As Integer.
sum = 0;
loop
generate new number
if sum + new number <= constant{
sum += new number
break out of loop
}
The most easy approach is to take a brte force mthod and generate all possible combinations and take a random select of the this result set.
function generate(from, to, size, sum) {
function iter(right, delta) {
if (delta < 0) return;
if (!delta && right.length === size) return result.push(right);
if (!delta || right.length === size) return;
for (let i = from; i <= Math.min(delta, to); i++)
iter([...right, i], delta - i);
}
const result = [];
iter([], sum);
return result;
}
const
result = generate(0, 10, 4, 24);
console.log(result.length);
document.getElementById('out').innerHTML += result.map(a => a.map(v => v.toString().padStart(2, ' ')).join(' ')).join('\n');
<pre id="out"></pre>
If all you're looking for is the algorithm, this is the approach I would take:
One thing I feel I should point out is that numbers will become increasingly non-random as C approaches 0 - the speed with which this occurs kind of depends on your random number upper and lower bounds compared to C.
You could also figure out a few extra data points about this algorithm, such as how many times the loop runs (how many numbers you generated).