📄 chromo.cc
字号:
// chromo.cc// Implementation of class Chromo// Thomas Pederson, 950505#include "chromo.h"#include <stdlib.h>Chromo::Chromo(unsigned int _chromoLength, Gene *_genePool[]){ chromoLength = _chromoLength; genePool = _genePool; myGenePool = new (Gene *)[chromoLength]; myEval = -1.0; myModEval = -1.0;}Chromo::~Chromo(){ delete [] myGenePool;}// Copy constructor.Chromo& Chromo::operator=(Chromo& original){ if (this == &original) return *this; delete [] myGenePool; chromoLength = original.chromoLength; myGenePool = new (Gene *)[chromoLength]; for (int i = 0; i < chromoLength; i++) myGenePool[i] = original.myGenePool[i]; myEval = original.myEval;}// Chromosome initialization.void Chromo::init(){ int i, j; for (i = 1; i < (chromoLength - 1); i++) myGenePool[i] = (Gene *)0; myGenePool[0] = genePool[0]; myGenePool[chromoLength - 1] = genePool[chromoLength - 1]; for (i = 1; i < (chromoLength - 1); i++) { while (myGenePool[(j = myRand())] != (Gene *)0) continue; myGenePool[j] = genePool[i]; }}// Calculates (if necessary) and returns chromosome evaluation.eval_t Chromo::eval(){ if (myEval == -1.0) { myEval = 0.0; for (int i = 0; i < (chromoLength - 1); i++) myEval += myGenePool[i]->distanceTo(*myGenePool[i + 1]); } return myEval;}// Mates this chromosome with partner resulting in two new offsprings, child1 and child2.void Chromo::mate(float _crossover, cross_t crossoverType, float _mutation, Chromo& partner, Chromo& child1, Chromo& child2){ if (rand() <= (_crossover * RAND_MAX)) child1.crossover(crossoverType, *this, partner); else child1 = *this; if (rand() <= (_mutation * RAND_MAX)) child1.mutate(); if (rand() <= (_crossover * RAND_MAX)) child2.crossover(crossoverType, partner, *this); else child2 = partner; if (rand() <= (_mutation * RAND_MAX)) child2.mutate();}// Prints chromosome information to stream.ostream& operator<<(ostream& outStr, Chromo& chromo){ for (int i = 0; i < chromo.chromoLength; i++) cout << "[" << i << "]: " << *(chromo.myGenePool[i]) << endl; cout << "Distance: " << chromo.myEval << endl; return outStr;}// Keeping track of used genes during crossover.int Chromo::isUsed(Gene *gene, Gene *usedGene[], int noOfUsedGenes){ for (int i = 0; i < noOfUsedGenes; i++) if (usedGene[i] == gene) return 1; return 0;}// Performs crossover using parent1 and parent2 as templates.// This chromosome is assigned the result.void Chromo::crossover(cross_t crossoverType, Chromo& parent1, Chromo& parent2){ int i, j, k, l; int curGene = 0; Gene *usedGene[chromoLength]; usedGene[0] = (myGenePool[0] = parent1.myGenePool[0]); usedGene[chromoLength - 1] = (myGenePool[chromoLength - 1] = parent1.myGenePool[chromoLength - 1]); if (crossoverType == fixedPos) { j = 1; for (i = 1; i < (chromoLength - 1); i++) { if (rand() % 2) { usedGene[j] = (myGenePool[i] = parent1.myGenePool[i]); j++; } else myGenePool[i] = (Gene *)0; } } else // crossoverType == fixedPosSeq { int left, right; Gene *tmpGene; left = ((rand() % (chromoLength - 3)) + 1); right = ((rand() % (chromoLength - (2 + left))) + left + 1); j = 1; for (i = 1; i < (chromoLength - 1); i++) { if (i >= left && i <= right) { usedGene[j] = (myGenePool[i] = parent1.myGenePool[i]); j++; } else myGenePool[i] = (Gene *)0; } } curGene = 0; for (k = 0; k < chromoLength; k++) { if (myGenePool[k] == (Gene *)0) { for (l = curGene; l < chromoLength; l++) { if (!(isUsed(parent2.myGenePool[l], usedGene, j))) { myGenePool[k] = parent2.myGenePool[l]; curGene = (l + 1); break; } } } } myEval = -1.0;}// Performs mutation on this chromosome.void Chromo::mutate(){ int left, right, i, s; Gene *tmpGene; left = ((rand() % (chromoLength - 3)) + 1); right = ((rand() % (chromoLength - (2 + left))) + left + 1); for (i = left; i <= right; i++) { tmpGene = myGenePool[i]; s = left + rand() % (right - left); myGenePool[i] = myGenePool[s]; myGenePool[s] = tmpGene; } myEval = -1.0;}// Modified random generator.unsigned int Chromo::myRand(){ return ((rand() % (chromoLength - 2)) + 1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -