-
Notifications
You must be signed in to change notification settings - Fork 0
/
Knapsack01.java
101 lines (88 loc) · 3.55 KB
/
Knapsack01.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import java.util.*;
public class Knapsack01 {
/**
* Solves 0/1 knapsack in bottom up dynamic programming
*/
public int bottomUpDP(int val[], int wt[], int W){
int K[][] = new int[val.length+1][W+1];
for(int i=0; i <= val.length; i++){
for(int j=0; j <= W; j++){
if(i == 0 || j == 0){
K[i][j] = 0;
continue;
}
if(j - wt[i-1] >= 0){
K[i][j] = Math.max(K[i-1][j], K[i-1][j-wt[i-1]] + val[i-1]);
}else{
K[i][j] = K[i-1][j];
}
}
}
return K[val.length][W];
}
/**
* Key for memoization
*/
class Index {
int remainingWeight;
int remainingItems;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Index index = (Index) o;
if (remainingWeight != index.remainingWeight) return false;
return remainingItems == index.remainingItems;
}
@Override
public int hashCode() {
int result = remainingWeight;
result = 31 * result + remainingItems;
return result;
}
}
/**
* Solves 0/1 knapsack in top down DP
*/
public int topDownRecursive(int values[], int weights[], int W) {
//map of key(remainingWeight, remainingCount) to maximumValue they can get.
Map<Index, Integer> map = new HashMap<>();
return topDownRecursiveUtil(values, weights, W, values.length, 0, map);
}
public int topDownRecursiveUtil(int values[], int weights[], int remainingWeight, int totalItems, int currentItem, Map<Index, Integer> map) {
//if currentItem exceeds total item count or remainingWeight is less than 0 then
//just return with 0;
if(currentItem >= totalItems || remainingWeight <= 0) {
return 0;
}
//fom a key based on remainingWeight and remainingCount
Index key = new Index();
key.remainingItems = totalItems - currentItem -1;
key.remainingWeight = remainingWeight;
//see if key exists in map. If so then return the maximumValue for key stored in map.
if(map.containsKey(key)) {
return map.get(key);
}
int maxValue;
//if weight of item is more than remainingWeight then try next item by skipping current item
if(remainingWeight < weights[currentItem]) {
maxValue = topDownRecursiveUtil(values, weights, remainingWeight, totalItems, currentItem + 1, map);
} else {
//try to get maximumValue of either by picking the currentItem or not picking currentItem
maxValue = Math.max(values[currentItem] + topDownRecursiveUtil(values, weights, remainingWeight - weights[currentItem], totalItems, currentItem + 1, map),
topDownRecursiveUtil(values, weights, remainingWeight, totalItems, currentItem + 1, map));
}
//memoize the key with maxValue found to avoid recalculation
map.put(key, maxValue);
return maxValue;
}
public static void main(String args[]){
Knapsack01 k = new Knapsack01();
int val[] = {22, 20, 15, 30, 24, 54, 21, 32, 18, 25};
int wt[] = {4, 2, 3, 5, 5, 6, 9, 7, 8, 10};
int r = k.bottomUpDP(val, wt, 30);
int r1 = k.topDownRecursive(val, wt, 30);
System.out.println(r);
System.out.println(r1);
}
}