/
Sperm.pde
124 lines (111 loc) · 2.8 KB
/
Sperm.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
class Sperm {
int size;
Spermatozoid[] S;
float fitnessSum;
Spermatozoid bestSpermatozoid = new Spermatozoid();
Sperm() {
size = 200;
S = new Spermatozoid[size];
for( int i = 0; i < size; i++) {
S[i] = new Spermatozoid();
}
}
Sperm( int s) {
size = s;
S = new Spermatozoid[size];
for( int i = 0; i < size; i++) {
S[i] = new Spermatozoid();
}
}
//Draw the Sperm on the screen
void show() {
for( int i = 1; i < size; i++) {
S[i].show(255);
}
S[0].show(#00FF00);
}
//Move the Sperm
void update( Egg E) {
for( int i = 0; i < size; i++) {
S[i].update(E);
}
}
//if all Spermatozoids are dead
boolean allSpermDead() {
for( int i = 0; i < size; i++) {
if( !(S[i].dead)) {
return false;
}
}
return true;
}
//Success rate : reaching the egg
int successRate() {
int successRate = 0;
for( int i = 0; i < size; i++) {
if( S[i].reachedEgg) {
successRate++;
}
}
return successRate;
}
//Calculate Fitness of every Spermatozoid
void calculateFitness(Egg E) {
float bestFitness = 0;
for (int i = 0; i< size; i++) {
S[i].calculateFitness(E);
if ( S[i].fitness > bestFitness) {
bestFitness = S[i].fitness;
bestSpermatozoid = S[i];
}
}
}
//Self-explanatory
void calculateFitnessSum() {
fitnessSum = 0;
for (int i = 0; i< size; i++) {
fitnessSum = fitnessSum + S[i].fitness;
}
}
/*chooses a spermatozoid from the population to return
randomly(considering fitness) : this function
works by randomly choosing a value between 0
and the sum of all the fitnesses
then goes through all the spermatozoids and adds
their fitness to a running sum and if that
sum is greater than the random value generated
that spermatozoid is chosen. Since spermatozoids with a higher
fitness function add more to the running sum
they have a higher chance of being chosen*/
Spermatozoid selectParent() {
float rand = random(fitnessSum);
float runningSum = 0;
for (int i = 0; i < size; i++) {
runningSum += S[i].fitness;
if (runningSum > rand) {
return S[i];
}
}
//should never get to this point
return null;
}
//Natural selection
void naturalSelection(){
calculateFitnessSum();
Spermatozoid[] SNew = new Spermatozoid[size];
for( int i = 0; i < size; i++) {
SNew[i] = new Spermatozoid();
SNew[i].B = selectParent().B.clone();
}
S = SNew;
}
//Mutation
void mutation( float mutationRate) {
for( int i = 0; i < size; i++) {
S[i].B.mutate(mutationRate);
}
//keep the brain of the best Spermatozoid
//unchanged to avoid negative evolution
S[0].B = bestSpermatozoid.B.clone();
}
}