template <class T> int GA3DArrayAlleleGenome<T>::resize(int w, int h, int d){ unsigned int oldx = nx; unsigned int oldy = ny; unsigned int oldz = nz; GA3DArrayGenome<T>::resize(w,h,d); // set new elements to proper randomly selected values if(nx > oldx && ny > oldy){ int z=GAMin(oldz,nz); for(int k=z-1; k>=0; k--){ int j; for(j=oldy-1; j>=0; j--) for(unsigned int i=oldx; i<nx; i++) a[k*ny*nx+j*nx+i] = aset[(k*ny*nx+j*nx+i) % naset].allele(); for(j=oldy; j<(int)ny; j++) for(unsigned int i=0; i<nx; i++) a[k*ny*nx+j*nx+i] = aset[(k*ny*nx+j*nx+i) % naset].allele(); } } else if(nx > oldx){ int z=GAMin(oldz,nz); for(int k=z-1; k>=0; k--) for(int j=ny-1; j>=0; j--) for(unsigned int i=oldx; i<nx; i++) a[k*ny*nx+j*nx+i] = aset[(k*ny*nx+j*nx+i) % naset].allele(); } else if(ny > oldy){ int z=GAMin(oldz,nz); for(int k=z-1; k>=0; k--) for(unsigned int j=oldy; j<ny; j++) for(unsigned int i=0; i<nx; i++) a[k*ny*nx+j*nx+i] = aset[(k*ny*nx+j*nx+i) % naset].allele(); } if(nz > oldz){ // change in depth is always new elements for(unsigned int i=nx*ny*oldz; i<nx*ny*nz; i++) a[i] = aset[i % naset].allele(); } return sz; }
void CCombineGenome::Initializer( GAGenome& g) { CCombineGenome& genome = (CCombineGenome&)g; if (m_inputData != NULL) { ComRuleData* pData = (ComRuleData*)m_inputData; size_t objNum = pData->m_inputData.size(); map<YK_ID,std::list<YK_ID>>::iterator objIter = pData->m_inputData.begin(); if (pData->m_ObjGroupLimit.empty()) { int averageSize = objNum / genome.npaths(); if (averageSize > 0) { for (int i = 0; objIter != pData->m_inputData.end(); ++i,++objIter) { int index = (i / averageSize) < genome.npaths() ? (i / averageSize ) : (genome.npaths()-1) ; genome.path(index).insert(objIter->first,GAListBASE::TAIL); } } }else { for (; objIter != pData->m_inputData.end(); ++objIter) { YK_LLONG objId = objIter->first; std::set<YKString> validSet = pData->m_ObjGroupLimit[objId]; if (!validSet.empty()) { if (validSet.size() == 1) { genome.path(m_groupToIndexMap[*validSet.begin()]).insert(objIter->first,GAListBASE::TAIL); }else { int maxIndex = GAMin(validSet.size()-1,genome.npaths()-1); int index = GARandomInt(0,maxIndex); std::set<YKString>::iterator indexIter = validSet.begin(); advance(indexIter,index); if (indexIter != validSet.end()) { int pathNum = m_groupToIndexMap[*indexIter]; genome.path(pathNum).insert(objId,GAListBASE::TAIL); } } } } } } }
/// Do the scaling on the population. Like the statistics and diversity, this /// method does not change the contents of the population, but it does change /// the values of the status members of the object. So we allow it to work on /// a const population. void GAPopulation::scale(GABoolean flag) const { if(scaled == gaTrue && flag != gaTrue) { return; } GAPopulation* This = (GAPopulation*)this; if(n > 0) { sclscm->evaluate(*This); float tmpsum; This->fitMin = This->fitMax = tmpsum = sind[0]->fitness(); unsigned int i; for(i = 1; i < n; i++) { tmpsum += sind[i]->fitness(); This->fitMax = GAMax(fitMax, sind[i]->fitness()); This->fitMin = GAMin(fitMin, sind[i]->fitness()); } float tmpave = tmpsum / n; This->fitAve = tmpave; This->fitSum = tmpsum; /// if scores are huge we'll lose data here float tmpvar = 0.0; if(n > 1) { for(i = 0; i < n; i++) { float s = sind[i]->fitness() - This->fitAve; s *= s; tmpvar += s; } tmpvar /= (n - 1); } This->fitDev = (float)sqrt(tmpvar); This->fitVar = tmpvar; /// could lose data if huge variance } else { This->fitMin = This->fitMax = This->fitSum = 0.0; This->fitVar = This->fitDev = 0.0; } This->scaled = gaTrue; This->ssorted = gaFalse; }
/// Evaluate each member of the population and store basic population statistics /// in the member variables. It is OK to run this on a const object - it /// changes to physical state of the population, but not the logical state. /// The partial sums are normalized to the range [0,1] so that they can be /// used whether the population is sorted as low-is-best or high-is-best. /// Individual 0 is always the best individual, and the partial sums are /// calculated so that the worst individual has the smallest partial sum. All /// of the partial sums add to 1.0. void GAPopulation::statistics(GABoolean flag) const { if(statted == gaTrue && flag != gaTrue) { return; } GAPopulation * This = (GAPopulation *)this; if(n > 0) { float tmpsum; This->rawMin = This->rawMax = tmpsum = rind[0]->score(); unsigned int i; for(i = 1; i < n; i++) { float scr = rind[i]->score(); tmpsum += scr; This->rawMax = GAMax(rawMax, scr); This->rawMin = GAMin(rawMin, scr); } float tmpave = tmpsum / n; This->rawAve = tmpave; This->rawSum = tmpsum; /// if scores are huge we'll lose data here float tmpvar = 0.0; if(n > 1) { for(i = 0; i < n; i++) { float s = rind[i]->score() - This->rawAve; s *= s; tmpvar += s; } tmpvar /= (n - 1); } This->rawDev = (float)sqrt(tmpvar); This->rawVar = tmpvar; /// could lose data if huge variance } else { This->rawMin = This->rawMax = This->rawSum = 0.0; This->rawDev = This->rawVar = 0.0; } This->statted = gaTrue; }
template <class T> int GA3DArrayGenome<T>::resize(int w, int h, int d) { if(w == (int)nx && h == (int)ny && d == (int)nz) return sz; if(w == GAGenome::ANY_SIZE) w = GARandomInt(minX, maxX); else if(w < 0) w = nx; // do nothing else if(minX == maxX) minX=maxX = w; else{ if(w < (int)minX) w=minX; if(w > (int)maxX) w=maxX; } if(h == GAGenome::ANY_SIZE) h = GARandomInt(minY, maxY); else if(h < 0) h = ny; // do nothing else if(minY == maxY) minY=maxY = h; else{ if(h < (int)minY) h=minY; if(h > (int)maxY) h=maxY; } if(d == GAGenome::ANY_SIZE) d = GARandomInt(minZ, maxZ); else if(d < 0) d = nz; // do nothing else if(minZ == maxZ) minZ=maxZ = d; else{ if(d < (int)minZ) d=minZ; if(d > (int)maxZ) d=maxZ; } if(w < (int)nx && h < (int)ny){ int z=GAMin((int)nz,d); for(int k=0; k<z; k++) for(int j=0; j<h; j++) GAArray<T>::move(k*h*w+j*w,k*ny*nx+j*nx,w); } else if(w < (int)nx){ int z=GAMin((int)nz,d); for(int k=0; k<z; k++) for(int j=0; j<(int)ny; j++) GAArray<T>::move(k*ny*w+j*w,k*ny*nx+j*nx,w); } else if(h < (int)ny){ int z=GAMin((int)nz,d); for(int k=0; k<z; k++) for(int j=0; j<h; j++) GAArray<T>::move(k*h*nx+j*nx,k*ny*nx+j*nx,nx); } GAArray<T>::size(w*h*d); if(w > (int)nx && h > (int)ny){ int z=GAMin((int)nz,d); for(int k=z-1; k>=0; k--) for(int j=ny-1; j>=0; j--) GAArray<T>::move(k*h*w+j*w,k*ny*nx+j*nx,nx); } else if(w > (int)nx){ int z=GAMin((int)nz,d); for(int k=z-1; k>=0; k--) for(int j=h-1; j>=0; j--) GAArray<T>::move(k*h*w+j*w,k*h*nx+j*nx,nx); } else if(h > (int)ny){ int z=GAMin((int)nz,d); for(int k=z-1; k>=0; k--) for(int j=ny-1; j>=0; j--) GAArray<T>::move(k*h*w+j*w,k*ny*w+j*w,w); } nx = w; ny = h; nz = d; _evaluated = gaFalse; return sz; }
// Pick a single point in the 3D block and grab alternating quadrants for each // child. If the children are resizable, this crossover does clipping. template <class T> int GA3DArrayGenome<T>:: OnePointCrossover(const GAGenome& p1, const GAGenome& p2, GAGenome* c1, GAGenome* c2){ GA3DArrayGenome<T> &mom=(GA3DArrayGenome<T> &)p1; GA3DArrayGenome<T> &dad=(GA3DArrayGenome<T> &)p2; int nc=0; unsigned int momsitex, momlenx, momsitey, momleny, momsitez, momlenz; unsigned int dadsitex, dadlenx, dadsitey, dadleny, dadsitez, dadlenz; unsigned int sitex, lenx, sitey, leny, sitez, lenz; if(c1 && c2){ GA3DArrayGenome<T> &sis=(GA3DArrayGenome<T> &)*c1; GA3DArrayGenome<T> &bro=(GA3DArrayGenome<T> &)*c2; if(sis.resizeBehaviour(GAGenome::WIDTH) == GAGenome::FIXED_SIZE && bro.resizeBehaviour(GAGenome::WIDTH) == GAGenome::FIXED_SIZE){ if(mom.width() != dad.width() || sis.width() != bro.width() || sis.width() != mom.width()){ GAErr(GA_LOC, mom.className(), "one-point cross", gaErrSameLengthReqd); return nc; } sitex = momsitex = dadsitex = GARandomInt(0, mom.width()); lenx = momlenx = dadlenx = mom.width() - momsitex; } else if(sis.resizeBehaviour(GAGenome::WIDTH) == GAGenome::FIXED_SIZE || bro.resizeBehaviour(GAGenome::WIDTH) == GAGenome::FIXED_SIZE){ GAErr(GA_LOC, mom.className(), "one-point cross", gaErrSameBehavReqd); return nc; } else{ momsitex = GARandomInt(0, mom.width()); dadsitex = GARandomInt(0, dad.width()); momlenx = mom.width() - momsitex; dadlenx = dad.width() - dadsitex; sitex = GAMin(momsitex, dadsitex); lenx = GAMin(momlenx, dadlenx); } if(sis.resizeBehaviour(GAGenome::HEIGHT) == GAGenome::FIXED_SIZE && bro.resizeBehaviour(GAGenome::HEIGHT) == GAGenome::FIXED_SIZE){ if(mom.height() != dad.height() || sis.height() != bro.height() || sis.height() != mom.height()){ GAErr(GA_LOC, mom.className(), "one-point cross", gaErrSameLengthReqd); return nc; } sitey = momsitey = dadsitey = GARandomInt(0, mom.height()); leny = momleny = dadleny = mom.height() - momsitey; } else if(sis.resizeBehaviour(GAGenome::HEIGHT) == GAGenome::FIXED_SIZE || bro.resizeBehaviour(GAGenome::HEIGHT) == GAGenome::FIXED_SIZE){ GAErr(GA_LOC, mom.className(), "one-point cross", gaErrSameBehavReqd); return nc; } else{ momsitey = GARandomInt(0, mom.height()); dadsitey = GARandomInt(0, dad.height()); momleny = mom.height() - momsitey; dadleny = dad.height() - dadsitey; sitey = GAMin(momsitey, dadsitey); leny = GAMin(momleny, dadleny); } if(sis.resizeBehaviour(GAGenome::DEPTH) == GAGenome::FIXED_SIZE && bro.resizeBehaviour(GAGenome::DEPTH) == GAGenome::FIXED_SIZE){ if(mom.depth() != dad.depth() || sis.depth() != bro.depth() || sis.depth() != mom.depth()){ GAErr(GA_LOC, mom.className(), "one-point cross", gaErrSameLengthReqd); return nc; } sitez = momsitez = dadsitez = GARandomInt(0, mom.depth()); lenz = momlenz = dadlenz = mom.depth() - momsitez; } else if(sis.resizeBehaviour(GAGenome::DEPTH) == GAGenome::FIXED_SIZE || bro.resizeBehaviour(GAGenome::DEPTH) == GAGenome::FIXED_SIZE){ GAErr(GA_LOC, mom.className(), "one-point cross", gaErrSameBehavReqd); return nc; } else{ momsitez = GARandomInt(0, mom.depth()); dadsitez = GARandomInt(0, dad.depth()); momlenz = mom.depth() - momsitez; dadlenz = dad.depth() - dadsitez; sitez = GAMin(momsitez, dadsitez); lenz = GAMin(momlenz, dadlenz); } sis.resize(sitex+lenx, sitey+leny, sitez+lenz); bro.resize(sitex+lenx, sitey+leny, sitez+lenz); sis.copy(mom, 0, 0, 0, momsitex-sitex, momsitey-sitey, momsitez-sitez, sitex, sitey, sitez); sis.copy(dad, sitex, 0, 0, dadsitex, dadsitey-sitey, dadsitez-sitez, lenx, sitey, sitez); sis.copy(dad, 0, sitey, 0, dadsitex-sitex, dadsitey, dadsitez-sitez, sitex, leny, sitez); sis.copy(mom, sitex, sitey, 0, momsitex, momsitey, momsitez-sitez, lenx, leny, sitez); sis.copy(dad, 0, 0, sitez, dadsitex-sitex, dadsitey-sitey, dadsitez, sitex, sitey, lenz); sis.copy(mom, sitex, 0, sitez, momsitex, momsitey-sitey, momsitez, lenx, sitey, lenz); sis.copy(mom, 0, sitey, sitez, momsitex-sitex, momsitey, momsitez, sitex, leny, lenz); sis.copy(dad, sitex, sitey, sitez, dadsitex, dadsitey, dadsitez, lenx, leny, lenz); bro.copy(dad, 0, 0, 0, dadsitex-sitex, dadsitey-sitey, dadsitez-sitez, sitex, sitey, sitez); bro.copy(mom, sitex, 0, 0, momsitex, momsitey-sitey, momsitez-sitez, lenx, sitey, sitez); bro.copy(mom, 0, sitey, 0, momsitex-sitex, momsitey, momsitez-sitez, sitex, leny, sitez); bro.copy(dad, sitex, sitey, 0, dadsitex, dadsitey, dadsitez-sitez, lenx, leny, sitez); bro.copy(mom, 0, 0, sitez, momsitex-sitex, momsitey-sitey, momsitez, sitex, sitey, lenz); bro.copy(dad, sitex, 0, sitez, dadsitex, dadsitey-sitey, dadsitez, lenx, sitey, lenz); bro.copy(dad, 0, sitey, sitez, dadsitex-sitex, dadsitey, dadsitez, sitex, leny, lenz); bro.copy(mom, sitex, sitey, sitez, momsitex, momsitey, momsitez, lenx, leny, lenz); nc = 2; } else if(c1){ GA3DArrayGenome<T> &sis=(GA3DArrayGenome<T> &)*c1; if(sis.resizeBehaviour(GAGenome::WIDTH) == GAGenome::FIXED_SIZE){ if(mom.width() != dad.width() || sis.width() != mom.width()){ GAErr(GA_LOC, mom.className(), "one-point cross", gaErrSameLengthReqd); return nc; } sitex = momsitex = dadsitex = GARandomInt(0, mom.width()); lenx = momlenx = dadlenx = mom.width() - momsitex; } else{ momsitex = GARandomInt(0, mom.width()); dadsitex = GARandomInt(0, dad.width()); momlenx = mom.width() - momsitex; dadlenx = dad.width() - dadsitex; sitex = GAMin(momsitex, dadsitex); lenx = GAMin(momlenx, dadlenx); } if(sis.resizeBehaviour(GAGenome::HEIGHT) == GAGenome::FIXED_SIZE){ if(mom.height() != dad.height() || sis.height() != mom.height()){ GAErr(GA_LOC, mom.className(), "one-point cross", gaErrSameLengthReqd); return nc; } sitey = momsitey = dadsitey = GARandomInt(0, mom.height()); leny = momleny = dadleny = mom.height() - momsitey; } else{ momsitey = GARandomInt(0, mom.height()); dadsitey = GARandomInt(0, dad.height()); momleny = mom.height() - momsitey; dadleny = dad.height() - dadsitey; sitey = GAMin(momsitey, dadsitey); leny = GAMin(momleny, dadleny); } if(sis.resizeBehaviour(GAGenome::DEPTH) == GAGenome::FIXED_SIZE){ if(mom.depth() != dad.depth() || sis.depth() != mom.depth()){ GAErr(GA_LOC, mom.className(), "one-point cross", gaErrSameLengthReqd); return nc; } sitez = momsitez = dadsitez = GARandomInt(0, mom.depth()); lenz = momlenz = dadlenz = mom.depth() - momsitez; } else{ momsitez = GARandomInt(0, mom.depth()); dadsitez = GARandomInt(0, dad.depth()); momlenz = mom.depth() - momsitez; dadlenz = dad.depth() - dadsitez; sitez = GAMin(momsitez, dadsitez); lenz = GAMin(momlenz, dadlenz); } sis.resize(sitex+lenx, sitey+leny, sitez+lenz); if(GARandomBit()){ sis.copy(mom, 0, 0, 0, momsitex-sitex, momsitey-sitey, momsitez-sitez, sitex, sitey, sitez); sis.copy(dad, sitex, 0, 0, dadsitex, dadsitey-sitey, dadsitez-sitez, lenx, sitey, sitez); sis.copy(dad, 0, sitey, 0, dadsitex-sitex, dadsitey, dadsitez-sitez, sitex, leny, sitez); sis.copy(mom, sitex, sitey, 0, momsitex, momsitey, momsitez-sitez, lenx, leny, sitez); sis.copy(dad, 0, 0, sitez, dadsitex-sitex, dadsitey-sitey, dadsitez, sitex, sitey, lenz); sis.copy(mom, sitex, 0, sitez, momsitex, momsitey-sitey, momsitez, lenx, sitey, lenz); sis.copy(mom, 0, sitey, sitez, momsitex-sitex, momsitey, momsitez, sitex, leny, lenz); sis.copy(dad, sitex, sitey, sitez, dadsitex, dadsitey, dadsitez, lenx, leny, lenz); } else{ sis.copy(dad, 0, 0, 0, dadsitex-sitex, dadsitey-sitey, dadsitez-sitez, sitex, sitey, sitez); sis.copy(mom, sitex, 0, 0, momsitex, momsitey-sitey, momsitez-sitez, lenx, sitey, sitez); sis.copy(mom, 0, sitey, 0, momsitex-sitex, momsitey, momsitez-sitez, sitex, leny, sitez); sis.copy(dad, sitex, sitey, 0, dadsitex, dadsitey, dadsitez-sitez, lenx, leny, sitez); sis.copy(mom, 0, 0, sitez, momsitex-sitex, momsitey-sitey, momsitez, sitex, sitey, lenz); sis.copy(dad, sitex, 0, sitez, dadsitex, dadsitey-sitey, dadsitez, lenx, sitey, lenz); sis.copy(dad, 0, sitey, sitez, dadsitex-sitex, dadsitey, dadsitez, sitex, leny, lenz); sis.copy(mom, sitex, sitey, sitez, momsitex, momsitey, momsitez, lenx, leny, lenz); } nc = 1; } return nc; }
int GA3DBinaryStringGenome::resize(int w, int h, int d) { if(w == (int)nx && h == (int)ny && d == (int)nz) return sz; if(w == GAGenome::ANY_SIZE) w = GARandomInt(minX, maxX); else if(w < 0) w = nx; // do nothing else if(minX == maxX) minX=maxX = w; else{ if(w < (int)minX) w=minX; if(w > (int)maxX) w=maxX; } if(h == GAGenome::ANY_SIZE) h = GARandomInt(minY, maxY); else if(h < 0) h = ny; // do nothing else if(minY == maxY) minY=maxY = h; else{ if(h < (int)minY) h=minY; if(h > (int)maxY) h=maxY; } if(d == GAGenome::ANY_SIZE) d = GARandomInt(minZ, maxZ); else if(d < 0) d = nz; // do nothing else if(minZ == maxZ) minZ=maxZ = d; else{ if(d < (int)minZ) d=minZ; if(d > (int)maxZ) d=maxZ; } if(w < (int)nx && h < (int)ny){ int z=GAMin((int)nz,d); for(int k=0; k<z; k++) for(int j=0; j<h; j++) GABinaryString::move(k*h*w+j*w,k*ny*nx+j*nx,w); } else if(w < (int)nx){ int z=GAMin((int)nz,d); for(int k=0; k<z; k++) for(int j=0; j<(int)ny; j++) GABinaryString::move(k*ny*w+j*w,k*ny*nx+j*nx,w); } else if(h < (int)ny){ int z=GAMin((int)nz,d); for(int k=0; k<z; k++) for(int j=0; j<h; j++) GABinaryString::move(k*h*nx+j*nx,k*ny*nx+j*nx,nx); } GABinaryString::resize(w*h*d); if(w > (int)nx && h > (int)ny){ // adjust the existing bits int z=GAMin((int)nz,d); for(int k=z-1; k>=0; k--){ int j; for(j=ny-1; j>=0; j--){ GABinaryString::move(k*h*w+j*w,k*ny*nx+j*nx,nx); for(int i=nx; i<w; i++) bit(k*h*w+j*w+i, GARandomBit()); } for(j=ny; j<h; j++) for(int i=0; i<w; i++) bit(k*h*w+j*w+i, GARandomBit()); } } else if(w > (int)nx){ int z=GAMin((int)nz,d); for(int k=z-1; k>=0; k--){ for(int j=h-1; j>=0; j--){ GABinaryString::move(k*h*w+j*w,k*h*nx+j*nx,nx); for(int i=nx; i<w; i++) bit(k*h*w+j*w+i, GARandomBit()); } } } else if(h > (int)ny){ int z=GAMin((int)nz,d); for(int k=z-1; k>=0; k--){ int j; for(j=ny-1; j>=0; j--) GABinaryString::move(k*h*w+j*w,k*ny*w+j*w,w); for(j=ny; j<h; j++) for(int i=0; i<w; i++) bit(k*h*w+j*w+i, GARandomBit()); } } if(d > (int)nz){ // change in depth is always new bits for(int i=w*h*nz; i<w*h*d; i++) bit(i, GARandomBit()); } nx = w; ny = h; nz = d; _evaluated = gaFalse; return sz; }
// For even crossover we take the even bits from the mother (for the daughter) // and the odd bits from the father. Just the opposite for the son. // This is designed only for genomes that are the same length. If the child // is not the same length as the parent, or if the children are not the same // size, we don't do the crossover. // In the interest of speed we do not do any checks for size. Do not use // this crossover method when the parents and children may be different sizes. // It might break! int GA3DBinaryStringGenome:: EvenOddCrossover(const GAGenome& p1, const GAGenome& p2, GAGenome* c1, GAGenome* c2){ GA3DBinaryStringGenome &mom=(GA3DBinaryStringGenome &)p1; GA3DBinaryStringGenome &dad=(GA3DBinaryStringGenome &)p2; int nc=0; int i,j,k; if(c1 && c2){ GA3DBinaryStringGenome &sis=(GA3DBinaryStringGenome &)*c1; GA3DBinaryStringGenome &bro=(GA3DBinaryStringGenome &)*c2; if(sis.width() == bro.width() && sis.height() == bro.height() && sis.depth() == bro.depth() && mom.width() == dad.width() && mom.height() == dad.height() && mom.depth() == dad.depth() && sis.width() == mom.width() && sis.height() == mom.height() && sis.depth() == mom.depth()){ int count=0; for(i=sis.width()-1; i>=0; i--){ for(j=sis.height()-1; j>=0; j--){ for(k=sis.depth()-1; k>=0; k--){ if(count%2 == 0){ sis.gene(i,j,k, mom.gene(i,j,k)); bro.gene(i,j,k, dad.gene(i,j,k)); } else{ sis.gene(i,j,k, dad.gene(i,j,k)); bro.gene(i,j,k, mom.gene(i,j,k)); } count++; } } } } else{ int minx = GAMin(mom.width(), dad.width()); int miny = GAMin(mom.height(), dad.height()); int minz = GAMin(mom.depth(), dad.depth()); minx = GAMin(sis.width(), minx); miny = GAMin(sis.height(), miny); minz = GAMin(sis.depth(), minz); for(i=minx-1; i>=0; i--) for(j=miny-1; j>=0; j--) for(k=minz-1; k>=0; k--) sis.gene(i,j,k, (((i*miny*minz+j*minz+k)%2 == 0) ? mom.gene(i,j,k) : dad.gene(i,j,k))); minx = (bro.width() < minx) ? bro.width() : minx; miny = (bro.height() < miny) ? bro.height() : miny; minz = (bro.depth() < minz) ? bro.depth() : minz; for(i=minx-1; i>=0; i--) for(j=miny-1; j>=0; j--) for(k=minz-1; k>=0; k--) bro.gene(i,j,k, (((i*miny*minz+j*minz+k)%2 == 0) ? dad.gene(i,j,k) : mom.gene(i,j,k))); } nc = 2; } else if(c1 || c2){ GA3DBinaryStringGenome &sis = (c1 ? (GA3DBinaryStringGenome &)*c1 : (GA3DBinaryStringGenome &)*c2); if(mom.width() == dad.width() && mom.height() == dad.height() && mom.depth() == dad.depth() && sis.width() == mom.width() && sis.height() == mom.height() && sis.depth() == mom.depth()){ int count=0; for(i=sis.width()-1; i>=0; i--){ for(j=sis.height()-1; j>=0; j--){ for(k=sis.depth()-1; k>=0; k--){ sis.gene(i,j,k,((count%2 == 0) ? mom.gene(i,j,k):dad.gene(i,j,k))); count++; } } } } else{ int minx = GAMin(mom.width(), dad.width()); int miny = GAMin(mom.height(), dad.height()); int minz = GAMin(mom.depth(), dad.depth()); minx = GAMin(sis.width(), minx); miny = GAMin(sis.height(), miny); minz = GAMin(sis.depth(), minz); for(i=minx-1; i>=0; i--) for(j=miny-1; j>=0; j--) for(k=minz-1; k>=0; k--) sis.gene(i,j, (((i*miny*minz+j*minz+k)%2 == 0) ? mom.gene(i,j,k) : dad.gene(i,j,k))); } nc = 1; } return nc; }
// Make sure our bitmask is big enough, generate a mask, then use it to // extract the information from each parent to stuff the two children. // We don't deallocate any space for the masks under the assumption that we'll // have to use them again in the future. // For now we'll implement this only for fixed length genomes. If you use // this crossover method on genomes of different sizes it might break! int GA3DBinaryStringGenome:: UniformCrossover(const GAGenome& p1, const GAGenome& p2, GAGenome* c1, GAGenome* c2){ GA3DBinaryStringGenome &mom=(GA3DBinaryStringGenome &)p1; GA3DBinaryStringGenome &dad=(GA3DBinaryStringGenome &)p2; int i,j,k, nc=0;; if(c1 && c2){ GA3DBinaryStringGenome &sis=(GA3DBinaryStringGenome &)*c1; GA3DBinaryStringGenome &bro=(GA3DBinaryStringGenome &)*c2; if(sis.width() == bro.width() && sis.height() == bro.height() && sis.depth() == bro.depth() && mom.width() == dad.width() && mom.height() == dad.height() && mom.depth() == dad.depth() && sis.width() == mom.width() && sis.height() == mom.height() && sis.depth() == mom.depth()){ for(i=sis.width()-1; i>=0; i--){ for(j=sis.height()-1; j>=0; j--){ for(k=sis.depth()-1; k>=0; k--){ if(GARandomBit()){ sis.gene(i,j,k, mom.gene(i,j,k)); bro.gene(i,j,k, dad.gene(i,j,k)); } else{ sis.gene(i,j,k, dad.gene(i,j,k)); bro.gene(i,j,k, mom.gene(i,j,k)); } } } } } else{ GAMask mask; int maxx = GAMax(sis.width(), bro.width()); int minx = GAMin(mom.width(), dad.width()); int maxy = GAMax(sis.height(), bro.height()); int miny = GAMin(mom.height(), dad.height()); int maxz = GAMax(sis.depth(), bro.depth()); int minz = GAMin(mom.depth(), dad.depth()); mask.size(maxx*maxy*maxz); for(i=0; i<maxx; i++) for(j=0; j<maxy; j++) for(k=0; k<maxz; k++) mask[i*maxy*maxz+j*maxz+k] = GARandomBit(); minx = GAMin(sis.width(), minx); miny = GAMin(sis.height(), miny); minz = GAMin(sis.depth(), minz); for(i=minx-1; i>=0; i--) for(j=miny-1; j>=0; j--) for(k=minz-1; k>=0; k--) sis.gene(i,j,k, (mask[i*miny*minz+j*minz+k] ? mom.gene(i,j,k) : dad.gene(i,j,k))); minx = GAMin(bro.width(), minx); miny = GAMin(bro.height(), miny); minz = GAMin(bro.depth(), minz); for(i=minx-1; i>=0; i--) for(j=miny-1; j>=0; j--) for(k=minz-1; k>=0; k--) bro.gene(i,j,k, (mask[i*miny*minz+j*minz+k] ? dad.gene(i,j,k) : mom.gene(i,j,k))); } nc = 2; } else if(c1 || c2){ GA3DBinaryStringGenome &sis = (c1 ? (GA3DBinaryStringGenome&)*c1 : (GA3DBinaryStringGenome&)*c2); if(mom.width() == dad.width() && mom.height() == dad.height() && mom.depth() == dad.depth() && sis.width() == mom.width() && sis.height() == mom.height() && sis.depth() == mom.depth()){ for(i=sis.width()-1; i>=0; i--) for(j=sis.height()-1; j>=0; j--) for(k=sis.depth()-1; k>=0; k--) sis.gene(i,j,k, (GARandomBit() ? mom.gene(i,j,k):dad.gene(i,j,k))); } else{ int minx = GAMin(mom.width(), dad.width()); int miny = GAMin(mom.height(), dad.height()); int minz = GAMin(mom.depth(), dad.depth()); minx = GAMin(sis.width(), minx); miny = GAMin(sis.height(), miny); minz = GAMin(sis.depth(), minz); for(i=minx-1; i>=0; i--) for(j=miny-1; j>=0; j--) for(k=minz-1; k>=0; k--) sis.gene(i,j,k, (GARandomBit() ? mom.gene(i,j,k):dad.gene(i,j,k))); } nc = 1; } return nc; }