PragmaGames
@PragmaGames
Увлекаюсь Unity.

Как раскидать элементы максимально рандомно согласно условию?

Всем привет. Есть x стопок, каждая может вместить в себе разное количество блоков y (для каждой стопки y свой). Дается z блоков ( z меньше либо равно суммы блоков в стопке (y1 + y2 + y3 ... yn)). Нужно рандомно разместить данные блоки (z) по стопкам так что бы не осталось лишних блоков. Не обязательно это делать за один проход, но чем меньше тем лучше. Так же допускается что в одной из стопок после размещения не окажется блоков.
  • Вопрос задан
  • 116 просмотров
Решения вопроса 2
Alexandroppolus
@Alexandroppolus
кодир
на JS, переделать в C# нетрудно

function randomSets(boxSizes, z) {
    const arr = [];
    const result = [];
    for (let i = 0; i < boxSizes.length; ++i) {
        result.push([]);
        const y = boxSizes[i];
        for (let j = 0; j < y; ++j) {
            arr.push(i);
        }
    }
    let len = arr.length;
    for (let i = 0; i < z && len > 0; ++i) {
        const pos = Math.floor(Math.random() * len);
        result[arr[pos]].push(i);
        arr[pos] = arr[--len];
    }

    return result;
}

const fill = randomSets([1, 2, 2], 5); // в качестве блоков - номера от 0 до z-1


пример результата:
[
  [1], // содержимое 0 стопки
  [0, 4], // содержимое 1 стопки
  [2, 3] // содержимое 2 стопки
]
Ответ написан
wataru
@wataru Куратор тега Математика
Разработчик на С++, экс-олимпиадник.
Надо чтобы все возможные варинаты были равновероятны или возможны перекосы?

Если возможны перекосы, то есть простой алгоритм.
Сначала за один проход подсчитайте частичные суммы s1=y1, s2=y1+y2, s3=y1+y2+y3...

Потом идем с конца. В последнюю стопку можно положить от max(0, z-s(n-1)) до yn блоков. Все оставшиеся блоки гарантированно влезают в предыдущие стопки. Уменьшайте z на сгенерированное случайное число блоков и повторяйте дальше.

Если надо все равновернятно, то все сложно. Надо динамическим программированем уметь считать, сколько вариантов разместить k блоков на первых i стопках. Потом сгенерировать случайный номер среди всевозможного количества размещений и считать, а сколько бывает вариантов при последней стопке с 0, 1, ... yn блоках и так можно понять, сколько блоков надо поставить в последнюю стопку, чтобы накрыть нужный вариант в лексикографическом порядке. Для этого используйте подсчитанные динмическим программированием значения.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы