я читал о проблеме субпопуляции-суммах, когда я пришел с тем, что, как представляется, универсальный алгоритм для ее решения:Проблема подмножеств суммы и разрешимость NP-полной задачи
(defun subset-contains-sum (set sum)
(let ((subsets) (new-subset) (new-sum))
(dolist (element set)
(dolist (subset-sum subsets)
(setf new-subset (cons element (car subset-sum)))
(setf new-sum (+ element (cdr subset-sum)))
(if (= new-sum sum)
(return-from subset-contains-sum new-subset))
(setf subsets (cons (cons new-subset new-sum) subsets)))
(setf subsets (cons (cons element element) subsets)))))
«set» - это список, не содержащий дубликатов, а «sum» - сумма для поиска подмножеств. «подмножества» - это список ячеек cons, в которых «автомобиль» представляет собой список подмножеств, а «cdr» - это сумма этого подмножества. Новые подмножества создаются из старых в O (1) раз, просто конспектируя элемент на фронт.
Я не уверен, что это сложность выполнения, но кажется, что с каждым элементом «сумма» растет, размер «подмножеств» удваивается, плюс один, поэтому мне представляется, по крайней мере, квадратичным.
Я публикую это, потому что раньше у меня было впечатление, что проблемы с NP-комплексом, как правило, неразрешимы и что лучшее, на что можно надеяться, это эвристика, но это, похоже, универсальное решение, которое, имеют циклы процессора, всегда дают правильный ответ. Сколько других NP-полных проблем можно решить, как этот?
Да, мое решение в основном является исчерпывающим поиском всех возможных подмножеств «набора» до тех пор, пока не будет найдена правильная сумма, поэтому я думаю, что это не близко к эффективному алгоритму. –