Эффективный алгоритм объединения элементов (itertools / numpy)

Я думаю, что это обычная проблема комбинаторики, но я не могу найти название для нее или чего-то еще. материал об этом. Я делаю это на Python и numpy, но если для этого есть быстрый матричный метод, я, вероятно, смогу перевести.

В основном, учитывая n элементов, мне нужно сгенерировать все способы их размещения м бункеров. Например, объединение 4 элементов в 3 ячейки даст что-то вроде [(4, 0, 0), (3, 1, 0), (3, 0, 1), (2, 2, 0), (2, 1, 1), ...] . Это продукт с фиксированной суммой.

Реализовать это с помощью itertools очень просто.

import itertools

def fixed_total_product(bins, num_items):
""" Return iterator of all item binning possibilities. """
return itertools.ifilter(lambda combo: sum(combo) == num_items,
                         itertools.product(xrange(num_items + 1), repeat=bins))

К сожалению, я думаю, что выполнение последующих вычислений в циклах будет неэффективным. Работа с этим как с двумерным массивом numpy позже будет быстрее, но я не могу найти эффективный способ создания массива с этим. Я мог бы перебрать результат ifilter, составив список возможностей,и использовать это для создания массива, но это кажется огромной тратой.

Я предполагаю, что лучший способ сделать это - построить все «беспорядочным способом», но я не уверен, как это сделать. Существует быстрая реализация продукта на stackoverflow: Использование numpy для построения массива всех комбинаций двух массивов . Я предполагаю, что вы можете изменить это только для вывода продуктов с правильной суммой. Размер массива должен быть ((m-1) + n), выберите n, так как существует m-1 границ бункера.

Есть идеи? Бенчмарки приветствуются, но не требуются.

10
задан Community 23 May 2017 в 12:24
поделиться