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

📄 ga1darraygenome.c

📁 关于遗传算法代码。比较全。希望能给大家带来帮助。
💻 C
📖 第 1 页 / 共 3 页
字号:
GA1DArrayGenome<T>::
EvenOddCrossover(const GAGenome& p1, const GAGenome& p2, 
		 GAGenome* c1, GAGenome* c2){
  const GA1DArrayGenome<T> &mom=DYN_CAST(const GA1DArrayGenome<T> &, p1);
  const GA1DArrayGenome<T> &dad=DYN_CAST(const GA1DArrayGenome<T> &, p2);

  int nc=0;
  int i;

  if(c1 && c2){
    GA1DArrayGenome<T> &sis=DYN_CAST(GA1DArrayGenome<T> &, *c1);
    GA1DArrayGenome<T> &bro=DYN_CAST(GA1DArrayGenome<T> &, *c2);
    if(sis.length() == bro.length() &&
       mom.length() == dad.length() &&
       sis.length() == mom.length()){
      for(i=sis.length()-1; i>=1; i-=2){
	sis.gene(i, mom.gene(i));
	bro.gene(i, dad.gene(i));
	sis.gene(i-1, dad.gene(i-1));
	bro.gene(i-1, mom.gene(i-1));
      }
      if(i==0){
	sis.gene(0, mom.gene(0));
	bro.gene(0, dad.gene(0));
      }
    }
    else{
      int start;
      int min = (mom.length() < dad.length()) ? mom.length() : dad.length();
      start = (sis.length() < min) ? sis.length()-1 : min-1;
      for(i=start; i>=0; i--)
	sis.gene(i, ((i%2 == 0) ? mom.gene(i) : dad.gene(i)));
      start = (bro.length() < min) ? bro.length()-1 : min-1;
      for(i=start; i>=0; i--)
	bro.gene(i, ((i%2 == 0) ? dad.gene(i) : mom.gene(i)));
    }

    nc = 2;
  }
  else if(c1 || c2){
    GA1DArrayGenome<T> &sis = (c1 ? 
			       DYN_CAST(GA1DArrayGenome<T> &, *c1) : 
			       DYN_CAST(GA1DArrayGenome<T> &, *c2));
    
    if(mom.length() == dad.length() && sis.length() == mom.length()){
      for(i=sis.length()-1; i>=1; i-=2){
	sis.gene(i, mom.gene(i));
	sis.gene(i-1, dad.gene(i-1));
      }
      if(i==0){
	sis.gene(0, mom.gene(0));
      }
    }
    else{
      int min = (mom.length() < dad.length()) ? mom.length() : dad.length();
      min = (sis.length() < min) ? sis.length()-1 : min-1;
      for(i=min; i>=0; i--)
	sis.gene(i, ((i%2 == 0) ? mom.gene(i) : dad.gene(i)));
    }

    nc = 1;
  }

  return nc;
}





// Partial match crossover for the 1D array genome.  This uses the partial
// matching algorithm described in Goldberg's book.
//   Parents and children must be the same size for this crossover to work.  If
// they are not, we post an error message.
//   We make sure that b will be greater than a.
template <class T> int
GA1DArrayGenome<T>::
PartialMatchCrossover(const GAGenome& p1, const GAGenome& p2, 
		      GAGenome* c1, GAGenome* c2){
  const GA1DArrayGenome<T> &mom=DYN_CAST(const GA1DArrayGenome<T> &, p1);
  const GA1DArrayGenome<T> &dad=DYN_CAST(const GA1DArrayGenome<T> &, p2);

  int nc=0;
  int a = GARandomInt(0, mom.length());
  int b = GARandomInt(0, dad.length());
  if(b < a) SWAP(a,b);
  int i,j,index;

  if(mom.length() != dad.length()){
    GAErr(GA_LOC, mom.className(), "parial match cross", gaErrBadParentLength);
    return nc;
  }
  
  if(c1 && c2){
    GA1DArrayGenome<T> &sis=DYN_CAST(GA1DArrayGenome<T> &, *c1);
    GA1DArrayGenome<T> &bro=DYN_CAST(GA1DArrayGenome<T> &, *c2);

    sis.GAArray<T>::copy(mom);
    for(i=a, index=a; i<b; i++, index++){
      for(j=0; j<sis.length()-1 && sis.gene(j) != dad.gene(index); j++);
      sis.swap(i,j);
    }
    bro.GAArray<T>::copy(dad);
    for(i=a, index=a; i<b; i++, index++){
      for(j=0; j<bro.length()-1 && bro.gene(j) != mom.gene(index); j++);
      bro.swap(i,j);
    }

    nc = 2;
  }
  else if(c1 || c2){
    GA1DArrayGenome<T> &sis = (c1 ? 
			       DYN_CAST(GA1DArrayGenome<T> &, *c1) : 
			       DYN_CAST(GA1DArrayGenome<T> &, *c2));

    const GA1DArrayGenome<T> *parent1, *parent2;
    if(GARandomBit()) { parent1 = &mom; parent2 = &dad; }
    else              { parent1 = &dad; parent2 = &mom; }

    sis.GAArray<T>::copy(*parent1);
    for(i=a, index=a; i<b; i++, index++){
      for(j=0; j<sis.length()-1 && sis.gene(j) != parent2->gene(index); j++);
      sis.swap(i,j);
    }

    nc = 1;
  }

  return nc;
}





