From 3b8c5dfcf9c331ab78f2e6c3a6708e117a0d3ac4 Mon Sep 17 00:00:00 2001 From: sai Date: Sun, 20 Jul 2025 16:38:29 +0530 Subject: [PATCH 1/6] feat: Add 0/1 Knapsack and its tabulation implementation with their corresponding tests --- .../dynamicprogramming/ZeroOneKnapsack.java | 50 ++++++++++++++++ .../ZeroOneKnapsackTab.java | 42 +++++++++++++ .../ZeroOneKnapsackTabTest.java | 49 +++++++++++++++ .../ZeroOneKnapsackTest.java | 60 +++++++++++++++++++ 4 files changed, 201 insertions(+) create mode 100644 src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsack.java create mode 100644 src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTab.java create mode 100644 src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTabTest.java create mode 100644 src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTest.java diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsack.java b/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsack.java new file mode 100644 index 000000000000..b359838fac24 --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsack.java @@ -0,0 +1,50 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * Class to solve the 0/1 Knapsack Problem using recursion. + * + * The 0/1 Knapsack problem is a classic dynamic programming problem + * where we are given weights and values of `n` items. We need to put + * these items in a knapsack of capacity `W` to get the maximum total value + * in the knapsack. We can either include an item or exclude it — but cannot + * include it more than once. + * + * Time Complexity: O(2^n) in worst case for the pure recursive approach (due to overlapping subproblems). + * Using memoization or bottom-up dynamic programming reduces the time complexity to O(nW). + * + * Example: + * val[] = {15, 14, 10, 45, 30} + * wt[] = {2, 5, 1, 3, 4} + * W = 7 + * Output: 75 + */ +public class ZeroOneKnapsack { + + /** + * Solves the 0/1 Knapsack problem using recursion. + * + * @param val Array of item values (must have length at least n) + * @param wt Array of item weights (must have length at least n) + * @param W Total capacity of the knapsack + * @param n Number of items to consider + * @return The maximum value that can be obtained + */ + public static int knapsack(int[] val, int[] wt, int W, int n) { + if (val == null || wt == null || val.length != wt.length) { + throw new IllegalArgumentException("Value and weight arrays must be non-null and of equal length."); + } + if (W == 0 || n == 0) { + return 0; + } + if (wt[n - 1] <= W) { + // Include the current item + int include = val[n - 1] + knapsack(val, wt, W - wt[n - 1], n - 1); + // Exclude the current item + int exclude = knapsack(val, wt, W, n - 1); + return Math.max(include, exclude); + } else { + // Cannot include the item, move to next + return knapsack(val, wt, W, n - 1); + } + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTab.java b/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTab.java new file mode 100644 index 000000000000..71e2428cca8f --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTab.java @@ -0,0 +1,42 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * Dynamic Programming approach for solving 0-1 Knapsack problem using tabulation. + * + * Problem Statement: + * Given weights and values of n items, put these items in a knapsack of capacity W + * to get the maximum total value in the knapsack. You cannot break an item. + * + * Time Complexity: O(n * W) + * Space Complexity: O(n * W) + */ +public class ZeroOneKnapsackTab { + + /** + * Solves the 0-1 Knapsack problem using a tabulation approach (bottom-up DP). + * + * @param val The values of the items + * @param wt The weights of the items + * @param W The total capacity of the knapsack + * @param n The number of items + * @return The maximum value that can be put in a knapsack of capacity W + */ + public static int knapsackTab(int[] val, int[] wt, int W, int n) { + int[][] dp = new int[n + 1][W + 1]; + + for (int i = 1; i <= n; i++) { + int v = val[i - 1]; // value of current item + int w = wt[i - 1]; // weight of current item + for (int j = 1; j <= W; j++) { + if (w <= j) { + int include = v + dp[i - 1][j - w]; + int exclude = dp[i - 1][j]; + dp[i][j] = Math.max(include, exclude); + } else { + dp[i][j] = dp[i - 1][j]; + } + } + } + return dp[n][W]; + } +} diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTabTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTabTest.java new file mode 100644 index 000000000000..f6c554dc59ea --- /dev/null +++ b/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTabTest.java @@ -0,0 +1,49 @@ +package com.thealgorithms.dynamicprogramming; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +/** + * Unit tests for the ZeroOneKnapsackTab class. + */ +public class ZeroOneKnapsackTabTest { + + /** + * Test knapsackTab with a typical set of values and weights. + * Checks if the maximum value for the given capacity is correct. + */ + @Test + public void testKnapsackTab() { + int[] val = {15, 14, 10, 45, 30}; + int[] wt = {2, 5, 1, 3, 4}; + int W = 7; + int expected = 75; + assertEquals(expected, ZeroOneKnapsackTab.knapsackTab(val, wt, W, val.length)); + } + + /** + * Test knapsackTab with empty arrays. + * Should return 0 as there are no items to include. + */ + @Test + public void testKnapsackTabEmpty() { + int[] val = {}; + int[] wt = {}; + int W = 10; + int expected = 0; + assertEquals(expected, ZeroOneKnapsackTab.knapsackTab(val, wt, W, 0)); + } + + /** + * Test knapsackTab with zero capacity. + * Should return 0 as no items can be included. + */ + @Test + public void testKnapsackTabZeroCapacity() { + int[] val = {10, 20, 30}; + int[] wt = {1, 1, 1}; + int W = 0; + int expected = 0; + assertEquals(expected, ZeroOneKnapsackTab.knapsackTab(val, wt, W, val.length)); + } +} diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTest.java new file mode 100644 index 000000000000..8751827ef9be --- /dev/null +++ b/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTest.java @@ -0,0 +1,60 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; + +/** + * Unit tests for the ZeroOneKnapsack algorithm. + */ +public class ZeroOneKnapsackTest { + + /** + * Test the knapsack algorithm with a basic example. + */ + @Test + void testKnapsackBasic() { + int[] val = {15, 14, 10, 45, 30}; + int[] wt = {2, 5, 1, 3, 4}; + int W = 7; + int expected = 75; + assertEquals(expected, ZeroOneKnapsack.knapsack(val, wt, W, val.length)); + } + + /** + * Test the knapsack algorithm when the knapsack capacity is zero. + * Expected result is zero since nothing can be added. + */ + @Test + void testZeroCapacity() { + int[] val = {10, 20, 30}; + int[] wt = {1, 1, 1}; + int W = 0; + int expected = 0; + assertEquals(expected, ZeroOneKnapsack.knapsack(val, wt, W, val.length)); + } + + /** + * Test the knapsack algorithm when there are no items. + * Expected result is zero since there is nothing to add. + */ + @Test + void testNoItems() { + int[] val = {}; + int[] wt = {}; + int W = 10; + int expected = 0; + assertEquals(expected, ZeroOneKnapsack.knapsack(val, wt, W, 0)); + } + + /** + * Test the knapsack algorithm with items that exactly fit the knapsack. + */ + @Test + void testExactFit() { + int[] val = {60, 100, 120}; + int[] wt = {10, 20, 30}; + int W = 50; + int expected = 220; + assertEquals(expected, ZeroOneKnapsack.knapsack(val, wt, W, val.length)); + } +} From 8a8d1e25e78ab189f41f08f25cd46179acb3ee5a Mon Sep 17 00:00:00 2001 From: sai Date: Sun, 20 Jul 2025 18:26:41 +0530 Subject: [PATCH 2/6] feat: Add 0/1 Knapsack and its tabulation implementation with their corresponding tests --- .../dynamicprogramming/ZeroOneKnapsack.java | 52 ++++++--------- .../ZeroOneKnapsackTab.java | 53 ++++++++------- .../ZeroOneKnapsackTabTest.java | 65 +++++++++++-------- .../ZeroOneKnapsackTest.java | 37 +++++------ 4 files changed, 105 insertions(+), 102 deletions(-) diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsack.java b/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsack.java index b359838fac24..d7d41ca64644 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsack.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsack.java @@ -1,50 +1,38 @@ package com.thealgorithms.dynamicprogramming; /** - * Class to solve the 0/1 Knapsack Problem using recursion. + * The {@code ZeroOneKnapsack} class provides a method to solve the classic 0/1 Knapsack problem. + * It returns the maximum value that can be obtained by selecting items within the weight limit. * - * The 0/1 Knapsack problem is a classic dynamic programming problem - * where we are given weights and values of `n` items. We need to put - * these items in a knapsack of capacity `W` to get the maximum total value - * in the knapsack. We can either include an item or exclude it — but cannot - * include it more than once. + * Problem Description: Given weights and values of n items, put these items in a knapsack of capacity W + * such that the total value is maximized. You cannot break an item, either pick the complete item or don't pick it. * - * Time Complexity: O(2^n) in worst case for the pure recursive approach (due to overlapping subproblems). - * Using memoization or bottom-up dynamic programming reduces the time complexity to O(nW). - * - * Example: - * val[] = {15, 14, 10, 45, 30} - * wt[] = {2, 5, 1, 3, 4} - * W = 7 - * Output: 75 + * https://en.wikipedia.org/wiki/Knapsack_problem */ -public class ZeroOneKnapsack { +public final class ZeroOneKnapsack { + private ZeroOneKnapsack() { + } /** * Solves the 0/1 Knapsack problem using recursion. * - * @param val Array of item values (must have length at least n) - * @param wt Array of item weights (must have length at least n) - * @param W Total capacity of the knapsack - * @param n Number of items to consider - * @return The maximum value that can be obtained + * @param values the array containing values of the items + * @param weights the array containing weights of the items + * @param capacity the total capacity of the knapsack + * @param n the number of items + * @return the maximum total value achievable within the given weight limit */ - public static int knapsack(int[] val, int[] wt, int W, int n) { - if (val == null || wt == null || val.length != wt.length) { - throw new IllegalArgumentException("Value and weight arrays must be non-null and of equal length."); - } - if (W == 0 || n == 0) { + public static int KnapsackCompute(int[] values, int[] weights, int capacity, int n) { + if (n == 0 || capacity == 0) { return 0; } - if (wt[n - 1] <= W) { - // Include the current item - int include = val[n - 1] + knapsack(val, wt, W - wt[n - 1], n - 1); - // Exclude the current item - int exclude = knapsack(val, wt, W, n - 1); + + if (weights[n - 1] <= capacity) { + int include = values[n - 1] + KnapsackCompute(values, weights, capacity - weights[n - 1], n - 1); + int exclude = KnapsackCompute(values, weights, capacity, n - 1); return Math.max(include, exclude); } else { - // Cannot include the item, move to next - return knapsack(val, wt, W, n - 1); + return KnapsackCompute(values, weights, capacity, n - 1); } } } diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTab.java b/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTab.java index 71e2428cca8f..c6d57c1374a6 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTab.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTab.java @@ -1,42 +1,49 @@ package com.thealgorithms.dynamicprogramming; /** - * Dynamic Programming approach for solving 0-1 Knapsack problem using tabulation. - * - * Problem Statement: - * Given weights and values of n items, put these items in a knapsack of capacity W - * to get the maximum total value in the knapsack. You cannot break an item. + * The {@code ZeroOneKnapsackTab} class provides a method to solve the 0-1 Knapsack problem + * using dynamic programming (tabulation approach). * - * Time Complexity: O(n * W) - * Space Complexity: O(n * W) + *

0-1 Knapsack Problem - + * Given weights and values of n items, and a maximum weight W, + * determine the maximum total value of items that can be included in the knapsack + * such that their total weight does not exceed W. Each item can be picked only once. + * + * Problem Link: https://www.geeksforgeeks.org/0-1-knapsack-problem-dp-10/ */ -public class ZeroOneKnapsackTab { +public final class ZeroOneKnapsackTab { + + private ZeroOneKnapsackTab() { + // prevent instantiation + } /** - * Solves the 0-1 Knapsack problem using a tabulation approach (bottom-up DP). + * Solves the 0-1 Knapsack problem using the bottom-up tabulation technique. * - * @param val The values of the items - * @param wt The weights of the items - * @param W The total capacity of the knapsack - * @param n The number of items - * @return The maximum value that can be put in a knapsack of capacity W + * @param val the values of the items + * @param wt the weights of the items + * @param W the total capacity of the knapsack + * @param n the number of items + * @return the maximum value that can be put in the knapsack */ - public static int knapsackTab(int[] val, int[] wt, int W, int n) { + public static int kcompute(int[] val, int[] wt, int W, int n) { int[][] dp = new int[n + 1][W + 1]; for (int i = 1; i <= n; i++) { - int v = val[i - 1]; // value of current item - int w = wt[i - 1]; // weight of current item - for (int j = 1; j <= W; j++) { - if (w <= j) { - int include = v + dp[i - 1][j - w]; - int exclude = dp[i - 1][j]; - dp[i][j] = Math.max(include, exclude); + int value = val[i - 1]; + int weight = wt[i - 1]; + + for (int w = 1; w <= W; w++) { + if (weight <= w) { + int include = value + dp[i - 1][w - weight]; + int exclude = dp[i - 1][w]; + dp[i][w] = Math.max(include, exclude); } else { - dp[i][j] = dp[i - 1][j]; + dp[i][w] = dp[i - 1][w]; } } } + return dp[n][W]; } } diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTabTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTabTest.java index f6c554dc59ea..3cf8fc1f90e5 100644 --- a/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTabTest.java +++ b/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTabTest.java @@ -1,49 +1,58 @@ package com.thealgorithms.dynamicprogramming; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; /** - * Unit tests for the ZeroOneKnapsackTab class. + * Test class for {@code ZeroOneKnapsackTab}. */ -public class ZeroOneKnapsackTabTest { +public class ZeroOneknapsackTabTest { /** - * Test knapsackTab with a typical set of values and weights. - * Checks if the maximum value for the given capacity is correct. + * Tests the 0-1 Knapsack tabulation approach with known values. */ @Test - public void testKnapsackTab() { - int[] val = {15, 14, 10, 45, 30}; - int[] wt = {2, 5, 1, 3, 4}; - int W = 7; - int expected = 75; - assertEquals(expected, ZeroOneKnapsackTab.knapsackTab(val, wt, W, val.length)); + public void testKnownValues() { + int[] val = {60, 100, 120}; + int[] wt = {10, 20, 30}; + int W = 50; + int n = val.length; + + // Expected result is 220 (items with weight 20 and 30) + assertEquals(220, ZeroOneKnapsackTab.kcompute(val, wt, W, n), "Maximum value for capacity 50 should be 220."); + } + + @Test + public void testZeroCapacity() { + int[] val = {10, 20, 30}; + int[] wt = {1, 1, 1}; + int W = 0; + int n = val.length; + + // With zero capacity, the result should be 0 + assertEquals(0, ZeroOneKnapsackTab.kcompute(val, wt, W, n), "Maximum value for capacity 0 should be 0."); } - /** - * Test knapsackTab with empty arrays. - * Should return 0 as there are no items to include. - */ @Test - public void testKnapsackTabEmpty() { + public void testZeroItems() { int[] val = {}; int[] wt = {}; int W = 10; - int expected = 0; - assertEquals(expected, ZeroOneKnapsackTab.knapsackTab(val, wt, W, 0)); + int n = val.length; + + // With no items, the result should be 0 + assertEquals(0, ZeroOneKnapsackTab.kcompute(val, wt, W, n), "Maximum value with no items should be 0."); } - /** - * Test knapsackTab with zero capacity. - * Should return 0 as no items can be included. - */ @Test - public void testKnapsackTabZeroCapacity() { - int[] val = {10, 20, 30}; - int[] wt = {1, 1, 1}; - int W = 0; - int expected = 0; - assertEquals(expected, ZeroOneKnapsackTab.knapsackTab(val, wt, W, val.length)); + public void testExactFit() { + int[] val = {5, 10, 15}; + int[] wt = {1, 2, 3}; + int W = 6; + int n = val.length; + + // All items fit exactly into capacity 6 + assertEquals(30, ZeroOneKnapsackTab.kcompute(val, wt, W, n), "Maximum value for exact fit should be 30."); } } diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTest.java index 8751827ef9be..95a22e91a199 100644 --- a/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTest.java +++ b/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTest.java @@ -1,60 +1,59 @@ package com.thealgorithms.dynamicprogramming; import static org.junit.jupiter.api.Assertions.assertEquals; + import org.junit.jupiter.api.Test; /** - * Unit tests for the ZeroOneKnapsack algorithm. + * Test class for {@code ZeroOneKnapsack}. */ public class ZeroOneKnapsackTest { /** - * Test the knapsack algorithm with a basic example. + * Tests the knapsack computation for a basic example. */ @Test - void testKnapsackBasic() { + public void testKnapsackBasic() { int[] val = {15, 14, 10, 45, 30}; int[] wt = {2, 5, 1, 3, 4}; int W = 7; - int expected = 75; - assertEquals(expected, ZeroOneKnapsack.knapsack(val, wt, W, val.length)); + assertEquals(75, ZeroOneKnapsack.KnapsackCompute(val, wt, W, val.length), + "Expected maximum value is 75."); } /** - * Test the knapsack algorithm when the knapsack capacity is zero. - * Expected result is zero since nothing can be added. + * Tests the knapsack computation when the knapsack capacity is zero. */ @Test - void testZeroCapacity() { + public void testZeroCapacity() { int[] val = {10, 20, 30}; int[] wt = {1, 1, 1}; int W = 0; - int expected = 0; - assertEquals(expected, ZeroOneKnapsack.knapsack(val, wt, W, val.length)); + assertEquals(0, ZeroOneKnapsack.KnapsackCompute(val, wt, W, val.length), + "Expected maximum value is 0 for zero capacity."); } /** - * Test the knapsack algorithm when there are no items. - * Expected result is zero since there is nothing to add. + * Tests the knapsack computation when there are no items. */ @Test - void testNoItems() { + public void testNoItems() { int[] val = {}; int[] wt = {}; int W = 10; - int expected = 0; - assertEquals(expected, ZeroOneKnapsack.knapsack(val, wt, W, 0)); + assertEquals(0, ZeroOneKnapsack.KnapsackCompute(val, wt, W, 0), + "Expected maximum value is 0 when no items are available."); } /** - * Test the knapsack algorithm with items that exactly fit the knapsack. + * Tests the knapsack computation when items exactly fit the capacity. */ @Test - void testExactFit() { + public void testExactFit() { int[] val = {60, 100, 120}; int[] wt = {10, 20, 30}; int W = 50; - int expected = 220; - assertEquals(expected, ZeroOneKnapsack.knapsack(val, wt, W, val.length)); + assertEquals(220, ZeroOneKnapsack.KnapsackCompute(val, wt, W, val.length), + "Expected maximum value is 220 for exact fit."); } } From 36fd4b2e3a8b71dd24bf0c7656958180d46f2e58 Mon Sep 17 00:00:00 2001 From: sai Date: Sun, 20 Jul 2025 19:09:12 +0530 Subject: [PATCH 3/6] feat: Add 0/1 Knapsack and its tabulation implementation with their corresponding tests --- .../dynamicprogramming/ZeroOneKnapsack.java | 8 ++++---- .../dynamicprogramming/ZeroOneKnapsackTab.java | 6 +++--- .../dynamicprogramming/ZeroOneKnapsackTabTest.java | 8 ++++---- .../dynamicprogramming/ZeroOneKnapsackTest.java | 12 ++++-------- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsack.java b/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsack.java index d7d41ca64644..3c29e30d625a 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsack.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsack.java @@ -22,17 +22,17 @@ private ZeroOneKnapsack() { * @param n the number of items * @return the maximum total value achievable within the given weight limit */ - public static int KnapsackCompute(int[] values, int[] weights, int capacity, int n) { + public static int compute(int[] values, int[] weights, int capacity, int n) { if (n == 0 || capacity == 0) { return 0; } if (weights[n - 1] <= capacity) { - int include = values[n - 1] + KnapsackCompute(values, weights, capacity - weights[n - 1], n - 1); - int exclude = KnapsackCompute(values, weights, capacity, n - 1); + int include = values[n - 1] + compute(values, weights, capacity - weights[n - 1], n - 1); + int exclude = compute(values, weights, capacity, n - 1); return Math.max(include, exclude); } else { - return KnapsackCompute(values, weights, capacity, n - 1); + return compute(values, weights, capacity, n - 1); } } } diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTab.java b/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTab.java index c6d57c1374a6..d2b1c18db11b 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTab.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTab.java @@ -4,11 +4,11 @@ * The {@code ZeroOneKnapsackTab} class provides a method to solve the 0-1 Knapsack problem * using dynamic programming (tabulation approach). * - *

0-1 Knapsack Problem - + *

0-1 Knapsack Problem - * Given weights and values of n items, and a maximum weight W, * determine the maximum total value of items that can be included in the knapsack * such that their total weight does not exceed W. Each item can be picked only once. - * + * * Problem Link: https://www.geeksforgeeks.org/0-1-knapsack-problem-dp-10/ */ public final class ZeroOneKnapsackTab { @@ -26,7 +26,7 @@ private ZeroOneKnapsackTab() { * @param n the number of items * @return the maximum value that can be put in the knapsack */ - public static int kcompute(int[] val, int[] wt, int W, int n) { + public static int compute(int[] val, int[] wt, int W, int n) { int[][] dp = new int[n + 1][W + 1]; for (int i = 1; i <= n; i++) { diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTabTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTabTest.java index 3cf8fc1f90e5..9f011ade695e 100644 --- a/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTabTest.java +++ b/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTabTest.java @@ -20,7 +20,7 @@ public void testKnownValues() { int n = val.length; // Expected result is 220 (items with weight 20 and 30) - assertEquals(220, ZeroOneKnapsackTab.kcompute(val, wt, W, n), "Maximum value for capacity 50 should be 220."); + assertEquals(220, ZeroOneKnapsackTab.compute(val, wt, W, n), "Maximum value for capacity 50 should be 220."); } @Test @@ -31,7 +31,7 @@ public void testZeroCapacity() { int n = val.length; // With zero capacity, the result should be 0 - assertEquals(0, ZeroOneKnapsackTab.kcompute(val, wt, W, n), "Maximum value for capacity 0 should be 0."); + assertEquals(0, ZeroOneKnapsackTab.compute(val, wt, W, n), "Maximum value for capacity 0 should be 0."); } @Test @@ -42,7 +42,7 @@ public void testZeroItems() { int n = val.length; // With no items, the result should be 0 - assertEquals(0, ZeroOneKnapsackTab.kcompute(val, wt, W, n), "Maximum value with no items should be 0."); + assertEquals(0, ZeroOneKnapsackTab.compute(val, wt, W, n), "Maximum value with no items should be 0."); } @Test @@ -53,6 +53,6 @@ public void testExactFit() { int n = val.length; // All items fit exactly into capacity 6 - assertEquals(30, ZeroOneKnapsackTab.kcompute(val, wt, W, n), "Maximum value for exact fit should be 30."); + assertEquals(30, ZeroOneKnapsackTab.compute(val, wt, W, n), "Maximum value for exact fit should be 30."); } } diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTest.java index 95a22e91a199..285524bb77da 100644 --- a/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTest.java +++ b/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTest.java @@ -17,8 +17,7 @@ public void testKnapsackBasic() { int[] val = {15, 14, 10, 45, 30}; int[] wt = {2, 5, 1, 3, 4}; int W = 7; - assertEquals(75, ZeroOneKnapsack.KnapsackCompute(val, wt, W, val.length), - "Expected maximum value is 75."); + assertEquals(75, ZeroOneKnapsack.compute(val, wt, W, val.length), "Expected maximum value is 75."); } /** @@ -29,8 +28,7 @@ public void testZeroCapacity() { int[] val = {10, 20, 30}; int[] wt = {1, 1, 1}; int W = 0; - assertEquals(0, ZeroOneKnapsack.KnapsackCompute(val, wt, W, val.length), - "Expected maximum value is 0 for zero capacity."); + assertEquals(0, ZeroOneKnapsack.compute(val, wt, W, val.length), "Expected maximum value is 0 for zero capacity."); } /** @@ -41,8 +39,7 @@ public void testNoItems() { int[] val = {}; int[] wt = {}; int W = 10; - assertEquals(0, ZeroOneKnapsack.KnapsackCompute(val, wt, W, 0), - "Expected maximum value is 0 when no items are available."); + assertEquals(0, ZeroOneKnapsack.compute(val, wt, W, 0), "Expected maximum value is 0 when no items are available."); } /** @@ -53,7 +50,6 @@ public void testExactFit() { int[] val = {60, 100, 120}; int[] wt = {10, 20, 30}; int W = 50; - assertEquals(220, ZeroOneKnapsack.KnapsackCompute(val, wt, W, val.length), - "Expected maximum value is 220 for exact fit."); + assertEquals(220, ZeroOneKnapsack.compute(val, wt, W, val.length), "Expected maximum value is 220 for exact fit."); } } From 40b8bc5e2c5aa5691c746e9c64d1ab69e2cbb121 Mon Sep 17 00:00:00 2001 From: sai Date: Mon, 21 Jul 2025 19:45:32 +0530 Subject: [PATCH 4/6] Feat:add 0/1knapsack and 0/1knapsacktabulation along with their tests --- .../dynamicprogramming/KnapsackZeroOne.java | 53 ++++++++++++++ .../KnapsackZeroOneTabulation.java | 71 +++++++++++++++++++ .../dynamicprogramming/ZeroOneKnapsack.java | 38 ---------- .../ZeroOneKnapsackTab.java | 49 ------------- .../KnapsackZeroOneTabulationTest.java | 40 +++++++++++ .../KnapsackZeroOneTest.java | 67 +++++++++++++++++ .../ZeroOneKnapsackTabTest.java | 58 --------------- .../ZeroOneKnapsackTest.java | 55 -------------- 8 files changed, 231 insertions(+), 200 deletions(-) create mode 100644 src/main/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOne.java create mode 100644 src/main/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTabulation.java delete mode 100644 src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsack.java delete mode 100644 src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTab.java create mode 100644 src/test/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTabulationTest.java create mode 100644 src/test/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTest.java delete mode 100644 src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTabTest.java delete mode 100644 src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTest.java diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOne.java b/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOne.java new file mode 100644 index 000000000000..abc1e321ca8f --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOne.java @@ -0,0 +1,53 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * The {@code KnapsackZeroOne} provides Recursive solution for the 0/1 Knapsack + * problem. Solves by exploring all combinations of items using recursion. No + * memoization or dynamic programming optimizations are applied. + * + * Time Complexity: O(2^n) — explores all subsets. + * Space Complexity: O(n) — due to recursive call stack. + * + * Problem Reference: https://en.wikipedia.org/wiki/Knapsack_problem + */ +public final class KnapsackZeroOne { + + private KnapsackZeroOne() { + // Prevent instantiation + } + + /** + * Solves the 0/1 Knapsack problem using recursion. + * + * @param values the array containing values of the items + * @param weights the array containing weights of the items + * @param capacity the total capacity of the knapsack + * @param n the number of items + * @return the maximum total value achievable within the given weight limit + * @throws IllegalArgumentException if input arrays are null, empty, or + * lengths mismatch + */ + public static int compute(final int[] values, final int[] weights, final int capacity, final int n) { + if (values == null || weights == null) { + throw new IllegalArgumentException("Input arrays cannot be null."); + } + if (values.length != weights.length) { + throw new IllegalArgumentException("Value and weight arrays must be of the same length."); + } + if (capacity < 0 || n < 0) { + throw new IllegalArgumentException("Invalid input: arrays must be non-empty and capacity/n " + + "non-negative."); + } + if (n == 0 || capacity == 0 || values.length == 0) { + return 0; + } + + if (weights[n - 1] <= capacity) { + final int include = values[n - 1] + compute(values, weights, capacity - weights[n - 1], n - 1); + final int exclude = compute(values, weights, capacity, n - 1); + return Math.max(include, exclude); + } else { + return compute(values, weights, capacity, n - 1); + } + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTabulation.java b/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTabulation.java new file mode 100644 index 000000000000..20b83995de8f --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTabulation.java @@ -0,0 +1,71 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * Tabulation (Bottom-Up) Solution for 0-1 Knapsack Problem. + * This method uses dynamic programming to build up a solution iteratively, + * filling a 2-D array where each entry dp[i][w] represents the maximum value + * achievable with the first i items and a knapsack capacity of w. + * + * The tabulation approach is efficient because it avoids redundant calculations + * by solving all subproblems in advance and storing their results, ensuring + * each subproblem is solved only once. This is a key technique in dynamic programming, + * making it possible to solve problems that would otherwise be infeasible due to + * exponential time complexity in naive recursive solutions. + * + * Time Complexity: O(n * W), where n is the number of items and W is the knapsack capacity. + * Space Complexity: O(n * W) for the DP table. + * + * For more information, see: + * https://en.wikipedia.org/wiki/Knapsack_problem#Dynamic_programming + */ +public final class KnapsackZeroOneTabulation { + + private KnapsackZeroOneTabulation() { + // Prevent instantiation + } + + /** + * Solves the 0-1 Knapsack problem using the bottom-up tabulation technique. + * + * @param values the values of the items + * @param weights the weights of the items + * @param capacity the total capacity of the knapsack + * @param itemCount the number of items + * @return the maximum value that can be put in the knapsack + * @throws IllegalArgumentException if input arrays are null, of different lengths, + * or if capacity or itemCount is invalid + */ + public static int compute(final int[] values, final int[] weights, final int capacity, final int itemCount) { + if (values == null || weights == null) { + throw new IllegalArgumentException("Values and weights arrays must not be null."); + } + if (values.length != weights.length) { + throw new IllegalArgumentException("Values and weights arrays must be non-null and of same length"); + } + if (capacity < 0) { + throw new IllegalArgumentException("Capacity must not be negative."); + } + if (itemCount < 0 || itemCount > values.length) { + throw new IllegalArgumentException("Item count must be between 0 and the length of the values array."); + } + + final int[][] dp = new int[itemCount + 1][capacity + 1]; + + for (int i = 1; i <= itemCount; i++) { + final int currentValue = values[i - 1]; + final int currentWeight = weights[i - 1]; + + for (int w = 1; w <= capacity; w++) { + if (currentWeight <= w) { + final int includeItem = currentValue + dp[i - 1][w - currentWeight]; + final int excludeItem = dp[i - 1][w]; + dp[i][w] = Math.max(includeItem, excludeItem); + } else { + dp[i][w] = dp[i - 1][w]; + } + } + } + + return dp[itemCount][capacity]; + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsack.java b/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsack.java deleted file mode 100644 index 3c29e30d625a..000000000000 --- a/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsack.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.thealgorithms.dynamicprogramming; - -/** - * The {@code ZeroOneKnapsack} class provides a method to solve the classic 0/1 Knapsack problem. - * It returns the maximum value that can be obtained by selecting items within the weight limit. - * - * Problem Description: Given weights and values of n items, put these items in a knapsack of capacity W - * such that the total value is maximized. You cannot break an item, either pick the complete item or don't pick it. - * - * https://en.wikipedia.org/wiki/Knapsack_problem - */ -public final class ZeroOneKnapsack { - private ZeroOneKnapsack() { - } - - /** - * Solves the 0/1 Knapsack problem using recursion. - * - * @param values the array containing values of the items - * @param weights the array containing weights of the items - * @param capacity the total capacity of the knapsack - * @param n the number of items - * @return the maximum total value achievable within the given weight limit - */ - public static int compute(int[] values, int[] weights, int capacity, int n) { - if (n == 0 || capacity == 0) { - return 0; - } - - if (weights[n - 1] <= capacity) { - int include = values[n - 1] + compute(values, weights, capacity - weights[n - 1], n - 1); - int exclude = compute(values, weights, capacity, n - 1); - return Math.max(include, exclude); - } else { - return compute(values, weights, capacity, n - 1); - } - } -} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTab.java b/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTab.java deleted file mode 100644 index d2b1c18db11b..000000000000 --- a/src/main/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTab.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.thealgorithms.dynamicprogramming; - -/** - * The {@code ZeroOneKnapsackTab} class provides a method to solve the 0-1 Knapsack problem - * using dynamic programming (tabulation approach). - * - *

0-1 Knapsack Problem - - * Given weights and values of n items, and a maximum weight W, - * determine the maximum total value of items that can be included in the knapsack - * such that their total weight does not exceed W. Each item can be picked only once. - * - * Problem Link: https://www.geeksforgeeks.org/0-1-knapsack-problem-dp-10/ - */ -public final class ZeroOneKnapsackTab { - - private ZeroOneKnapsackTab() { - // prevent instantiation - } - - /** - * Solves the 0-1 Knapsack problem using the bottom-up tabulation technique. - * - * @param val the values of the items - * @param wt the weights of the items - * @param W the total capacity of the knapsack - * @param n the number of items - * @return the maximum value that can be put in the knapsack - */ - public static int compute(int[] val, int[] wt, int W, int n) { - int[][] dp = new int[n + 1][W + 1]; - - for (int i = 1; i <= n; i++) { - int value = val[i - 1]; - int weight = wt[i - 1]; - - for (int w = 1; w <= W; w++) { - if (weight <= w) { - int include = value + dp[i - 1][w - weight]; - int exclude = dp[i - 1][w]; - dp[i][w] = Math.max(include, exclude); - } else { - dp[i][w] = dp[i - 1][w]; - } - } - } - - return dp[n][W]; - } -} diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTabulationTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTabulationTest.java new file mode 100644 index 000000000000..d2487b05bbf0 --- /dev/null +++ b/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTabulationTest.java @@ -0,0 +1,40 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class KnapsackZeroOneTabulationTest { + + @Test + public void basicCheck() { + int[] values = {60, 100, 120}; + int[] weights = {10, 20, 30}; + int capacity = 50; + int itemCount = values.length; + + int expected = 220; // Best choice: item 1 (100) and item 2 (120) + int result = KnapsackZeroOneTabulation.compute(values, weights, capacity, itemCount); + assertEquals(expected, result); + } + + @Test + public void emptyKnapsack() { + int[] values = {}; + int[] weights = {}; + int capacity = 50; + int itemCount = 0; + + assertEquals(0, KnapsackZeroOneTabulation.compute(values, weights, capacity, itemCount)); + } + + @Test + public void zeroCapacity() { + int[] values = {60, 100, 120}; + int[] weights = {10, 20, 30}; + int capacity = 0; + int itemCount = values.length; + + assertEquals(0, KnapsackZeroOneTabulation.compute(values, weights, capacity, itemCount)); + } +} diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTest.java new file mode 100644 index 000000000000..80307d64537b --- /dev/null +++ b/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTest.java @@ -0,0 +1,67 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +class KnapsackZeroOneTest { + + @Test + void basicCheck() { + int[] values = {60, 100, 120}; + int[] weights = {10, 20, 30}; + int capacity = 50; + int expected = 220; + + int result = KnapsackZeroOne.compute(values, weights, capacity, values.length); + assertEquals(expected, result); + } + + @Test + void zeroCapacity() { + int[] values = {10, 20, 30}; + int[] weights = {1, 1, 1}; + int capacity = 0; + + int result = KnapsackZeroOne.compute(values, weights, capacity, values.length); + assertEquals(0, result); + } + + @Test + void zeroItems() { + int[] values = {}; + int[] weights = {}; + int capacity = 10; + + int result = KnapsackZeroOne.compute(values, weights, capacity, 0); + assertEquals(0, result); + } + + @Test + void weightsExceedingCapacity() { + int[] values = {10, 20}; + int[] weights = {100, 200}; + int capacity = 50; + + int result = KnapsackZeroOne.compute(values, weights, capacity, values.length); + assertEquals(0, result); + } + + @Test + void throwsOnNullArrays() { + assertThrows(IllegalArgumentException.class, () -> KnapsackZeroOne.compute(null, new int[] {1}, 10, 1)); + assertThrows(IllegalArgumentException.class, () -> KnapsackZeroOne.compute(new int[] {1}, null, 10, 1)); + } + + @Test + void throwsOnMismatchedArrayLengths() { + assertThrows(IllegalArgumentException.class, () -> KnapsackZeroOne.compute(new int[] {10, 20}, new int[] {5}, 15, 2)); + } + + @Test + void throwsOnNegativeInputs() { + assertThrows(IllegalArgumentException.class, () -> KnapsackZeroOne.compute(new int[] {10}, new int[] {5}, -1, 1)); + + assertThrows(IllegalArgumentException.class, () -> KnapsackZeroOne.compute(new int[] {10}, new int[] {5}, 5, -1)); + } +} diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTabTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTabTest.java deleted file mode 100644 index 9f011ade695e..000000000000 --- a/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTabTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.thealgorithms.dynamicprogramming; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.junit.jupiter.api.Test; - -/** - * Test class for {@code ZeroOneKnapsackTab}. - */ -public class ZeroOneknapsackTabTest { - - /** - * Tests the 0-1 Knapsack tabulation approach with known values. - */ - @Test - public void testKnownValues() { - int[] val = {60, 100, 120}; - int[] wt = {10, 20, 30}; - int W = 50; - int n = val.length; - - // Expected result is 220 (items with weight 20 and 30) - assertEquals(220, ZeroOneKnapsackTab.compute(val, wt, W, n), "Maximum value for capacity 50 should be 220."); - } - - @Test - public void testZeroCapacity() { - int[] val = {10, 20, 30}; - int[] wt = {1, 1, 1}; - int W = 0; - int n = val.length; - - // With zero capacity, the result should be 0 - assertEquals(0, ZeroOneKnapsackTab.compute(val, wt, W, n), "Maximum value for capacity 0 should be 0."); - } - - @Test - public void testZeroItems() { - int[] val = {}; - int[] wt = {}; - int W = 10; - int n = val.length; - - // With no items, the result should be 0 - assertEquals(0, ZeroOneKnapsackTab.compute(val, wt, W, n), "Maximum value with no items should be 0."); - } - - @Test - public void testExactFit() { - int[] val = {5, 10, 15}; - int[] wt = {1, 2, 3}; - int W = 6; - int n = val.length; - - // All items fit exactly into capacity 6 - assertEquals(30, ZeroOneKnapsackTab.compute(val, wt, W, n), "Maximum value for exact fit should be 30."); - } -} diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTest.java deleted file mode 100644 index 285524bb77da..000000000000 --- a/src/test/java/com/thealgorithms/dynamicprogramming/ZeroOneKnapsackTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.thealgorithms.dynamicprogramming; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.junit.jupiter.api.Test; - -/** - * Test class for {@code ZeroOneKnapsack}. - */ -public class ZeroOneKnapsackTest { - - /** - * Tests the knapsack computation for a basic example. - */ - @Test - public void testKnapsackBasic() { - int[] val = {15, 14, 10, 45, 30}; - int[] wt = {2, 5, 1, 3, 4}; - int W = 7; - assertEquals(75, ZeroOneKnapsack.compute(val, wt, W, val.length), "Expected maximum value is 75."); - } - - /** - * Tests the knapsack computation when the knapsack capacity is zero. - */ - @Test - public void testZeroCapacity() { - int[] val = {10, 20, 30}; - int[] wt = {1, 1, 1}; - int W = 0; - assertEquals(0, ZeroOneKnapsack.compute(val, wt, W, val.length), "Expected maximum value is 0 for zero capacity."); - } - - /** - * Tests the knapsack computation when there are no items. - */ - @Test - public void testNoItems() { - int[] val = {}; - int[] wt = {}; - int W = 10; - assertEquals(0, ZeroOneKnapsack.compute(val, wt, W, 0), "Expected maximum value is 0 when no items are available."); - } - - /** - * Tests the knapsack computation when items exactly fit the capacity. - */ - @Test - public void testExactFit() { - int[] val = {60, 100, 120}; - int[] wt = {10, 20, 30}; - int W = 50; - assertEquals(220, ZeroOneKnapsack.compute(val, wt, W, val.length), "Expected maximum value is 220 for exact fit."); - } -} From 229d28b2915cb9b63f21976d9ec287d39ff66ea0 Mon Sep 17 00:00:00 2001 From: sai Date: Mon, 21 Jul 2025 23:15:28 +0530 Subject: [PATCH 5/6] Feat:add 0/1knapsack and 0/1knapsacktabulation along with their tests --- .../dynamicprogramming/KnapsackZeroOneTabulation.java | 6 ++---- .../dynamicprogramming/KnapsackZeroOneTest.java | 3 ++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTabulation.java b/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTabulation.java index 20b83995de8f..c560efc61c71 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTabulation.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTabulation.java @@ -26,21 +26,19 @@ private KnapsackZeroOneTabulation() { /** * Solves the 0-1 Knapsack problem using the bottom-up tabulation technique. - * * @param values the values of the items * @param weights the weights of the items * @param capacity the total capacity of the knapsack * @param itemCount the number of items * @return the maximum value that can be put in the knapsack - * @throws IllegalArgumentException if input arrays are null, of different lengths, - * or if capacity or itemCount is invalid + * @throws IllegalArgumentException if input arrays are null, of different lengths,or if capacity or itemCount is invalid */ public static int compute(final int[] values, final int[] weights, final int capacity, final int itemCount) { if (values == null || weights == null) { throw new IllegalArgumentException("Values and weights arrays must not be null."); } if (values.length != weights.length) { - throw new IllegalArgumentException("Values and weights arrays must be non-null and of same length"); + throw new IllegalArgumentException("Values and weights arrays must be non-null and of same length."); } if (capacity < 0) { throw new IllegalArgumentException("Capacity must not be negative."); diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTest.java index 80307d64537b..0ca2b91fc273 100644 --- a/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTest.java +++ b/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.dynamicprogramming; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; From 72ce8a257bc313f1d5e4753c4108d34e24168469 Mon Sep 17 00:00:00 2001 From: sai Date: Tue, 22 Jul 2025 11:51:18 +0530 Subject: [PATCH 6/6] Feat:add 0/1knapsack and 0/1knapsacktabulation along with their tests --- .../KnapsackZeroOneTabulationTest.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTabulationTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTabulationTest.java index d2487b05bbf0..6c61ad2130e3 100644 --- a/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTabulationTest.java +++ b/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTabulationTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.dynamicprogramming; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; @@ -37,4 +38,41 @@ public void zeroCapacity() { assertEquals(0, KnapsackZeroOneTabulation.compute(values, weights, capacity, itemCount)); } + + @Test + public void negativeCapacity() { + int[] values = {10, 20, 30}; + int[] weights = {1, 1, 1}; + int capacity = -10; + int itemCount = values.length; + + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> KnapsackZeroOneTabulation.compute(values, weights, capacity, itemCount)); + assertEquals("Capacity must not be negative.", exception.getMessage()); + } + + @Test + public void mismatchedLengths() { + int[] values = {60, 100}; // Only 2 values + int[] weights = {10, 20, 30}; // 3 weights + int capacity = 50; + int itemCount = 2; // Matches `values.length` + + // You could either expect 0 or throw an IllegalArgumentException in your compute function + assertThrows(IllegalArgumentException.class, () -> { KnapsackZeroOneTabulation.compute(values, weights, capacity, itemCount); }); + } + + @Test + public void nullInputs() { + int[] weights = {1, 2, 3}; + int capacity = 10; + int itemCount = 3; + + IllegalArgumentException exception1 = assertThrows(IllegalArgumentException.class, () -> KnapsackZeroOneTabulation.compute(null, weights, capacity, itemCount)); + assertEquals("Values and weights arrays must not be null.", exception1.getMessage()); + + int[] values = {1, 2, 3}; + + IllegalArgumentException exception2 = assertThrows(IllegalArgumentException.class, () -> KnapsackZeroOneTabulation.compute(values, null, capacity, itemCount)); + assertEquals("Values and weights arrays must not be null.", exception2.getMessage()); + } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy