⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ga3darraygenome.c

📁 关于遗传算法代码。比较全。希望能给大家带来帮助。
💻 C
📖 第 1 页 / 共 3 页
字号:
  delete [] aset;
}


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> 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<STA_CAST(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;
}


#ifndef NO_STREAMS
template <class T> int
GA3DArrayAlleleGenome<T>::read(istream& is){
  return GA3DArrayGenome<T>::read(is);
}

template <class T> int
GA3DArrayAlleleGenome<T>::write(ostream& os) const {
  return GA3DArrayGenome<T>::write(os);
}
#endif

template <class T> int
GA3DArrayAlleleGenome<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> float
GA3DArrayGenome<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> int
GA3DArrayGenome<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> int
GA3DArrayGenome<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();
      startx = (sis.width() < minx) ? sis.width() : minx;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -