-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathPopulation.pde
More file actions
147 lines (105 loc) · 3.6 KB
/
Population.pde
File metadata and controls
147 lines (105 loc) · 3.6 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
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
// Akash Yadav
// @Hudson Lane, Delhi
// 26th June 18
// Genetic Algorithm, Evolving Images
// A class to describe a population of virtual organisms
// In this case, each organism is just an instance of a DNA object
class Population {
float mutationRate; // Mutation rate
DNA[] population; // Array to hold the current population
ArrayList<DNA> matingPool; // ArrayList which we will use for our "mating pool"
PImage target; // Target phrase
int generations; // Number of generations
boolean finished; // Are we finished evolving?
int perfectScore;
float bestScore;
Population(PImage p, float m, int num) {
target = p;
mutationRate = m;
population = new DNA[num];
bestScore = 0;
for (int i = 0; i < population.length; i++)
population[i] = new DNA(target);
calcFitness();
matingPool = new ArrayList<DNA>();
finished = false;
generations = 0;
perfectScore = 1;
}
// Fill our fitness array with a value for every member of the population
void calcFitness() {
for (int i = 0; i < population.length; i++)
population[i].fitness(target);
}
// Generate a mating pool
void naturalSelection() {
// Clear the ArrayList
matingPool.clear();
float maxFitness = 0;
for (int i = 0; i < population.length; i++)
if (population[i].fitness > maxFitness)
maxFitness = population[i].fitness;
// Based on fitness, each member will get added to the mating pool a certain number of times
// a higher fitness = more entries to mating pool = more likely to be picked as a parent
// a lower fitness = fewer entries to mating pool = less likely to be picked as a parent
for (int i = 0; i < population.length; i++) {
float fitness = map(population[i].fitness, 0, maxFitness, 0, 1);
int n = int(fitness * 100); // Arbitrary multiplier, we can also use monte carlo method and pick two random numbers
for (int j = 0; j < n; j++)
matingPool.add(population[i]);
}
}
// Create a new generation
void generate() {
// Refill the population with children from the mating pool
for (int i = 0; i < population.length; i++) {
int a = int(random(matingPool.size()));
int b = int(random(matingPool.size()));
DNA partnerA = matingPool.get(a);
DNA partnerB = matingPool.get(b);
DNA child = partnerA.crossover(partnerB);
child.mutate(mutationRate);
population[i] = child;
}
generations++;
}
// Compute the current "most fit" member of the population
PImage getBest() {
float worldrecord = 0.0;
int index = 0;
for (int i = 0; i < population.length; i++) {
if (population[i].fitness > worldrecord) {
index = i;
worldrecord = population[i].fitness;
}
}
if (worldrecord == perfectScore ) finished = true;
return population[index].getImage();
}
boolean finished() {
return finished;
}
int getGenerations() {
return generations;
}
// Compute average fitness for the population
float getAverageFitness() {
float total = 0;
for (int i = 0; i < population.length; i++)
total += population[i].fitness;
return total / (population.length);
}
float getBestFitness(){
float record = population[0].fitness;
for (int i = 0; i < population.length; i++)
if(population[i].fitness > record)
record = population[i].fitness;
return record;
}
float allTimeBest(){
float record = getBestFitness();
if(record > bestScore)
bestScore = record;
return bestScore;
}
}