// This function determines whether or not an indexed position is a hole that
// we can substitute into.  It does a linear search to find the holes (yuk).
template <class T> int
GA1DArrayIsHole(const GA1DArrayGenome<T> &c, const GA1DArrayGenome<T> &dad,
		int index, int a, int b){
  for(int i=a; i<b; i++)
    if(c.gene(index) == dad.gene(i)) return 1;
  return 0;
}


// Order crossover for the 1D array genome.  This uses the order crossover
// described in Goldberg's book.
//   Parents and children must be the same length.
//   We make sure that b will be greater than a.
//   This implementation isn't terribly smart.  For example, I do a linear
// search rather than caching and doing binary search or smarter hash tables.
//   First we copy the mother into the sister.  Then move the 'holes' into the
// crossover section and maintain the ordering of the non-hole elements.  
// Finally, put the 'holes' in the proper order within the crossover section.
// After we have done the sister, we do the brother.
template <class T> int
GA1DArrayGenome<T>::
OrderCrossover(const GAGenome& p1, const GAGenome& p2,
	       GAGenome* c1, GAGenome* c2){
  const GA1DArrayGenome<T> &mom=DYN_CAST(const GA1DArrayGenome<T> &, p1);
  const GA1DArrayGenome<T> &dad=DYN_CAST(const GA1DArrayGenome<T> &, p2);

  int nc=0;
  int a = GARandomInt(0, mom.length());
  int b = GARandomInt(0, mom.length());
  if(b < a) SWAP(a,b);
  int i,j, index;

  if(mom.length() != dad.length()){
    GAErr(GA_LOC, mom.className(), "order cross", gaErrBadParentLength);
    return nc;
  }
  
  if(c1 && c2){
    GA1DArrayGenome<T> &sis=DYN_CAST(GA1DArrayGenome<T> &, *c1);
    GA1DArrayGenome<T> &bro=DYN_CAST(GA1DArrayGenome<T> &, *c2);

// Copy the parent
    sis.GAArray<T>::copy(mom);

// Move all the 'holes' into the crossover section
    for(i=0, index=b; i<sis.size(); i++, index++){
      if(index >= sis.size()) index=0;
      if(GA1DArrayIsHole(sis,dad,index,a,b)) break;
    }
    
    for(; i<sis.size()-b+a; i++, index++){
      if(index >= sis.size()) index=0;
      j=index;
      do{
	j++;
	if(j >= sis.size()) j=0;
      } while(GA1DArrayIsHole(sis,dad,j,a,b));
      sis.swap(index,j);
    }

// Now put the 'holes' in the proper order within the crossover section.
    for(i=a; i<b; i++){
      if(sis.gene(i) != dad.gene(i)){
	for(j=i+1; j<b; j++)
	  if(sis.gene(j) == dad.gene(i)) sis.swap(i,j);
      }
    }

// Now do the other child
    bro.GAArray<T>::copy(dad);

// Move all the 'holes' into the crossover section
    for(i=0, index=b; i<bro.size(); i++, index++){
      if(index >= bro.size()) index=0;
      if(GA1DArrayIsHole(bro,mom,index,a,b)) break;
    }

    for(; i<bro.size()-b+a; i++, index++){
      if(index >= bro.size()) index=0;
      j=index;
      do{
	j++;
	if(j >= bro.size()) j=0;
      } while(GA1DArrayIsHole(bro,mom,j,a,b));
      bro.swap(index,j);
    }
    
// Now put the 'holes' in the proper order within the crossover section.
    for(i=a; i<b; i++){
      if(bro.gene(i) != mom.gene(i)){
	for(j=i+1; j<b; j++)
	  if(bro.gene(j) == mom.gene(i)) bro.swap(i,j);
      }
    }

    nc = 2;
  }
  else if(c1 || c2){
    GA1DArrayGenome<T> &sis = (c1 ? 
			       DYN_CAST(GA1DArrayGenome<T> &, *c1) : 
			       DYN_CAST(GA1DArrayGenome<T> &, *c2));

    const GA1DArrayGenome<T> *parent1, *parent2;
    if(GARandomBit()) { parent1 = &mom; parent2 = &dad; }
    else              { parent1 = &dad; parent2 = &mom; }

    sis.GAArray<T>::copy(*parent1);
    for(i=0, index=b; i<sis.size(); i++, index++){
      if(index >= sis.size()) index=0;
      if(GA1DArrayIsHole(sis,*parent2,index,a,b)) break;
    }
    for(; i<sis.size()-b+a; i++, index++){
      if(index >= sis.size()) index=0;
      j=index;
      do{
	j++;
	if(j >= sis.size()) j=0;
      } while(GA1DArrayIsHole(sis,*parent2,j,a,b));
      sis.swap(index,j);
    }
    for(i=a; i<b; i++){
      if(sis.gene(i) != parent2->gene(i)){
	for(j=i+1; j<b; j++)
	  if(sis.gene(j) == parent2->gene(i)) sis.swap(i,j);
      }
    }

    nc = 1;
  }

  return nc;
}








