que estaba leyendo sobre el problema subconjunto sumas cuando vine con lo que parece ser un algoritmo de propósito general para resolverlo:El problema subconjuntos de suma y la solvencia de NP-completo los problemas
(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" es una lista que no contiene duplicados y "sum" es la suma de los subconjuntos de búsqueda. "subconjuntos" es una lista de células de cons donde el "automóvil" es una lista de subconjuntos y el "cdr" es la suma de ese subconjunto. Se crean nuevos subconjuntos a partir de los antiguos en el tiempo O (1) simplemente considerando el elemento al frente.
No estoy seguro de cuál es la complejidad del tiempo de ejecución, pero parece que con cada elemento "suma" crece, el tamaño de "subconjuntos" se duplica, más uno, por lo que me parece al menos cuadrático.
Lo publico porque mi impresión anterior era que los problemas NP-completos tienden a ser insolubles y que lo mejor que se puede esperar es una heurística, pero esta parece ser una solución de uso general que, asumiéndote tener los ciclos de la CPU, siempre le dará la respuesta correcta. ¿Cuántos otros problemas NP-completos se pueden resolver como este?
Sí, mi solución es básicamente una búsqueda exhaustiva de todos los subconjuntos posibles de "conjunto" hasta que se encuentre uno con la suma correcta, así que supongo que no está cerca de ser un algoritmo eficiente. –