Reputation: 161
I need to randomly generate an array with 7 slots in Java. All these slots must have a value of at LEAST 1, but combined, have a total value of another defined number. They also all need to be an int value, no 1.5 or 0.9816465684646 numbers. Example:
int a=10;
int[] ar = new int[7]
ar[0] = 1
ar[1] = 1
ar[2] = 2
ar[3] = 2
ar[4] = 1
ar[5] = 2
ar[6] = 1
I want it to generate something like that, but if int a=15, all the numbers would total 15 in any order
Upvotes: 13
Views: 11499
Reputation: 13171
The standard way to generate N random numbers that add to a given sum is to think of your sum as a number line, generate N-1 random points on the line, sort them, then use the differences between the points as your final values. To get the minimum 1, start by subtracting N from your sum, run the algorithm given, then add 1 back to each segment.
public class Rand {
public static void main(String[] args) {
int count = 8;
int sum = 100;
java.util.Random g = new java.util.Random();
int vals[] = new int[count];
sum -= count;
for (int i = 0; i < count-1; ++i) {
vals[i] = g.nextInt(sum);
}
vals[count-1] = sum;
java.util.Arrays.sort(vals);
for (int i = count-1; i > 0; --i) {
vals[i] -= vals[i-1];
}
for (int i = 0; i < count; ++i) { ++vals[i]; }
for (int i = 0; i < count; ++i) {
System.out.printf("%4d", vals[i]);
}
System.out.printf("\n");
}
}
Upvotes: 40
Reputation: 10810
A good way to achieve uniformity is, for example, to fill up a = 15
units into an 8 element array:
In this way, you'll meet your minimum conditions by having each element have minimum value 1. Then you distribute the remaining totals in a completely random way.
Upvotes: 14
Reputation: 1193
My java is horrible, so I'm not providing the actual code here, as it would probably be wrong. I've done this exact thing in SQL before though, so I know it works...
Upvotes: 1
Reputation: 128
Adding on to what @Kon said, you could use two random numbers rather than one for more randomness. That is:
Fill every element in the array with the value 1
valuesToDistribute = a - array.length-1
randomIndex = Roll a number between 0 and array.length-1
randomValue = Roll a number between 1 and valuesToDistribute
Add to randomIndex the value randomValue
Subtract randomValue from valuesToDistribute
Repeat until valuesToDistribute = 0
Upvotes: 2