// Cycle crossover for the 1D array genome.  This is implemented as described 
// in goldberg's book.  The first is picked from mom, then cycle using dad.
// Finally, fill in the gaps with the elements from dad.
//   We allocate space for a temporary array in this routine.  It never frees
// the memory that it uses, so you might want to re-think this if you're really
// memory-constrained (similar to what we do with the uniform crossover when
// the children are resizeable).
//  Allocate space for an array of flags.  We use this to keep track of whether
// the child's contents came from the mother or the father.  We don't free the
// space here, but it is not a memory leak.
//   The first step is to cycle through mom & dad to get the cyclic part of 
// the crossover.  Then fill in the rest of the sis with dad's contents that 
// we didn't use in the cycle.  Finally, do the same thing for the other child.
//   Notice that this implementation makes serious use of the operator= for the
// objects in the array.  It also requires the operator != and == comparators.
template <class T> int
GA1DArrayGenome<T>::
CycleCrossover(const GAGenome& p1, const GAGenome& p2,
	       GAGenome* c1, GAGenome* c2){
  const GA1DArrayGenome<T> &mom=DYN_CAST(const GA1DArrayGenome<T> &, p1);
  const GA1DArrayGenome<T> &dad=DYN_CAST(const GA1DArrayGenome<T> &, p2);

  int nc=0;
  int i, current=0;

  if(mom.length() != dad.length()){
    GAErr(GA_LOC, mom.className(), "cycle cross", gaErrBadParentLength);
    return nc;
  }

  if(c1 && c2){
    GAMask mask;
    GA1DArrayGenome<T> &sis=DYN_CAST(GA1DArrayGenome<T> &, *c1);
    GA1DArrayGenome<T> &bro=DYN_CAST(GA1DArrayGenome<T> &, *c2);

    mask.size(sis.length());
    mask.clear();

    sis.gene(0, mom.gene(0));
    mask[0] = 1;
    while(dad.gene(current) != mom.gene(0)){
      for(i=0; i<sis.size(); i++){
	if(mom.gene(i) == dad.gene(current)){
	  sis.gene(i, mom.gene(i));
	  mask[i] = 1;
	  current = i;
	  break;
	}
      }
    }

    for(i=0; i<sis.size(); i++)
      if(mask[i] == 0) sis.gene(i, dad.gene(i));

    mask.clear();

    bro.gene(0, dad.gene(0));
    mask[0] = 1;
    while(mom.gene(current) != dad.gene(0)){
      for(i=0; i<bro.size(); i++){
	if(dad.gene(i) == mom.gene(current)){
	  bro.gene(i, dad.gene(i));
	  mask[i] = 1;
	  current = i;
	  break;
	}
      }
    }

    for(i=0; i<bro.size(); i++)
      if(mask[i] == 0) bro.gene(i, mom.gene(i));

    nc = 2;
  }
  else if(c1 || c2){
    GA1DArrayGenome<T> &sis = (c1 ?
			       DYN_CAST(GA1DArrayGenome<T> &, *c1) :
			       DYN_CAST(GA1DArrayGenome<T> &, *c2));

    const GA1DArrayGenome<T> *parent1, *parent2;
    if(GARandomBit()) { parent1 = &mom; parent2 = &dad; }
    else              { parent1 = &dad; parent2 = &mom; }

    GAMask mask;
    mask.size(sis.length());
    mask.clear();
    
    sis.gene(0, parent1->gene(0));
    mask[0] = 1;
    while(parent2->gene(current) != parent1->gene(0)){
      for(i=0; i<sis.size(); i++){
	if(parent1->gene(i) == parent2->gene(current)){
	  sis.gene(i, parent1->gene(i));
	  mask[i] = 1;
	  current = i;
	  break;
	}
      }
    }
    for(i=0; i<sis.size(); i++)
      if(mask[i] == 0) sis.gene(i, parent2->gene(i));

    nc = 1;
  }

  return nc;
}

#undef SWAP

#endif

⌨️ 快捷键说明

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