# Types of Knapsack Problems in Python

Python itself doesn't have a "Knapsack Problem" but it is a well-known optimization problem that can be solved using Python. The Knapsack Problem is a classic optimization problem in computer science where a set of items each have a weight and a value, and you need to determine which items to include in a collection such that the total weight of the items is less than or equal to a given limit (the capacity of the "knapsack"), and the total value of the items is maximized.

There are different variations of the Knapsack Problem, including the 0/1 Knapsack Problem, where each item can only be included once or not at all, and the Fractional Knapsack Problem, where you can include a fraction of an item. The Knapsack Problem has a variety of real-world applications, such as resource allocation, scheduling, and packing optimization.

Python is a popular language for solving optimization problems such as the Knapsack Problem because it has powerful libraries and frameworks for numerical computing, linear algebra, and optimization. For example, you can use the NumPy library to manipulate arrays and matrices, the SciPy library to perform optimization and linear programming and the PuLP library to model and solve linear programming problems.

In Python, there are various types of Knapsack problems that can be solved using different algorithms. Here are some of them:

• 0/1 Knapsack Problem: In this problem, each item can be either included or excluded from the knapsack. The goal is to maximize the total value of the items included in the knapsack without exceeding its capacity.
• Fractional Knapsack Problem: In this problem, a fraction of an item can be included in the knapsack. The goal is to maximize the total value of the items included in the knapsack without exceeding its capacity.
• Bounded Knapsack Problem: In this problem, there are a limited number of copies available for each item, and each item can be included in the knapsack at most as many times as its copies.
• Unbounded Knapsack Problem: In this problem, there are an unlimited number of copies available for each item, and each item can be included in the knapsack any number of times.

Here are some examples of Knapsack Problems that can be solved in Python:

### 0/1 Knapsack Problem

Example 1:

``````def knapSack(W, wt, val, n):
if n == 0 or W == 0 :
return 0
if (wt[n-1] > W):
return knapSack(W, wt, val, n-1)
else:
return max(val[n-1] + knapSack(W-wt[n-1], wt, val, n-1),
knapSack(W, wt, val, n-1))
val = [60, 100, 120]
wt = [10, 20, 30]
W = 50
n = len(val)
print (knapSack(W, wt, val, n))``````

Output:

`220`

Example 2:

``````def knapSack(W, wt, val, n):
K = [[0 for x in range(W + 1)] for x in range(n + 1)]
for i in range(n + 1):
for w in range(W + 1):
if i == 0 or w == 0:
K[i][w] = 0
elif wt[i-1] <= w:
K[i][w] = max(val[i-1] + K[i-1][w-wt[i-1]], K[i-1][w])
else:
K[i][w] = K[i-1][w]
return K[n][W]
val = [60, 100, 120]
wt = [10, 20, 30]
W = 50
n = len(val)
print(knapSack(W, wt, val, n))``````

Output:

`220`

In these example, the 0/1 Knapsack Problem is solved using dynamic programming. The input values and weights of each item are given, along with the maximum capacity of the knapsack. The output is the maximum value that can be obtained by selecting items to include in the knapsack. In this case, the output is 220, which means that the maximum value that can be obtained by selecting items is 220.

### Fractional Knapsack Problem

``````def knapsack_fractional(values, weights, W):
n = len(values)
ratios = [(values[i]/weights[i], i) for i in range(n)]
ratios.sort(reverse=True)
max_value = 0
for ratio, i in ratios:
if weights[i] <= W:
max_value += values[i]
W -= weights[i]
else:
max_value += W * ratio
break
returnmax_value
values = [60, 100, 120]
weights = [10, 20, 30]
W = 50
print(knapsack_fractional(values, weights, W))``````

Output:

`240.0`

In this example, the Fractional Knapsack Problem is solved using a greedy algorithm. The input values and weights of each item are given, along with the maximum capacity of the knapsack. In this case, the output is 240.0, which means that the maximum value that can be obtained by selecting items is 240.0.

Bounded Knapsack Problem

``````def knapsack_bounded(values, weights, copies, W):
n = len(values)
dp = [[0 for _ in range(W+1)] for _ in range(n+1)]
for i in range(1, n+1):
for j in range(1, W+1):
k = 0
while k <= copies[i-1] and k*weights[i-1] <= j:
dp[i][j] = max(dp[i][j], dp[i-1][j-k*weights[i-1]] + k*values[i-1])
k += 1
return dp[n][W]

values = [60, 100, 120]
weights = [10, 20, 30]
copies = [2, 1, 1]
W = 50
print(knapsack_bounded(values, weights, copies, W))``````

Output:

`280`

### Unbounded Knapsack Problem

``````def knapsack_unbounded(values, weights, W):
n = len(values)
dp = [0 for _ in range(W+1)]
for i in range(1, W+1):
for j in range(n):
if weights[j] <= i:
dp[i] = max(dp[i], dp[i-weights[j]] + values[j])
return dp[W]
values = [10, 30, 20]
weights = [5, 10, 15]
W = 100
print(knapsack_unbounded(values, weights, W))
``````

Output:

`300`

In this example, the Unbounded Knapsack Problem is solved using dynamic programming. The input values and weights of each item are given, along with the maximum capacity of the knapsack. The output is the maximum value that can be obtained by selecting items to include in the knapsack, subject to the constraint that there is an unlimited supply of each item. In this case, the output is 300, which means that the maximum value that can be obtained by selecting items is 300.