Problema de mochila rama y límite | enfoques de programación dinámica
Problema de mochila bifurcado y atado
Escriba código de Python para resolver el problema de la mochila utilizando enfoques de programación dinámicos y de ramificación y acotación:
Problema de la mochila
El problema de la mochila es un problema de optimización clásico que implica seleccionar un subconjunto de artículos para empacar en una mochila con capacidad limitada con el fin de maximizar el valor total de los artículos seleccionados. El problema se define por un conjunto de elementos, cada uno con un peso y un valor, y una mochila con una capacidad máxima. El objetivo es seleccionar un subconjunto de los artículos para empacar en la mochila de modo que el peso total no exceda la capacidad de la mochila, y el valor total de los artículos seleccionados sea lo más grande posible.
El problema de la mochila es un problema NP-hard bien conocido, lo que significa que no existe un algoritmo conocido que pueda resolverlo en tiempo polinómico. Sin embargo, hay varios enfoques que se pueden utilizar para encontrar soluciones casi óptimas, incluida la programación dinámica y la bifurcación y enlace.
Ramificación y encuadernación
El algoritmo de bifurcación y enlace es una técnica de optimización general que se utiliza a menudo para resolver problemas de optimización combinatoria, como el problema de la mochila. El algoritmo funciona explorando el espacio de búsqueda de posibles soluciones de manera sistemática, eliminando gradualmente las ramas que no pueden conducir a mejores soluciones que la mejor encontrada hasta ahora.
En el caso del problema de la mochila, el algoritmo de bifurcación y enlace se puede utilizar para explorar el espacio de búsqueda de todos los posibles subconjuntos de elementos que se pueden empacar en la mochila. El algoritmo mantiene una cola de prioridad de soluciones parciales, donde cada solución parcial representa un subconjunto de los elementos que se han considerado hasta ahora, junto con el peso total y el valor de esos elementos. La prioridad de cada solución parcial se basa en una estimación del valor máximo posible que podría obtenerse agregando los elementos restantes a la mochila.
El algoritmo comienza con un subconjunto vacío de elementos y agrega dos ramas a la cola de prioridad: una donde no se toma el siguiente elemento y otra donde se toma. A continuación, el algoritmo continúa explorando el espacio de búsqueda seleccionando la solución parcial de mayor prioridad de la cola de prioridad y agregando dos ramas a la cola para cada elemento inexplorado. El algoritmo poda las ramas que excederían la capacidad de la mochila o que no podrían conducir a una solución mejor que la mejor encontrada hasta ahora.
El algoritmo de bifurcación y encuadernación puede ser muy eficaz para resolver el problema de la mochila cuando los elementos se ordenan en orden descendente de relación valor-peso. Esto se debe a que el algoritmo puede identificar rápidamente las ramas que no pueden conducir a una mejor solución que la mejor encontrada hasta ahora, y podarlas antes de explorarlas más a fondo.
Programación dinámica
La programación dinámica es otra técnica que se puede utilizar para resolver el problema de la mochila. El enfoque de programación dinámica implica dividir el problema en una serie de subproblemas y resolver cada subproblema solo una vez, utilizando las soluciones a los subproblemas anteriores para construir la solución al problema completo.
En el caso del problema de la mochila, el algoritmo de programación dinámica implica crear una matriz bidimensional para representar el valor máximo que se puede obtener para cada combinación de elementos y capacidades. Luego, el algoritmo rellena la matriz utilizando un bucle anidado, considerando cada elemento por turno y calculando el valor máximo que se puede obtener con ese elemento utilizando los
valores almacenados en la matriz para los elementos anteriores. La entrada final en la matriz da el valor máximo que se puede obtener con todos los elementos y la capacidad dada.
Solución
Aquí hay un ejemplo de código Python para resolver el problema de la mochila utilizando enfoques de programación dinámica y de bifurcación y enlazada:
Problema de mochila usando Branch y Bound
def knapsack_branch_and_bound(valores , pesos , capacidad): [( [] n = len(valores) items = sorted([(values[i], weights[i]) for i in range(n)], key=lambda x:0 x[0]/x[1], reverse=True) q =, 0, )] best_value = 0 while : q: items_taken(0)if weight > capacity:continue [, weight, value = q.pop items[0][0] continue if value + (capacity-weight) */items0][1] < best_value if not [ items:if value > best_value: best_value = value continue q.append((items_taken + [ False,], weight] ], weight, value)) q.append((items_taken + [True [0] + items[0][1 value + items 0])) items = items[1:] return best_value
Problema de mochila usando programación dinámica
def knapsack_dynamic_programming(valores , pesos, ): , capacidad): n = lenvalores) dp = [[0 para _ en rango(capacidad+1)] para _ en rango(n+1)]para en n+1 (i rango(1 para j en rango(dp[i-1][j], dp[i-1][(1, capacidad+1) :if [ pesos[i-1] > j: dp[i][j] = dp[i-1][j][j]else: dp[i][j] = maxi-i-1] [j-weights] + values1]) devolver DP[n][capacidad]
Explicación
Ambas funciones tienen los mismos parámetros de entrada: valores es una lista de valores para cada elemento, pesos es una lista de pesos para cada artículo y capacidad es la capacidad máxima de la mochila. La salida de las funciones es el valor máximo que se puede obtener.
La función knapsack_branch_and_bound utiliza una cola de prioridad para explorar el espacio de búsqueda de una manera que probablemente conduzca a la solución óptima más rápidamente. La prioridad de cada nodo se basa en una estimación del valor máximo posible que podría obtenerse agregando los elementos restantes a la mochila. La función ordena los elementos en orden descendente de relación valor-peso y, a continuación, explora dos ramas del árbol de búsqueda: una donde no se toma el elemento actual y otra donde se toma. La función poda las ramas que excederían la capacidad de la mochila o que no podrían conducir a una solución mejor que la mejor encontrada hasta ahora.
La función knapsack_dynamic_programming resuelve el problema utilizando programación dinámica. Crea una matriz bidimensional para representar el valor máximo que se puede obtener para cada combinación de elementos y capacidades. A continuación, la función rellena la matriz utilizando un bucle anidado, considerando cada elemento por turno y calculando el valor máximo que se puede obtener con ese elemento utilizando los valores almacenados en la matriz para los elementos anteriores. La entrada final en la matriz da el valor máximo que se puede obtener con todos los elementos y la capacidad dada.