-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbnbKnapsack.java
More file actions
103 lines (80 loc) · 2.78 KB
/
bnbKnapsack.java
File metadata and controls
103 lines (80 loc) · 2.78 KB
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
102
103
import java.util.*;
public class bnbKnapsack extends BNBSolver {
private class Node implements Comparable<Node> {
public int h;
List<Item> taken;
public double bound;
public double value;
public double weight;
public Node() {
taken = new ArrayList<Item>();
}
public Node(Node parent) {
h = parent.h + 1;
taken = new ArrayList<Item>(parent.taken);
bound = parent.bound;
value = parent.value;
weight = parent.weight;
}
// Sort by bound
public int compareTo(Node other) {
return (int) (other.bound - bound);
}
public void computeBound() {
int i = h;
double w = weight;
bound = value;
Item item;
do {
item = items.get(i);
if (w + item.weight > capacity) break;
w += item.weight;
bound += item.value;
i++;
} while (i < items.size());
bound += (capacity - w) * (item.value / item.weight);
}
}
public bnbKnapsack(List<Item> items, int capacity) {
super(items, capacity);
}
@Override
public BNBSolution solve() {
Collections.sort(items, Item.byRatio());
Node best = new Node();
Node root = new Node();
root.computeBound();
PriorityQueue<Node> q = new PriorityQueue<Node>();
q.offer(root);
while (!q.isEmpty()) {
Node node = q.poll();
if (node.bound > best.value && node.h < items.size() - 1) {
Node with = new Node(node);
Item item = items.get(node.h);
with.weight += item.weight;
if (with.weight <= capacity) {
with.taken.add(items.get(node.h));
with.value += item.value;
with.computeBound();
if (with.value > best.value) {
best = with;
}
if (with.bound > best.value) {
q.offer(with);
}
}
Node without = new Node(node);
without.computeBound();
if (without.bound > best.value) {
q.offer(without);
}
}
}
BNBSolution solution = new BNBSolution();
solution.value = best.value;
solution.weight = best.weight;
solution.items = best.taken;
solution.message = "Using Branch and Bound the best feasible solution found";
return solution;
}
}