From 99a9f1e09385ab3a5343848bbf104acdac32bb39 Mon Sep 17 00:00:00 2001 From: Srinjan Dutta Date: Thu, 5 Oct 2023 21:26:28 +0530 Subject: [PATCH 1/4] knapsack problem with memoization --- knapsack/knapsack_memoization.py | 87 ++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 knapsack/knapsack_memoization.py diff --git a/knapsack/knapsack_memoization.py b/knapsack/knapsack_memoization.py new file mode 100644 index 000000000000..e6be03a103c9 --- /dev/null +++ b/knapsack/knapsack_memoization.py @@ -0,0 +1,87 @@ +""" +A shopkeeper has bags of wheat that each have different weights and different profits. +eg. +no_of_items : 5 +profit [15, 14,10,45,30] +weight [2,5,1,3,4] +max_weight that can be carried : 7 + +Constraints: + max_weight > 0 + profit[i] >= 0 + weight[i] >= 0 + +Calculate: + The maximum profit that the shopkeeper can make given maxmum weight that can +be carried. + +This problem is implemented here with MEMOIZATION method using the concept of Dynamic Programming +""" + + +def knapsack(values:list, weights:list, num_of_items:int, max_weight:int, dp:list) -> int: + """ + Function description is as follows- + :param weights: Take a list of weights + :param values: Take a list of profits corresponding to the weights + :param number_of_items: number of items available to pick from + :param max_weight: Maximum weight that could be carried + :param dp: it is a list of list, i.e, a table whose (i,j) cell represents the maximum profit earned + for i items and j as the maximum weight allowed, it is an essential part for implementing this problems + using memoization dynamic programming + :return: Maximum expected gain + + Testcase 1: + >>> values = [1, 2, 4, 5] + >>> wt = [5, 4, 8, 6] + >>> n = len(values) + >>> w = 5 + >>> dp = [[-1 for x in range(w+1)] for y in range(n+1)] + >>> knapsack(values,wt,n,w,dp) + 2 + + Testcase 2: + >>> values = [3 ,4 , 5] + >>> wt = [10, 9 , 8] + >>> n = len(values) + >>> w = 25 + >>> dp = [[-1 for x in range(w+1)] for y in range(n+1)] + >>> knapsack(values,wt,n,w,dp) + 9 + + Testcase 3: + >>> values = [15, 14,10,45,30] + >>> wt = [2,5,1,3,4] + >>> n = len(values) + >>> w = 7 + >>> dp = [[-1 for x in range(w+1)] for y in range(n+1)] + >>> knapsack(values,wt,n,w,dp) + 75 + """ + if max_weight == 0 or num_of_items == 0: #no profit gain if any of these two become zero + dp[num_of_items][max_weight] = 0 + return 0 + + elif dp[num_of_items][max_weight] != -1: #if this case is previously encountered => maximum gain for this case is already + #in dp table + return dp[num_of_items][max_weight] + + elif weights[num_of_items-1] <= max_weight: #if the item can be included in the bag + # ans1 stores the maximum profit if the item at index num_of_items -1 is included in the bag + ans1 = values[num_of_items - 1] + knapsack(values, weights, num_of_items-1, max_weight-weights[num_of_items-1], dp) + # ans2 stores the maximum profit if the item at index num_of_items -1 is not included in the bag + ans2 = knapsack(values, weights, num_of_items-1, max_weight, dp) + # the final answer is the maximum profit gained from any of ans1 or ans2 + dp[num_of_items][max_weight] = max(ans1, ans2) + return dp[num_of_items][max_weight] + + # if the item's weight exceeds the max_weight of the bag => it cannot be included in the bag + else: + dp[num_of_items][max_weight] = knapsack(values, weights, num_of_items-1, max_weight, dp) + return dp[num_of_items][max_weight] + + + +if __name__ == '__main__': + import doctest + doctest.testmod(name='knapsack', verbose=True) \ No newline at end of file From 954f5d170549cba0bc2d2bcbffa26c3e21c1fdac Mon Sep 17 00:00:00 2001 From: Srinjan Dutta Date: Thu, 5 Oct 2023 21:50:31 +0530 Subject: [PATCH 2/4] knapsack with memoization and URL to algorithm added --- knapsack/knapsack_memoization.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/knapsack/knapsack_memoization.py b/knapsack/knapsack_memoization.py index e6be03a103c9..49c22c5f1f23 100644 --- a/knapsack/knapsack_memoization.py +++ b/knapsack/knapsack_memoization.py @@ -17,7 +17,9 @@ This problem is implemented here with MEMOIZATION method using the concept of Dynamic Programming """ - +""" +for more information visit https://en.wikipedia.org/wiki/Memoization +""" def knapsack(values:list, weights:list, num_of_items:int, max_weight:int, dp:list) -> int: """ From 0e789ce3ec1b14024738fe4f109f361fa4a1c9ec Mon Sep 17 00:00:00 2001 From: Srinjan Dutta Date: Mon, 9 Oct 2023 19:03:45 +0530 Subject: [PATCH 3/4] Knapsack solved with memoization --- knapsack/knapsack_memoization.py | 38 +++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/knapsack/knapsack_memoization.py b/knapsack/knapsack_memoization.py index 49c22c5f1f23..6643025ca92e 100644 --- a/knapsack/knapsack_memoization.py +++ b/knapsack/knapsack_memoization.py @@ -15,21 +15,25 @@ The maximum profit that the shopkeeper can make given maxmum weight that can be carried. -This problem is implemented here with MEMOIZATION method using the concept of Dynamic Programming +This problem is implemented here with MEMOIZATION method using the concept of +Dynamic Programming """ """ for more information visit https://en.wikipedia.org/wiki/Memoization """ -def knapsack(values:list, weights:list, num_of_items:int, max_weight:int, dp:list) -> int: +def knapsack(values:list, weights:list, num_of_items:int, max_weight:int, dp:list + ) -> int: """ Function description is as follows- :param weights: Take a list of weights :param values: Take a list of profits corresponding to the weights :param number_of_items: number of items available to pick from :param max_weight: Maximum weight that could be carried - :param dp: it is a list of list, i.e, a table whose (i,j) cell represents the maximum profit earned - for i items and j as the maximum weight allowed, it is an essential part for implementing this problems + :param dp: it is a list of list, i.e, a table whose (i,j) + cell represents the maximum profit earned + for i items and j as the maximum weight allowed, it + is an essential part for implementing this problem using memoization dynamic programming :return: Maximum expected gain @@ -60,26 +64,34 @@ def knapsack(values:list, weights:list, num_of_items:int, max_weight:int, dp:lis >>> knapsack(values,wt,n,w,dp) 75 """ - if max_weight == 0 or num_of_items == 0: #no profit gain if any of these two become zero + #no profit gain if any of these two become zero + if max_weight == 0 or num_of_items == 0: dp[num_of_items][max_weight] = 0 return 0 - - elif dp[num_of_items][max_weight] != -1: #if this case is previously encountered => maximum gain for this case is already + #if this case is previously encountered => maximum gain for this case is already + elif dp[num_of_items][max_weight] != -1: #in dp table return dp[num_of_items][max_weight] - elif weights[num_of_items-1] <= max_weight: #if the item can be included in the bag - # ans1 stores the maximum profit if the item at index num_of_items -1 is included in the bag - ans1 = values[num_of_items - 1] + knapsack(values, weights, num_of_items-1, max_weight-weights[num_of_items-1], dp) - # ans2 stores the maximum profit if the item at index num_of_items -1 is not included in the bag + #if the item can be included in the bag + elif weights[num_of_items-1] <= max_weight: + # ans1 stores the maximum profit if the item at + # index num_of_items -1 is included in the bag + incl = knapsack(values,weights,num_of_items-1, + max_weight-weights[num_of_items-1],dp) + ans1 = values[num_of_items - 1] + incl + # ans2 stores the maximum profit if the item at + # index num_of_items -1 is not included in the bag ans2 = knapsack(values, weights, num_of_items-1, max_weight, dp) # the final answer is the maximum profit gained from any of ans1 or ans2 dp[num_of_items][max_weight] = max(ans1, ans2) return dp[num_of_items][max_weight] - # if the item's weight exceeds the max_weight of the bag => it cannot be included in the bag + # if the item's weight exceeds the max_weight of the bag + # => it cannot be included in the bag else: - dp[num_of_items][max_weight] = knapsack(values, weights, num_of_items-1, max_weight, dp) + dp[num_of_items][max_weight] = knapsack(values, weights, + num_of_items-1, max_weight, dp) return dp[num_of_items][max_weight] From 1d756e462141769ce974b8f2bf9f3375f6a20c08 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 9 Oct 2023 14:09:11 +0000 Subject: [PATCH 4/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- knapsack/knapsack_memoization.py | 56 ++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/knapsack/knapsack_memoization.py b/knapsack/knapsack_memoization.py index 6643025ca92e..704ac0dd42cd 100644 --- a/knapsack/knapsack_memoization.py +++ b/knapsack/knapsack_memoization.py @@ -15,24 +15,26 @@ The maximum profit that the shopkeeper can make given maxmum weight that can be carried. -This problem is implemented here with MEMOIZATION method using the concept of +This problem is implemented here with MEMOIZATION method using the concept of Dynamic Programming """ """ for more information visit https://en.wikipedia.org/wiki/Memoization """ -def knapsack(values:list, weights:list, num_of_items:int, max_weight:int, dp:list - ) -> int: + +def knapsack( + values: list, weights: list, num_of_items: int, max_weight: int, dp: list +) -> int: """ Function description is as follows- :param weights: Take a list of weights :param values: Take a list of profits corresponding to the weights :param number_of_items: number of items available to pick from :param max_weight: Maximum weight that could be carried - :param dp: it is a list of list, i.e, a table whose (i,j) + :param dp: it is a list of list, i.e, a table whose (i,j) cell represents the maximum profit earned - for i items and j as the maximum weight allowed, it + for i items and j as the maximum weight allowed, it is an essential part for implementing this problem using memoization dynamic programming :return: Maximum expected gain @@ -64,38 +66,44 @@ def knapsack(values:list, weights:list, num_of_items:int, max_weight:int, dp:lis >>> knapsack(values,wt,n,w,dp) 75 """ - #no profit gain if any of these two become zero - if max_weight == 0 or num_of_items == 0: + # no profit gain if any of these two become zero + if max_weight == 0 or num_of_items == 0: dp[num_of_items][max_weight] = 0 return 0 - #if this case is previously encountered => maximum gain for this case is already - elif dp[num_of_items][max_weight] != -1: - #in dp table + # if this case is previously encountered => maximum gain for this case is already + elif dp[num_of_items][max_weight] != -1: + # in dp table return dp[num_of_items][max_weight] - - #if the item can be included in the bag - elif weights[num_of_items-1] <= max_weight: + + # if the item can be included in the bag + elif weights[num_of_items - 1] <= max_weight: # ans1 stores the maximum profit if the item at # index num_of_items -1 is included in the bag - incl = knapsack(values,weights,num_of_items-1, - max_weight-weights[num_of_items-1],dp) + incl = knapsack( + values, + weights, + num_of_items - 1, + max_weight - weights[num_of_items - 1], + dp, + ) ans1 = values[num_of_items - 1] + incl - # ans2 stores the maximum profit if the item at + # ans2 stores the maximum profit if the item at # index num_of_items -1 is not included in the bag - ans2 = knapsack(values, weights, num_of_items-1, max_weight, dp) + ans2 = knapsack(values, weights, num_of_items - 1, max_weight, dp) # the final answer is the maximum profit gained from any of ans1 or ans2 dp[num_of_items][max_weight] = max(ans1, ans2) return dp[num_of_items][max_weight] - + # if the item's weight exceeds the max_weight of the bag # => it cannot be included in the bag - else: - dp[num_of_items][max_weight] = knapsack(values, weights, - num_of_items-1, max_weight, dp) + else: + dp[num_of_items][max_weight] = knapsack( + values, weights, num_of_items - 1, max_weight, dp + ) return dp[num_of_items][max_weight] - -if __name__ == '__main__': +if __name__ == "__main__": import doctest - doctest.testmod(name='knapsack', verbose=True) \ No newline at end of file + + doctest.testmod(name="knapsack", verbose=True)