Dynamic programming (DP) based solver for 0-1 knapsack problems and the standard "sorting based" algorithm for fractional "between 0-1" knapsack problems.
The DP algorithm is not fancy as it implements the standard dynamic programming algorithm running in numpy.
Given is solve_knapsack-function. Here, we represent an optimal solution as the indices of the items in the optimal set
Here we are again given x, where x[i] equals the share of item x[i]=1 then item 0<x[i]<1 item x[i]=0 item
To solve a 0-1 knapsack problem, one simply
import time # For timing the algorithms
import KPdp as Knapsack # Provides the algorithms
kpsolver = Knapsack.KPsolver() # Create a KPsolver-object
# Data for the instance
p = [27, 18, 43, 40, 55, 15, 10, 91, 90, 95] # Profits
w = [20, 2, 16, 30, 19, 42, 2, 21, 13, 2] # Weights
cap = 80 # Capacity
# Set the data in the object
psolver.setData(len(p), p, w, cap)
start = time.time()
opt_value, opt_solution = kpsolver.solve_knapsack() # Solve the knapsack problem
print(f'Total time for DP-algorithm is {time.time() - start} seconds')
print (f'Optimal solution value is {opt_value}') # Print the optimal objective function value
print(f'Optimal solution consists of items: {opt_solution}') # Print indices of included items
This provides the following output
Total time for DP-algorithm is 0.0003962516784667969 seconds
Optimal solution value is 402
Optimal solution consists of items: [9, 8, 7, 6, 4, 2, 1]
Note here that the optimal solution opt_solution consists of the indices of the items included in the knapsack only.
To solve the fractional version (LP relaxation) of the problem, we simply use the solveFractionalKP()-function:
import time # For timing the algorithms
import KPdp as Knapsack # Provides the algorithms
kpsolver = Knapsack.KPsolver() # Create a KPsolver-object
# Data for the instance
p = [27, 18, 43, 40, 55, 15, 10, 91, 90, 95] # Profits
w = [20, 2, 16, 30, 19, 42, 2, 21, 13, 2] # Weights
cap = 80 # Capacity
# Set the data in the object
psolver.setData(len(p), p, w, cap)
start = time.time()
opt_value, opt_solution = kpsolver.solveFractionalKP() # Solve the fractional knapsack problem
print(f'Total time for fractional DP is {time.time() - start} seconds')
print(f'Optimal fractional solution value is {opt_value}') # Print the optimal objective function value
print(f'Optimal solution is given by: {opt_solution}') # Print the optimal solution
This provides the following output:
Total time for fractional DP is 0.0002090930938720703 seconds
Optimal fractional solution value is 408.75
Optimal solution is given by: [0.25 1. 1. 0. 1. 0. 1. 1. 1. 1. ]
Note here that the solution returned by the solveFractionalKP()-function specifies the share of item