From c5fd075f1ea9b6dc11cca2d36605aaddbd0ab5fa Mon Sep 17 00:00:00 2001 From: Arun Babu PT <36483987+ptarun@users.noreply.github.com> Date: Fri, 22 Nov 2019 20:25:19 +0530 Subject: [PATCH] Fractional knapsack (#1524) * Add files via upload * Added doctests, type hints, f-strings, URLs * Rename knapsack.py to fractional_knapsack.py * Rename graphs/fractional_knapsack.py to dynamic_programming/fractional_knapsack_2.py --- dynamic_programming/fractional_knapsack_2.py | 60 ++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 dynamic_programming/fractional_knapsack_2.py diff --git a/dynamic_programming/fractional_knapsack_2.py b/dynamic_programming/fractional_knapsack_2.py new file mode 100644 index 000000000..eadb73c61 --- /dev/null +++ b/dynamic_programming/fractional_knapsack_2.py @@ -0,0 +1,60 @@ +# https://en.wikipedia.org/wiki/Continuous_knapsack_problem +# https://www.guru99.com/fractional-knapsack-problem-greedy.html +# https://medium.com/walkinthecode/greedy-algorithm-fractional-knapsack-problem-9aba1daecc93 + +from typing import List, Tuple + + +def fractional_knapsack( + value: List[int], weight: List[int], capacity: int +) -> Tuple[int, List[int]]: + """ + >>> value = [1, 3, 5, 7, 9] + >>> weight = [0.9, 0.7, 0.5, 0.3, 0.1] + >>> fractional_knapsack(value, weight, 5) + (25, [1, 1, 1, 1, 1]) + >>> fractional_knapsack(value, weight, 15) + (25, [1, 1, 1, 1, 1]) + >>> fractional_knapsack(value, weight, 25) + (25, [1, 1, 1, 1, 1]) + >>> fractional_knapsack(value, weight, 26) + (25, [1, 1, 1, 1, 1]) + >>> fractional_knapsack(value, weight, -1) + (-90.0, [0, 0, 0, 0, -10.0]) + >>> fractional_knapsack([1, 3, 5, 7], weight, 30) + (16, [1, 1, 1, 1]) + >>> fractional_knapsack(value, [0.9, 0.7, 0.5, 0.3, 0.1], 30) + (25, [1, 1, 1, 1, 1]) + >>> fractional_knapsack([], [], 30) + (0, []) + """ + index = list(range(len(value))) + ratio = [v / w for v, w in zip(value, weight)] + index.sort(key=lambda i: ratio[i], reverse=True) + + max_value = 0 + fractions = [0] * len(value) + for i in index: + if weight[i] <= capacity: + fractions[i] = 1 + max_value += value[i] + capacity -= weight[i] + else: + fractions[i] = capacity / weight[i] + max_value += value[i] * capacity / weight[i] + break + + return max_value, fractions + + +if __name__ == "__main__": + n = int(input("Enter number of items: ")) + value = input(f"Enter the values of the {n} item(s) in order: ").split() + value = [int(v) for v in value] + weight = input(f"Enter the positive weights of the {n} item(s) in order: ".split()) + weight = [int(w) for w in weight] + capacity = int(input("Enter maximum weight: ")) + + max_value, fractions = fractional_knapsack(value, weight, capacity) + print("The maximum value of items that can be carried:", max_value) + print("The fractions in which the items should be taken:", fractions)