I found this very handy example code which implements a DP solution to the knapsack problem (kudos to the person who posted it).
https://codereview.stackexchange.com/questions/20569/dynamic-programming-solution-to-knapsack-problem
I am trying to modify it to include a constraint on the number of items k in the knapsack.
I added a third argument
def knapsack(items, maxweight, maxitems):
and modified the reconstruction as follows:
while i > 0:
if bestvalues[i][j] != bestvalues[i - 1][j] and len(reconstruction) < maxitems:
reconstruction.append(items[i - 1])
j -= items[i - 1][1]
i -= 1
Provided I input enough items to choose from this will always converge to the desired k number of items. However, I am fairly certain that this is not finding the closest approximation of the global optimum. The discussions I have read after some searching refer to adding a third dimension k and accounting for the constraint before the reconstruction (I *think this would be during the best value assessment).
Can someone provide an example of how to do this? Ideally a working python example would be fantastic but I'll settle for pseudocode. I have read a few instructions using notation but I am still not sure how to constrain with k (outside of what I have done here).
Thanks!
As i stated in the comment above a third dimension is required, i have written a recursive dynamic programming solution :
#include<bits/stdc++.h>
using namespace std;
int noOfItems, items[100], maxWeight, maxItems, value[100];
int dp[100][1000][100];
int solve(int idx, int currentWeight, int itemsLeft){
if(idx == noOfItems || itemsLeft == 0) return 0;
if(dp[idx][currentWeight][itemsLeft] != -1) return dp[idx][currentWeight][itemsLeft];
int v1 = 0, v2 = 0;
//try to included the current item
if(currentWeight >= items[idx]) v1 = solve(idx+1, currentWeight-items[idx], itemsLeft-1) + value[idx];
//exclude current item
v2 = solve(idx+1, currentWeight, itemsLeft);
return dp[idx][currentWeight][itemsLeft] = max(v1, v2);
}
//print the contents of the knapsack
void print(int idx, int currentWeight, int itemsLeft){
if(idx == noOfItems || itemsLeft == 0) return;
int v1 = 0, v2 = 0;
if(currentWeight >= items[idx]) v1 = solve(idx+1, currentWeight-items[idx], itemsLeft-1) + value[idx];
v2 = solve(idx+1, currentWeight, itemsLeft);
if(v1 >= v2){
cout << idx << " " << items[idx] << " " << value[idx] << endl;
print(idx+1, currentWeight-items[idx], itemsLeft-1);
return;
}else{
print(idx+1, currentWeight, itemsLeft);
return;
}
}
int main(){
cin >> noOfItems >> maxWeight >> maxItems;
for(int i = 0;i < noOfItems;i++) cin >> items[i] >> value[i];
memset(dp, -1, sizeof dp);
cout << solve(0, maxWeight, maxItems) << endl; //prints the maximum value that we can get from the constraints
cout << "Printing the elements in the knapsack" << endl;
print(0, maxWeight, maxItems);
return 0;
}
Link to solution on ideone : https://ideone.com/wKzqXk
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With