ECF 1.7
AlgGEP.cpp
1#include "AlgGEP.h"
2
3
4AlgGEP::AlgGEP()
5{
6 name_ = "GEP";
7 selFitPropOp = (SelFitnessProportionalOpP)(new SelFitnessProportionalOp);
8 selBestOp = (SelBestOpP)(new SelBestOp);
9 selRandomOp = (SelRandomOpP)(new SelRandomOp);
10}
11
13{
14 registerParameter(state, "crxprob", (voidP) new double(0.5), ECF::DOUBLE, "crossover rate");
15 registerParameter(state, "selpressure", (voidP) new double(10), ECF::DOUBLE,
16 "selection pressure: how much is the best individual 'better' than the worst");
17 registerParameter(state, "inv.prob", (voidP) new double(0.1), ECF::DOUBLE, "inversion rate");
18 registerParameter(state, "erc.inv.prob", (voidP) new double(0.1), ECF::DOUBLE, "ERC inversion rate");
19 registerParameter(state, "trans.is.prob", (voidP) new double(0.1), ECF::DOUBLE, "IS transposition rate");
20 registerParameter(state, "trans.ris.prob", (voidP) new double(0.1), ECF::DOUBLE, "RIS transposition rate");
21 registerParameter(state, "trans.gene.prob", (voidP) new double(0.1), ECF::DOUBLE, "gene transposition rate");
22 registerParameter(state, "trans.erc.prob", (voidP) new double(0.1), ECF::DOUBLE, "ERC transposition rate");
23 registerParameter(state, "trans.max.length", (voidP) new double(3), ECF::DOUBLE, "maximum length of the transposition sequence");
24 registerParameter(state, "inv.max.length", (voidP) new double(3), ECF::DOUBLE, "maximum length of the inversion sequence");
25}
26
27bool AlgGEP::initialize(StateP state)
28{
29 selFitPropOp->initialize(state);
30 selFitPropOp->setSelPressure(10);
31 selBestOp->initialize(state);
32 selRandomOp->initialize(state);
33
34 voidP crRateP = getParameterValue(state, "crxprob");
35 crxRate_ = *((double*)crRateP.get());
36
37 voidP selPressP = getParameterValue(state, "selpressure");
38 selPressure_ = *((double*)selPressP.get());
39 selFitPropOp->setSelPressure(selPressure_);
40
41 voidP invRateP = getParameterValue(state, "inv.prob");
42 invRate_ = *((double*)invRateP.get());
43
44 invRateP = getParameterValue(state, "erc.inv.prob");
45 invDcRate_ = *((double*)invRateP.get());
46
47 invRateP = getParameterValue(state, "inv.max.length");
48 invMaxLength_ = *((double*)invRateP.get());
49
50 voidP transRateP = getParameterValue(state, "trans.is.prob");
51 transISRate_ = *((double*)transRateP.get());
52
53 transRateP = getParameterValue(state, "trans.ris.prob");
54 transRISRate_ = *((double*)transRateP.get());
55
56 transRateP = getParameterValue(state, "trans.gene.prob");
57 transGeneRate_ = *((double*)transRateP.get());
58
59 transRateP = getParameterValue(state, "trans.erc.prob");
60 transDcRate_ = *((double*)transRateP.get());
61
62 transRateP = getParameterValue(state, "trans.max.length");
63 transMaxLength_ = *((double*)transRateP.get());
64
65 GEPChromosomeP gen(new GEP::GEPChromosome);
66 if (state->getGenotypes()[0]->getName() != gen->getName()){
67 ECF_LOG_ERROR(state, "Error: this algorithm accepts only a single GEPChromosome genotype.");
68 throw("");
69 }
70
71 return true;
72}
73
74bool AlgGEP::advanceGeneration(StateP state, DemeP deme)
75{
76 // elitism: copy current best individual
77 IndividualP best = selBestOp->select(*deme);
78 best = copy(best);
79
80 // select individuals
81 std::vector<IndividualP> wheel;
82 wheel = selFitPropOp->selectMany(*deme, (uint)deme->size());
83
84 // copy selected to new population
85 for (uint i = 0; i < wheel.size(); ++i)
86 wheel[i] = copy(wheel[i]);
87
88 // replace old population
89 for (uint i = 0; i < deme->size(); i++)
90 replaceWith((*deme)[i], wheel[i]);
91
92 ECF_LOG(state, 5, "Selected individuals:");
93 for (uint i = 0; i < deme->size(); i++){
94 ECF_LOG(state, 5, dbl2str(deme->at(i)->fitness->getValue()));
95 }
96
97 // determine the number of crx operations
98 uint noCrx = (int)(deme->size() * crxRate_ / 2);
99
100 // perform crossover
101 for (uint i = 0; i < noCrx; i++){
102
103 // select parents
104 IndividualP parent1 = selRandomOp->select(*deme);
105 IndividualP parent2 = selRandomOp->select(*deme);
106 ECF_LOG(state, 5, "Parents: " + dbl2str(parent1->fitness->getValue()) + ", " + dbl2str(parent2->fitness->getValue()));
107
108 // create children
109 IndividualP child1 = copy(parent1);
110 IndividualP child2 = copy(parent2);
111
112 // perform crx operations
113 mate(parent1, parent2, child1);
114 mate(parent1, parent2, child2);
115
116 // replace parents with children
117 replaceWith(parent1, child1);
118 replaceWith(parent2, child2);
119 }
120
121 // perform mutation on whole population
122 mutate(*deme);
123
124 // perform inversion on population
125 invert(state, *deme);
126 invertDc(state, *deme);
127 // perform transposition on population
128 transpose(state, *deme);
129 // evaluate new individuals
130 for (uint i = 0; i < deme->size(); i++)
131 if (!deme->at(i)->fitness->isValid()) {
132 evaluate(deme->at(i));
133 }
134
135 // elitism: preserve best individual
136 IndividualP random = selRandomOp->select(*deme);
137 if (best->fitness->isBetterThan(random->fitness))
138 replaceWith(random, best);
139
140 return true;
141}
142
143void AlgGEP::invert(StateP state, const std::vector<IndividualP>& pool)
144{
145 for (uint i = 0; i < pool.size(); i++) {
146 if (state_->getRandomizer()->getRandomDouble() <= invRate_) {
147 // invert the i-th individual
148 ECF_LOG(state, 5, "Inverting individual: \n" + pool.at(i)->toString());
149 // first, choose a random gene in the individual
150 GEPChromosomeP individual = std::static_pointer_cast<GEP::GEPChromosome> (pool.at(i)->getGenotype());
151 pool.at(i)->fitness->setInvalid();
152 uint invGene = state_->getRandomizer()->getRandomInteger(individual->genes);
153 uint geneOffset = invGene * (individual->geneLength);
154
155 // next, choose two random points in the head area
156 uint bitInv = state_->getRandomizer()->getRandomInteger(individual->headLength);
157 uint bitInvSecond, tmp;
158 do
159 {
160 bitInvSecond = state_->getRandomizer()->getRandomInteger(individual->headLength);
161 } while (bitInv == bitInvSecond);
162
163 if (bitInv>bitInvSecond)
164 {
165 tmp = bitInv;
166 bitInv = bitInvSecond;
167 bitInvSecond = tmp;
168 }
169 // shorten the sequence to the specified maximum length
170 if (bitInvSecond - bitInv >= invMaxLength_){
171 bitInvSecond = bitInv + (uint) invMaxLength_ - 1;
172 }
173
174 ECF_LOG(state, 5, "Inverting the sequence in gene ["+uint2str(invGene)+"] from point (" + uint2str(bitInv) + ") to point (" + uint2str(bitInvSecond) + ")");
175 // copy the selected sequence in reverse order
176 std::vector<Tree::NodeP> seq;
177 for (int j = (geneOffset + bitInvSecond); j >= (int) (geneOffset + bitInv); j--){
178 seq.push_back(static_cast<Tree::NodeP>(new Tree::Node(individual->at(j))));
179 }
180 // replace the original sequence with its inversion
181 uint seqIdx = 0;
182 for (uint j = (geneOffset + bitInv); j <= (geneOffset + bitInvSecond); j++){
183 individual->at(j) = static_cast<Tree::NodeP>(new Tree::Node(seq.at(seqIdx++)));
184 }
185 ECF_LOG(state, 5, "Inverted individual: \n" + pool[i]->toString());
186 }
187
188 }
189}
190
191void AlgGEP::invertDc(StateP state, const std::vector<IndividualP>& pool)
192{
193 // Do a test and check whether the Dc domain actually exists
194 GEPChromosomeP test = std::static_pointer_cast<GEP::GEPChromosome> (pool.at(0)->getGenotype());
195 if (test->dcLength < 1){
196 ECF_LOG(state, 5, "ERCs not used in the cromosome. Dc inversion aborted.");
197 return; // Do nothing if ERCs are not used
198 }
199 for (uint i = 0; i < pool.size(); i++) {
200 if (state_->getRandomizer()->getRandomDouble() <= invDcRate_) {
201 // invert the i-th individual
202 pool.at(i)->fitness->setInvalid();
203 ECF_LOG(state, 5, "Inverting ERCs of individual: \n" + pool.at(i)->toString());
204 // first, choose a random gene in the individual
205 GEPChromosomeP individual = std::static_pointer_cast<GEP::GEPChromosome> (pool.at(i)->getGenotype());
206 uint invGene = state_->getRandomizer()->getRandomInteger(individual->genes);
207 uint geneOffset = invGene * (individual->geneLength);
208 uint dcStart = geneOffset + individual->headLength + individual->tailLength;
209
210 // next, choose two random points in the Dc tail area
211 uint bitInv = state_->getRandomizer()->getRandomInteger(individual->dcLength);
212 uint bitInvSecond, tmp;
213 do
214 {
215 bitInvSecond = state_->getRandomizer()->getRandomInteger(individual->dcLength);
216 } while (bitInv == bitInvSecond);
217
218 if (bitInv>bitInvSecond)
219 {
220 tmp = bitInv;
221 bitInv = bitInvSecond;
222 bitInvSecond = tmp;
223 }
224 // shorten the sequence to the specified maximum length
225 if (bitInvSecond - bitInv >= invMaxLength_){
226 bitInvSecond = bitInv + (uint)invMaxLength_ - 1;
227 }
228
229 ECF_LOG(state, 5, "Inverting the sequence in gene [" + uint2str(invGene) + "] from point (" + uint2str(bitInv) + ") to point (" + uint2str(bitInvSecond) + ")");
230 // copy the selected sequence in reverse order
231 std::vector<Tree::NodeP> seq;
232 for (int j = (dcStart + bitInvSecond); j >= (int)(dcStart + bitInv); j--){
233 seq.push_back(static_cast<Tree::NodeP>(new Tree::Node(individual->at(j))));
234 }
235 // replace the original sequence with its inversion
236 uint seqIdx = 0;
237 for (uint j = (dcStart + bitInv); j <= (dcStart + bitInvSecond); j++){
238 individual->at(j) = static_cast<Tree::NodeP>(new Tree::Node(seq.at(seqIdx++)));
239 }
240 ECF_LOG(state, 5, "Inverted individual: \n" + pool[i]->toString());
241 }
242
243 }
244}
245
246void AlgGEP::transpose(StateP state, const std::vector<IndividualP>& pool)
247{
248 if(transISRate_ > 0) transposeIS(state, pool);
249 if(transRISRate_ > 0) transposeRIS(state, pool);
250 if(transGeneRate_ > 0) transposeGene(state, pool);
251 if (transDcRate_ > 0) transposeDc(state, pool);
252
253}
254
255void AlgGEP::transposeIS(StateP state, const std::vector<IndividualP>& pool)
256{
257 for (uint i = 0; i < pool.size(); i++) {
258 if (state_->getRandomizer()->getRandomDouble() <= transISRate_) {
259 ECF_LOG(state, 5, "Transposing individual using IS transposition: \n" + pool.at(i)->toString());
260 pool.at(i)->fitness->setInvalid();
261 // first, choose a random gene in the individual
262 GEPChromosomeP individual = std::static_pointer_cast<GEP::GEPChromosome> (pool.at(i)->getGenotype());
263 uint invGene = state_->getRandomizer()->getRandomInteger(individual->genes);
264 uint geneOffset = invGene * (individual->geneLength);
265
266 // next, choose two random points in the gene which delimit the copied sequence
267 uint bitSeq = state_->getRandomizer()->getRandomInteger(individual->headLength+individual->tailLength);
268 uint bitSeqSecond, tmp;
269 do
270 {
271 bitSeqSecond = state_->getRandomizer()->getRandomInteger(individual->headLength+individual->tailLength);
272 } while (bitSeq == bitSeqSecond);
273
274 if (bitSeq > bitSeqSecond)
275 {
276 tmp = bitSeq;
277 bitSeq = bitSeqSecond;
278 bitSeqSecond = tmp;
279 }
280
281 // shorten the sequence to the specified maximum length
282 if (bitSeqSecond - bitSeq >= transMaxLength_){
283 bitSeqSecond = bitSeq + (uint) transMaxLength_ - 1;
284 }
285
286
287 // next, choose the random point in the head area in which the sequence will be inserted (root excluded)
288 uint bitPos = state_->getRandomizer()->getRandomInteger(1, individual->headLength - 1);
289 ECF_LOG(state, 5, "Transposing the sequence in gene [" + uint2str(invGene) + "] from point (" + uint2str(bitSeq) + ") to point (" + uint2str(bitSeqSecond) + ") into position (" + uint2str(bitPos) + ")");
290
291 // make a copy of the entire gene
292 std::vector<Tree::NodeP> seq;
293 for (uint j = geneOffset; j < (geneOffset + individual->headLength + individual->tailLength); j++){
294 seq.push_back(static_cast<Tree::NodeP>(new Tree::Node(individual->at(j))));
295 }
296 // replace the original sequence first with the transposon
297 uint seqIdx = bitSeq;
298 uint r;
299 for (r = (geneOffset+bitPos); r <= (geneOffset+bitPos+bitSeqSecond-bitSeq) && r < (geneOffset+individual->headLength); r++){
300 individual->at(r) = static_cast<Tree::NodeP>(new Tree::Node(seq.at(seqIdx++)));
301 }
302 // now, copy the original elements from the transposition point until the end of the head
303 seqIdx = bitPos;
304 for (; r < (geneOffset+individual->headLength); r++){
305 individual->at(r) = static_cast<Tree::NodeP>(new Tree::Node(seq.at(seqIdx++)));
306 }
307 ECF_LOG(state, 5, "Transposed individual: \n" + pool[i]->toString());
308 }
309 }
310}
311
312void AlgGEP::transposeRIS(StateP state, const std::vector<IndividualP>& pool)
313{
314 for (uint i = 0; i < pool.size(); i++) {
315 if (state_->getRandomizer()->getRandomDouble() <= transRISRate_) {
316 ECF_LOG(state, 5, "Transposing individual using RIS transposition: \n" + pool.at(i)->toString());
317 // first, choose a random gene in the individual
318 GEPChromosomeP individual = std::static_pointer_cast<GEP::GEPChromosome> (pool.at(i)->getGenotype());
319 uint invGene = state_->getRandomizer()->getRandomInteger(individual->genes);
320 uint geneOffset = invGene * (individual->geneLength);
321
322 // next, choose a random point in the head and scan until a function is found or the end of the head is reached
323 uint bitSeq = state_->getRandomizer()->getRandomInteger(1, individual->headLength-1);
324 while (bitSeq < individual->headLength && !(individual->primitiveSet_->getFunctionByName(individual->at(bitSeq)->primitive_->getName()))){
325 bitSeq++;
326 }
327 // do nothing if no function found
328 if (bitSeq >= individual->headLength){
329 ECF_LOG(state, 5, "No function nodes found. Transposition aborted.");
330 continue;
331 }
332 pool.at(i)->fitness->setInvalid();
333 // randomly choose a point between the first one and the end of the gene
334 uint bitSeqSecond, tmp;
335 do
336 {
337 bitSeqSecond = state_->getRandomizer()->getRandomInteger(bitSeq,individual->headLength+individual->tailLength - 1);
338 } while (bitSeq == bitSeqSecond);
339
340 if (bitSeq > bitSeqSecond)
341 {
342 tmp = bitSeq;
343 bitSeq = bitSeqSecond;
344 bitSeqSecond = tmp;
345 }
346
347 // shorten the sequence to the specified maximum length
348 if (bitSeqSecond - bitSeq >= transMaxLength_){
349 bitSeqSecond = bitSeq + (uint) transMaxLength_ - 1;
350 }
351
352 // transpose to the root
353 ECF_LOG(state, 5, "Transposing the sequence in gene [" + uint2str(invGene) + "] from point (" + uint2str(bitSeq) + ") to point (" + uint2str(bitSeqSecond) + ") into root");
354
355 // make a copy of the entire gene
356 std::vector<Tree::NodeP> seq;
357 for (uint j = geneOffset; j < (geneOffset + individual->headLength + individual->tailLength); j++){
358 seq.push_back(static_cast<Tree::NodeP>(new Tree::Node(individual->at(j))));
359 }
360 // replace the original sequence first with the transposon
361 uint seqIdx = bitSeq;
362 uint r;
363 for (r = geneOffset; r <= (geneOffset + bitSeqSecond - bitSeq) && r < (geneOffset + individual->headLength); r++){
364 individual->at(r) = static_cast<Tree::NodeP>(new Tree::Node(seq.at(seqIdx++)));
365 }
366 // now, copy the original elements from the transposition point until the end of the head
367 seqIdx = 0;
368 for (; r < (geneOffset + individual->headLength); r++){
369 individual->at(r) = static_cast<Tree::NodeP>(new Tree::Node(seq.at(seqIdx++)));
370 }
371 ECF_LOG(state, 5, "Transposed individual: \n" + pool[i]->toString());
372 }
373 }
374}
375
376void AlgGEP::transposeGene(StateP state, const std::vector<IndividualP>& pool)
377{
378 for (uint i = 0; i < pool.size(); i++) {
379 if (state_->getRandomizer()->getRandomDouble() <= transGeneRate_) {
380 ECF_LOG(state, 5, "Transposing individual using gene transposition: \n" + pool.at(i)->toString());
381 // first, choose a random gene in the individual
382 GEPChromosomeP individual = std::static_pointer_cast<GEP::GEPChromosome> (pool.at(i)->getGenotype());
383 if (individual->genes == 1){
384 ECF_LOG(state, 5, "Gene transposition failed: genotype consists of one gene");
385 return;
386 }
387 pool.at(i)->fitness->setInvalid();
388 uint invGene = state_->getRandomizer()->getRandomInteger(1,individual->genes-1);
389 uint geneOffset = invGene * (individual->geneLength);
390
391 ECF_LOG(state, 5, "Transposing gene (" + uint2str(invGene)+") to head");
392
393 // make separate copies of the transposon gene and the rest of the chromosome
394 std::vector<Tree::NodeP> seq, copy;
395 for (uint j = 0; j < individual->size(); j++){
396 if (j >= geneOffset && j < (geneOffset + individual->geneLength))
397 seq.push_back(static_cast<Tree::NodeP>(new Tree::Node(individual->at(j))));
398 else
399 copy.push_back(static_cast<Tree::NodeP>(new Tree::Node(individual->at(j))));
400 }
401 // replace the original sequence first with the transposon
402 uint copyIdx = 0;
403 individual->clear();
404 for (uint r = 0; r < seq.size(); r++){
405 individual->push_back(static_cast<Tree::NodeP>(new Tree::Node(seq.at(r))));
406 }
407 // now, copy the rest of the original elements
408 for (uint r = 0; r < copy.size(); r++){
409 individual->push_back(static_cast<Tree::NodeP>(new Tree::Node(copy.at(r))));
410 }
411 ECF_LOG(state, 5, "Transposed individual: \n" + pool[i]->toString());
412 std::vector<int> x;
413 }
414 }
415}
416
417void AlgGEP::transposeDc(StateP state, const std::vector<IndividualP>& pool)
418{
419 // Do a test and check whether the Dc domain actually exists
420 GEPChromosomeP test = std::static_pointer_cast<GEP::GEPChromosome> (pool.at(0)->getGenotype());
421 if (test->dcLength < 1){
422 ECF_LOG(state, 5, "ERCs not used in the chromosome. Dc transposition aborted.");
423 return; // Do nothing if ERCs are not used
424 }
425 for (uint i = 0; i < pool.size(); i++) {
426 if (state_->getRandomizer()->getRandomDouble() <= transDcRate_) {
427 pool.at(i)->fitness->setInvalid();
428 ECF_LOG(state, 5, "Transposing the constant domain: \n" + pool.at(i)->toString());
429 // first, choose a random gene in the individual
430 GEPChromosomeP individual = std::static_pointer_cast<GEP::GEPChromosome> (pool.at(i)->getGenotype());
431 uint invGene = state_->getRandomizer()->getRandomInteger(individual->genes);
432 uint geneOffset = invGene * (individual->geneLength);
433 uint dcStart = geneOffset + individual->headLength + individual->tailLength;
434 // next, choose two random points in the gene which delimit the copied sequence
435 uint bitSeq = state_->getRandomizer()->getRandomInteger(individual->dcLength);
436 uint bitSeqSecond, tmp;
437 do
438 {
439 bitSeqSecond = state_->getRandomizer()->getRandomInteger(individual->dcLength);
440 } while (bitSeq == bitSeqSecond);
441
442 if (bitSeq > bitSeqSecond)
443 {
444 tmp = bitSeq;
445 bitSeq = bitSeqSecond;
446 bitSeqSecond = tmp;
447 }
448
449 // shorten the sequence to the specified maximum length
450 if (bitSeqSecond - bitSeq >= transMaxLength_){
451 bitSeqSecond = bitSeq + (uint)transMaxLength_ - 1;
452 }
453
454 // next, choose the random point in the ERC area in which the sequence will be inserted
455 uint bitPos = state_->getRandomizer()->getRandomInteger(individual->dcLength);
456 ECF_LOG(state, 5, "Transposing the sequence in gene [" + uint2str(invGene) + "] from point (" + uint2str(bitSeq) + ") to point (" + uint2str(bitSeqSecond) + ") into position (" + uint2str(bitPos) + ")");
457
458 // make a copy of the entire Dc tail
459 std::vector<Tree::NodeP> seq;
460 for (uint j = dcStart; j < (dcStart + individual->dcLength); j++){
461 seq.push_back(static_cast<Tree::NodeP>(new Tree::Node(individual->at(j))));
462 }
463 // replace the original sequence first with the transposon
464 uint seqIdx = bitSeq;
465 uint r;
466 for (r = (dcStart + bitPos); r <= (dcStart + bitPos + bitSeqSecond - bitSeq) && r < (dcStart + individual->dcLength); r++){
467 individual->at(r) = static_cast<Tree::NodeP>(new Tree::Node(seq.at(seqIdx++)));
468 }
469 // now, copy the original elements from the transposition point until the end of the Dc tail
470 seqIdx = bitPos;
471 for (; r < (dcStart + individual->dcLength); r++){
472 individual->at(r) = static_cast<Tree::NodeP>(new Tree::Node(seq.at(seqIdx++)));
473 }
474 ECF_LOG(state, 5, "Transposed individual: \n" + pool[i]->toString());
475 }
476 }
477}
void registerParameters(StateP state)
Register algorithm's parameters (if any).
Definition AlgGEP.cpp:12
bool advanceGeneration(StateP state, DemeP deme)
Perform a single generation on a single deme.
Definition AlgGEP.cpp:74
double crxRate_
crossover rate
Definition AlgGEP.h:50
double transRISRate_
RIS transposition rate.
Definition AlgGEP.h:56
double transGeneRate_
gene transposition rate
Definition AlgGEP.h:57
double invRate_
inversion rate
Definition AlgGEP.h:52
double invMaxLength_
inversion maximum sequence length
Definition AlgGEP.h:54
double invDcRate_
Constant domain inversion rate.
Definition AlgGEP.h:53
bool initialize(StateP state)
Initialize the algorithm, read parameters from the system, do a sanity check.
Definition AlgGEP.cpp:27
double transMaxLength_
maximum sequence transposition length
Definition AlgGEP.h:59
double selPressure_
selection pressure
Definition AlgGEP.h:51
double transDcRate_
constant domain transposition rate
Definition AlgGEP.h:58
double transISRate_
IS transposition rate.
Definition AlgGEP.h:55
uint mutate(const std::vector< IndividualP > &pool)
Helper function: send a vector of individuals to mutation.
Definition Algorithm.h:169
IndividualP copy(IndividualP source)
Helper function: make a copy of an individual.
Definition Algorithm.h:291
std::string name_
algorithm name
Definition Algorithm.h:23
bool registerParameter(StateP state, std::string name, voidP value, enum ECF::type T, std::string description="")
Helper function: register a single parameter with the system.
Definition Algorithm.h:35
voidP getParameterValue(StateP state, std::string name)
Helper function: get parameter value from the system.
Definition Algorithm.h:46
bool mate(IndividualP p1, IndividualP p2, IndividualP child)
Helper function: crossover two individuals.
Definition Algorithm.h:285
void replaceWith(IndividualP oldInd, IndividualP newInd)
Helper function: replace an individual in current deme.
Definition Algorithm.h:187
void evaluate(IndividualP ind)
Helper function: evaluate an individual.
Definition Algorithm.h:157
GEPChromosome class - implements genotype as a Gene Expression Programming chromosome.