Как генерировать случайные числа в массиве, которые суммируются до определенной суммы?

Мне нужно случайным образом создать массив с 7 слотами в Java. Все эти слоты должны иметь значение на уровне 1, но вместе взятые, имеют общее значение другого определенного числа. Они также должны быть значениями int, no 1.5 или 0.9816465684646. Пример:

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

Я хочу, чтобы он генерировал что-то подобное, но если int a = 15, все числа будут составлять 15 в любом порядке

Ответ 1

Стандартный способ генерации N случайных чисел, добавляющих к данной сумме, состоит в том, чтобы думать о вашей сумме как числовой строке, генерировать N-1 случайные точки на линии, сортировать их, а затем использовать различия между точками как ваши конечные значения. Чтобы получить минимум 1, начните с вычитания N из вашей суммы, запустите указанный алгоритм, затем добавьте 1 к каждому сегменту.

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");
    }
}

Ответ 2

Хорошим способом достижения однородности является, например, заполнение единиц a = 15 в массив из 8 элементов:

  • Поместите 1 в каждый элемент массива, так как это ваше требование, теперь у вас осталось 7 значений для распространения
  • Сверните случайное число между 0 и максимальным индексом массива и добавьте 1 к этому элементу и вычтите 1 из 7. Сделайте это до тех пор, пока 7 не опустится до нуля.

Таким образом, вы встретите свои минимальные условия, если каждый элемент имеет минимальное значение 1. Затем вы распределяете оставшиеся суммы полностью случайным образом.

Ответ 3

Добавляя к тому, что сказал @Kon, вы могли бы использовать два случайных числа, а не одно для большей случайности. То есть:

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

Ответ 4

Моя java ужасна, поэтому я не предоставляю код здесь, так как это, вероятно, было бы неправильно. Я сделал эту точную вещь в SQL раньше, поэтому, я знаю, что это работает...

  • Пусть Y - это общее значение, которое вы хотите добавить к
  • Начните цикл с переменной Z, идущей от 1 до X, где X - числовые элементы в вашем массиве (здесь называется AR)
  • В цикле установите AR (Z) на случайное число между 1 и Y-X + Z
  • Вычтите новое значение из Y, поэтому Y = Y - AR (Z)
  • Конечный цикл: возврат к шагу 2, продвижение Z на 1