-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMutation.cpp
More file actions
134 lines (112 loc) · 4.12 KB
/
Copy pathMutation.cpp
File metadata and controls
134 lines (112 loc) · 4.12 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
#include <cmath>
#include <iostream>
#include <stdexcept>
#include "Individual.h"
#include "Mutation.h"
#include "Random.h"
using namespace std;
SubtreeMutation::SubtreeMutation() : SubtreeMutation(0.0, FunctionSet(), TerminalSet())
{
}
SubtreeMutation::SubtreeMutation(const double& mutationProb, const FunctionSet& funcSet, const TerminalSet& termSet)
{
this->mutationProb = mutationProb;
this->termSet = termSet;
this->funcSet = funcSet;
}
void SubtreeMutation::mutate(Individual& individual, const int& maxDepth)
{
double seed = Random::randProb();
if (seed <= this->mutationProb) {
int mutNodeIdx = individual.pickRandomNodeIdx();
int mutNodeDepth = Individual::calculateDepthFromIdx(mutNodeIdx);
int treeDepth = individual.getMaxDepth();
int newDepthUpperbound = max(1, min(treeDepth + 3 - mutNodeDepth, maxDepth - mutNodeDepth));
int newDepth = Random::randInt(1, newDepthUpperbound);
if (newDepth <= 0) {
cout << "mutNodeIdx: " << mutNodeIdx
<< " mutNodeDepth: " << mutNodeDepth
<< " treeDepth: " << treeDepth
<< " newDepth: " << newDepth << endl;
throw invalid_argument("New Depth has to be greater than 1");
exit(1);
}
double seed2 = Random::randProb();
Individual subTree = (seed2 <= 0.25)
? Individual::generateRandomTreeFullMethod(newDepth, this->funcSet, this->termSet)
: Individual::generateRandomTreeGrowMethod(newDepth, this->funcSet, this->termSet);
individual.replaceNodeWithSubTree(subTree, mutNodeIdx, mutNodeDepth);
individual.validateTreeStructure();
individual.resetDagMap();
}
if (individual.getMaxDepth() > maxDepth) {
cout << "individual.getMaxDepth(): " << individual.getMaxDepth() << " maxDepth: " << maxDepth << endl;
throw invalid_argument("Depth is greater than max depth after subtree mutation");
exit(1);
}
}
void SubtreeMutation::setTerminalSet(TerminalSet termSet)
{
this->termSet = termSet;
}
NodeReplacementMutation::NodeReplacementMutation() : NodeReplacementMutation(0.0, FunctionSet(), TerminalSet())
{
}
NodeReplacementMutation::NodeReplacementMutation(const double& mutationProb, const FunctionSet& funcSet, const TerminalSet& termSet)
{
this->mutationProb = mutationProb;
this->termSet = termSet;
this->funcSet = funcSet;
}
void NodeReplacementMutation::setTerminalSet(TerminalSet termSet)
{
this->termSet = termSet;
}
void NodeReplacementMutation::mutate(Individual& individual, const int & maxDepth)
{
for (int i = 0; i <= individual.getLastNodeIdx(); i++) {
Node* current = individual.getNodeAt(i);
if (current != nullptr) {
double seed = Random::randProb();
if (seed <= this->mutationProb) {
if (current->isFunctionNode()) {
Function newFunc = this->funcSet.getRandomFunction();
FunctionNode* fnode = dynamic_cast<FunctionNode*>(current);
fnode->setFunc(newFunc);
}
else if (current->isTerminalNode()) {
Terminal newTerm = this->termSet.getRandomTerminal();
TerminalNode* tnode = dynamic_cast<TerminalNode*>(current);
// One more constant or one less constant
if (newTerm.isDataPoint() != tnode->getTerminalReference().isDataPoint())
individual.resetConstantTable();
tnode->setTerminal(newTerm);
}
else {
throw invalid_argument("Node isnt terminal neither func");
}
individual.resetDagMap();
}
}
}
individual.validateTreeStructure();
}
CombinedMutation::CombinedMutation(const double& nodeReplacementMutationProb, const double & subTreeMutationProb, const FunctionSet& funcSet, const TerminalSet& termSet)
{
this->mutationProb = mutationProb;
this->termSet = termSet;
this->funcSet = funcSet;
this->nodeReplacementMutation = NodeReplacementMutation(nodeReplacementMutationProb, funcSet, termSet);
this->subTreeMutation = SubtreeMutation(subTreeMutationProb, funcSet, termSet);
}
void CombinedMutation::mutate(Individual& individual, const int& maxDepth)
{
this->subTreeMutation.mutate(individual, maxDepth);
this->nodeReplacementMutation.mutate(individual, maxDepth);
}
void CombinedMutation::setTerminalSet(TerminalSet termSet)
{
this->termSet = termSet;
this->subTreeMutation.setTerminalSet(termSet);
this->nodeReplacementMutation.setTerminalSet(termSet);
}