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
Naive Approach: To solve the problem follow the below idea:
Try all possible subsets with all different fractions.
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:
Below is the implementation of the above approach:
// 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;
// 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[0]);
// Function call
cout << fractionalKnapsack(W, arr, N);
return 0;
}
// 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<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 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);
}
}
# 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# 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
Output
Maximum value we can obtain = 240
Time Complexity: O(N * log N)
Auxiliary Space: O(N)
81 videos|80 docs|33 tests
|
|
Explore Courses for Computer Science Engineering (CSE) exam
|