-
Notifications
You must be signed in to change notification settings - Fork 0
/
GenAlg.pde
125 lines (103 loc) · 4.28 KB
/
GenAlg.pde
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
class GenAlg{
ArrayList<Car> prev;
ArrayList<Car> newPop;
ArrayList<Car> genPop(ArrayList<Car> prev){
//println("Creating new Generation");
this.prev = prev;
this.newPop = new ArrayList();
if(prev.isEmpty()){
// generate random population
for(int i = 0; i< Constants.popSize; i++){
//Create Location
PVector sLoc = Constants.start.copy();
//Create random Path
ArrayList<PVector> rPath = new ArrayList();
PVector pr = sLoc;
for(int k=0; k<Constants.pathSize; k++){
pr = new PVector(random(-Constants.pathRange, Constants.pathRange), random(-Constants.pathRange, Constants.pathRange));
rPath.add(pr);
}
//Create random car
//println("New car");
Car r = new Car(sLoc, rPath);
newPop.add(r);
}
}
else{
calcFitness();
//println("FITNESS: \n");
for(int i=0; i<prev.size(); i++){
//println(i+" : "+prev.get(i).getFitness());
}
mate();
}
return newPop;
}
void calcFitness(){
//println("Calculating fitness");
float sum = 0F;
float sumDist = 0F;
for(Car c: this.prev){
c.setFitness(1/ (pow(c.loc.dist(Constants.target), Constants.exponential)));
sum += c.getFitness();
sumDist += c.loc.dist(Constants.target);
}
println("Average Distance from Target : "+sumDist / Constants.popSize);
for(Car c: this.prev){
c.setFitness(map(c.getFitness(), 0, sum, 0, 1));
}
}
void mate(){
//println("mate()");
while(this.newPop.size() < Constants.popSize){
//println("Adding car");
Car p1 = getFitParent();
//print(" <3 ");
Car p2 = getFitParent();
//println();
if(p1.equals(p2)){
continue;
}
Car child = crossOver(p1, p2);
if(/*random(1) < Constants.mutationRate*/ true){
mutate(child);
}
this.newPop.add(child);
}
}
Car getFitParent(){
while(true){
int index = int(random(this.prev.size()));
float num = random(0, 1);
if(this.prev.get(index).getFitness() > num){
//print(index);
return this.prev.get(index);
}
}
}
Car crossOver(Car p1, Car p2){
ArrayList<PVector> path = new ArrayList();
//int midPoint = int(random(Constants.pathSize)); //Not really the middle - just the place in which the genes are split.
int midPoint = round(Constants.pathSize / 2);
for(int i=0; i<midPoint; i++){
path.add(p1.getPath().get(i).copy());
}
for(int k=midPoint; k<Constants.pathSize; k++){
path.add(p2.getPath().get(k).copy());
}
//println("parent1: "+p1.targets);
//println("parent2: "+p2.targets);
//println("child: "+new Car(Constants.start.copy(), path).targets);
return new Car(Constants.start.copy(), path);
}
void mutate(Car car){
for(int j=0; j<car.getPath().size(); j++){
if(random(1) < 0.1){
//println("Mutating child");
car.getPath().set(j, new PVector((int)random(-Constants.pathRange, Constants.pathRange), (int)random(-Constants.pathRange, Constants.pathRange)));
}
}
car.targets = car.getTargets(Constants.start.copy());
//println("After mutation: "+ car.targets);
}
}