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);
}
}
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