Skip to content
Related Articles

Related Articles

Fractional Knapsack Problem

View Discussion
Improve Article
Save Article
  • Difficulty Level : Medium
  • Last Updated : 17 Aug, 2022
View Discussion
Improve Article
Save Article
 

Given the weights and values of N items, put these items in a knapsack of capacity W to get the maximum total value in the knapsack. In Fractional Knapsack, we can break items for maximizing the total value of the knapsack

Note: In the 0-1 Knapsack problem, we are not allowed to break items. We either take the whole item or don’t take it. 

Input: 
Items as (value, weight) pairs 
arr[] = {{60, 10}, {100, 20}, {120, 30}} 
Knapsack Capacity, W = 50

Output: Maximum possible value = 240 
Explanation: by taking items of weight 10 and 20 kg and 2/3 fraction of 30 kg. 
Hence total price will be 60+100+(2/3)(120) = 240

Input:  
Items as (value, weight) pairs 
arr[] = {{500, 30}}
Knapsack Capacity, W = 10
Output: 166.667

Recommended Practice

Naive Approach: Try all possible subsets with all different fractions but that will be very inefficient. 

Greedy approach for fractional knapsack problem:

An efficient solution is to use the Greedy approach. The basic idea of the greedy approach is to calculate the ratio value/weight for each item and sort the item on the basis of this ratio. Then take the item with the highest ratio and add them until we can’t add the next item as a whole and at the end add the next item as much as we can. Which will always be the optimal solution to this problem.

Follow the given steps to solve the problem using the above approach:

  • Calculate the ratio(value/weight) for each item.
  • Sort all the items in decreasing order of the ratio.
  • Initialize res =0, curr_cap = given_cap.
  • Do the following for every item “i” in the sorted order:
    • If the weight of the current item is less than or equal to the remaining capacity then add the value of that item into the result
    • else add the current item as much as we can and break out of the loop
  • Return res

Below is the implementation of the above approach:

C++




// C++ program to solve fractional Knapsack Problem
#include <bits/stdc++.h>
 
using namespace std;
 
// Structure for an item which stores weight and
// corresponding value of Item
struct Item {
    int value, weight;
 
    // Constructor
    Item(int value, int weight)
    {
        this->value = value;
        this->weight = weight;
    }
};
 
// Comparison function to sort Item according to val/weight
// ratio
bool cmp(struct Item a, struct Item b)
{
    double r1 = (double)a.value / (double)a.weight;
    double r2 = (double)b.value / (double)b.weight;
    return r1 > r2;
}
 
// Main greedy function to solve problem
double fractionalKnapsack(int W, struct Item arr[], int N)
{
    //    sorting Item on basis of ratio
    sort(arr, arr + N, cmp);
 
    double finalvalue = 0.0; // Result (value in Knapsack)
 
    // Looping through all Items
    for (int i = 0; i < N; i++) {
        // If adding Item won't overflow, add it completely
        if (arr[i].weight <= W) {
            W -= arr[i].weight;
            finalvalue += arr[i].value;
        }
 
        // If we can't add current Item, add fractional part
        // of it
        else {
            finalvalue
                += arr[i].value
                   * ((double)W / (double)arr[i].weight);
            break;
        }
    }
 
    // Returning final value
    return finalvalue;
}
 
// Driver's code
int main()
{
    int W = 50; //    Weight of knapsack
    Item arr[] = { { 60, 10 }, { 100, 20 }, { 120, 30 } };
 
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Function call
    cout << "Maximum value we can obtain = "
         << fractionalKnapsack(W, arr, N);
    return 0;
}


Java




// Java program to solve fractional Knapsack Problem
import java.util.Arrays;
import java.util.Comparator;
 
// Greedy approach
public class FractionalKnapSack {
    // function to get maximum value
    private static double getMaxValue(ItemValue[] arr,
                                      int capacity)
    {
        // sorting items by value/weight ratio;
        Arrays.sort(arr, new Comparator<ItemValue>() {
            @Override
            public int compare(ItemValue item1,
                               ItemValue item2)
            {
                double cpr1
                    = new Double((double)item1.value
                                 / (double)item1.weight);
                double cpr2
                    = new Double((double)item2.value
                                 / (double)item2.weight);
 
                if (cpr1 < cpr2)
                    return 1;
                else
                    return -1;
            }
        });
 
        double totalValue = 0d;
 
        for (ItemValue i : arr) {
 
            int curWt = (int)i.weight;
            int curVal = (int)i.value;
 
            if (capacity - curWt >= 0) {
 
                // this weight can be picked while
                capacity = capacity - curWt;
                totalValue += curVal;
            }
            else {
 
                // item cant be picked whole
                double fraction
                    = ((double)capacity / (double)curWt);
                totalValue += (curVal * fraction);
                capacity
                    = (int)(capacity - (curWt * fraction));
                break;
            }
        }
 
        return totalValue;
    }
 
