Implementing Greedy Knapsack Algorithm in Java: Alternate Way

The Fractional Knapsack problem is a classic greedy algorithm problem in combinatorial optimization. You are given a set of items, each with a weight and a profit, and a knapsack with a fixed capacity. Unlike the 0-1 Knapsack, here you can take fractions of an item — meaning if an item doesn’t fit whole, you may take a portion of it proportional to the remaining capacity. The greedy strategy is to always pick the item with the highest profit-per-unit-weight ratio first, continuing until the knapsack is full.

Fractional Knapsack (Greedy) Implementation in Java

import java.io.*;

public class FractionalKnapsack {

    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        System.out.println("Enter number of items:");
        int itemCount = Integer.parseInt(reader.readLine());

        int[] profitArray = new int[itemCount];  // profit of each item
        int[] weightArray = new int[itemCount];  // weight of each item

        // Read profit and weight for each item
        for (int i = 0; i < itemCount; i++) {
            System.out.println("Enter Profit of item " + (i + 1) + ":");
            profitArray[i] = Integer.parseInt(reader.readLine());
            System.out.println("Enter Weight of item " + (i + 1) + ":");
            weightArray[i] = Integer.parseInt(reader.readLine());
        }

        System.out.println("Enter knapsack capacity:");
        int remainingCapacity = Integer.parseInt(reader.readLine());

        // Compute profit-per-unit-weight ratio for each item
        float[] profitPerWeight = new float[itemCount];
        for (int i = 0; i < itemCount; i++) {
            profitPerWeight[i] = (float) profitArray[i] / weightArray[i];
        }

        // Sort items in descending order of profit-per-unit-weight (selection sort)
        for (int i = 0; i < itemCount; i++) {
            for (int j = i; j < itemCount; j++) {
                if (profitPerWeight[i] < profitPerWeight[j]) {
                    // Swap profit-per-weight ratios
                    float tempRatio   = profitPerWeight[i];
                    profitPerWeight[i] = profitPerWeight[j];
                    profitPerWeight[j] = tempRatio;

                    // Swap corresponding profits
                    int tempProfit   = profitArray[i];
                    profitArray[i]   = profitArray[j];
                    profitArray[j]   = tempProfit;

                    // Swap corresponding weights
                    int tempWeight   = weightArray[i];
                    weightArray[i]   = weightArray[j];
                    weightArray[j]   = tempWeight;
                }
            }
        }

        // Greedily fill the knapsack
        float totalProfit      = 0;
        float[] fractionTaken  = new float[itemCount];  // fraction of each item selected

        for (int i = 0; i < itemCount; i++) {
            if (remainingCapacity - weightArray[i] >= 0) {
                // Whole item fits: take it entirely
                remainingCapacity -= weightArray[i];
                totalProfit       += profitArray[i];
                fractionTaken[i]   = 1;
            } else if (remainingCapacity != 0) {
                // Only a fraction fits: take what we can
                float fraction    = (float) remainingCapacity / weightArray[i];
                totalProfit      += profitArray[i] * fraction;
                fractionTaken[i]  = fraction;
                break;  // knapsack is now full
            } else {
                break;  // no remaining capacity
            }
        }

        System.out.println("Maximum Profit: " + totalProfit);
    }
}

How the Code Works

  1. Input: Profit and weight for each item are stored in profitArray[] and weightArray[]. The knapsack capacity is held in remainingCapacity.
  2. Ratio computation: profitPerWeight[i] stores the profit-per-unit-weight for item i. This is the greedy criterion — items with higher ratios are more valuable per unit of capacity used.
  3. Sorting: A selection sort arranges items in descending order of profitPerWeight. The profit and weight arrays are kept in sync during swaps so each index still refers to the same item.
  4. Greedy fill: Items are considered in order (highest ratio first). If the whole item fits (remainingCapacity >= weight), it is taken entirely. If only a fraction fits, the fractional portion is taken and the loop ends.
  5. Output: totalProfit holds the maximum achievable profit for the given capacity.

Sample Output

Enter number of items:
5
Enter Profit of item 1: 10
Enter Weight of item 1: 2
Enter Profit of item 2: 5
Enter Weight of item 2: 6
Enter Profit of item 3: 3
Enter Weight of item 3: 4
Enter Profit of item 4: 2
Enter Weight of item 4: 3
Enter Profit of item 5: 11
Enter Weight of item 5: 7
Enter knapsack capacity: 20

Maximum Profit: 29.666666

Output Explanation

  1. The 5 items have profit/weight ratios: 5.0, 0.83, 0.75, 0.67, 1.57. After sorting in descending order: item1 (5.0), item5 (1.57), item2 (0.83), item3 (0.75), item4 (0.67).
  2. Item 1 (weight 2, profit 10) fits entirely → capacity left = 18, profit = 10.
  3. Item 5 (weight 7, profit 11) fits entirely → capacity left = 11, profit = 21.
  4. Item 2 (weight 6, profit 5) fits entirely → capacity left = 5, profit = 26.
  5. Item 3 (weight 4, profit 3) fits entirely → capacity left = 1, profit = 29.
  6. Item 4 (weight 3, profit 2): only 1 unit of capacity remains → fraction = 1/3, profit added = 2 × (1/3) ≈ 0.667.
  7. Total profit = 29 + 0.667 ≈ 29.666666.

See Also

Conclusion

The Fractional Knapsack problem is a textbook demonstration of greedy algorithm design: by sorting on the local optimum criterion (profit/weight ratio) and always making the locally best choice, we arrive at the globally optimal solution. This works because the fractional relaxation means there is no penalty for taking partial items — a property that does not hold for the 0-1 Knapsack, which requires dynamic programming instead.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.