vendredi 18 décembre 2020

Generating random numbers with a min and max, and a set sum (Java)

My problem is as follows: I wish to generate n random numbers, which each have a min and a max, where the sum of all the random numbers combined is n*(max-min)/2. I have searched far and wide for similar questions, but have not found one with the constraint of a maximum value for the random numbers.

These are the two different approaches I have tried:

final int amount = 4;
final int min = 0;
final int max = 100;
final int average = 50;

int totalSum = amount * average;
int currentSum = 0;
ArrayList<Integer> numbers = new ArrayList<Integer>(amount);
Random randomizer = new Random();
while (numbers.size() < amount) {
    if (numbers.size() + 1 != amount) {
        int totalLeft = totalSum - currentSum;
        int averagePerNumber = totalLeft / (amount - numbers.size());
        int random = randomizer.nextInt(averagePerNumber * 2 > max + 1 ? max + 1 : averagePerNumber * 2);
        numbers.add(random);
        currentSum += random;
    } else {
        int number = totalSum - currentSum;
        numbers.add(number);
        currentSum += number;
    }
}
    final int amount = 4;
    final int min = 0;
    final int max = 100;
    final int average = 50;
    
    Random r = new Random();
    List<Integer> numbers = new ArrayList<Integer>(amount - 1);
    for (int i = 0; i < amount - 1; i++) {
        int number = min + r.nextInt(max - min);
        numbers.add(number);
    }
    Collections.sort(numbers);
    List<Integer> ranges = new ArrayList<Integer>(amount);
    Integer previousNumber = 0;
    for (Integer number : numbers) {
        ranges.add(number - previousNumber);
        previousNumber = number;
    }
    ranges.add(amount * average - previousNumber);

Both of them have the same problem: if a few numbers are generated with values that are low on the spectrum, one of the numbers will end up being over my maximum.

One solution that I have thought of, is changing the first approach so that if the last value is over my maximum, take the "extra" and add it to the lowest number in the list. For example, if the last value is 140 which is over my maximum of 100, then remove 40 from that number and re-add it to the lowest number in the list. However, this solution will not produce truly random numbers. I'm fairly confident that because of my maximum constraint, it isn't possible to get truly random numbers in this problem.

If you know of a way where I can always get truly random numbers even with these three constraints, I would appreciate it.

Thanks in advanced!




Aucun commentaire:

Enregistrer un commentaire