From e5e3b60085b232cbef0b55a9a708ec7fd4ba579c Mon Sep 17 00:00:00 2001 From: HarshitDawar55 Date: Thu, 21 May 2020 02:31:35 +0530 Subject: [PATCH] Corrected the solution of fractional Knapsack Problem! --- .../fractional_knapsack.py | 65 ++++++++++--------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/fractional_knapsack/fractional_knapsack.py b/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/fractional_knapsack/fractional_knapsack.py index 4f559d8..cf5bffd 100644 --- a/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/fractional_knapsack/fractional_knapsack.py +++ b/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/fractional_knapsack/fractional_knapsack.py @@ -1,29 +1,36 @@ -# Uses python3 -import sys -import unittest - - -def get_optimal_value(capacity, weights, values): - value = 0. - proportion = [float(v) / float(w) for v, w in zip(values, weights)] - for _ in range(len(weights) + 1): - if capacity == 0: - return value - break - max_weight = max(proportion) - index = proportion.index(max_weight) - proportion[index] = -1 - add_capacity = min(capacity, weights[index]) - value += add_capacity * max_weight - weights[index] -= add_capacity - capacity -= add_capacity - return value - - -if __name__ == "__main__": - data = list(map(int, sys.stdin.read().split())) - n, capacity = data[0:2] - values = data[2:(2 * n + 2):2] - weights = data[3:(2 * n + 2):2] - opt_value = get_optimal_value(capacity, weights, values) - print("{:.10f}".format(opt_value)) +def max_value_loot(value_p_w, knapsack): + max_value = 0 + + for i in value_p_w: + if i[1] <= knapsack: + max_value += round((i[0] * i[1]), 3) + knapsack -= i[1] + else: + max_value += round((i[0] * i[1] * knapsack) / i[1], 3) + knapsack = 0 + + return max_value + + +items, knapsack = [int(i) for i in input().split()] + +if 1 <= items <= 10 ** 3 and 0 <= knapsack <= 2 * (10 ** 6): + weights = [] + values = [] + value_p_w = {} + # value_per_unit_weight = [] + for i in range(items): + value, weight = list(map(int, input().split())) + if 0 <= value <= 2 * (10 ** 6) and 0 < weight <= 2 * (10 ** 6): + # value_per_unit_weight.append(value / weight) + weights.append(weight) + values.append(value) + + for i in range(len(weights)): + value_p_w[values[i] / weights[i]] = weights[i] + + value_p_w = sorted(value_p_w.items(), reverse=True) + #print(value_p_w) + + print(max_value_loot(value_p_w, knapsack)) +