-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.cpp
126 lines (97 loc) · 3.22 KB
/
main.cpp
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
#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <random>
#include <functional>
#include <math.h>
#include <tuple>
#include <map>
#include <limits>
#include <fstream>
// population
#define N 4
class Point {
std::tuple<int, int, double> _xy;
public:
Point() {}
Point(int x, int y) { _xy = std::make_tuple(x, y, func(x,y)); }
std::tuple<int, int, double> get() { return _xy; }
void setX(int x) { std::get<0>(_xy) += x; }
void setY(int y) { std::get<1>(_xy) += y; }
void setValue() { std::get<2>(_xy) = func(std::get<0>(_xy), std::get<1>(_xy)); }
double func(double x, double y) { return x / ((x * x) + 2 * (y * y) + 1); }
std::string print() { return "(" + std::to_string(std::get<0>(_xy)) + ", " + std::to_string(std::get<1>(_xy)) + ") = " + std::to_string(std::get<2>(_xy)); }
bool operator != (const Point& p) { return _xy != p._xy; }
bool operator == (const Point& p) { return _xy == p._xy; }
};
class Genetic {
std::vector<Point> _population;
public:
Genetic() {}
int rand(int from, int to) {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(from, to);
return dis(gen);
}
Point best() {
double f = -999999999;
Point bestValue;
size_t id = 0;
for (size_t i = 0; i < _population.size(); ++i) {
if (std::get<2>(_population[i].get()) > f) { bestValue = _population[i]; f = std::get<2>(_population[i].get()); id = i; }
}
_population.erase(_population.begin() + id);
return bestValue;
}
void delWorst() {
double f = 999999999;
size_t id = 0;
for (size_t i = 0; i < _population.size(); ++i)
if (std::get<2>(_population[i].get()) < f) { f = std::get<2>(_population[i].get()); id = i; }
_population.erase(_population.begin() + id);
}
void mutate(Point &p, int axis, int newValue) {
if (axis == 0) { p.setX(newValue); }
else { p.setY(newValue); }
p.setValue();
}
void mix(int range) {
delWorst();
Point bestUnit = best();
Point p1(std::get<0>(bestUnit.get()), std::get<1>( _population[0].get()));
Point p2(std::get<0>(bestUnit.get()), std::get<1>(_population[1].get()));
Point p3(std::get<0>( _population[0].get()), std::get<1>(bestUnit.get()));
Point p4 (std::get<0>(_population[1].get()), std::get<1>(bestUnit.get()));
Point arr[N] = { p1, p2, p3, p4 };
for (size_t i = 0; i < N; ++i) {
for (size_t j = i + 1; j < N; ++j)
if (arr[i] == arr[j]) mutate(arr[i], rand(0, 1), rand(-1, 1));
}
_population.clear();
for (size_t i = 0; i < N; i++)
_population.push_back(arr[i]);
}
void run(size_t iterLimit, int range) {
for (size_t i = 0; i < N; ++i)
_population.push_back(Point(rand(-range, range), rand(-range, range)));
std::ofstream resultsFile;
resultsFile.open("results.txt", std::ios_base::app);
size_t it = 0;
while (it < iterLimit) {
mix(range);
resultsFile << "== generation " << it << " ==" << std::endl;
for (auto el : _population)
resultsFile << el.print() << std::endl;
++it;
}
resultsFile.close();
}
};
int main() {
Genetic g;
g.run(1500, 500);
return EXIT_SUCCESS;
}