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
|
//
// Copyright (C) 2020 Gareth Jones, Glysade LLC
//
// @@ All Rights Reserved @@
// This file is part of the RDKit.
// The contents are covered by the terms of the BSD license
// which is included in the file license.txt, found at the root
// of the RDKit source tree.
//
#include "StringChromosome.h"
namespace GapeGa {
/**
* A decode to integer function for binary string chromosomes
*
* @param start
* @param nBits
* @return
*/
int StringChromosome<bool, BinaryStringChromosomePolicy>::decodeToInt(
int start, int nBits) const {
assert(length >= (start + nBits));
int mask = 1, result = 0;
bool *ptr = string.get() + start;
for (int i = 0; i < nBits; i++, mask <<= 1) {
if (*ptr++) {
result |= mask;
}
}
return result;
}
/**
* Performs full mixing. Assumes that the strings primarily comprise dummy
* values. The children then comprise all non dummy values from the parents.
* Where both parents have non-dummy values set at the same position child1
* takes the value from parent1 and child2 takes the value from parent2.
* @param parent2
* @param child1
* @param child2
*/
void StringChromosome<int, IntegerStringChromosomePolicy>::fullMixing(
const IntegerStringChromosome &parent2, IntegerStringChromosome &child1,
IntegerStringChromosome &child2) const {
int *c1 = child1.getString();
int *c2 = child2.getString();
int *p1 = getString();
int *p2 = parent2.getString();
for (int i = 0; i < length; i++, c1++, c2++, p1++, p2++) {
if (*p1 == -1 && *p2 == -1) {
*c1 = *c2 = -1;
} else if (*p1 != -1 && *p2 == -1) {
*c1 = *c2 = *p1;
} else if (*p1 == -1 && *p2 != -1) {
*c1 = *c2 = *p2;
} else {
*c1 = *p1;
*c2 = *p2;
}
}
}
/**
* Assumes that the strings primarily comprise dummy values. Proceed as for
* 1 point crossover on integer strings. However if the child is given a
* dummy value when the other parent has a non-dummy value at a position,
* then that value is copied to the child.
* @param parent2
* @param child1
* @param child2
*/
void StringChromosome<int, IntegerStringChromosomePolicy>::
fullMixingAndCrossover(const IntegerStringChromosome &parent2,
IntegerStringChromosome &child1,
IntegerStringChromosome &child2) const {
// select crossover site
int site = getRng().randomInt(0, length);
bool switchFlag = false;
if (getChromosomePolicy().isAllowSwitch()) {
switchFlag = getRng().randomBoolean();
}
int *c1 = switchFlag ? child2.string.get() : child1.string.get();
int *c2 = switchFlag ? child1.string.get() : child2.string.get();
int *p1 = string.get();
int *p2 = parent2.string.get();
// create child before cross point
int i = 0;
for (; i < site; i++, p1++, p2++, c1++, c2++) {
if (*p1 == -1 && *p2 != -1) {
*c1 = *c2 = *p2;
} else if (*p1 != -1 && *p2 == -1) {
*c1 = *c2 = *p1;
} else {
*c2 = *p2;
*c1 = *p1;
}
}
// child after cross point
for (; i < length; i++, p1++, p2++, c1++, c2++) {
if (*p1 == -1 && *p2 != -1) {
*c1 = *c2 = *p2;
} else if (*p1 != -1 && *p2 == -1) {
*c1 = *c2 = *p1;
} else {
*c2 = *p1;
*c1 = *p2;
}
}
}
} // namespace GapeGa
|