    // item value class
    static class ItemValue {
 
        int value, weight;
 
        // item value function
        public ItemValue(int val, int wt)
        {
            this.weight = wt;
            this.value = val;
        }
    }
 
    // Driver's code
    public static void main(String[] args)
    {
 
        ItemValue[] arr = { new ItemValue(60, 10),
                            new ItemValue(100, 20),
                            new ItemValue(120, 30) };
 
        int capacity = 50;
 
        double maxValue = getMaxValue(arr, capacity);
 
        // Function call
        System.out.println("Maximum value we can obtain = "
                           + maxValue);
    }
}


Python3




# Structure for an item which stores weight and
# corresponding value of Item
class Item:
    def __init__(self, value, weight):
        self.value = value
        self.weight = weight
 
# Main greedy function to solve problem
def fractionalKnapsack(W, arr):
 
    # sorting Item on basis of ratio
    arr.sort(key=lambda x: (x.value/x.weight), reverse=True)
 
    # Uncomment to see new order of Items with their
    # ratio
    # for item in arr:
    #     print(item.value, item.weight, item.value/item.weight)
 
    # Result(value in Knapsack)
    finalvalue = 0.0
 
    # Looping through all Items
    for item in arr:
 
        # If adding Item won't overflow, add it completely
        if item.weight <= W:
            W -= item.weight
            finalvalue += item.value
 
        # If we can't add current Item, add fractional part
        # of it
        else:
            finalvalue += item.value * W / item.weight
            break
    # Returning final value
    return finalvalue
 
 
# Driver's Code
if __name__ == "__main__":
 
    # Weight of Knapsack
    W = 50
    arr = [Item(60, 10), Item(100, 20), Item(120, 30)]
 
    # Function call
    max_val = fractionalKnapsack(W, arr)
    print ('Maximum value we can obtain = {}'.format(max_val))


C#




// C# program to solve fractional Knapsack Problem
 
using System;
using System.Collections;
 
class GFG {
 
    // Class for an item which stores weight and
    // corresponding value of Item
    class item {
        public int value;
        public int weight;
 
        public item(int value, int weight)
        {
            this.value = value;
            this.weight = weight;
        }
    }
 
    // Comparison function to sort Item according
    // to val/weight ratio
    class cprCompare : IComparer {
        public int Compare(Object x, Object y)
        {
            item item1 = (item)x;
            item item2 = (item)y;
            double cpr1 = (double)item1.value
                          / (double)item1.weight;
            double cpr2 = (double)item2.value
                          / (double)item2.weight;
 
            if (cpr1 < cpr2)
                return 1;
 
            return cpr1 > cpr2 ? -1 : 0;
        }
    }
 
    // Main greedy function to solve problem
    static double FracKnapSack(item[] items, int w)
    {
 
        // Sort items based on cost per units
        cprCompare cmp = new cprCompare();
        Array.Sort(items, cmp);
 
        // Traverse items, if it can fit,
        // take it all, else take fraction
        double totalVal = 0f;
        int currW = 0;
 
        foreach(item i in items)
        {
            float remaining = w - currW;
 
            // If the whole item can be
            // taken, take it
            if (i.weight <= remaining) {
                totalVal += (double)i.value;
                currW += i.weight;
            }
 
            // dd fraction until we run out of space
            else {
                if (remaining == 0)
                    break;
 
                double fraction
                    = remaining / (double)i.weight;
                totalVal += fraction * (double)i.value;
                currW += (int)(fraction * (double)i.weight);
            }
        }
        return totalVal;
    }
 
    // Driver's code
    static void Main(string[] args)
    {
        item[] arr = { new item(60, 10), new item(100, 20),
                       new item(120, 30) };
 
          // Function call
        Console.WriteLine("Maximum value we can obtain = "
                          + FracKnapSack(arr, 50));
    }
}
 
// This code is contributed by Mohamed Adel


Output

Maximum value we can obtain = 240

Time Complexity: O(N log N)
Auxiliary Space: O(N)

This article is contributed by Utkarsh Trivedi.
 Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!