From 83c0ea64904fadc3379022320ca5d489a579757b Mon Sep 17 00:00:00 2001
From: Hardik Pawar
Date: Tue, 8 Oct 2024 15:38:32 +0530
Subject: [PATCH 1/4] Add tests, remove `main` method, improve docs in
`BruteForceKnapsack.java`
---
.../BruteForceKnapsack.java | 78 ++++++++++-----
.../BruteForceKnapsackTest.java | 96 +++++++++++++++++++
2 files changed, 151 insertions(+), 23 deletions(-)
create mode 100644 src/test/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsackTest.java
diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java b/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java
index b433c44b9077..153ac8312ee7 100644
--- a/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java
+++ b/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java
@@ -1,39 +1,71 @@
package com.thealgorithms.dynamicprogramming;
-/* A Naive recursive implementation
-of 0-1 Knapsack problem */
+/**
+ * A naive recursive implementation of the 0-1 Knapsack problem.
+ *
+ * The 0-1 Knapsack problem is a classic optimization problem where you are
+ * given a set of items, each with a weight and a value, and a knapsack with a
+ * fixed capacity. The goal is to determine the maximum value that can be
+ * obtained by selecting a subset of the items such that the total weight does
+ * not exceed the knapsack's capacity. Each item can either be included (1) or
+ * excluded (0), hence the name "0-1" Knapsack.
+ *
+ * This class provides a brute-force recursive approach to solving the
+ * problem. It evaluates all possible combinations of items to find the optimal
+ * solution, but this approach has exponential time complexity and is not
+ * suitable for large input sizes.
+ *
+ * Time Complexity: O(2^n), where n is the number of items.
+ *
+ * Space Complexity: O(n), due to the recursive function call stack.
+ */
public final class BruteForceKnapsack {
private BruteForceKnapsack() {
}
- // Returns the maximum value that
- // can be put in a knapsack of
- // capacity W
+
+ /**
+ * Solves the 0-1 Knapsack problem using a recursive brute-force approach.
+ *
+ * @param w the total capacity of the knapsack
+ * @param wt an array where wt[i] represents the weight of the i-th item
+ * @param val an array where val[i] represents the value of the i-th item
+ * @param n the number of items available for selection
+ * @return the maximum value that can be obtained with the given capacity
+ *
+ * The function uses recursion to explore all possible subsets of items.
+ * For each item, it has two choices: either include it in the knapsack
+ * (if it fits) or exclude it. It returns the maximum value obtainable
+ * through these two choices.
+ *
+ * Base Cases:
+ *
+ * - If no items are left (n == 0), the maximum value is 0.
+ * - If the knapsack's remaining capacity is 0 (w == 0), no more items can
+ * be included, and the value is 0.
+ *
+ *
+ * Recursive Steps:
+ *
+ * - If the weight of the n-th item exceeds the current capacity, it is
+ * excluded from the solution, and the function proceeds with the remaining
+ * items.
+ * - Otherwise, the function considers two possibilities: include the n-th
+ * item or exclude it, and returns the maximum value of these two scenarios.
+ *
+ */
static int knapSack(int w, int[] wt, int[] val, int n) {
- // Base Case
if (n == 0 || w == 0) {
return 0;
}
- // If weight of the nth item is
- // more than Knapsack capacity W,
- // then this item cannot be included
- // in the optimal solution
if (wt[n - 1] > w) {
return knapSack(w, wt, val, n - 1);
- } // Return the maximum of two cases:
- // (1) nth item included
- // (2) not included
+ }
else {
- return Math.max(val[n - 1] + knapSack(w - wt[n - 1], wt, val, n - 1), knapSack(w, wt, val, n - 1));
+ return Math.max(
+ knapSack(w, wt, val, n - 1),
+ val[n - 1] + knapSack(w - wt[n - 1], wt, val, n - 1)
+ );
}
}
-
- // Driver code
- public static void main(String[] args) {
- int[] val = new int[] {60, 100, 120};
- int[] wt = new int[] {10, 20, 30};
- int w = 50;
- int n = val.length;
- System.out.println(knapSack(w, wt, val, n));
- }
}
diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsackTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsackTest.java
new file mode 100644
index 000000000000..ef96f16e04f7
--- /dev/null
+++ b/src/test/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsackTest.java
@@ -0,0 +1,96 @@
+package com.thealgorithms.dynamicprogramming;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+public class BruteForceKnapsackTest {
+
+ @Test
+ void testKnapSackBasicCase() {
+ int[] val = {60, 100, 120};
+ int[] wt = {10, 20, 30};
+ int w = 50;
+ int n = val.length;
+
+ // The expected result for this case is 220 (items 2 and 3 are included)
+ assertEquals(220, BruteForceKnapsack.knapSack(w, wt, val, n));
+ }
+
+ @Test
+ void testKnapSackNoItems() {
+ int[] val = {};
+ int[] wt = {};
+ int w = 50;
+ int n = val.length;
+
+ // With no items, the maximum value should be 0
+ assertEquals(0, BruteForceKnapsack.knapSack(w, wt, val, n));
+ }
+
+ @Test
+ void testKnapSackZeroCapacity() {
+ int[] val = {60, 100, 120};
+ int[] wt = {10, 20, 30};
+ int w = 0;
+ int n = val.length;
+
+ // With a knapsack of 0 capacity, no items can be included, so the value is 0
+ assertEquals(0, BruteForceKnapsack.knapSack(w, wt, val, n));
+ }
+
+ @Test
+ void testKnapSackSingleItemFits() {
+ int[] val = {100};
+ int[] wt = {20};
+ int w = 30;
+ int n = val.length;
+
+ // Only one item, and it fits in the knapsack, so the result is 100
+ assertEquals(100, BruteForceKnapsack.knapSack(w, wt, val, n));
+ }
+
+ @Test
+ void testKnapSackSingleItemDoesNotFit() {
+ int[] val = {100};
+ int[] wt = {20};
+ int w = 10;
+ int n = val.length;
+
+ // Single item does not fit in the knapsack, so the result is 0
+ assertEquals(0, BruteForceKnapsack.knapSack(w, wt, val, n));
+ }
+
+ @Test
+ void testKnapSackAllItemsFit() {
+ int[] val = {20, 30, 40};
+ int[] wt = {1, 2, 3};
+ int w = 6;
+ int n = val.length;
+
+ // All items fit into the knapsack, so the result is the sum of all values (20 + 30 + 40 = 90)
+ assertEquals(90, BruteForceKnapsack.knapSack(w, wt, val, n));
+ }
+
+ @Test
+ void testKnapSackNoneFit() {
+ int[] val = {100, 200, 300};
+ int[] wt = {100, 200, 300};
+ int w = 50;
+ int n = val.length;
+
+ // None of the items fit into the knapsack, so the result is 0
+ assertEquals(0, BruteForceKnapsack.knapSack(w, wt, val, n));
+ }
+
+ @Test
+ void testKnapSackSomeItemsFit() {
+ int[] val = {60, 100, 120};
+ int[] wt = {10, 20, 30};
+ int w = 40;
+ int n = val.length;
+
+ // Here, only the 2nd and 1st items should be included for a total value of 160
+ assertEquals(180, BruteForceKnapsack.knapSack(w, wt, val, n));
+ }
+}
From c1fcd401761345fb01192a04320f3051a3413bb4 Mon Sep 17 00:00:00 2001
From: Hardvan
Date: Tue, 8 Oct 2024 10:09:01 +0000
Subject: [PATCH 2/4] Update directory
---
DIRECTORY.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/DIRECTORY.md b/DIRECTORY.md
index 228735aa8ea9..efd6710cfca1 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -267,6 +267,7 @@
* [SumOfSubset](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/SumOfSubset.java)
* [Tribonacci](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/Tribonacci.java)
* [UniquePaths](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java)
+ * [UniqueSubsequencesCount](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/UniqueSubsequencesCount.java)
* [WildcardMatching](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java)
* [WineProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/WineProblem.java)
* geometry
@@ -769,6 +770,7 @@
* [StrassenMatrixMultiplicationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplicationTest.java)
* dynamicprogramming
* [BoardPathTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/BoardPathTest.java)
+ * [BruteForceKnapsackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsackTest.java)
* [CatalanNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/CatalanNumberTest.java)
* [ClimbStairsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/ClimbStairsTest.java)
* [EditDistanceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/EditDistanceTest.java)
@@ -794,6 +796,7 @@
* [SumOfSubsetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/SumOfSubsetTest.java)
* [TribonacciTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/TribonacciTest.java)
* [UniquePathsTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/UniquePathsTests.java)
+ * [UniqueSubsequencesCountTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/UniqueSubsequencesCountTest.java)
* [WildcardMatchingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/WildcardMatchingTest.java)
* geometry
* [GrahamScanTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/geometry/GrahamScanTest.java)
From 648821422307e40304f494640534e1bf81ef6b38 Mon Sep 17 00:00:00 2001
From: Hardik Pawar
Date: Tue, 8 Oct 2024 15:39:52 +0530
Subject: [PATCH 3/4] Fix
---
.../thealgorithms/dynamicprogramming/BruteForceKnapsack.java | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java b/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java
index 153ac8312ee7..f8693a222a59 100644
--- a/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java
+++ b/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java
@@ -62,10 +62,7 @@ static int knapSack(int w, int[] wt, int[] val, int n) {
return knapSack(w, wt, val, n - 1);
}
else {
- return Math.max(
- knapSack(w, wt, val, n - 1),
- val[n - 1] + knapSack(w - wt[n - 1], wt, val, n - 1)
- );
+ return Math.max(knapSack(w, wt, val, n - 1), val[n - 1] + knapSack(w - wt[n - 1], wt, val, n - 1));
}
}
}
From aad6a411061ac7ffd3cb4034953b26f1a9e8c96a Mon Sep 17 00:00:00 2001
From: Hardik Pawar
Date: Tue, 8 Oct 2024 15:56:20 +0530
Subject: [PATCH 4/4] Fix
---
.../thealgorithms/dynamicprogramming/BruteForceKnapsack.java | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java b/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java
index f8693a222a59..3c1851a8c46c 100644
--- a/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java
+++ b/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java
@@ -60,8 +60,7 @@ static int knapSack(int w, int[] wt, int[] val, int n) {
if (wt[n - 1] > w) {
return knapSack(w, wt, val, n - 1);
- }
- else {
+ } else {
return Math.max(knapSack(w, wt, val, n - 1), val[n - 1] + knapSack(w - wt[n - 1], wt, val, n - 1));
}
}