-
Notifications
You must be signed in to change notification settings - Fork 0
/
gauss_specimen.h
90 lines (72 loc) · 2.39 KB
/
gauss_specimen.h
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
#pragma once
#include <string>
#include <random>
static const size_t NUM_GAUSS_PARAMS = 3;
static const std::vector<double> x = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
static const std::vector<double> y = {0, 1, 3, 9, 11, 8, 4, 2, 1, 0};
class GaussSpecimen {
public:
GaussSpecimen() : GaussSpecimen(random_genes()) {}
void update_fitness() {
std::vector<double> inten = gauss(x, genes[0], genes[1], genes[2]);
double sum_of_sq_error = 0;
for (size_t i = 0; i < inten.size(); i++) {
double diff = inten[i] - y[i];
sum_of_sq_error += diff * diff;
}
fitness = sum_of_sq_error;
}
bool is_ideal() const {
return fitness == 0;
}
GaussSpecimen child_with(const GaussSpecimen& other_parent) const {
size_t num_genes = genes.size();
size_t spos = rand() % num_genes;
std::vector<double> child_genes(num_genes);
for (size_t i = 0; i < spos; i++) {
child_genes[i] = genes[i];
}
for (size_t i = spos; i < num_genes; i++) {
child_genes[i] = other_parent.genes[i];
}
return GaussSpecimen(child_genes);
}
void mutate() {
size_t i = rand() % genes.size();
static std::default_random_engine generator;
static std::uniform_real_distribution<double> distribution(-1.1, 1.1);
genes[i] *= distribution(generator);
}
bool operator<(const GaussSpecimen& other) {
return this->fitness < other.fitness;
}
std::string to_s() const {
return "{" + std::to_string(genes[0]) + ", " + std::to_string(genes[1]) + ", " + std::to_string(genes[2]) + "}" + " (" + std::to_string(fitness) + ")";
}
private:
std::vector<double> genes;
double fitness;
GaussSpecimen(const std::vector<double>& genes) : genes(genes) {}
static std::vector<double> random_genes() {
std::vector<double> s;
for (int j = 0; j < NUM_GAUSS_PARAMS; j++) {
s.push_back(random_gene());
}
return s;
}
static double random_gene() {
static std::default_random_engine generator;
static std::uniform_real_distribution<double> distribution(-1e6, 1e6);
return distribution(generator);
}
static double gauss(double t, double a, double b, double c) {
return a * std::exp(-0.5 * std::pow((t - b) / c, 2));
}
static std::vector<double> gauss(const std::vector<double>& t, double a, double b, double c) {
std::vector<double> ret;
for (double x : t) {
ret.push_back(gauss(x, a, b, c));
}
return ret;
}
};