-
Notifications
You must be signed in to change notification settings - Fork 90
/
Copy pathfracional_knapsack.py
58 lines (42 loc) · 1.78 KB
/
fracional_knapsack.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
def knapsack(profits: list, weights: list, max_weight: int) -> int:
"""
:param profits: Take a list of profits
:param weights: Take a list of weight if bags corresponding to the profits
:param max_weight: Maximum weight that could be carried
"""
if max_weight <= 0:
raise ValueError("max_weight must be greater than zero.")
if len(profits) != len(weights):
raise ValueError("The length of profits and weights must be same.")
if any(p < 0 for p in profits):
raise ValueError("Profit can not be negative.")
if any(w < 0 for w in weights):
raise ValueError("Weight can not be negative.")
pw_ratios = [p / w for p, w in zip(profits, weights)]
sorted_pw_ratios = sorted(pw_ratios, reverse=True)
length = len(sorted_pw_ratios)
limit = 0
gain = 0
i = 0
while limit <= max_weight and i < length:
biggest_pw_ratio = sorted_pw_ratios[i]
index = pw_ratios.index(biggest_pw_ratio)
pw_ratios[index] = -1
if max_weight - limit >= biggest_pw_ratio:
limit += biggest_pw_ratio
gain += 1 * profits[index]
else:
gain += (max_weight - limit) / weights[index] * profits[index]
break
i += 1
return gain
if __name__ == "__main__":
print(
"Input profits, weights, and then max_weight (all positive ints) separated by "
"spaces."
)
profits = [int(x) for x in input("Input profits separated by spaces: ").split()]
weights = [int(x) for x in input("Input weights separated by spaces: ").split()]
max_weight = int(input("Max weight allowed: "))
gained = knapsack(profits, weights, max_weight)
print("The maxmium profit by greedy approach could be", gained)