2025-10-06 21:09:43 -04:00
|
|
|
# Task 1:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
def knapsack(capacity, weights, values, index):
|
|
|
|
|
if index == 0 or capacity == 0:
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if weights[index - 1] > capacity:
|
|
|
|
|
return knapsack(capacity, weights, values, n - 1)
|
|
|
|
|
|
|
|
|
|
skip_item = knapsack(capacity, weights, values, n - 1)
|
|
|
|
|
|
|
|
|
|
take_item = values[n - 1] + knapsack(capacity, weights, values, n - 1)
|
|
|
|
|
|
|
|
|
|
return max(skip_item, take_item)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
# Task 3:
|
|
|
|
|
|
|
|
|
|
- Fractional which has a worst case runtime of O(nlogn) compared to the
|
|
|
|
|
backtracking 0/1 knapsack solution which is exponential or O(2^n)
|
|
|
|
|
|
|
|
|
|
- The greedy strategy for the 0/1 knapsack problems would still select the items
|
|
|
|
|
in order of best value-to-weight ratio, but instead of "cutting" once the
|
|
|
|
|
availabe capacity was less than the weight of the next item, it would just
|
|
|
|
|
skip that item.
|
|
|
|
|
|
|
|
|
|
1. This approach would not always reach the optimal result.
|
|
|
|
|
2. The speed of the algorithm would be greatly improved from and exponential
|
|
|
|
|
runtime to a linear-logarithmic runtime.
|
|
|
|
|
|
|
|
|
|
- The following example input would produce a suboptimal solution with the
|
|
|
|
|
greedy approach to the 0/1 knapsack problem. This is because It would take the
|
|
|
|
|
first item which has the greates value-to-weight ratio (3) leaving it with a
|
|
|
|
|
remaining capacity of 4 and unable to choose any of the remaining, leaving us
|
|
|
|
|
with a final value of 18. The optimal solution in this case is to take the
|
|
|
|
|
latter two for a total value of 20 and 0 remaining capacity.
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
10
|
|
|
|
|
3
|
|
|
|
|
A 18 6
|
|
|
|
|
B 14 5
|
|
|
|
|
C 6 5
|
|
|
|
|
```
|