Skip to content

Commit 0603acc

Browse files
authored
Add tests, remove main method, improve docs in BruteForceKnapsack (#5641)
1 parent 49a87d3 commit 0603acc

File tree

3 files changed

+149
-24
lines changed

3 files changed

+149
-24
lines changed

DIRECTORY.md

+1
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,7 @@
783783
* [StrassenMatrixMultiplicationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplicationTest.java)
784784
* dynamicprogramming
785785
* [BoardPathTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/BoardPathTest.java)
786+
* [BruteForceKnapsackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsackTest.java)
786787
* [CatalanNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/CatalanNumberTest.java)
787788
* [ClimbStairsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/ClimbStairsTest.java)
788789
* [CountFriendsPairingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/CountFriendsPairingTest.java)
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,67 @@
11
package com.thealgorithms.dynamicprogramming;
22

3-
/* A Naive recursive implementation
4-
of 0-1 Knapsack problem */
3+
/**
4+
* A naive recursive implementation of the 0-1 Knapsack problem.
5+
*
6+
* <p>The 0-1 Knapsack problem is a classic optimization problem where you are
7+
* given a set of items, each with a weight and a value, and a knapsack with a
8+
* fixed capacity. The goal is to determine the maximum value that can be
9+
* obtained by selecting a subset of the items such that the total weight does
10+
* not exceed the knapsack's capacity. Each item can either be included (1) or
11+
* excluded (0), hence the name "0-1" Knapsack.</p>
12+
*
13+
* <p>This class provides a brute-force recursive approach to solving the
14+
* problem. It evaluates all possible combinations of items to find the optimal
15+
* solution, but this approach has exponential time complexity and is not
16+
* suitable for large input sizes.</p>
17+
*
18+
* <p><b>Time Complexity:</b> O(2^n), where n is the number of items.</p>
19+
*
20+
* <p><b>Space Complexity:</b> O(n), due to the recursive function call stack.</p>
21+
*/
522
public final class BruteForceKnapsack {
623
private BruteForceKnapsack() {
724
}
8-
// Returns the maximum value that
9-
// can be put in a knapsack of
10-
// capacity W
25+
26+
/**
27+
* Solves the 0-1 Knapsack problem using a recursive brute-force approach.
28+
*
29+
* @param w the total capacity of the knapsack
30+
* @param wt an array where wt[i] represents the weight of the i-th item
31+
* @param val an array where val[i] represents the value of the i-th item
32+
* @param n the number of items available for selection
33+
* @return the maximum value that can be obtained with the given capacity
34+
*
35+
* <p>The function uses recursion to explore all possible subsets of items.
36+
* For each item, it has two choices: either include it in the knapsack
37+
* (if it fits) or exclude it. It returns the maximum value obtainable
38+
* through these two choices.</p>
39+
*
40+
* <p><b>Base Cases:</b>
41+
* <ul>
42+
* <li>If no items are left (n == 0), the maximum value is 0.</li>
43+
* <li>If the knapsack's remaining capacity is 0 (w == 0), no more items can
44+
* be included, and the value is 0.</li>
45+
* </ul></p>
46+
*
47+
* <p><b>Recursive Steps:</b>
48+
* <ul>
49+
* <li>If the weight of the n-th item exceeds the current capacity, it is
50+
* excluded from the solution, and the function proceeds with the remaining
51+
* items.</li>
52+
* <li>Otherwise, the function considers two possibilities: include the n-th
53+
* item or exclude it, and returns the maximum value of these two scenarios.</li>
54+
* </ul></p>
55+
*/
1156
static int knapSack(int w, int[] wt, int[] val, int n) {
12-
// Base Case
1357
if (n == 0 || w == 0) {
1458
return 0;
1559
}
1660

17-
// If weight of the nth item is
18-
// more than Knapsack capacity W,
19-
// then this item cannot be included
20-
// in the optimal solution
2161
if (wt[n - 1] > w) {
2262
return knapSack(w, wt, val, n - 1);
23-
} // Return the maximum of two cases:
24-
// (1) nth item included
25-
// (2) not included
26-
else {
27-
return Math.max(val[n - 1] + knapSack(w - wt[n - 1], wt, val, n - 1), knapSack(w, wt, val, n - 1));
63+
} else {
64+
return Math.max(knapSack(w, wt, val, n - 1), val[n - 1] + knapSack(w - wt[n - 1], wt, val, n - 1));
2865
}
2966
}
30-
31-
// Driver code
32-
public static void main(String[] args) {
33-
int[] val = new int[] {60, 100, 120};
34-
int[] wt = new int[] {10, 20, 30};
35-
int w = 50;
36-
int n = val.length;
37-
System.out.println(knapSack(w, wt, val, n));
38-
}
3967
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package com.thealgorithms.dynamicprogramming;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
5+
import org.junit.jupiter.api.Test;
6+
7+
public class BruteForceKnapsackTest {
8+
9+
@Test
10+
void testKnapSackBasicCase() {
11+
int[] val = {60, 100, 120};
12+
int[] wt = {10, 20, 30};
13+
int w = 50;
14+
int n = val.length;
15+
16+
// The expected result for this case is 220 (items 2 and 3 are included)
17+
assertEquals(220, BruteForceKnapsack.knapSack(w, wt, val, n));
18+
}
19+
20+
@Test
21+
void testKnapSackNoItems() {
22+
int[] val = {};
23+
int[] wt = {};
24+
int w = 50;
25+
int n = val.length;
26+
27+
// With no items, the maximum value should be 0
28+
assertEquals(0, BruteForceKnapsack.knapSack(w, wt, val, n));
29+
}
30+
31+
@Test
32+
void testKnapSackZeroCapacity() {
33+
int[] val = {60, 100, 120};
34+
int[] wt = {10, 20, 30};
35+
int w = 0;
36+
int n = val.length;
37+
38+
// With a knapsack of 0 capacity, no items can be included, so the value is 0
39+
assertEquals(0, BruteForceKnapsack.knapSack(w, wt, val, n));
40+
}
41+
42+
@Test
43+
void testKnapSackSingleItemFits() {
44+
int[] val = {100};
45+
int[] wt = {20};
46+
int w = 30;
47+
int n = val.length;
48+
49+
// Only one item, and it fits in the knapsack, so the result is 100
50+
assertEquals(100, BruteForceKnapsack.knapSack(w, wt, val, n));
51+
}
52+
53+
@Test
54+
void testKnapSackSingleItemDoesNotFit() {
55+
int[] val = {100};
56+
int[] wt = {20};
57+
int w = 10;
58+
int n = val.length;
59+
60+
// Single item does not fit in the knapsack, so the result is 0
61+
assertEquals(0, BruteForceKnapsack.knapSack(w, wt, val, n));
62+
}
63+
64+
@Test
65+
void testKnapSackAllItemsFit() {
66+
int[] val = {20, 30, 40};
67+
int[] wt = {1, 2, 3};
68+
int w = 6;
69+
int n = val.length;
70+
71+
// All items fit into the knapsack, so the result is the sum of all values (20 + 30 + 40 = 90)
72+
assertEquals(90, BruteForceKnapsack.knapSack(w, wt, val, n));
73+
}
74+
75+
@Test
76+
void testKnapSackNoneFit() {
77+
int[] val = {100, 200, 300};
78+
int[] wt = {100, 200, 300};
79+
int w = 50;
80+
int n = val.length;
81+
82+
// None of the items fit into the knapsack, so the result is 0
83+
assertEquals(0, BruteForceKnapsack.knapSack(w, wt, val, n));
84+
}
85+
86+
@Test
87+
void testKnapSackSomeItemsFit() {
88+
int[] val = {60, 100, 120};
89+
int[] wt = {10, 20, 30};
90+
int w = 40;
91+
int n = val.length;
92+
93+
// Here, only the 2nd and 1st items should be included for a total value of 160
94+
assertEquals(180, BruteForceKnapsack.knapSack(w, wt, val, n));
95+
}
96+
}

0 commit comments

Comments
 (0)