forked from phishman3579/java-algorithms-implementation
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Knapsack.java
64 lines (57 loc) · 2.26 KB
/
Knapsack.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
package com.jwetherell.algorithms.mathematics;
import java.util.ArrayList;
import java.util.List;
/**
* The knapsack problem or rucksack problem is a problem in combinatorial optimization: Given a set of items, each with a weight and a value, determine the number of each item to include in a
* collection so that the total weight is less than or equal to a given limit and the total value is as large as possible. It derives its name from the problem faced by someone who is constrained
* by a fixed-size knapsack and must fill it with the most valuable items.
* <p>
* @see <a href="https://en.wikipedia.org/wiki/Knapsack_problem">Knapsack Problem (Wikipedia)</a>
* <br>
* @author Justin Wetherell <[email protected]>
*/
public class Knapsack {
public static final int[] zeroOneKnapsack(int[] values, int[] weights, int capacity) {
if (weights.length != values.length)
return null;
int height = weights.length + 1; // weights==values
int width = capacity + 1;
int[][] output = new int[height][width];
for (int i = 1; i < height; i++) {
int index = i - 1;
for (int j = 1; j < width; j++) {
if (i == 0 || j == 0) {
output[i][j] = 0;
} else {
if (weights[index] > j) {
output[i][j] = output[i - 1][j];
} else {
int v = values[index] + output[i - 1][j - weights[index]];
output[i][j] = Math.max(output[i - 1][j], v);
}
}
}
}
final List<Integer> list = new ArrayList<Integer>();
int i = height - 1;
int j = width - 1;
while (i != 0 && j != 0) {
int current = output[i][j];
int above = output[i - 1][j];
if (current == above) {
i -= 1;
} else {
i -= 1;
j -= weights[i];
list.add(i);
}
}
int count = 0;
int[] result = new int[list.size()];
for (Object obj : list.toArray()) {
if (obj instanceof Integer)
result[count++] = (Integer) obj;
}
return result;
}
}