Найти сумму в массиве, равную нулю - PullRequest
2 голосов
/ 31 января 2011

Учитывая массив целых чисел, найдите набор из хотя бы одного целого числа, сумма которого равна 0.

Например, учитывая [-1, 8, 6, 7, 2, 1, -2, -5], алгоритм может вывести [-1, 6, 2, -2, -5], потому что это подмножество входного массива, сумма которого равна 0.

Решение должно выполняться за полиномиальное время.

Ответы [ 3 ]

8 голосов
/ 31 января 2011

Вам будет трудно сделать это за полиномиальное время, так как эта проблема известна как Задача суммы подмножеств и известна как NP-полная . * 1005. *

Однако, если вы найдете полиномиальное решение, вы решите проблему " P = NP? ", которая сделает вас достаточно богатым.

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

4 голосов
/ 31 января 2011

Это проблема Подмножество сумм , это NP-Compelete, но для нее есть алгоритм псевдополиномиального времени. см. вики.

Проблема может быть решена в полиноме, если сумма элементов в наборе полиномиально связана с количеством элементов из вики:

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

x1, ..., xn

и мы хотим определить, есть ли непустое подмножество, сумма которого равна 0. Пусть N быть суммой отрицательных значений и P сумма положительных значений. Определить булевозначную функцию Q (i, s) будет значением (true или false) из

"there is a nonempty subset of x1, ..., xi which sums to s".

Таким образом, решение проблемы значение Q (n, 0).

Ясно, Q (i, s) = false, если s

P, поэтому эти значения не нужно хранить или вычислять. Создать массив для держать значения Q (i, s) для 1 ≤ i ≤ n и N ≤ s ≤ P.

Теперь массив можно заполнить с помощью простая рекурсия. Первоначально для N ≤ s ≤ P, установите

Q(1,s) := (x1 = s).

Тогда для i = 2,…, n, установите

Q(i,s) := Q(i − 1,s) or (xi = s) or Q(i − 1,s − xi)   for N ≤ s ≤ P.

Для каждого присвоения значения Q на правой стороне уже известны, либо потому, что они были сохранены в таблица для предыдущего значения I или потому что Q (i - 1, s - xi) = false, если s - xi P. Следовательно, общее количество арифметических операций является O (n (P - N)). Например, если все Значения O (nk) для некоторого k, тогда требуемое время O (nk + 2).

Этот алгоритм легко изменить на вернуть подмножество с суммой 0, если есть это один.

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

Более общая проблема требует суммирование подмножества до указанного значения (не обязательно 0). Это можно решить простой модификацией алгоритм выше. Для случая, когда каждый XI является положительным и ограничен та же константа, Пизингер нашел линейный алгоритм времени. [2]

1 голос
/ 31 января 2011

Хорошо известна проблема сумм подмножеств , какая NP-полная задача.

Если вас интересуют алгоритмы, то, скорее всего, вы любитель математики, и я советую вам посмотреть на

и здесь вы можете найти алгоритм для него

инициализировать список S, содержащий один элемент 0.

для каждого i от 1 до N делай

пусть T будет списком, состоящим из xi + y, для всех у в S

пусть U будет объединением T и S сортировка U

сделать S пустым

пусть у будет наименьшим элементом U

добавить y к S

для каждого элемента z U в в порядке увеличения do // обрезать список устранение номеров близко друг к другу если y <(1-c / N) z, установите y = z и добавьте z к S </p>

если S содержит число между (1-c) s и s, выведите yes, в противном случае no

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...