-
Notifications
You must be signed in to change notification settings - Fork 0
/
population.js
117 lines (93 loc) · 3.15 KB
/
population.js
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
class Population {
constructor() {
this.rockets = new Array(POPULATION_SIZE);
this.dnaCounter = 0;
}
generatePopulation() {
for (let i = 0; i < this.rockets.length; ++i) {
this.rockets[i] = new Rocket(CANVAS_WIDTH / 2, CANVAS_HEIGHT - 100);
}
}
setInitPositions() {
for (let i = 0; i < this.rockets.length; ++i) {
this.rockets[i].position.x = CANVAS_WIDTH / 2;
this.rockets[i].position.y = CANVAS_HEIGHT - 100;
}
}
calculateFitness() {
for (let i = 0; i < this.rockets.length; ++i) {
this.rockets[i].calculateFitness();
}
}
findMaxFitness() {
let maxFitness = 0;
for (let i = 0; i < this.rockets.length; ++i) {
if (this.rockets[i].fitness > maxFitness) {
maxFitness = this.rockets[i].fitness;
}
}
return maxFitness;
}
normalizeFitness() {
let maxFitness = this.findMaxFitness();
for(let i = 0; i < this.rockets.length; ++i) {
this.rockets[i].fitness /= float(maxFitness);
}
}
crossover(parent1, parent2) {
let child = new Rocket(0, 0);
//let middle = child.dna.genes.length / 2;
let middle = random(child.dna.genes.length);
for (let i = 0; i < child.dna.genes.length; ++i) {
if (i <= middle) {
child.dna.genes[i] = parent1.dna.genes[i];
} else {
child.dna.genes[i] = parent2.dna.genes[i];
}
// Mutation of 1%
if (random(1) <= MUTATION_RATE / 100.0) {
child.dna.genes[i] = p5.Vector.random2D();
}
}
return child;
}
generateNewPopulation() {
this.normalizeFitness();
let newPopulation = new Array(POPULATION_SIZE);
for (let i = 0; i < newPopulation.length; ++i) {
let parent1 = this.acceptReject();
let parent2 = this.acceptReject();
newPopulation[i] = this.crossover(parent1, parent2);
}
generationCounter++; // Global variable from main.js
this.rockets = newPopulation;
}
acceptReject() {
while (true) {
let index = floor(random(POPULATION_SIZE));
let r = random(1);
if (r <= this.rockets[index].fitness) {
return this.rockets[index];
}
}
}
tickAndDraw() {
for (let i = 0; i < this.rockets.length; ++i) {
this.rockets[i].applyForce(this.rockets[i].dna.genes[this.dnaCounter]);
if (this.dnaCounter == this.rockets[0].dna.genes.length) {
this.dnaCounter = 0;
this.calculateFitness();
this.generateNewPopulation();
this.setInitPositions();
if (numOfHits > bestNumOfHits) {
bestNumOfHits = numOfHits;
}
numOfHits = 0; // Global variable from main.js
break;
}
this.rockets[i].tick();
this.rockets[i].draw();
}
this.dnaCounter++;
}
};