El problema de la mochila es el siguiente problema de optimización combinatoria :
Su nombre deriva del problema al que se enfrenta alguien que está limitado por una mochila de tamaño fijo y debe llenarla con los artículos más valiosos. El problema suele surgir en la asignación de recursos , donde los encargados de la toma de decisiones tienen que elegir entre un conjunto de proyectos o tareas no divisibles con un presupuesto fijo o una limitación de tiempo, respectivamente.
El problema de la mochila se ha estudiado durante más de un siglo y los primeros trabajos se remontan a 1897. [1]
Los problemas de mochila aparecen en los procesos de toma de decisiones del mundo real en una amplia variedad de campos, como encontrar la forma menos derrochadora de cortar materias primas, [2] la selección de inversiones y carteras , [3] la selección de activos para la titulización respaldada por activos , [4] y la generación de claves para Merkle–Hellman [5] y otros criptosistemas de mochila .
Una de las primeras aplicaciones de los algoritmos de mochila fue la construcción y calificación de exámenes en los que los examinados tienen la opción de elegir qué preguntas responder. Para ejemplos pequeños, es un proceso bastante simple proporcionar a los examinados esa opción. Por ejemplo, si un examen contiene 12 preguntas, cada una con un valor de 10 puntos, el examinado solo necesita responder 10 preguntas para lograr una puntuación máxima posible de 100 puntos. Sin embargo, en exámenes con una distribución heterogénea de valores de puntos, es más difícil proporcionar opciones. Feuerman y Weiss propusieron un sistema en el que se les da a los estudiantes un examen heterogéneo con un total de 125 puntos posibles. Se les pide a los estudiantes que respondan todas las preguntas lo mejor que puedan. De los posibles subconjuntos de problemas cuyos valores de puntos totales suman 100, un algoritmo de mochila determinaría qué subconjunto le da a cada estudiante la puntuación más alta posible. [6]
Un estudio de 1999 del Repositorio de Algoritmos de la Universidad Stony Brook mostró que, de 75 problemas algorítmicos relacionados con el campo de los algoritmos combinatorios y la ingeniería de algoritmos, el problema de la mochila fue el 19º más popular y el tercero más necesario después de los árboles de sufijos y el problema de empaquetamiento de contenedores . [7]
El problema más común que se resuelve es el problema de la mochila 0-1 , que restringe el número de copias de cada tipo de artículo a cero o uno. Dado un conjunto de artículos numerados del 1 al , cada uno con un peso y un valor , junto con una capacidad máxima de peso ,
Aquí se representa el número de instancias del elemento que se incluirá en la mochila. De manera informal, el problema consiste en maximizar la suma de los valores de los elementos de la mochila de modo que la suma de los pesos sea menor o igual a la capacidad de la mochila.
El problema de la mochila acotada ( BKP ) elimina la restricción de que solo existe uno de cada elemento, pero restringe el número de copias de cada tipo de elemento a un valor entero máximo no negativo :
El problema de la mochila ilimitada ( UKP ) no impone un límite superior al número de copias de cada tipo de artículo y se puede formular como se indicó anteriormente, excepto que la única restricción es que sea un número entero no negativo.
Un ejemplo del problema de la mochila ilimitada se da utilizando la figura que se muestra al comienzo de este artículo y el texto "si hay alguna cantidad disponible de cada libro" en el título de esa figura.
El problema de la mochila es interesante desde la perspectiva de la informática por muchas razones:
Existe un vínculo entre los problemas de "decisión" y de "optimización" en el sentido de que si existe un algoritmo polinomial que resuelve el problema de "decisión", entonces se puede encontrar el valor máximo para el problema de optimización en tiempo polinomial aplicando este algoritmo de manera iterativa mientras se aumenta el valor de k. Por otro lado, si un algoritmo encuentra el valor óptimo del problema de optimización en tiempo polinomial, entonces el problema de decisión se puede resolver en tiempo polinomial comparando el valor de la solución obtenida por este algoritmo con el valor de k. Por lo tanto, ambas versiones del problema tienen una dificultad similar.
Un tema en la literatura de investigación es identificar cómo se ven las instancias "duras" del problema de la mochila, [8] [9] o visto de otra manera, identificar qué propiedades de las instancias en la práctica podrían hacerlas más manejables de lo que sugiere su comportamiento NP-completo en el peor de los casos. [10] El objetivo de encontrar estas instancias "duras" es su uso en sistemas de criptografía de clave pública , como el criptosistema de mochila de Merkle-Hellman . De manera más general, una mejor comprensión de la estructura del espacio de instancias de un problema de optimización ayuda a avanzar en el estudio del problema en particular y puede mejorar la selección de algoritmos.
Además, es notable el hecho de que la dificultad del problema de la mochila depende de la forma de la entrada. Si los pesos y las ganancias se dan como números enteros, es débilmente NP-completo , mientras que es fuertemente NP-completo si los pesos y las ganancias se dan como números racionales. [11] Sin embargo, en el caso de pesos y ganancias racionales, todavía admite un esquema de aproximación de tiempo completamente polinomial .
La NP-dureza del problema de la mochila se relaciona con modelos computacionales en los que el tamaño de los números enteros importa (como la máquina de Turing ). Por el contrario, los árboles de decisión cuentan cada decisión como un solo paso. Dobkin y Lipton [12] muestran un límite inferior en los árboles de decisión lineales para el problema de la mochila, es decir, árboles donde los nodos de decisión prueban el signo de las funciones afines . [13] Esto fue generalizado a los árboles de decisión algebraicos por Steele y Yao. [14] Si los elementos del problema son números reales o racionales , el límite inferior del árbol de decisión se extiende al modelo de máquina de acceso aleatorio real con un conjunto de instrucciones que incluye suma, resta y multiplicación de números reales, así como comparación y división o resto ("piso"). [15] Este modelo cubre más algoritmos que el modelo de árbol de decisión algebraico, ya que abarca algoritmos que utilizan indexación en tablas. Sin embargo, en este modelo se cuentan todos los pasos del programa, no solo las decisiones. Meyer auf der Heide [16] proporcionó un límite superior para un modelo de árbol de decisión y demostró que para cada n existe un árbol de decisión lineal de profundidad O ( n 4 ) que resuelve el problema de suma de subconjuntos con n elementos. Obsérvese que esto no implica ningún límite superior para un algoritmo que debería resolver el problema para cualquier n dado .
Existen varios algoritmos disponibles para resolver problemas de mochila, basados en el enfoque de programación dinámica, [17] el enfoque de ramificación y acotación [18] o hibridaciones de ambos enfoques. [10] [19] [20] [21]
El problema de la mochila ilimitada ( UKP ) no impone ninguna restricción en cuanto al número de copias de cada tipo de artículo. Además, aquí suponemos que
Observe que tiene las siguientes propiedades:
1. (la suma de cero elementos, es decir, la suma del conjunto vacío).
2. , , donde es el valor del -ésimo tipo de elemento.
La segunda propiedad debe explicarse en detalle. Durante el proceso de ejecución de este método, ¿cómo obtenemos el peso ? Solo hay formas y los pesos anteriores son donde hay un total de tipos de elementos diferentes (al decir diferentes, queremos decir que el peso y el valor no son completamente iguales). Si conocemos cada valor de estos elementos y el valor máximo relacionado previamente, simplemente los comparamos entre sí y obtenemos el valor máximo en última instancia y listo.
Aquí se toma como cero el máximo del conjunto vacío. Tabulando los resultados de arriba a abajo se obtiene la solución. Dado que el cálculo de cada uno implica examinar como máximo elementos y hay como máximo valores de para calcular, el tiempo de ejecución de la solución de programación dinámica es . Dividir por su máximo común divisor es una forma de mejorar el tiempo de ejecución.
Incluso si P≠NP , la complejidad no contradice el hecho de que el problema de la mochila es NP-completo , ya que , a diferencia de , no es polinomial en la longitud de la entrada al problema. La longitud de la entrada al problema es proporcional al número de bits en , , no a sí misma. Sin embargo, dado que este tiempo de ejecución es pseudopolinomial , esto hace que el (versión de decisión del) problema de la mochila sea un problema débilmente NP-completo .
Una solución de programación dinámica similar para el problema de la mochila 0-1 también se ejecuta en tiempo pseudopolinomial. Supongamos que son números enteros estrictamente positivos. Definamos que es el valor máximo que se puede alcanzar con un peso menor o igual a utilizando elementos hasta (primeros elementos).
Podemos definir recursivamente de la siguiente manera: (Definición A)
La solución se puede encontrar calculando . Para hacerlo de manera eficiente, podemos usar una tabla para almacenar los cálculos anteriores.
El siguiente es el pseudocódigo para el programa dinámico:
// Aporte:// Valores (almacenados en la matriz v)// Pesos (almacenados en la matriz w)// Número de elementos distintos (n)// Capacidad de la mochila (W)// NOTA: Se supone que la matriz "v" y la matriz "w" almacenan todos los valores relevantes a partir del índice 1.matriz m [ 0. . n , 0. . W ]; Para j de 0 a W hacemos : m [ 0 , j ] := 0 para i de 1 a n hacer : m [ yo , 0 ] := 0 para i de 1 a n hacer : Para j de 1 a W hacemos : Si w [ i ] > j entonces : m [ i , j ] := m [ i -1 , j ] demás : m [ i , j ] := máx ( m [ i -1 , j ], m [ i -1 , j - w [ i ]] + v [ i ])
Por lo tanto, esta solución se ejecutará en el tiempo y el espacio. (Si solo necesitamos el valor m[n,W], podemos modificar el código para que la cantidad de memoria requerida sea O(W), que almacena las dos líneas recientes de la matriz "m").
Sin embargo, si lo llevamos un paso o dos más allá, deberíamos saber que el método se ejecutará en el tiempo entre y . A partir de la Definición A , sabemos que no es necesario calcular todos los pesos cuando la cantidad de elementos y los elementos mismos que elegimos son fijos. Es decir, el programa anterior calcula más de lo necesario porque el peso cambia de 0 a W con frecuencia. Desde esta perspectiva, podemos programar este método para que se ejecute de forma recursiva.
// Aporte:// Valores (almacenados en la matriz v)// Pesos (almacenados en la matriz w)// Número de elementos distintos (n)// Capacidad de la mochila (W)// NOTA: Se supone que la matriz "v" y la matriz "w" almacenan todos los valores relevantes a partir del índice 1.Definir valor [ n , W ] Inicializar todos los valores [ i , j ] = -1 Define m := ( i , j ) // Define la función m para que represente el valor máximo que podemos obtener bajo la condición: usar los primeros i artículos, el límite de peso total es j { Si i == 0 o j <= 0 entonces : valor [ i , j ] = 0 devolver si ( valor [ i -1 , j ] == -1 ) entonces : // m[i-1, j] no se ha calculado, tenemos que llamar a la función m m ( i -1 , j ) si w [ i ] > j entonces : // el artículo no cabe en la bolsa valor [ i , j ] = valor [ i -1 , j ] demás : si ( valor [ i -1 , j - w [ i ]] == -1 ) entonces : // m[i-1,jw[i]] no se ha calculado, tenemos que llamar a la función m m ( i -1 , j - w [ i ]) valor [ i , j ] = máx ( valor [ i -1 , j ], valor [ i -1 , j - w [ i ]] + v [ i ]) }Ejecutar m ( n , W )
Por ejemplo, hay 10 elementos diferentes y el límite de peso es 67. Entonces, si usa el método anterior para calcular , obtendrá esto, excluyendo las llamadas que producen :
Además, podemos romper la recursión y convertirla en un árbol. Luego podemos cortar algunas hojas y utilizar computación paralela para acelerar la ejecución de este método.
Para encontrar el subconjunto real de elementos, en lugar de solo su valor total, podemos ejecutar esto después de ejecutar la función anterior:
/*** Devuelve los índices de los artículos de la mochila óptima.* i: Podemos incluir los artículos 1 a i en la mochila.* j: peso máximo de la mochila*/función mochila ( i : int , j : int ) : Establecer < int > { Si i == 0 entonces : devolver {} si m [ i , j ] > m [ i -1 , j ] entonces : devuelve { i } ∪ mochila ( i -1 , j - w [ i ]) demás : volver mochila ( i -1 , j ) }mochila ( n , W )
Otro algoritmo para la mochila 0-1, descubierto en 1974 [22] y a veces llamado "encuentro en el medio" debido a los paralelismos con un algoritmo de nombre similar en criptografía , es exponencial en el número de elementos diferentes, pero puede ser preferible al algoritmo DP cuando es grande en comparación con n . En particular, si son no negativos pero no enteros, aún podríamos usar el algoritmo de programación dinámica mediante escalado y redondeo (es decir, usando aritmética de punto fijo ), pero si el problema requiere dígitos fraccionarios de precisión para llegar a la respuesta correcta, necesitará ser escalado por , y el algoritmo DP requerirá espacio y tiempo.
El algoritmo Meet-in-the-middle es entrada: un conjunto de elementos con pesos y valores. salida: el mayor valor combinado de un subconjunto. Dividir el conjunto {1... n } en dos conjuntos A y B de tamaño aproximadamente igual. Calcular los pesos y valores de todos los subconjuntos de cada conjunto. Para cada subconjunto de A, encuentre el subconjunto de B de mayor valor tal que el peso combinado sea menor que W. Realizar un seguimiento del mayor valor combinado visto hasta ahora
El algoritmo ocupa espacio, y las implementaciones eficientes del paso 3 (por ejemplo, ordenar los subconjuntos de B por peso, descartar subconjuntos de B que pesen más que otros subconjuntos de B de valor mayor o igual, y usar la búsqueda binaria para encontrar la mejor coincidencia) dan como resultado un tiempo de ejecución de . Al igual que con el ataque de encuentro en el medio en criptografía, esto mejora el tiempo de ejecución de un enfoque de fuerza bruta ingenuo (examinar todos los subconjuntos de ), a costa de usar espacio exponencial en lugar de constante (ver también paso de bebé paso de gigante ). La mejora actual del estado del arte del algoritmo de encuentro en el medio, que utiliza conocimientos del Algoritmo para la suma de subconjuntos de Schroeppel y Shamir, proporciona como corolario un algoritmo aleatorio para Knapsack que preserva el tiempo de ejecución (hasta factores polinómicos) y reduce los requisitos de espacio a (ver [23] Corolario 1.4). En contraste, el algoritmo determinista más conocido se ejecuta en el tiempo con una complejidad espacial ligeramente peor de . [24]
Como en la mayoría de los problemas NP-completos, puede ser suficiente encontrar soluciones viables incluso si no son óptimas. Sin embargo, es preferible que la aproximación venga con una garantía de la diferencia entre el valor de la solución encontrada y el valor de la solución óptima.
Al igual que ocurre con muchos algoritmos útiles pero computacionalmente complejos, se han llevado a cabo importantes investigaciones sobre la creación y el análisis de algoritmos que se aproximan a una solución. El problema de la mochila, aunque es NP-Hard, forma parte de una colección de algoritmos que aún pueden aproximarse a cualquier grado especificado. Esto significa que el problema tiene un esquema de aproximación de tiempo polinomial. Para ser exactos, el problema de la mochila tiene un esquema de aproximación de tiempo completamente polinomial (FPTAS). [25]
George Dantzig propuso un algoritmo de aproximación voraz para resolver el problema de la mochila ilimitada. [26] Su versión ordena los artículos en orden decreciente de valor por unidad de peso, . Luego procede a insertarlos en la bolsa, comenzando con tantas copias como sea posible del primer tipo de artículo hasta que ya no haya espacio en la bolsa para más. Siempre que haya un suministro ilimitado de cada tipo de artículo, si es el valor máximo de los artículos que caben en la bolsa, entonces se garantiza que el algoritmo voraz logrará al menos un valor de .
Para el problema acotado, donde la oferta de cada tipo de artículo es limitada, el algoritmo anterior puede estar lejos de ser óptimo. Sin embargo, una modificación simple nos permite resolver este caso: supongamos para simplificar que todos los artículos caben individualmente en el saco ( para todos ). Construya una solución empaquetando artículos con avidez el mayor tiempo posible, es decir, donde . Además, construya una segunda solución que contenga el primer artículo que no cabía. Dado que proporciona un límite superior para la relajación LP del problema, uno de los conjuntos debe tener un valor de al menos ; por lo tanto, devolvemos el que de y tenga mejor valor para obtener una aproximación.
Se puede demostrar que el rendimiento promedio converge a la solución óptima en la distribución en la tasa de error [27]
El esquema de aproximación de tiempo completamente polinomial (FPTAS) para el problema de la mochila aprovecha el hecho de que la razón por la que el problema no tiene soluciones de tiempo polinomial conocidas es porque las ganancias asociadas con los artículos no están restringidas. Si uno redondea algunos de los dígitos menos significativos de los valores de las ganancias, entonces estarán limitados por un polinomio y 1/ε donde ε es un límite en la exactitud de la solución. Esta restricción significa entonces que un algoritmo puede encontrar una solución en tiempo polinomial que sea correcta dentro de un factor de (1-ε) de la solución óptima. [25]
Se ingresa el algoritmo FPTAS : ε ∈ (0,1] una lista A de n elementos, especificados por sus valores, y pesos salida: S' la solución FPTAS P := max // el valor del artículo más alto K := ε para i de 1 a n hacer := fin para Devuelve la solución, S', utilizando los valores del programa dinámico descrito anteriormente.
Teorema: El conjunto calculado por el algoritmo anterior satisface , donde es una solución óptima.
El algoritmo de optimización aproximada cuántica (QAOA) se puede emplear para resolver el problema de Knapsack mediante computación cuántica al minimizar el hamiltoniano del problema. El hamiltoniano de Knapsack se construye incorporando la condición de restricción a la función de costo del problema con un término de penalización. [28] donde es la constante de penalización que se determina mediante un ajuste fino específico del caso.
La solución del problema de la mochila ilimitada se puede hacer más fácil si se desechan los elementos que nunca se necesitarán. Para un elemento dado , supongamos que pudiéramos encontrar un conjunto de elementos tales que su peso total sea menor que el peso de , y su valor total sea mayor que el valor de . Entonces no puede aparecer en la solución óptima, porque siempre podríamos mejorar cualquier solución potencial que contenga reemplazando con el conjunto . Por lo tanto, podemos descartar el elemento -ésimo por completo. En tales casos, se dice que domina . (Tenga en cuenta que esto no se aplica a los problemas de mochilas acotadas, ya que es posible que ya hayamos usado los elementos en ).
Encontrar relaciones de dominancia nos permite reducir significativamente el tamaño del espacio de búsqueda. Existen varios tipos diferentes de relaciones de dominancia, [10] y todas satisfacen una desigualdad de la forma:
, y para algunos
donde y . El vector denota el número de copias de cada miembro de .
Existen muchas variantes del problema de la mochila que han surgido a partir de la gran cantidad de aplicaciones del problema básico. Las principales variaciones se producen al cambiar el número de algún parámetro del problema, como el número de elementos, el número de objetivos o incluso el número de mochilas.
Esta variación cambia el objetivo del individuo que llena la mochila. En lugar de un objetivo, como maximizar la ganancia monetaria, el objetivo podría tener varias dimensiones. Por ejemplo, podría haber preocupaciones ambientales o sociales, así como objetivos económicos. Los problemas que se abordan con frecuencia incluyen optimizaciones de la logística de transporte y de la cartera. [29] [30]
Por ejemplo, supongamos que gestionas un crucero. Tienes que decidir cuántos comediantes famosos vas a contratar. Este barco no puede transportar más de una tonelada de pasajeros y los artistas deben pesar menos de 1000 libras. Cada comediante tiene un peso, genera clientes en función de su popularidad y pide un salario específico. En este ejemplo, tienes varios objetivos. Por supuesto, quieres maximizar la popularidad de tus artistas y minimizar sus salarios. Además, quieres tener tantos artistas como sea posible.
En esta variación, el peso del elemento de la mochila está dado por un vector de dimensión D y la mochila tiene un vector de capacidad de dimensión D. El objetivo es maximizar la suma de los valores de los elementos de la mochila de modo que la suma de los pesos en cada dimensión no exceda .
La mochila multidimensional es computacionalmente más difícil que la mochila; incluso para , el problema no tiene EPTAS a menos que P NP. [31] Sin embargo, se muestra que el algoritmo en [32] resuelve instancias dispersas de manera eficiente. Una instancia de mochila multidimensional es dispersa si hay un conjunto para tal que para cada elemento de mochila , tal que y . Tales instancias ocurren, por ejemplo, al programar paquetes en una red inalámbrica con nodos de retransmisión. [32] El algoritmo de [32] también resuelve instancias dispersas de la variante de opción múltiple, mochila multidimensional de opción múltiple.
El algoritmo IHS (Increasing Height Shelf) es óptimo para una mochila 2D (empaquetado de cuadrados en un cuadrado de tamaño unitario bidimensional): cuando hay como máximo cinco cuadrados en un empaquetamiento óptimo. [33]
Esta variación es similar al problema de empaquetado de contenedores . Se diferencia de este último en que se puede seleccionar un subconjunto de elementos, mientras que en este último se deben empaquetar todos los elementos en contenedores determinados. El concepto es que hay varias mochilas. Esto puede parecer un cambio trivial, pero no es equivalente a aumentar la capacidad de la mochila inicial. Esta variación se utiliza en muchos problemas de carga y programación en la investigación de operaciones y tiene un esquema de aproximación de tiempo polinomial . [34]
El problema de la mochila cuadrática maximiza una función objetivo cuadrática sujeta a restricciones de capacidad binaria y lineal. [35] El problema fue introducido por Gallo, Hammer y Simeone en 1980, [36] sin embargo el primer tratamiento del problema se remonta a Witzgall en 1975. [37]
El problema de la suma de subconjuntos es un caso especial de los problemas de decisión y 0-1 donde cada tipo de elemento, el peso es igual al valor: . En el campo de la criptografía , el término problema de la mochila se utiliza a menudo para referirse específicamente al problema de la suma de subconjuntos. El problema de la suma de subconjuntos es uno de los 21 problemas NP-completos de Karp . [38]
Una generalización del problema de suma de subconjuntos se denomina problema de suma de subconjuntos múltiples, en el que existen múltiples contenedores con la misma capacidad. Se ha demostrado que la generalización no tiene un FPTAS . [39]
En el problema geométrico de la mochila, hay un conjunto de rectángulos con diferentes valores y una mochila rectangular. El objetivo es meter el mayor valor posible en la mochila. [40]