📄 ga3darraygenome.cpp
字号:
template <class T> GAGenome *GA3DArrayAlleleGenome<T>::clone(GAGenome::CloneMethod) const { return new GA3DArrayAlleleGenome<T>(*this);}template <class T> void GA3DArrayAlleleGenome<T>::copy(const GAGenome& orig){ if(&orig == this) return; const GA3DArrayAlleleGenome<T>* c = DYN_CAST(const GA3DArrayAlleleGenome<T>*, &orig); if(c) { GA3DArrayGenome<T>::copy(*c); if(naset != c->naset){ delete [] aset; naset = c->naset; aset = new GAAlleleSet<T>[c->naset]; } for(int i=0; i<naset; i++) aset[i].link(c->aset[i]); }}template <class T> intGA3DArrayAlleleGenome<T>::resize(int w, int h, int d){ unsigned int oldx = this->nx; unsigned int oldy = this->ny; unsigned int oldz = this->nz; GA3DArrayGenome<T>::resize(w,h,d);// set new elements to proper randomly selected values if(this->nx > oldx && this->ny > oldy){ int z=GAMin(oldz,this->nz); for(int k=z-1; k>=0; k--){ int j; for(j=oldy-1; j>=0; j--) for(unsigned int i=oldx; i<this->nx; i++) this->a[k * this->ny * this->nx + j * this->nx + i] = aset[(k*this->ny*this->nx+j*this->nx+i) % naset].allele(); for(j=oldy; j<STA_CAST(int,this->ny); j++) for(unsigned int i=0; i<this->nx; i++) this->a[k * this->ny * this->nx + j * this->nx + i] = aset[(k * this->ny * this->nx + j * this->nx + i) % naset].allele(); } } else if(this->nx > oldx){ int z=GAMin(oldz,this->nz); for(int k=z-1; k>=0; k--) for(int j=this->ny-1; j>=0; j--) for(unsigned int i=oldx; i<this->nx; i++) this->a[k*this->ny*this->nx+j*this->nx+i] = aset[(k*this->ny*this->nx+j*this->nx+i) % naset].allele(); } else if(this->ny > oldy){ int z=GAMin(oldz,this->nz); for(int k=z-1; k>=0; k--) for(unsigned int j=oldy; j<this->ny; j++) for(unsigned int i=0; i<this->nx; i++) this->a[k*this->ny*this->nx+j*this->nx+i] = aset[(k*this->ny*this->nx+j*this->nx+i) % naset].allele(); } if(this->nz > oldz){ // change in depth is always new elements for(unsigned int i=this->nx*this->ny*oldz; i<this->nx*this->ny*this->nz; i++) this->a[i] = aset[i % naset].allele(); } return this->sz;}#ifdef GALIB_USE_STREAMStemplate <class T> intGA3DArrayAlleleGenome<T>::read(STD_ISTREAM& is){ return GA3DArrayGenome<T>::read(is);}template <class T> intGA3DArrayAlleleGenome<T>::write(STD_OSTREAM& os) const { return GA3DArrayGenome<T>::write(os);}#endiftemplate <class T> intGA3DArrayAlleleGenome<T>::equal(const GAGenome & c) const { return GA3DArrayGenome<T>::equal(c);}/* ---------------------------------------------------------------------------- Operator definitions---------------------------------------------------------------------------- */// this does not handle genomes with multiple allele sets!template <class ARRAY_TYPE> void GA3DArrayAlleleGenome<ARRAY_TYPE>::UniformInitializer(GAGenome & c){ GA3DArrayAlleleGenome<ARRAY_TYPE> &child= DYN_CAST(GA3DArrayAlleleGenome<ARRAY_TYPE> &, c); child.resize(GAGenome::ANY_SIZE,GAGenome::ANY_SIZE,GAGenome::ANY_SIZE); for(int i=child.width()-1; i>=0; i--) for(int j=child.height()-1; j>=0; j--) for(int k=child.depth()-1; k>=0; k--) child.gene(i, j, k, child.alleleset().allele());}template <class ARRAY_TYPE> int GA3DArrayAlleleGenome<ARRAY_TYPE>::FlipMutator(GAGenome & c, float pmut){ GA3DArrayAlleleGenome<ARRAY_TYPE> &child= DYN_CAST(GA3DArrayAlleleGenome<ARRAY_TYPE> &, c); register int n, m, d, i, j, k; if(pmut <= 0.0) return(0); float nMut = pmut * STA_CAST(float,child.size()); if(nMut < 1.0){ // we have to do a flip test on each bit nMut = 0; for(i=child.width()-1; i>=0; i--){ for(j=child.height()-1; j>=0; j--){ for(k=child.depth()-1; k>=0; k--){ if(GAFlipCoin(pmut)){ child.gene(i, j, k, child.alleleset().allele()); nMut++; } } } } } else{ // only flip the number of bits we need to flip for(n=0; n<nMut; n++){ m = GARandomInt(0, child.size()-1); d = child.height() * child.depth(); i = m / d; j = (m % d) / child.depth(); k = (m % d) % child.depth(); child.gene(i, j, k, child.alleleset().allele()); } } return(STA_CAST(int,nMut));}template <class ARRAY_TYPE> int GA3DArrayGenome<ARRAY_TYPE>::SwapMutator(GAGenome & c, float pmut){ GA3DArrayGenome<ARRAY_TYPE> &child=DYN_CAST(GA3DArrayGenome<ARRAY_TYPE>&, c); register int n, i; if(pmut <= 0.0) return(0); float nMut = pmut * STA_CAST(float,child.size()); int size = child.size()-1; if(nMut < 1.0){ // we have to do a flip test on each bit nMut = 0; for(i=size; i>=0; i--){ if(GAFlipCoin(pmut)){ child.GAArray<ARRAY_TYPE>::swap(i, GARandomInt(0, size)); nMut++; } } } else{ // only flip the number of bits we need to flip for(n=0; n<nMut; n++) child.GAArray<ARRAY_TYPE>::swap(GARandomInt(0, size), GARandomInt(0, size)); } return(STA_CAST(int,nMut));}template <class ARRAY_TYPE> floatGA3DArrayGenome<ARRAY_TYPE>::ElementComparator(const GAGenome& a, const GAGenome& b){ const GA3DArrayGenome<ARRAY_TYPE>& sis= DYN_CAST(const GA3DArrayGenome<ARRAY_TYPE>&, a); const GA3DArrayGenome<ARRAY_TYPE>& bro= DYN_CAST(const GA3DArrayGenome<ARRAY_TYPE>&, b); if(sis.size() != bro.size()) return -1; if(sis.size() == 0) return 0; float count = 0.0; for(int i=sis.width()-1; i>=0; i--) for(int j=sis.height()-1; j>=0; j--) for(int k=sis.depth()-1; k>=0; k--) count += ((sis.gene(i,j,k) == bro.gene(i,j,k)) ? 0 : 1); return count/sis.size();}// 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!template <class T> intGA3DArrayGenome<T>::UniformCrossover(const GAGenome& p1, const GAGenome& p2, GAGenome* c1, GAGenome* c2){ const GA3DArrayGenome<T> &mom=DYN_CAST(const GA3DArrayGenome<T> &, p1); const GA3DArrayGenome<T> &dad=DYN_CAST(const GA3DArrayGenome<T> &, p2); int nc=0; int i,j,k; if(c1 && c2){ GA3DArrayGenome<T> &sis=DYN_CAST(GA3DArrayGenome<T> &, *c1); GA3DArrayGenome<T> &bro=DYN_CAST(GA3DArrayGenome<T> &, *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 startx, starty, startz; int maxx = (sis.width() > bro.width()) ? sis.width() : bro.width(); int minx = (mom.width() < dad.width()) ? mom.width() : dad.width(); int maxy = (sis.height() > bro.height()) ? sis.height() : bro.height(); int miny = (mom.height() < dad.height()) ? mom.height() : dad.height(); int maxz = (sis.depth() > bro.depth()) ? sis.depth() : bro.depth(); int minz = (mom.depth() < dad.depth()) ? 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(); startx = (sis.width() < minx) ? sis.width() : minx; starty = (sis.height() < miny) ? sis.height() : miny; startz = (sis.depth() < minz) ? sis.depth() : minz; for(i=startx-1; i>=0; i--) for(j=starty-1; j>=0; j--) for(k=startz-1; k>=0; k--) sis.gene(i,j,k, (mask[i*starty*startz+j*startz+k] ? mom.gene(i,j,k) : dad.gene(i,j,k))); startx = (bro.width() < minx) ? bro.width() : minx; starty = (bro.height() < miny) ? bro.height() : miny; startz = (bro.depth() < minz) ? bro.depth() : minz; for(i=startx-1; i>=0; i--) for(j=starty-1; j>=0; j--) for(k=startz-1; k>=0; k--) bro.gene(i,j,k, (mask[i*starty*startz+j*startz+k] ? dad.gene(i,j,k) : mom.gene(i,j,k))); } nc = 2; } else if(c1){ GA3DArrayGenome<T> &sis=DYN_CAST(GA3DArrayGenome<T> &, *c1); 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 = (mom.width() < dad.width()) ? mom.width() : dad.width(); int miny = (mom.height() < dad.height()) ? mom.height() : dad.height(); int minz = (mom.depth() < dad.depth()) ? mom.depth() : dad.depth(); minx = (sis.width() < minx) ? sis.width() : minx; miny = (sis.height() < miny) ? sis.height() : miny; minz = (sis.depth() < minz) ? 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;}// 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!template <class T> intGA3DArrayGenome<T>::EvenOddCrossover(const GAGenome& p1, const GAGenome& p2, GAGenome* c1, GAGenome* c2){ const GA3DArrayGenome<T> &mom=DYN_CAST(const GA3DArrayGenome<T> &, p1); const GA3DArrayGenome<T> &dad=DYN_CAST(const GA3DArrayGenome<T> &, p2); int nc=0; int i,j,k; if(c1 && c2){ GA3DArrayGenome<T> &sis=DYN_CAST(GA3DArrayGenome<T> &, *c1); GA3DArrayGenome<T> &bro=DYN_CAST(GA3DArrayGenome<T> &, *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--){ sis.gene(i,j,k,((count%2 == 0) ? mom.gene(i,j,k):dad.gene(i,j,k))); bro.gene(i,j,k,((count%2 == 0) ? dad.gene(i,j,k):mom.gene(i,j,k))); count++; } } } } else{ int startx, starty, startz; int maxx = (sis.width() > bro.width()) ? sis.width() : bro.width(); int minx = (mom.width() < dad.width()) ? mom.width() : dad.width(); int maxy = (sis.height() > bro.height()) ? sis.height() : bro.height(); int miny = (mom.height() < dad.height()) ? mom.height() : dad.height(); int maxz = (sis.depth() > bro.depth()) ? sis.depth() : bro.depth(); int minz = (mom.depth() < dad.depth()) ? mom.depth() : dad.depth();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -