Algorithm
double fractionalKnapsack(int W, int[] value, int[] weight) {
Integer[] idx = new Integer[value.length];
for (int i = 0; i < idx.length; i++) idx[i] = i;
Arrays.sort(idx, (a, b) -> Double.compare(
(double) value[b] / weight[b], (double) value[a] / weight[a]));
double total = 0;
int remaining = W;
for (int i : idx) {
if (weight[i] <= remaining) { total += value[i]; remaining -= weight[i]; }
else { total += (double) value[i] * remaining / weight[i]; break; }
}
return total;
}Advertisement
Why greedy works
Exchange argument: swapping any part of high-ratio item for low-ratio item can only decrease value.
Advertisement
vs 0/1 knapsack
0/1 is NP-hard (needs DP). Fractional is P (greedy). Continuity is the reason.
Applications
Portfolio optimization (divisible investments). Resource allocation with fractional resources.