El problema de la mochila es el siguiente problema de optimización combinatoria :
Su nombre deriva del problema que enfrenta alguien que está limitado por una mochila de tamaño fijo y debe llenarla con los artículos más valiosos. El problema surge a menudo en la asignación de recursos , cuando quienes toman las decisiones tienen que elegir entre un conjunto de proyectos o tareas no divisibles bajo un presupuesto fijo o una restricció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] selección de inversiones y carteras , [3] selección de activos para la titulización respaldada por activos. , [4] y generar claves para Merkle-Hellman [5] y otros criptosistemas de mochila .
Una de las primeras aplicaciones de los algoritmos de mochila fue en la construcción y puntuación de pruebas en las que los examinados podían elegir qué preguntas responder. Para ejemplos pequeños, es un proceso bastante simple brindar a los examinados esa opción. Por ejemplo, si un examen contiene 12 preguntas con un valor de 10 puntos cada una, el examinado solo necesita responder 10 preguntas para lograr una puntuación máxima posible de 100 puntos. Sin embargo, en pruebas con una distribución heterogénea de valores de puntos, es más difícil ofrecer opciones. Feuerman y Weiss propusieron un sistema en el que a los estudiantes se les aplica una prueba heterogénea con un total de 125 puntos posibles. Se pide a los estudiantes que respondan todas las preguntas lo mejor que puedan. De los posibles subconjuntos de problemas cuyos valores totales de puntos 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 de 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 era el 19º más popular y el tercero más necesario después de los árboles de sufijos y el problema del embalaje 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í representa el número de instancias de artículo a incluir en la mochila. Informalmente, el problema es maximizar la suma de los valores de los artículos en 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 hay una de cada artículo, pero restringe el número de copias de cada tipo de artículo a un valor entero máximo no negativo :
El problema de la mochila ilimitada ( UKP ) no impone ningún límite superior al número de copias de cada tipo de artículo y puede formularse 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 principio de este artículo y el texto "si hay algún número de cada libro disponible" 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 polinómico aplicando este algoritmo de forma iterativa mientras aumentando el valor de k. Por otro lado, si un algoritmo encuentra el valor óptimo del problema de optimización en tiempo polinómico, entonces el problema de decisión se puede resolver en tiempo polinómico comparando el valor de la solución generada por este algoritmo con el valor de k. Por tanto, ambas versiones del problema presentan una dificultad similar.
Un tema en la literatura de investigación es identificar cómo son los casos "difíciles" del problema de la mochila, [8] [9] [10] o, vistos de otra manera, identificar qué propiedades de los casos en la práctica podrían hacerlos más manejables que sus sugiere el comportamiento NP-completo en el peor de los casos. [11] [12] El objetivo de encontrar estas instancias "duras" es su uso en sistemas de criptografía de clave pública , como el criptosistema de mochila 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 particular y puede mejorar la selección de algoritmos.
Además, cabe destacar el hecho de que la dureza del problema de la mochila depende de la forma de la entrada. Si los pesos y beneficios se dan como números enteros, es débilmente NP-completo , mientras que es fuertemente NP-completo si los pesos y beneficios se dan como números racionales. [13] Sin embargo, en el caso de pesos y beneficios racionales todavía admite un esquema de aproximación en tiempo totalmente polinomial .
La dureza NP del problema de 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 [14] muestran un límite inferior en los árboles de decisión lineal para el problema de la mochila, es decir, árboles donde los nodos de decisión prueban el signo de funciones afines . [15] Steele y Yao generalizaron esto a árboles de decisión algebraicos. [16] 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 real de acceso aleatorio con un conjunto de instrucciones que incluye suma, resta y multiplicación de números reales, así como comparación y ya sea división o resto ("piso"). [17] 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 sólo las decisiones. Meyer auf der Heide [18] dio un límite superior para un modelo de árbol de decisión , quien demostró que para cada n existe un árbol de decisión lineal profundo O ( n 4 ) que resuelve el problema de suma de subconjuntos con n elementos. Tenga en cuenta que esto no implica ningún límite superior para un algoritmo que debería resolver el problema para cualquier n dado .
Se encuentran disponibles varios algoritmos para resolver problemas de mochila, basados en el enfoque de programación dinámica, [19] el enfoque de rama y enlace [20] o hibridaciones de ambos enfoques. [11] [21] [22] [23]
El problema de la mochila ilimitada ( UKP ) no impone ninguna restricción al número de copias de cada tipo de artículo. Además aquí suponemos que
Observa que tiene las siguientes propiedades:
1. (la suma de cero elementos, es decir, la suma del conjunto vacío).
2. , , donde está el valor del -ésimo tipo de artículo.
La segunda propiedad necesita ser explicada en detalle. Durante el proceso de ejecución de este método, ¿cómo obtenemos el peso ? Sólo hay formas y en los pesos anteriores es donde hay totales de tipos de artículos 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 finalmente obtenemos el valor máximo y listo.
Aquí el máximo del conjunto vacío se toma como cero. Tabular los resultados desde arriba da la solución. Dado que el cálculo de cada uno implica examinar como máximo los 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 polinomio 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 la (versión de decisión del) problema de 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. Defina como el valor máximo que se puede alcanzar con un peso menor o igual al uso de artículos hasta (primeros artículos).
Podemos definir recursivamente de la siguiente manera: (Definición A)
Luego se puede encontrar la solución calculando . Para hacer esto de manera eficiente, podemos usar una tabla para almacenar 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 mochila (W)// NOTA: Se supone que la matriz "v" y la matriz "w" almacenan todos los valores relevantes comenzando en el índice 1.matriz m [ 0. . norte , 0. . W ]; para j de 0 a W haga : metro [ 0 , j ] := 0 para i de 1 a n hacer : metro [ yo , 0 ] := 0 para i de 1 a n hacer : para j de 1 a W haga : si w [ i ] > j entonces : metro [ yo , j ] := metro [ yo -1 , j ] demás : m [ i , j ] := máx ( m [ i -1 , j ], m [ i -1 , j - w [ i ]] + v [ i ])
Por tanto, esta solución funcionará 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 avanzamos uno o dos pasos más, debemos saber que el método se ejecutará en el tiempo comprendido entre y . Por la Definición A , sabemos que no es necesario calcular todos los pesos cuando el número 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 mochila (W)// NOTA: Se supone que la matriz "v" y la matriz "w" almacenan todos los valores relevantes comenzando en el índice 1.Definir valor [ n , W ] Inicializar todos los valores [ i , j ] = -1 Definir m := ( i , j ) // Definir la función m para que represente el valor máximo que podemos obtener bajo la condición: usar los primeros i elementos, 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 ha sido calculado, tenemos que llamar a la función m metro ( yo -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 ha sido calculado, tenemos que llamar a la función m metro ( yo -1 , j - w [ yo ]) 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 recursividad y convertirla en un árbol. Luego podemos cortar algunas hojas y usar 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 del 1 al i en la mochila* j: peso máximo de la mochila*/función mochila ( i : int , j : int ) : Establecer <int> { si yo == 0 entonces : devolver {} si m [ i , j ] > m [ i -1 , j ] entonces : return { i } ∪ mochila ( i -1 , j - w [ i ]) demás : mochila de regreso ( i -1 , j ) }mochila ( n , W )
Otro algoritmo para mochila 0-1, descubierto en 1974 [24] y a veces llamado "encuentro en el medio" debido a los paralelos con un algoritmo de nombre similar en criptografía , es exponencial en el número de elementos diferentes, pero puede ser preferible a el algoritmo DP cuando es grande en comparación con n . En particular, si no son negativos pero no son enteros, aún podríamos usar el algoritmo de programación dinámica escalando y redondeando (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, será necesario para ser escalado por , y el algoritmo DP requerirá espacio y tiempo.
El algoritmo Meet-in-the-middle es la 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 aproximadamente el mismo tamaño 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 realice un seguimiento del mayor valor combinado visto hasta el momento
El algoritmo requiere espacio e implementaciones eficientes del paso 3 (por ejemplo, ordenar los subconjuntos de B por peso, descartar subconjuntos de B que pesan más que otros subconjuntos de B de mayor o igual valor 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 ingenuo de fuerza bruta (examinando 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, utilizando conocimientos del algoritmo de Schroeppel y Shamir para la suma de subconjuntos, proporciona como corolario un algoritmo aleatorio para Knapsack que preserva el tiempo de ejecución (hasta factores polinomiales) y reduce los requisitos de espacio a (ver [25] Corolario 1.4). Por el contrario, el algoritmo determinista más conocido se ejecuta en el tiempo con una complejidad espacial ligeramente peor de . [26]
Como ocurre con la mayoría de los problemas NP completos, puede ser suficiente encontrar soluciones viables incluso si no son óptimas. Preferiblemente, sin embargo, la aproximación viene con una garantía de la diferencia entre el valor de la solución encontrada y el valor de la solución óptima.
Como ocurre con muchos algoritmos útiles pero computacionalmente complejos, se han realizado importantes investigaciones sobre la creación y análisis de algoritmos que se aproximan a una solución. El problema de la mochila, aunque NP-Hard, forma parte de una colección de algoritmos que aún pueden aproximarse a cualquier grado específico. 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 totalmente polinomial (FPTAS). [27]
George Dantzig propuso un algoritmo de aproximación codiciosa para resolver el problema de la mochila ilimitada. [28] Su versión clasifica los artículos en orden decreciente de valor por unidad de peso, . Luego procede a introducirlos en el saco, comenzando con tantas copias como sea posible del primer tipo de artículo hasta que ya no haya espacio en el saco para más. Siempre que haya un suministro ilimitado de cada tipo de artículo, si es el valor máximo de artículos que caben en el saco, entonces se garantiza que el algoritmo codicioso alcanzará 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 simple modificación nos permite resolver este caso: Supongamos por simplicidad que todos los artículos caben individualmente en el saco ( para todos ). Construya una solución empaquetando los artículos con avidez el mayor tiempo posible, es decir, donde . Además, construya una segunda solución que contenga el primer elemento que no encajaba. Dado que proporciona un límite superior para la relajación PL del problema, uno de los conjuntos debe tener un valor al menos ; por lo tanto, devolvemos cualquiera de y que 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 con la tasa de error [29]
El esquema de aproximación de tiempo totalmente 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 polinomiales conocidas es porque las ganancias asociadas con los artículos no están restringidas. Si se redondean algunos de los dígitos menos significativos de los valores de beneficio, entonces estarán acotados por un polinomio y 1/ε donde ε es un límite de la corrección de la solución. Esta restricción significa entonces que un algoritmo puede encontrar una solución en tiempo polinómico que sea correcta dentro de un factor de (1-ε) de la solución óptima. [27]
Se ingresa el algoritmo FPTAS : ε ∈ (0,1] una lista A de n elementos, especificados por sus valores, y pesos de salida: S' la solución FPTAS P := max // el valor más alto del artículo K := ε para i de 1 a n hacer := fin para devolver la solución, S', usando los valores en el 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 cuántica aproximada (QAOA) se puede emplear para resolver el problema de mochila mediante computación cuántica minimizando el hamiltoniano del problema. El hamiltoniano de mochila se construye incorporando la condición de restricción a la función de costos del problema con un término de penalización. [30] donde es la constante de penalización que se determina mediante un ajuste específico de cada caso.
La solución al problema de la mochila ilimitada se puede facilitar desechando elementos que nunca serán necesarios. Para un artículo dado , supongamos que podemos encontrar un conjunto de artículos cuyo peso total es menor que el peso de y su valor total es mayor que el valor de . Entonces no puede aparecer en la solución óptima, porque siempre podemos mejorar cualquier solución potencial que contenga reemplazándola con el conjunto . Por lo tanto, podemos ignorar el elemento -ésimo por completo. En tales casos, se dice que domina . (Tenga en cuenta que esto no se aplica a los problemas de mochila limitada, ya que es posible que ya hayamos agotado los elementos en ).
Encontrar relaciones de dominancia nos permite reducir significativamente el tamaño del espacio de búsqueda. Hay varios tipos diferentes de relaciones de dominancia, [11] las cuales satisfacen una desigualdad de la forma:
, y para algunos
dónde y . El vector denota el número de copias de cada miembro de .
Hay muchas variaciones del problema de la mochila que han surgido 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 ítems, 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 el beneficio monetario, el objetivo podría tener varias dimensiones. Por ejemplo, podría haber preocupaciones ambientales o sociales, además de objetivos económicos. Los problemas que se abordan con frecuencia incluyen optimizaciones de la logística de cartera y transporte. [31] [32]
Como ejemplo, supongamos que dirige un crucero. Tienes que decidir cuántos comediantes famosos contratar. Este barco no puede transportar más de una tonelada de pasajeros y los animadores deben pesar menos de 1000 libras. Cada comediante tiene un peso, genera negocios en función de su popularidad y pide un salario específico. En este ejemplo, tiene múltiples objetivos. Por supuesto, desea maximizar la popularidad de sus artistas y al mismo tiempo minimizar sus salarios. Además, desea tener tantos animadores como sea posible.
En esta variación, el peso del artículo de la mochila viene dado por un vector de dimensiones D y la mochila tiene un vector de capacidad de dimensiones D. El objetivo es maximizar la suma de los valores de los artículos en la mochila para 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. [33] Sin embargo, se muestra que el algoritmo en [34] resuelve instancias dispersas de manera eficiente. Una instancia de mochila multidimensional es escasa si hay un conjunto tal que para cada elemento de la mochila , tal que y . Estos casos ocurren, por ejemplo, cuando se programan paquetes en una red inalámbrica con nodos de retransmisión. [34] El algoritmo de [34] también resuelve casos escasos de la variante de opción múltiple, mochila multidimensional de opción múltiple.
El algoritmo IHS (Increasing Height Shelf) es óptimo para mochila 2D (empacar cuadrados en un cuadrado de tamaño unitario bidimensional): cuando hay como máximo cinco cuadrados en un empaque óptimo. [35]
Esta variación es similar al problema del embalaje del contenedor . Se diferencia del Problema de embalaje en contenedores en que se puede seleccionar un subconjunto de artículos, mientras que, en el Problema de embalaje en contenedores, todos los artículos deben empaquetarse en determinados contenedores. El concepto es que hay múltiples mochilas. Esto puede parecer un cambio trivial, pero no equivale a aumentar la capacidad de la mochila inicial. Esta variación se utiliza en muchos problemas de carga y programación en Investigación de Operaciones y tiene un esquema de aproximación de tiempo polinomial . [36]
El problema de la mochila cuadrática maximiza una función objetivo cuadrática sujeta a restricciones de capacidad binarias y lineales. [37] El problema fue introducido por Gallo, Hammer y Simeone en 1980, [38] sin embargo, el primer tratamiento del problema se remonta a Witzgall en 1975. [39]
El problema de suma de subconjuntos es un caso especial de decisión y problemas 0-1 donde el peso de cada tipo de elemento es igual al valor: . En el campo de la criptografía , el término problema de mochila suele utilizarse para referirse específicamente al problema de suma de subconjuntos. El problema de la suma de subconjuntos es uno de los 21 problemas NP-completos de Karp . [40]
Una generalización del problema de suma de subconjuntos se denomina problema de suma de subconjuntos múltiples, en el que existen varios contenedores con la misma capacidad. Se ha demostrado que la generalización no tiene FPTAS . [41]
En el problema de la mochila geométrica, hay un conjunto de rectángulos con diferentes valores y una mochila rectangular. El objetivo es meter en la mochila el mayor valor posible. [42]