Sunday, April 17, 2016

Today we review the code for unit and fractional knapsack problems. In these problems, a thief is trying to fill his bag with as much value of items  with as little weight as possible.  The solution looks like this for the unit case:
recursive  solution
/ Input:
// Values (stored in array val)
// Weights (stored in array w)
// Number of distinct items (n)
// Knapsack capacity (W)
int knapsack( int W, int[] wt, int[] val, int n)
{
if (n== 0 || W == 0)
    return 0;
if (wt[n-1] > W)
   return knapsack(W, wt, val, n-1);

return max(
                    val[n-1] + knapsack(W-wt[n-1], wt, val, n-1),
                    knapsack(W, wt, val, n -1)
                   );
}
In the fractional case, we have the following:
int fractional-knapsack( int W, int[] wt, int[] val, int n) // wt is sorted based on val[i]/w[i]
{
if (n== 0 || W == 0)
    return 0;

return max(
                    val[n-1] + fractional-knapsack(W-wj + wj -w, wt, val, n),
                    val[n-1] + fractional-knapsack(W-wj, wt, val, n -1),
                    fractional-knapsack(W, wt, val, n-1)
                   );
}
which we can further improve by leaving the dynamic programming approach and applying the top down greedy choice property
wt.sort() // based on val[i]/wt[i]
n = wt.Count()
int fractional-knapsack-greedy-recursive(int W, int[] wt, int[] val, int n)
{
if (n== 0 || W == 0)
    return 0;

// first the selection
if (wt[n-1] > W)
{
return val[n-1]/wt[n-1]*W;
}
else
{
    // then the recursion
    return val[n-1] +  fractional-knapsack-recursive(W-wt[n-1], wt, val, n -1);
}
}

No comments:

Post a Comment