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

📄 ga1darraygenome.cpp

📁 遗传算法工具箱C++
💻 CPP
📖 第 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> intGA1DArrayGenome<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> intGA1DArrayIsHole(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> intGA1DArrayGenome<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> intGA1DArrayGenome<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 + -