szybkikon
szybkikon

Reputation: 9

Knapsack problem - Find which items are taken

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

enter image description here

Upvotes: 1

Views: 1386

Answers (1)

SomeDude
SomeDude

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

Related Questions