-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMating.cpp
More file actions
128 lines (97 loc) · 3.99 KB
/
Mating.cpp
File metadata and controls
128 lines (97 loc) · 3.99 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
//
// Created by Vladimir on 23.05.2021.
//
#include "Mating.h"
Mating::Mating(double crossProbability, double mutationProbability) : crossProbability(crossProbability),
mutationProbability(mutationProbability) {}
double Mating::getCrossProbability() const {
return crossProbability;
}
void Mating::setCrossProbability(double crossProbability) {
Mating::crossProbability = crossProbability;
}
double Mating::getMutationProbability() const {
return mutationProbability;
}
void Mating::setMutationProbability(double mutationProbability) {
Mating::mutationProbability = mutationProbability;
}
Mating::Mating(double crossProbability, double mutationProbability,
const std::vector<crossFunction> &crossOperators,
const std::vector<mutationFunction> &mutationOperators) : crossProbability(
crossProbability), mutationProbability(mutationProbability), crossOperators(crossOperators), mutationOperators(
mutationOperators) {}
void Mating::add(crossFunction crossOperator) {
Mating::crossOperators.push_back(crossOperator);
}
void Mating::add(mutationFunction mutationOperator) {
Mating::mutationOperators.push_back(mutationOperator);
}
Generation *Mating::executeForAll(Generation *generation) {
int crossOperatorsAmount = Mating::crossOperators.size();
int mutationOperatorsAmount = Mating::mutationOperators.size();
Generation* result = new Generation(generation->getIndex());
if(!Mating::crossOperators.empty())
for(int i = 0; i < generation->size(); i++){
Chromosome* A = generation->get(i);
for(int j = i + 1; j < generation->size(); j++){
Chromosome* B = generation->get(j);
//pairing any couples from source set, by chance
if(A != B){
//random pairing
if(rand() % 1000 < Mating::crossProbability * 1000){
//random cross operator choice
result->add(
Mating::crossOperators.at(
rand() % crossOperatorsAmount
)(A, B)
);
}
}
}
}
//random mutation
if(!Mating::mutationOperators.empty())
for(Chromosome* A : result->getIndividuals()){
if(rand() % 1000 < Mating::mutationProbability * 1000){
Mating::mutationOperators.at(rand() % mutationOperatorsAmount)(A);
}
}
return result;
}
Generation *Mating::executeSingle(Generation *generation) {
if(generation->size() < 2) throw "MATING CALLED FOR GENERATION WITH LESS THAN 2 INDIVIDUALS";
int crossOperatorsAmount = Mating::crossOperators.size();
int mutationOperatorsAmount = Mating::mutationOperators.size();
std::tuple<Chromosome*, Chromosome*> pair = Breeding::selectRandomPair(generation);
Generation* result = generation->copy();
if(!Mating::crossOperators.empty()){
if(rand() % 1000 < Mating::crossProbability * 1000){
//random cross operator choice
result->add(
Mating::crossOperators.at(
rand() % crossOperatorsAmount
)(std::get<0>(pair), std::get<1>(pair))
);
}
}
//random mutation
if(!Mating::mutationOperators.empty())
for(Chromosome* A : result->getIndividuals()){
if(rand() % 1000 < Mating::mutationProbability * 1000){
if(A->getDecimal() >= 2)
Mating::mutationOperators.at(rand() % mutationOperatorsAmount)(A);
}
}
return result;
}
void Mating::add(std::vector<crossFunction> crossOperators) {
for(std::function<Generation *(Chromosome *, Chromosome *)> function : crossOperators){
Mating::add(function);
}
}
void Mating::add(std::vector<mutationFunction> mutationOperators) {
for(std::function<Chromosome *(Chromosome *)> function : mutationOperators){
Mating::add(function);
}
}