-
Notifications
You must be signed in to change notification settings - Fork 2
/
GeneticAlgo.java
290 lines (202 loc) · 5.96 KB
/
GeneticAlgo.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
import java.util.*;
// Genetic Algorithm
public class GeneticAlgo extends ToolsTSP implements Answer {
// Random Number
public static Random ran = new Random();
// Population of Tours
public Tour[] pop = new Tour[30];
public MapInfo map;
// Mutation Rate
double mutationRate = 0.00001;
// Constructor for Genetic Algo
public GeneticAlgo(MapInfo map) {
super(map);
this.map = map;
}
// Evaluate the Population
public void evaluate() {
// Set to 0
double maxFit = 0;
// Adding up all the Fit's
for(Tour t : pop) {
maxFit += t.getFit();
}
double oldSingleMax = 0;
// Getting the Old Max
for(Tour t : pop) {
oldSingleMax = t.setSelectRange(maxFit, oldSingleMax);
}
}
// Choosing a Random Parent
private Tour randomParent() {
// Random Double
double rand = Math.random();
// Search the Population
for(int i = 0; i < pop.length; i++) {
// If it's within range of Random
if(pop[i].isInRange(rand)) {
// Return Parent Tour
return pop[i];
}
}
throw new RuntimeException("Error: Unable to Select Parent");
}
// Creates a Child Tour between a Dad and Mom
public Tour makeBebe(Tour dad, Tour mom) {
// Child Path
List<Integer> childPath = new ArrayList<Integer>();
// Creating Cities Considered
List<Integer> pathConsidered = new LinkedList<Integer>();
for(int i = 0; i < map.n; i++) {
pathConsidered.add(i);
}
// Both Parents Path
Integer[] dadPath = dad.givePath(false);
Integer[] momPath = mom.givePath(false);
if(ran.nextInt(2) == 0) {
childPath.add(dadPath[0]);
}
else {
childPath.add(momPath[0]);
}
pathConsidered.remove(childPath.get(0));
for(int i = 0; i < map.n - 1; i++) {
// Get's the Cities After
int dadNext = dad.getCityAfter(childPath.get(i));
int momNext = mom.getCityAfter(childPath.get(i));
// Get's the Distances
double dadNextDist = map.distances[childPath.get(i)][dadNext];
double momNextDist = map.distances[childPath.get(i)][momNext];
// If the Child Path doesn't have Dad or Mom's next city
if(!childPath.contains(dadNext) && !childPath.contains(momNext)) {
// If Dad is closer than Mom
if(dadNextDist < momNextDist) {
// Add the Dad's next City
childPath.add(dadNext);
}
// Else, Mom is closer than Dad
else {
// Add the Mom's next City
childPath.add(momNext);
}
}
// Else If, the Child path contains Dad and Mom's next city
else if (childPath.contains(dadNext) && childPath.contains(momNext)) {
// Add a random city form Path Considered
childPath.add(pathConsidered.get(ran.nextInt(pathConsidered.size())));
}
else {
// If the Child doesn't have Dad's next city
if(!childPath.contains(dadNext)) {
// Add Dad's next city
childPath.add(dadNext);
}
// Else, the Child doesn't have Mom's next city
else {
// Add Mom's next city
childPath.add(momNext);
}
}
// Remove the city from path considered
pathConsidered.remove(childPath.get(childPath.size() - 1));
}
childPath.add(childPath.get(0));
List<Edges> edges = new ArrayList<Edges>();
// Creating Edges for the Child Path
for(int i = 0; i < childPath.size() - 1; i++) {
int start = childPath.get(i);
int end = childPath.get(i + 1);
City here = map.Cities.get(start);
City there = map.Cities.get(end);
edges.add(new Edges(here, there, map.distances[start][end]));
}
// Finished new Child Tour
Tour child = new Tour(edges);
// Return the Child Tour
return child;
}
// Reproducing new Population with the Old Population
public Tour[] reproduce() {
// Making a new population
Tour[] newPop = new Tour[pop.length];
for(int i = 0; i < pop.length - 1; i += 2) {
// Random parent tours
Tour Daddy = randomParent();
Tour Mommy = randomParent();
// Making children for new population
newPop[i] = makeBebe(Daddy, Mommy);
newPop[i + 1] = makeBebe(Daddy, Mommy);
}
// Return the new population
return newPop;
}
// Mutation of a Tour
public Tour mutate(Tour t) {
// Get complete path of cities
Integer[] cities = t.giveCompletePath();
// Need a temp
Tour temp = t;
// Cycle through all the cities
for(int i = 1; i < cities.length - 1; i++) {
// Using Mutation Rate
if(Math.random() < mutationRate) {
// Changing the Tour
Tour changed = twoOptPath(temp);
// Is the Tour better now that it's changed?
if(changed.getDist() < temp.getDist()) {
// Make the new Temp Changed
temp = changed;
}
}
}
// Return the Mutated Tour
return temp;
}
// Gives the Average Tour
public double getAvgTour() {
double avg = 0;
for(int i = 0; i < pop.length; i++) {
avg += pop[i].getDist();
}
return avg / pop.length;
}
// Gives the Best Tour
public Tour bestTour() {
Tour bestPath = pop[0];
for(int i = 0; i < pop.length; i++) {
if(pop[i].getDist() < bestPath.getDist()) {
bestPath = pop[i];
}
}
return bestPath;
}
// Compute the Path
@Override
public Tour ComputePath() {
for(int i = 0; i < pop.length; i++) {
// Add a Random Tour to the Population
pop[i] = giveRandomTour();
}
// Cyclying through the amount we'd like to create
for(int i = 0; i < 1000001; i++) {
// Evaluate and Reproduce
evaluate();
pop = reproduce();
// Mutate the Population
for(int j = 0; j < pop.length; j++) {
pop[j] = mutate(pop[j]);
}
if(i % 1000 == 0) {
System.out.println(i);
System.out.println(getAvgTour());
}
if(i % 100000 == 0) {
System.out.println("<----------------------------------------->");
System.out.println(" THINKING ");
System.out.println("<----------------------------------------->");
}
}
// Returning the Best Tour
return bestTour();
}
}