En ciencias de la computación , la partición de números en tiempo pseudopolinomial es un algoritmo de tiempo pseudopolinomial para resolver el problema de partición .
El problema se puede resolver utilizando programación dinámica cuando el tamaño del conjunto y el tamaño de la suma de los números enteros en el conjunto no son demasiado grandes como para hacer que los requisitos de almacenamiento sean inviables.
Supongamos que la entrada al algoritmo es un multiconjunto de cardinalidad :
Sea K la suma de todos los elementos de S . Es decir: K = x 1 + ... + x N . Construiremos un algoritmo que determine si existe un subconjunto de S cuya suma sea . Si existe un subconjunto, entonces:
eg1 S = {1, 2, 3, 5}, K = suma(S) = 11, K/2 = 5, Encuentra un subconjunto de S que sea más cercano a K/2 -> {2, 3} = 5, 11 - 5 * 2 = 1
eg2 S = {1, 3, 7}, K = suma(S) = 11, K/2 = 5, Encuentra un subconjunto de S que sea más cercano a K/2 -> {1, 3} = 4, 11 - 4 * 2 = 3
Queremos determinar si existe un subconjunto de S cuya suma sea . Sea:
Entonces p ( , N ) es Verdadero si y solo si hay un subconjunto de S que suma . El objetivo de nuestro algoritmo será calcular p ( , N ). Para ello, tenemos la siguiente relación de recurrencia :
El razonamiento para esto es el siguiente: hay un subconjunto de S que suma i usando números.
si y sólo si se cumple cualquiera de las siguientes condiciones:
El algoritmo consiste en construir una tabla de tamaño que contenga los valores de la recurrencia. Recuerde que es la suma de todos los elementos de . Una vez que se completa toda la tabla, devolvemos . A continuación se muestra una representación de la tabla . Hay una flecha azul de un bloque a otro si el valor del bloque de destino puede depender del valor del bloque de origen. Esta dependencia es una propiedad de la relación de recurrencia.
La función can_be_partitioned_equally( S ) tiene como entrada: una lista de números enteros S . Salida: Verdadero si S se puede dividir en dos subconjuntos que tienen una suma igual. n ← |S| K ← suma( S ) P ← tabla booleana vacía de tamaño ( + 1) por (n + 1) inicializar la fila superior ( P (0, x )) de P a Verdadero inicializar la columna más a la izquierda ( P ( x , 0)) de P , excepto P (0, 0) a Falso para i de 1 a para j de 1 a n x = S [ j -1] si ( i - x ) >= 0 entonces P ( i , j ) ← P ( i , j -1) o P ( i - x , j -1) de lo contrario P ( i , j ) ← P ( i , j -1) devuelve P ( , n )
A continuación se muestra la tabla P para el conjunto de ejemplo utilizado anteriormente S = {3, 1, 1, 2, 2, 1}:
Este algoritmo se ejecuta en un tiempo O ( KN ) , donde N es el número de elementos en el conjunto de entrada y K es la suma de elementos en el conjunto de entrada.
El algoritmo se puede extender al problema de particionamiento múltiple de k vías, pero entonces requiere O ( n ( k − 1) m k − 1 ) de memoria donde m es el número más grande en la entrada, lo que lo hace poco práctico incluso para k = 3 a menos que las entradas sean números muy pequeños. [1]
Este algoritmo se puede generalizar a una solución para el problema de suma de subconjuntos .