 Open in App
Not now

# Fractional Knapsack Problem

• Difficulty Level : Medium
• Last Updated : 04 Feb, 2023

Given the weights and values of N items, in the form of {value, weight} 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: arr[] = {{60, 10}, {100, 20}, {120, 30}}, W = 50
Output: 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:  arr[] = {{500, 30}}, W = 10
Output: 166.667

Recommended Practice

Naive Approach: To solve the problem follow the below idea:

Try all possible subsets with all different fractions.

## Algorithm for Knapsack problem using Greedy Strategy:

```Algorithm Fr-Knapsack (M,n)
/*Input: Knapsack capacity = M. n is the number of available items with associated profits P[1: n] and weights W[1: n]. These items are such that P[i]/W[i]>=P[i+1]/W[i +1] where 1 ≤i≤n.

Output: S[1: n] is the fixed size solution vector. S[i] gives the fractional part xi, of item i placed into a knapsack, 0 ≤ xi ≤1 and 1 ≤ i ≤ n. */
{
for (i:=1; i <= n ;i++)

{

S[i] :=0.0; // Initialization of a solution vector.
}

balance:= M; /* 'balance' describes the remaining capacity of a knapsack. Initially it is equal to the knapsack capacity M. */

for(i:=1; i <= n ;i++)

{
if(W [i] > balance ) / *Insufficient capacity of a knapsack */
break;

S[i] :=1.0; // add whole item i.
balance := balance - W[i]; /*Update the remaining capacity after adding item i with weight W[i] into a knapsack.*/
}
f(i <= n) /*Due to insufficient capacity add fractional part of item i in the knapsack. */
S[i]:= (balance / W[i] ) ;
return S;
}```

## Fractional Knapsack Problem using Greedy algorithm:

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 ` `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` `static` `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;`   `    ``// 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 code` `int` `main()` `{` `    ``int` `W = 50;` `    ``Item arr[] = { { 60, 10 }, { 100, 20 }, { 120, 30 } };`   `    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);`   `    ``// Function call` `    ``cout << fractionalKnapsack(W, arr, N);` `    ``return` `0;` `}`

## Java

 `// Java program to solve fractional Knapsack Problem`   `import` `java.io.*;` `import` `java.util.Arrays;` `import` `java.util.Comparator;`   `// Greedy approach` `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() {` `            ``@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 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(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``)    `   `    ``# 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 Code` `if` `__name__ ``=``=` `"__main__"``:`   `    ``W ``=` `50` `    ``arr ``=` `[Item(``60``, ``10``), Item(``100``, ``20``), Item(``120``, ``30``)]`   `    ``# Function call` `    ``max_val ``=` `fractionalKnapsack(W, arr)` `    ``print``(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 code` `    ``static` `void` `Main(``string``[] args)` `    ``{` `        ``item[] arr = { ``new` `item(60, 10), ``new` `item(100, 20),` `                       ``new` `item(120, 30) };`   `        ``// Function call` `        ``Console.WriteLine(FracKnapSack(arr, 50));` `    ``}` `}`   `// This code is contributed by Mohamed Adel`

## Javascript

 `// JavaScript program to solve fractional Knapsack Problem`   `// Structure for an item which stores weight and` `// corresponding value of Item` `class Item {` `    ``constructor(value, weight) {` `        ``this``.value = value;` `        ``this``.weight = weight;` `    ``}` `}`   `// Comparison function to sort Item ` `// according to val/weight ratio` `function` `cmp(a, b) {` `    ``let r1 = a.value / a.weight;` `    ``let r2 = b.value / b.weight;` `    ``return` `r1 > r2;` `}`   `// Main greedy function to solve problem` `function` `fractionalKnapsack(W, arr) {` `    ``// Sorting Item on basis of ratio` `    ``arr.sort(cmp);`   `    ``let finalvalue = 0.0;`   `    ``// Looping through all items` `    ``for` `(let i = 0; i < arr.length; 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 * (W / arr[i].weight);` `            ``break``;` `        ``}` `    ``}`   `    ``// Returning final value` `    ``return` `finalvalue;` `}`   `// Driver code` `let W = 50;` `let arr = [``new` `Item(60, 10), ``new` `Item(100, 20), ``new` `Item(120, 30)];`   `console.log(fractionalKnapsack(W, arr));`   `// This code is contributed by lokeshpotta20`

Output

`Maximum value we can obtain = 240`

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