Reputation: 9
I need to find every optimal solution for knapsack problem. Here is my code
void knapSack(int W, int wt[], int val[], int n)
{
int i, w;
int K[W+1][n+1];
for (w = 0; w <= W; w++)
{
for(i=0;i<=n;i++){
if(i==0)
K[w][i]=0;
if(w<wt[i-1] && i!=0)
K[w][i]=K[w][i-1];
if(w>=wt[i-1] && i!=0)
K[w][i]=max(K[w][i-1],K[w-wt[i-1]][i-1]+val[i-1]);
}
}
i=n;
int j=W;
while(i,j>0){
if(K[j][i]!=K[j][i-1]){
cout<<"Item "<<i<<" is in the bag"<<endl;
i=i-1;
j=j-wt[i-1];
}
else
i=i-1;
}
}
Input data is:
4 6 //n W
2 1 //p1 w1
3 2 //p2 w2
3 4 //p3 w3
4 5 //p4 w4
And output should be like this:
1 4
2 3
The first part of my code which is packing the bag is working great, but the secound part where I try to find which items were taken is giving me answer: item 3, item 2, item 1 which is wrong because there is 2 solutions: you take item 1 and 4 or item 2 or 3. How can I fix this?
In the picture below there is table with table solution of packing
Upvotes: 1
Views: 1386
Reputation: 14238
I would use the same formula that you use to maximize the value to see which items picked i.e.
if (K[w][i] == K[w-wt[i-1]][i-1] + val[i-1])
then item i
is picked else this is not picked and go to previous item i-1
.
Also there could be more than 1 set of items which when picked can yield the maximum value.
In that case look for each such value in the array K[W][..]
for the maximum value K[W][n]
and traverse the array from that point to get the picked items.
Code is :
void knapSack(int W, int wt[], int val[], int n)
{
int i, w;
int K[W+1][n+1];
for (w = 0; w <= W; w++)
{
for(i=0;i<=n;i++){
if(i==0)
K[w][i]=0;
if(w<wt[i-1] && i!=0)
K[w][i]=K[w][i-1];
if(w>=wt[i-1] && i!=0)
K[w][i]=max(K[w][i-1],K[w-wt[i-1]][i-1]+val[i-1]);
}
}
cout << "\n" << "Maximum value obtained is : " << K[W][n] << "\n";
int j;
for ( j=1; j<=n; j++ ) {
if (K[W][j] == K[W][n]) {
int w = W;
int i = j;
while(i>0 && w>0){
if (K[w][i] == K[w-wt[i-1]][i-1] + val[i-1]) {
cout << "Item " << i << " is in the bag" << "\n";
w = w - wt[i-1];
i--;
} else {
i--;
}
}
cout<< "\n";
}
}
}
Upvotes: 1