Print the values of knapsack solution

1.1k views Asked by At

I have the following solution for the knapsack problem:(wt[] is the weights array, val[] is the values array, n is the arrays size, index is the current item that we are trying (for the recursion) and arr is an array that represents weather or not item i was included in the solution.

int knapSack(int W, int wt[], int val[], int n, int index, int arr[])
{
   if (n == index || W == 0)
       return 0;
   if (wt[index] > W)
       return knapSack(W, wt, val, n, index+1 );

   int with=val[index]+knapSack(W-wt[index], wt, val, n, index+1);
   int without=knapSack(W, wt, val, n, index+1);

   if(with>without){
       arr[index]=1;
       return with;
   }
   else{
       arr[index]=0;
       return without;
   }

}

I am trying to print, in this recursive solution the items that are chosen, by setting the indexes of the taken ones in an array (res) to 1.
As I understand, if with>without, it means that I am choosing the current item, or item #index. So why is this not returning a right value?
I am using the recursive algorithm for a reason, I know using the memoization version can be easier here. Example:
Weights: 5 6 7 10 11
Values: 2 4 5 6 9
W=25
Will return 5 ones in array res. When solution is 18 with items 2,3,5 (starting from index 1).

1

There are 1 answers

0
Loris Securo On BEST ANSWER

Premise 1: in your code, the recursion calls to knapSack are not passing arr, which should cause a compilation error, I assume it's just a copy/paste error.

Premise 2: with the data you proposed, the resulting arr value is not all 1 as you indicated, but 01011, which is still incorrect.

Consider the hypothetical situation in which, during the execution of your function, with is greater than without: during the with calculation arr is filled with the correct values; but then start the without calculation which is going to overwrite the arr values.

Since with is greater than without, the returned arr will be the wrong one, and this is the cause of the problem.

A simple fix would be to make a copy of the arr returned by the with calculation so it is not going to be overwritten by the without calculation, for example:

int with=val[index]+knapSack(W-wt[index], wt, val, n, index+1, arr);

// copy the "with" arr
int arrWith[n];
copyArr(arr, arrWith, n);

int without=knapSack(W, wt, val, n, index+1, arr);

if(with>without){
    // restore the "with" arr
    copyArr(arrWith, arr, n);

    arr[index]=1;
    return with;
}
else{
    arr[index]=0;
    return without;
}

copyArr is simply:

void copyArr(int arr[], int arrDest[], int n) {
    int i;
    for(i = 0; i < n; i++) {
        arrDest[i] = arr[i];
    }
}

With this fix the resulting value of arr is correctly 01101.