//chromosome.cpp #include #include #include //take this out #include "Chromosome.h" //no-arg constructor (need for declaring arrays) template Chromosome::Chromosome () {} //destructor template Chromosome::~Chromosome () { delete []gene; } //copy constructor template Chromosome::Chromosome (const Chromosome &chrom) { size = chrom.size; gene = new geneType[size]; fitness = chrom.fitness; for (int counter = 0; counter < size; ++counter) { gene[counter] = chrom.gene[counter]; } } //initializers - create array of genes, fill with random values //for integer (short, int) genes template void Chromosome::initialize (int numberGenes) { size = numberGenes; gene = new geneType[size]; for (int counter = 0; counter < size; ++counter) { gene[counter] = geneType(double (rand()) / double (RAND_MAX) + 0.5); } } //for double genes void Chromosome::initialize (int numberGenes) { size = numberGenes; gene = new double[size]; for (int counter = 0; counter < size; ++counter) { gene[counter] = double (rand()) / double (RAND_MAX) - 0.5; } } //equality operator template bool Chromosome::operator== (const Chromosome &chrom) { if (this == &chrom) return true; if (size != chrom.size) return false; for (int counter = 0; counter < size; ++counter) { if (gene[counter] != chrom.gene[counter]) return false; } return true; } //assigment operator template Chromosome& Chromosome::operator= (const Chromosome &chrom) { if (this != &chrom) { size = chrom.size; fitness = chrom.fitness; for (int counter = 0; counter < size; ++counter) { gene[counter] = chrom.gene[counter]; } } return *this; } //readers and writers template inline geneType Chromosome::readGene (int geneNumber) {return gene[geneNumber];} template inline void Chromosome::writeGene (int geneNumber, geneType value) { gene[geneNumber] = value; } template inline double Chromosome::readFitness () {return fitness;} template inline void Chromosome::writeFitness (double value) {fitness = value;} //mutation functions //mutation function for integer (short, int) genes - switches one to zero, zero to one template int Chromosome::mutate (double mutationProbability = 0.01) { int numberMutations = 0; for (int counter = 0; counter < size; ++counter) { if (double (rand()) / double (RAND_MAX) < mutationProbability) { ++numberMutations; if (gene[counter]) gene[counter] = 0; else gene[counter] = 1; } } return numberMutations; } //mutation function for double genes - adds random number between -1 and 1 to gene int Chromosome::mutate (double mutationProbability) { int numberMutations = 0; for (int counter = 0; counter < size; ++counter) { if (double (rand()) / double (RAND_MAX) < mutationProbability) { ++numberMutations; gene[counter] += 2 * (double (rand()) / double (RAND_MAX) - 0.5); } } return numberMutations; } //reproduction/crossover functions //the next functions modifies both the calling and parameter chromosomes, // producing two offspring from two parents with replacement of the parents template void Chromosome::reproduce (Chromosome &chrom, int crossoverType) { double pc = 0.7; //crossover probability geneType temporaryGene; //what type of crossover? if (crossoverType == singlePoint) { //single-point crossover - swap all genes after a random crossover point, //if we (randomly) make the decision to crossover if (double (rand())/double (RAND_MAX) < pc) { int crosspoint = int (double (rand ())/double (RAND_MAX)) * size; for (int counter = crosspoint; counter < size; ++counter) { temporaryGene = gene[counter]; gene[counter] = chrom.gene[counter]; chrom.gene[counter] = temporaryGene; } } } else { if (crossoverType == doublePoint) { //two-point crossover - swap all genes between two randomly selected //crossover points, if we (randomly) decide to crossover if (double (rand())/double (RAND_MAX) < pc) { int crosspoint = int (double (rand ())/double (RAND_MAX)) * size; int crosspoint2 = crosspoint + int (double (rand ())/double (RAND_MAX)) * (size-crosspoint); for (int counter = crosspoint; counter < crosspoint2; ++counter) { temporaryGene = gene[counter]; gene[counter] = chrom.gene[counter]; chrom.gene[counter] = temporaryGene; } } } else { //multipoint crossover (parameterized uniform crossover) - decide randomly //whether to swap each gene for (int counter = 0; counter < size; ++counter) { if (double (rand())/double (RAND_MAX) < pc) { temporaryGene = gene[counter]; gene[counter] = chrom.gene[counter]; chrom.gene[counter] = temporaryGene; } } } //end else } //end if } //the next function produces one offspring from two parents, without replacement // of the parents template Chromosome Chromosome::reproduceOneOffspring (const Chromosome &chrom, int crossoverType) { Chromosome newChrom; newChrom.initialize(size); double pc = 0.7; //crossover probability //what type of crossover? if (crossoverType == singlePoint) { //single-point crossover if (double (rand())/double (RAND_MAX) < pc) { int crosspoint = int (double (rand ())/double (RAND_MAX)) * size; for (int counter = 0; counter < crosspoint; ++counter) { newChrom.gene[counter] = gene[counter]; } for (counter = crosspoint; counter < size; ++counter) { newChrom.gene[counter] = chrom.gene[counter]; } } } else { if (crossoverType == doublePoint) { //two-point crossover if (double (rand())/double (RAND_MAX) < pc) { int crosspoint = int (double (rand ())/double (RAND_MAX)) * size; int crosspoint2 = crosspoint + int (double (rand ())/double (RAND_MAX)) * (size-crosspoint); for (int counter = 0; counter < crosspoint; ++counter) { newChrom.gene[counter] = gene[counter]; } for (counter = crosspoint; counter < crosspoint2; ++counter) { newChrom.gene[counter] = chrom.gene[counter]; } for (counter = crosspoint2; counter < size; ++counter) { newChrom.gene[counter] = gene[counter]; } } } else { //multipoint crossover - different from the two offspring case; // after writing each gene, continue writing genes from the same parent // only (1-pc) of the time; otherwise switch int oddOrEven = 1; for (int counter = 0; counter < size; ++counter) { if (oddOrEven%2 != 0) newChrom.gene[counter] = gene[counter]; else newChrom.gene[counter] = chrom.gene[counter]; if (double (rand())/double (RAND_MAX) < pc) ++oddOrEven; } } //end else } //end if return newChrom; }