Как перечислить комбинации комбинаций из одного набора
Я понимаю, что есть куча вопросов о комбинаторике и перечислении, но я искал вокруг и не нашел ничего, относящегося конкретно к тому, что я ищу. Если я что-то пропустил, пожалуйста, укажите мне на это, и вопрос может быть закрыт.
Итак, предположим, что у нас есть множество из N элементов, и у нас есть x положительных целых чисел k1,..., kx где Sum (k1,..., kx)
Надеюсь, я правильно выразился. На случай, если нет, приведу простой пример.
N = 4, x = 2, k1 = 2, k2 = 1.
Мы должны перечислить
- {1, 2} {3}
- {1, 2} {4}
- {1, 3} {2}
- {1, 3} {4}
- {1, 4} {2}
- {1, 4} {3}
- {2, 3} {1}
- {2, 3} {4}
- {2, 4} {1}
- {2, 4} {3}
- {3, 4} {1}
- {3, 4} {2}
В общем случае общее количество, я думаю, будет:
C(N, k1) * C(N - k1, k2)*... * C (N-сумма (k1,...,КН-1), кн).
Мое первоначальное предположение состоит в том, что это можно было бы сделать довольно легко, используя стек. На каждом уровне стека I подмножество ki будет генерироваться с использованием стандартного перечисления комбинаций, либо удаляя из исходного набора на каждом уровне те элементы, которые были выбраны, либо просто перечисляя из исходного набора и пропуская случаи, когда элемент был включен ранее.
Мой вопрос: есть ли более быстрое / элегантное решение?
1 ответ:
Ваш вопрос-это именно проблема перечисления перестановок мультинабора. (Предполагая, что ваши ki упорядочены).
Во - первых, заметим, что задача точно эквивалентна задаче, где Σk &равно N, потому что если Σk x+1, значение которого равно N-Σk.Теперь положите элементы исходного множества s в некоторый произвольный фиксированный порядок, и создать каждой перестановки мультимножества, состоящего из K1 1 это, к2 2 это, к3 3 это, ... k x X. Этот мультисет имеет одинаковый размер (N) S, потому что K i складываются в N. Мы создаем разбиение S, присваивая каждый элемент в S подмножеству, индекс которого является соответствующим значением в перестановке мультисета.
Например, S = {яблоко, банан, чиримоя, финик} (N = 4). Мы берем к1 = 2 и к2 = 1 и добавить k3 = 1 довести сумму до 4. (Мы просто проигнорируем элементы, назначенные подмножеству 3). Теперь перечислим перестановки множества1 1 2 3
(которое имеет два 1, Один 2 и один 3, соответствующие k):1 1 2 3 1 2 3 1 2 1 1 3 3 1 1 2 1 1 3 2 1 3 1 2 2 1 3 1 3 1 2 1 1 2 1 3 1 3 1 1 2 3 1 1 3 2 1 1
Мы преобразуем их обратно в разделы S. например, принимая
1 3 1 2
:apple 1 -> subset 1 banana 3 -> unused chirimoya 1 -> subset 1 date 2 -> subset 2
Итак, у нас есть
{{apple, chirimoya}, {date}}
Стандартный алгоритмдля нахождения перестановок множества работает так же хорошо на мультисетях, хотя он не является оптимальным, если мультисет имеет много дубликатов.