-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathstart.cpp
More file actions
155 lines (129 loc) · 4.04 KB
/
start.cpp
File metadata and controls
155 lines (129 loc) · 4.04 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
148
149
150
151
152
153
154
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <algorithm>
#include <random>
#include <math.h>
#include <iostream>
using namespace std;
typedef long double HighlyPrecise;
const int GENOME_LENGTH = 16;
const int NUMBER_CHROMOSOMES = 1024;
const double GENE_MIN = -1;
const double GENE_MAX = +1;
const float MUTATION_FACTOR = 0.2;
const float CROSSOVER_RATE = 0.6;
const int NUM_EPOCHS = 1000;
default_random_engine generator;
uniform_real_distribution<HighlyPrecise> geneValueDistribution(GENE_MIN, GENE_MAX);
uniform_real_distribution<HighlyPrecise> mutationFactorDistribution(0.0, 1.0);
uniform_real_distribution<HighlyPrecise> mutationMultiplierDistribution(-0.1, 0.1);
class Chromosome {
HighlyPrecise genes[GENOME_LENGTH];
public:
Chromosome() {
for (int j = 0; j < GENOME_LENGTH; j++) {
genes[j] = geneValueDistribution(generator);
}
}
Chromosome(HighlyPrecise genes[]) {
memcpy(this->genes, genes, GENOME_LENGTH * sizeof(HighlyPrecise));
}
HighlyPrecise* getGenes() {
return genes;
}
/**
* The current fitness function is: Summation (x * x). It needs to be minimized.
*/
HighlyPrecise getFitnessValue() {
HighlyPrecise value = 0.0;
for (int i = 0; i < GENOME_LENGTH; i++) {
value += genes[i] * genes[i];
}
return value;
}
/**
* Takes two chromosomes and crosses the caller with the arguments and returns the offspring
* as a result.
*/
Chromosome crossover(Chromosome b) {
int mid = GENOME_LENGTH / 2;
HighlyPrecise offspringGenes[GENOME_LENGTH];
for (int i = 0; i < GENOME_LENGTH; i++) {
if (i <= mid) {
offspringGenes[i] = genes[i];
} else {
offspringGenes[i] = b.getGenes()[i];
}
}
Chromosome offspring(offspringGenes);
// if(offspring.getFitnessValue() == getFitnessValue() || offspring.getFitnessValue() == b.getFitnessValue()) {
// printf("Baccha on maa baap\n");
// } else {
// printf("NOT on maa baap\n");
// }
return Chromosome(offspringGenes);
}
void mutate() {
for (int i = 0; i < GENOME_LENGTH; i++) {
/* Random Multiplier between [-0.1 to 0.1) */
HighlyPrecise multiplier = mutationMultiplierDistribution(generator);
genes[i] *= multiplier;
if (multiplier < -0.1 || multiplier > 0.1) {
printf("Multiplier is wrong. %Le", multiplier);
}
}
}
/**
* Prints the chromosome and its fitness function.
*/
void print() {
printf("Chromosome: ");
for (int i = 0; i < GENOME_LENGTH; i++) {
printf("%Le ", genes[i]);
}
printf("\n\n=> Fitness: %Le\n", getFitnessValue());
}
};
bool fitnessComparator(Chromosome &a, Chromosome &b) {
return a.getFitnessValue() < b.getFitnessValue();
}
void startIteration(Chromosome population[]) {
int num_parents = (1.0 * NUMBER_CHROMOSOMES * (1 - CROSSOVER_RATE));
int num_offsprings = NUMBER_CHROMOSOMES - num_parents;
uniform_int_distribution<int> parentIndexDistribution(0, num_parents);
std::sort(population, population + NUMBER_CHROMOSOMES, fitnessComparator);
int offspringStartIndex = num_parents;
for (int i = offspringStartIndex; i < NUMBER_CHROMOSOMES; i++) {
int fatherIndex = parentIndexDistribution(generator);
int motherIndex = parentIndexDistribution(generator);
if (motherIndex == fatherIndex) {
// Should we? Because if we won't, there will be duplicate chromosomes.
// TODO: Second opinion needed.
continue;
}
Chromosome male = population[fatherIndex];
Chromosome female = population[motherIndex];
Chromosome offspring = male.crossover(female);
// if mutation factor is greater than a random number from (0.0 to 1.0).
if (MUTATION_FACTOR >= mutationFactorDistribution(generator)) {
offspring.mutate();
}
population[i] = offspring;
}
}
Chromosome geneticAlgorithm(Chromosome population[]) {
for (int z = 0; z < NUM_EPOCHS; z++) {
startIteration(population);
}
std::sort(population, population + NUMBER_CHROMOSOMES, fitnessComparator);
return population[0];
}
int main() {
Chromosome population[NUMBER_CHROMOSOMES];
// Start genetic algorithm.
Chromosome best = geneticAlgorithm(population);
printf("==== CPU Results ====\n");
best.print();
return 0;
}