-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHeld_Karp_Algorithm.java
125 lines (122 loc) · 3.86 KB
/
Held_Karp_Algorithm.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import java.util.HashSet;
import java.util.Set;
public class Held_Karp_Algorithm {
private int[][] D;
private int numVertices = -1;
private HashTable minCostDP;
private HashTable parent;
private LinkedList sets;
public long run(int[][] data, int verticies) {
D = data;
numVertices = verticies;
sets = new LinkedList();
createSets();
int size = numVertices*numVertices;
minCostDP = new HashTable(size);
parent = new HashTable(size);
long startTime = System.currentTimeMillis();
int result = TSP();
long time = System.currentTimeMillis()-startTime;
printTour();
System.out.println(", Distance: " + result);
return time;
}
private int TSP(){
Node curr = sets.top;
while(curr != null){
for(int i = 1; i < numVertices; i++) {
if(curr.set.contains(i)) {
continue;
}
int[] temp = loop(curr.set, Integer.MAX_VALUE, 0, i);
if(curr.set.isEmpty()) {
temp[0] = D[0][i];
}
minCostDP.insert(curr.set, i, temp[0]);
parent.insert(curr.set, i, temp[1]);
}
curr = curr.next;
}
Set<Integer> set = new HashSet<>();
for(int i = 1; i < numVertices; i++) {
set.add(i);
}
int[] temp = loop(set, Integer.MAX_VALUE, -1, 0);
parent.insert(set, 0, temp[1]);
return temp[0];
}
private int[] loop(Set<Integer> set, int min, int minPos, int val){
int[] results = new int[2];
results[0] = min;
results[1] = minPos;
Set<Integer> setCopy = deepCopy(set); //you get an error if you use the normal set
for(int k : set) {
int cost = D[k][val] + Cost(setCopy, k);
if(cost < results[0]) {
results[0] = cost;
results[1] = k;
}
}
return results;
}
private int Cost(Set<Integer> set, int j) {
set.remove(j);
int cost = minCostDP.get(set, j);
set.add(j);
return cost;
}
private Set<Integer> deepCopy(Set<Integer> set){
Set<Integer> result = new HashSet<>();
for(int i: set){
result.add(i);
}
return result;
}
private void printTour() {
String order = "";
Set<Integer> set = new HashSet<>();
for(int i = 0; i < numVertices; i++) {
set.add(i);
}
int start = 0;
while(!set.isEmpty()) {
order = (start + 1) + " -> " + order;// fix for 0 indexing
set.remove(start);
start = parent.get(set,start);
}
order = (0 + 1) + " -> " + order;// we start from vertex 0
System.out.print("Shortest path: " + order.substring(0,order.length()-4));
// -4 to remove the last " -> "
}
private void printSets(){
Node top = sets.top;
while(top != null){
if(top.set.isEmpty()){
System.out.println("[0]");
}
else{
System.out.println(top.set);
}
top = top.next;
}
}
private void createSets() {
int result[] = new int[numVertices-1];
generateCombination(0, 0, result);
}
private void generateCombination(int start, int end, int result[]) {
if(end != result.length) {
Set<Integer> set = new HashSet<>();
if(end > 0){
for(int i = 0; i < end; i++) {
set.add(result[i]);
}
}
sets.addOrdered(set);
for(int i = start; i < result.length; i++) {
result[end] = i+1;
generateCombination(i+1, end+1, result);
}
}
}
}