Легче ли решить этот вариант задачи о сумме подмножеств?

У меня есть проблема, связанная с проблема подмножество сумме и мне интересно, облегчают ли различия, т. е. разрешимы за разумное количество времени.

учитывая значение V, размер набора L и последовательность чисел [1,N] S, сколько подмножеств размера L суммы S меньше V?

Это отличается от задачи суммы подмножества тремя способами:

  1. мне все равно, сколько подмножеств меньше чем заданное значение, а не сколько are равной.
  2. размеры подмножеств фиксированы.
  3. Я забочусь сколько устанавливает сумму меньше V, а не только существует ли она.

есть ли какой-либо разумно эффективный алгоритм для решения этой проблемы?

изменить: Очевидно, что это можно сделать в O (N выберите L), используя алгоритм генерации комбинации. Что меня действительно интересует, так это умные хаки, чтобы значительно ускорить его.

9 ответов


(решение версия) проблему NP-полной. Идея заключается в том, что если бы мы могли решить вашу проблему, то (для каждого подмножества размера, скажем) мы могли бы спросить, сколько комплектов сумма меньше V и сколько сумма меньше, чем Фау-1, и разность этих двух чисел скажет нам, является ли это подмножества, что суммы именно в ... Таким образом, мы могли бы решить подмножество сумма проблема. [Это не полное доказательство, потому что это сокращение Тьюринга, а не много сокращение.]

однако, есть простой динамическое программирование решение, которое выполняется во времени O (nLV). [Причина, по которой это не доказывает, что P=NP заключается в том, что V может быть экспоненциальным во входном размере: с N битами вы можете представлять значения до 2n. Но если предположить, что ваш V не экспоненциальный, это не проблема.]

пусть num[v][k][i] обозначает количество подмножеств размера k первых I элементов S, которые суммируются до v. вы можете вычислить их как (для каждого I):

    num[0][0][i] = 1
    for v = 1 to V:
        for k = 1 to L:
            num[v][k][i] = num[v][k][i-1] + num[v-S[i]][k-1][i-1]

где S[i] - i-й элемент в вашей последовательности. (Любой набор размера K, который подводит к V либо не использовать S[Я], так что это засчитывается в num[в][К][Я-1], или он использует С[Я], который означает, что остальные подмножества имеет K-1 элементов, использует только первые я-1 числа в последовательности, и суммы в-С[я].) Наконец, посчитайте num[v][L] [|S|] для каждого v меньше V; это ваш ответ.

кроме того, вы можете опустить третий индекс, если сделаете это осторожно (запустите цикл вниз для каждого I, и т. д.); Я включил его только для ясности.


Я не готов представить доказательство, но это звучит так, как будто это может быть поддается динамической схеме программирования: табулируйте список подмножеств размера 2, используйте их для компьютерных подмножеств размера 3 и т. д., Так что hyou нужно только изучить небольшую коллекцию перспектив.


одна оптимизация, которая приходит на ум: упорядочить последовательность (если это alerady не так). Выберите первые элементы L-1 с самого начала, а затем выберите последний элемент таким образом, чтобы это было максимально возможное значение (следующее по величине значение в последовательности даст слишком большую сумму). Отбросьте остальную часть последовательности, потому что эти элементы никогда не могут быть частью допустимого подмножества.

после этого я думаю, что это опять полный поиск. Но опять же там могут быть другие optimiziations возможный также.


Это не просто проблема с рюкзаком с закруткой? Возможно, я ошибаюсь.


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


Если это только положительные целые числа, вы можете сделать шаг проверки Если вам нужно;

возьмите сумму L-1 наименьших целых чисел в наборе. Если это сумма X, то n-X должно быть ниже самого большого элемента, если проблема должно есть решение. Подумайте об этом, вы можете устранить другую L таким образом...


Ну, во-первых, поскольку вы указываете size=L, то даже если вы не можете придумать ничего умного и просто использовать грубую силу, у вас будет (N выберите L) отдельные суммы в худшем случае, так что это немного лучше, чем n^^L (ну, L+1, так как вы бы суммировали каждое подмножество).


Это звучит как n выберите K категорию проблемы. Генерация K-подмножеств n рассматривается в руководстве по разработке алгоритмов Скиены, и в книге предлагается перечисление соответствующих подмножеств в лексикографическом порядке (рекурсивно, например). Затем сделайте свою сумму и сравнение по каждому подмножеству.

Если у вас есть отсортированный набор, Вы могли, вероятно, чернослив невозможные решения из пространства решений.


возможно, динамического программирования является amenamble в ПТС из FPTAS.