Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to implement the fractional knapsack problem in Python
The fractional knapsack problem is a greedy optimization algorithm where we can take fractions of items to maximize value within a weight capacity. Unlike the 0/1 knapsack, we can break items and take partial amounts.
The strategy is to sort items by their value-to-weight ratio in descending order, then greedily select items starting with the highest ratio.
Algorithm Steps
To solve this problem, we follow these steps ?
Calculate value-to-weight ratio for each item
Sort items by ratio in descending order
For each item, take as much as possible within remaining capacity
If item weight exceeds capacity, take fractional amount
Return the total value obtained
Example
Let's implement the fractional knapsack algorithm ?
def fractional_knapsack(weights, values, capacity):
# Create pairs of (weight, value, ratio)
items = []
for i in range(len(weights)):
ratio = values[i] / weights[i]
items.append((weights[i], values[i], ratio))
# Sort by value-to-weight ratio in descending order
items.sort(key=lambda x: x[2], reverse=True)
total_value = 0
for weight, value, ratio in items:
if capacity == 0:
break
if weight <= capacity:
# Take the entire item
total_value += value
capacity -= weight
else:
# Take fraction of the item
fraction = capacity / weight
total_value += value * fraction
capacity = 0
return int(total_value)
# Test the algorithm
weights = [6, 7, 3]
values = [110, 120, 2]
capacity = 10
result = fractional_knapsack(weights, values, capacity)
print(f"Maximum value: {result}")
Maximum value: 178
Step-by-Step Execution
Let's trace through the example to understand how it works ?
def fractional_knapsack_detailed(weights, values, capacity):
print("Initial items:")
items = []
for i in range(len(weights)):
ratio = values[i] / weights[i]
items.append((weights[i], values[i], ratio))
print(f"Item {i+1}: weight={weights[i]}, value={values[i]}, ratio={ratio:.2f}")
# Sort by ratio
items.sort(key=lambda x: x[2], reverse=True)
print("\nSorted by value-to-weight ratio:")
for i, (weight, value, ratio) in enumerate(items):
print(f"Item: weight={weight}, value={value}, ratio={ratio:.2f}")
total_value = 0
remaining_capacity = capacity
print(f"\nStarting with capacity: {capacity}")
for weight, value, ratio in items:
if remaining_capacity == 0:
break
if weight <= remaining_capacity:
total_value += value
remaining_capacity -= weight
print(f"Take full item: +{value}, remaining capacity: {remaining_capacity}")
else:
fraction = remaining_capacity / weight
fractional_value = value * fraction
total_value += fractional_value
print(f"Take {fraction:.2f} fraction: +{fractional_value:.2f}")
remaining_capacity = 0
return int(total_value)
weights = [6, 7, 3]
values = [110, 120, 2]
capacity = 10
result = fractional_knapsack_detailed(weights, values, capacity)
print(f"\nFinal maximum value: {result}")
Initial items: Item 1: weight=6, value=110, ratio=18.33 Item 2: weight=7, value=120, ratio=17.14 Item 3: weight=3, value=2, ratio=0.67 Sorted by value-to-weight ratio: Item: weight=6, value=110, ratio=18.33 Item: weight=7, value=120, ratio=17.14 Item: weight=3, value=2, ratio=0.67 Starting with capacity: 10 Take full item: +110, remaining capacity: 4 Take 0.57 fraction: +68.57 Final maximum value: 178
Key Points
Greedy approach: Always pick the item with highest value-to-weight ratio
Fractional items: Can take partial amounts when full item exceeds capacity
Optimal solution: Greedy strategy guarantees optimal result for fractional knapsack
Time complexity: O(n log n) due to sorting
Conclusion
The fractional knapsack problem uses a greedy algorithm that sorts items by value-to-weight ratio and selects them greedily. This approach guarantees an optimal solution and efficiently maximizes value within the given capacity constraint.
---