Skip to content

Commit b7d9330

Browse files
authored
Merge pull request #1681 from akgmage/dev
add knapsack in js
2 parents 707f3a6 + 93066d0 commit b7d9330

File tree

1 file changed

+143
-0
lines changed

1 file changed

+143
-0
lines changed

Dynamic Programming/knapsack.js

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
You're given an array of arrays where each subarray holds two integer values and represents an item;
3+
the first integer is the item's value, and the second integer is the item's weight.
4+
You're also given an integer representing the maximum capacity of a knapsack that you have.
5+
6+
Your goal is to fit items in your knapsack without having the sum of their weights exceed the knapsack's
7+
capacity, all the while maximizing their combined value. Note that you only have one of each item at your disposal.
8+
9+
Write a function that returns the maximized combined value of the items that you should pick as well as an array of
10+
the indices of each item picked.
11+
12+
Sample Input:= [[1, 2], [4, 3], [5, 6], [6, 7]]
13+
Output:= [10, [1, 3]] // items [4, 3] and [6, 7]
14+
15+
Explanation:
16+
17+
Sure! Let's break down the code step by step:
18+
19+
1. `KnapsackProblem` function: This function takes in two arguments - `items`, a 2D slice representing the
20+
list of items with their values and weights, and `capacity`, an integer representing the maximum weight
21+
capacity of the knapsack. It returns an interface slice containing the maximum value that can be achieved
22+
and the sequence of items included in the knapsack to achieve that maximum value.
23+
24+
2. Initializing the `values` array: The function creates a 2D slice called `values` to store the maximum
25+
achievable values for different knapsack configurations. The size of this array is `(len(items)+1) x (capacity+1)`,
26+
where `(len(items)+1)` represents the number of items, and `(capacity+1)` represents the weight capacity of the knapsack.
27+
The `values` array will be filled during the dynamic programming process.
28+
29+
3. Filling the `values` array: The function iterates through the `items` array and fills the `values`
30+
array using dynamic programming. For each item at index `i`, the function calculates the maximum achievable
31+
value for all possible capacities from `0` to `capacity`.
32+
33+
4. Inner loop: The inner loop iterates from `0` to `capacity` and calculates the maximum achievable value for
34+
the current item at index `i` and the current capacity `c`.
35+
36+
5. Updating the `values` array: There are two possibilities for each item:
37+
a. If the weight of the current item `items[i-1][1]` is greater than the current capacity `c`, we cannot
38+
include the item in the knapsack at this capacity. So, we use the value from the previous row `values[i-1][c]`
39+
for the current cell `values[i][c]`.
40+
b. If we can include the current item, we have two choices:
41+
i. Not include the current item, so the value remains the same as in the previous row `values[i-1][c]`.
42+
ii. Include the current item, which adds its value `items[i-1][0]` to the value of the knapsack at capacity `c - items[i-1][1]`.
43+
We choose the maximum of these two options and update the current cell `values[i][c]`.
44+
45+
6. Finding the maximum value: Once the `values` array is filled, the maximum achievable value for the knapsack is stored in the
46+
bottom-right cell `values[len(items)][capacity]`.
47+
48+
7. Calling `getKnapSackItems` function: The function calls the `getKnapSackItems` function to find the sequence of items included in
49+
the knapsack to achieve the maximum value.
50+
51+
8. `getKnapSackItems` function: This function takes in the `values` array and the `items` array as input and returns a slice containing
52+
the indices of the items included in the knapsack.
53+
54+
9. Traversing back to find the items: Starting from the bottom-right cell of the `values` array, the function traverses back to find the
55+
items included in the knapsack. It does this by comparing the value in the current cell `values[i][c]` with the value in the cell above
56+
`values[i-1][c]`. If the values are the same, it means the current item was not included, so it moves to the previous row. Otherwise,
57+
it means the current item was included, so it adds the index of the current item `(i-1)` to the `sequence` slice and updates the capacity `c` accordingly.
58+
59+
10. Reversing the `sequence`: The sequence of items is built in reverse order, so the function uses the `reverse` helper function to
60+
reverse the order of elements in the `sequence` slice.
61+
62+
11. Returning the result: The function returns the maximum value and the sequence of items included in the knapsack as an interface slice.
63+
64+
12. Helper functions: The `max` function is a simple helper function that returns the maximum of two integers, and the `reverse`
65+
function is used to reverse the order of elements in a slice.
66+
67+
Time and Space complexity:
68+
O(nc) time | O(nc) space - where n is the number of items and c is the capacity
69+
*/
70+
function KnapsackProblem(items, capacity) {
71+
// Create a 2D array to store the values of different knapsack configurations.
72+
const values = new Array(items.length + 1)
73+
.fill(0)
74+
.map(() => new Array(capacity + 1).fill(0));
75+
76+
// Iterate through the items and fill the values array.
77+
for (let i = 1; i < items.length + 1; i++) {
78+
const currentValue = items[i - 1][0];
79+
const currentWeight = items[i - 1][1];
80+
81+
for (let c = 0; c < capacity + 1; c++) {
82+
// If the current item's weight is more than the current capacity (c),
83+
// then we cannot include it, so we use the value from the previous row (i - 1).
84+
if (currentWeight > c) {
85+
values[i][c] = values[i - 1][c];
86+
} else {
87+
// If we can include the current item, we have two choices:
88+
// 1. Not include the current item, so the value remains the same as the previous row.
89+
// 2. Include the current item, which adds its value to the value of the knapsack at capacity (c - currentWeight).
90+
// We choose the maximum of these two options.
91+
values[i][c] = Math.max(
92+
values[i - 1][c],
93+
values[i - 1][c - currentWeight] + currentValue
94+
);
95+
}
96+
}
97+
}
98+
99+
// The value at the bottom-right corner of the values array represents the maximum achievable value for the knapsack problem.
100+
const value = values[items.length][capacity];
101+
102+
// Call the getKnapSackItems function to find the items that were included in the knapsack to achieve the maximum value.
103+
const sequence = getKnapSackItems(values, items);
104+
105+
// Return the maximum value and the sequence of items included in the knapsack as an array.
106+
return [value, sequence];
107+
}
108+
109+
// getKnapSackItems is a helper function to find the sequence of items included in the knapsack.
110+
function getKnapSackItems(values, items) {
111+
const sequence = [];
112+
let i = values.length - 1;
113+
let c = values[0].length - 1;
114+
115+
// Starting from the bottom-right corner of the values array,
116+
// we traverse back to find the items included in the knapsack.
117+
while (i > 0) {
118+
if (values[i][c] == values[i - 1][c]) {
119+
// If the value is the same as in the previous row, it means the current item was not included.
120+
// So, we move to the previous row without adding the item to the sequence.
121+
i--;
122+
} else {
123+
// If the value is greater than the value in the previous row, it means the current item was included.
124+
// So, we add the index of the current item (i-1) to the sequence and update the capacity (c) accordingly.
125+
sequence.push(i - 1);
126+
c -= items[i - 1][1];
127+
i--;
128+
}
129+
// If the capacity becomes 0, it means we have included all the items needed to achieve the maximum value.
130+
if (c == 0) {
131+
break;
132+
}
133+
}
134+
135+
// Reverse the sequence of items to get the correct order.
136+
sequence.reverse();
137+
return sequence;
138+
}
139+
140+
// max returns the maximum of two integers.
141+
function max(a, b) {
142+
return a > b ? a : b;
143+
}

0 commit comments

Comments
 (0)