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

📄 ga1darraygenome.cpp

📁 遗传算法工具箱C++
💻 CPP
📖 第 1 页 / 共 3 页
字号:
      if(GAFlipCoin(pmut)){	child.gene(i, child.alleleset(i).allele());	nMut++;      }    }  }  else{				// only flip the number of bits we need to flip    for(n=0; n<nMut; n++){      i = GARandomInt(0, child.length()-1);      child.gene(i, child.alleleset(i).allele());    }  }  return(STA_CAST(int,nMut));}// Randomly swap elements in the array.template <class ARRAY_TYPE> int GA1DArrayGenome<ARRAY_TYPE>::SwapMutator(GAGenome & c, float pmut){  GA1DArrayGenome<ARRAY_TYPE> &child=DYN_CAST(GA1DArrayGenome<ARRAY_TYPE>&, c);  register int n, i;  if(pmut <= 0.0) return(0);  float nMut = pmut * STA_CAST(float,child.length());  int length = child.length()-1;  if(nMut < 1.0){		// we have to do a flip test on each bit    nMut = 0;    for(i=length; i>=0; i--){      if(GAFlipCoin(pmut)){	child.swap(i, GARandomInt(0, length));	nMut++;      }    }  }  else{				// only flip the number of bits we need to flip    for(n=0; n<nMut; n++)      child.swap(GARandomInt(0, length), GARandomInt(0, length));  }  return(STA_CAST(int,nMut));}// The comparator is supposed to return a number that indicates how similar// two genomes are, so here we just compare elements and return a number that// indicates how many elements match.  If they are different lengths then we// return -1 to indicate that we could not calculate the differences.//   This assumes that there is an operator == defined for the object in the// elements of the array.template <class ARRAY_TYPE> floatGA1DArrayGenome<ARRAY_TYPE>::ElementComparator(const GAGenome& a, const GAGenome& b){  const GA1DArrayGenome<ARRAY_TYPE>& sis=    DYN_CAST(const GA1DArrayGenome<ARRAY_TYPE>&, a);  const GA1DArrayGenome<ARRAY_TYPE>& bro=    DYN_CAST(const GA1DArrayGenome<ARRAY_TYPE>&, b);  if(sis.length() != bro.length()) return -1;  if(sis.length() == 0) return 0;  float count = 0.0;  for(int i=sis.length()-1; i>=0; i--)    count += ((sis.gene(i) == bro.gene(i)) ? 0 : 1);  return count/sis.length();}#define SWAP(a,b) {unsigned int tmp=a; a=b; b=tmp;}// Randomly take bits from each parent.  For each bit we flip a coin to see if// that bit should come from the mother or the father.  If strings are // different lengths then we need to use the mask to get things right.template <class T> intGA1DArrayGenome<T>::UniformCrossover(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 n=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>=0; i--){	if(GARandomBit()){	  sis.gene(i, mom.gene(i));	  bro.gene(i, dad.gene(i));	}	else{	  sis.gene(i, dad.gene(i));	  bro.gene(i, mom.gene(i));	}      }    }    else{      GAMask mask;      int start;      int max = (sis.length() > bro.length()) ? sis.length() : bro.length();      int min = (mom.length() < dad.length()) ? mom.length() : dad.length();      mask.size(max);      for(i=0; i<max; i++)	mask[i] = GARandomBit();      start = (sis.length() < min) ? sis.length()-1 : min-1;      for(i=start; i>=0; i--)	sis.gene(i, (mask[i] ? mom.gene(i) : dad.gene(i)));      start = (bro.length() < min) ? bro.length()-1 : min-1;      for(i=start; i>=0; i--)	bro.gene(i, (mask[i] ? dad.gene(i) : mom.gene(i)));    }    n = 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>=0; i--)	sis.gene(i, (GARandomBit() ? mom.gene(i) : dad.gene(i)));    }    else{      int min = (mom.length() < dad.length()) ? mom.length() : dad.length();      min = (sis.length() < min) ? sis.length() : min;      for(i=min-1; i>=0; i--)	sis.gene(i, (GARandomBit() ? mom.gene(i) : dad.gene(i)));    }    n = 1;  }  return n;}// Single point crossover for 1D array genomes.  Pick a single point then// copy genetic material from each parent.  We must allow for resizable genomes// so be sure to check the behaviours before we do the crossovers.  If resizing// is allowed then the children will change depending on where the site is// located.  It is also possible to have a mixture of resize behaviours, but// we won't worry about that at this point.  If this happens we just say that// we cannot handle that and post an error message.template <class T> intGA1DArrayGenome<T>::OnePointCrossover(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;  unsigned int momsite, momlen;  unsigned int dadsite, dadlen;  if(c1 && c2){    GA1DArrayGenome<T> &sis=DYN_CAST(GA1DArrayGenome<T> &, *c1);    GA1DArrayGenome<T> &bro=DYN_CAST(GA1DArrayGenome<T> &, *c2);    if(sis.resizeBehaviour() == GAGenome::FIXED_SIZE &&       bro.resizeBehaviour() == GAGenome::FIXED_SIZE){      if(mom.length() != dad.length() || 	 sis.length() != bro.length() ||	 sis.length() != mom.length()){	GAErr(GA_LOC, mom.className(), "one-point cross", gaErrSameLengthReqd);	return nc;      }      momsite = dadsite = GARandomInt(0, mom.length());      momlen = dadlen = mom.length() - momsite;    }    else if(sis.resizeBehaviour() == GAGenome::FIXED_SIZE ||	    bro.resizeBehaviour() == GAGenome::FIXED_SIZE){      GAErr(GA_LOC, mom.className(), "one-point cross", gaErrSameBehavReqd);      return nc;    }    else{      momsite = GARandomInt(0, mom.length());      dadsite = GARandomInt(0, dad.length());      momlen = mom.length() - momsite;      dadlen = dad.length() - dadsite;      sis.resize(momsite+dadlen);      bro.resize(dadsite+momlen);    }        sis.copy(mom, 0, 0, momsite);    sis.copy(dad, momsite, dadsite, dadlen);    bro.copy(dad, 0, 0, dadsite);    bro.copy(mom, dadsite, momsite, momlen);      nc = 2;  }  else if(c1 || c2){    GA1DArrayGenome<T> &sis = (c1 ? 			       DYN_CAST(GA1DArrayGenome<T> &, *c1) : 			       DYN_CAST(GA1DArrayGenome<T> &, *c2));    if(sis.resizeBehaviour() == GAGenome::FIXED_SIZE){      if(mom.length() != dad.length() || sis.length() != mom.length()){	GAErr(GA_LOC, mom.className(), "one-point cross", gaErrSameLengthReqd);	return nc;      }      momsite = dadsite = GARandomInt(0, mom.length());      momlen = dadlen = mom.length() - momsite;    }    else{      momsite = GARandomInt(0, mom.length());      dadsite = GARandomInt(0, dad.length());      momlen = mom.length() - momsite;      dadlen = dad.length() - dadsite;      sis.resize(momsite+dadlen);    }        if(GARandomBit()){      sis.copy(mom, 0, 0, momsite);      sis.copy(dad, momsite, dadsite, dadlen);    }    else{      sis.copy(dad, 0, 0, dadsite);      sis.copy(mom, dadsite, momsite, momlen);    }    nc = 1;  }  return nc;}// Two point crossover for the 1D array genome.  Similar to the single point// crossover, but here we pick two points then grab the sections based upon // those two points.//   When we pick the points, it doesn't matter where they fall (one is not// dependent upon the other).  Make sure we get the lesser one into the first// position of our site array.template <class T> intGA1DArrayGenome<T>::TwoPointCrossover(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;  unsigned int momsite[2], momlen[2];  unsigned int dadsite[2], dadlen[2];  if(c1 && c2){    GA1DArrayGenome<T> &sis=DYN_CAST(GA1DArrayGenome<T> &, *c1);    GA1DArrayGenome<T> &bro=DYN_CAST(GA1DArrayGenome<T> &, *c2);    if(sis.resizeBehaviour() == GAGenome::FIXED_SIZE &&       bro.resizeBehaviour() == GAGenome::FIXED_SIZE){      if(mom.length() != dad.length() || 	 sis.length() != bro.length() ||	 sis.length() != mom.length()){	GAErr(GA_LOC, mom.className(), "two-point cross", gaErrSameLengthReqd);	return nc;      }      momsite[0] = GARandomInt(0, mom.length());      momsite[1] = GARandomInt(0, mom.length());      if(momsite[0] > momsite[1]) SWAP(momsite[0], momsite[1]);      momlen[0] = momsite[1] - momsite[0];      momlen[1] = mom.length() - momsite[1];            dadsite[0] = momsite[0];      dadsite[1] = momsite[1];      dadlen[0] = momlen[0];      dadlen[1] = momlen[1];    }    else if(sis.resizeBehaviour() == GAGenome::FIXED_SIZE ||	    bro.resizeBehaviour() == GAGenome::FIXED_SIZE){      return nc;    }    else{      momsite[0] = GARandomInt(0, mom.length());      momsite[1] = GARandomInt(0, mom.length());      if(momsite[0] > momsite[1]) SWAP(momsite[0], momsite[1]);      momlen[0] = momsite[1] - momsite[0];      momlen[1] = mom.length() - momsite[1];            dadsite[0] = GARandomInt(0, dad.length());      dadsite[1] = GARandomInt(0, dad.length());      if(dadsite[0] > dadsite[1]) SWAP(dadsite[0], dadsite[1]);      dadlen[0] = dadsite[1] - dadsite[0];      dadlen[1] = dad.length() - dadsite[1];            sis.resize(momsite[0]+dadlen[0]+momlen[1]);      bro.resize(dadsite[0]+momlen[0]+dadlen[1]);    }    sis.copy(mom, 0, 0, momsite[0]);    sis.copy(dad, momsite[0], dadsite[0], dadlen[0]);    sis.copy(mom, momsite[0]+dadlen[0], momsite[1], momlen[1]);    bro.copy(dad, 0, 0, dadsite[0]);    bro.copy(mom, dadsite[0], momsite[0], momlen[0]);    bro.copy(dad, dadsite[0]+momlen[0], dadsite[1], dadlen[1]);    nc = 2;  }  else if(c1 || c2){    GA1DArrayGenome<T> &sis = (c1 ?			       DYN_CAST(GA1DArrayGenome<T> &, *c1) :			       DYN_CAST(GA1DArrayGenome<T> &, *c2));    if(sis.resizeBehaviour() == GAGenome::FIXED_SIZE){      if(mom.length() != dad.length() || sis.length() != mom.length()){	GAErr(GA_LOC, mom.className(), "two-point cross", gaErrSameLengthReqd);	return nc;      }      momsite[0] = GARandomInt(0, mom.length());      momsite[1] = GARandomInt(0, mom.length());      if(momsite[0] > momsite[1]) SWAP(momsite[0], momsite[1]);      momlen[0] = momsite[1] - momsite[0];      momlen[1] = mom.length() - momsite[1];            dadsite[0] = momsite[0];      dadsite[1] = momsite[1];      dadlen[0] = momlen[0];      dadlen[1] = momlen[1];    }    else{      momsite[0] = GARandomInt(0, mom.length());      momsite[1] = GARandomInt(0, mom.length());      if(momsite[0] > momsite[1]) SWAP(momsite[0], momsite[1]);      momlen[0] = momsite[1] - momsite[0];      momlen[1] = mom.length() - momsite[1];            dadsite[0] = GARandomInt(0, dad.length());      dadsite[1] = GARandomInt(0, dad.length());      if(dadsite[0] > dadsite[1]) SWAP(dadsite[0], dadsite[1]);      dadlen[0] = dadsite[1] - dadsite[0];      dadlen[1] = dad.length() - dadsite[1];      sis.resize(momsite[0]+dadlen[0]+momlen[1]);    }    if(GARandomBit()){      sis.copy(mom, 0, 0, momsite[0]);      sis.copy(dad, momsite[0], dadsite[0], dadlen[0]);      sis.copy(mom, momsite[0]+dadlen[0], momsite[1], momlen[1]);    }    else{      sis.copy(dad, 0, 0, dadsite[0]);      sis.copy(mom, dadsite[0], momsite[0], momlen[0]);      sis.copy(dad, dadsite[0]+momlen[0], dadsite[1], dadlen[1]);    }    nc = 1;  }  return nc;}// Even and odd crossover for the array works just like it does for the // binary strings.  For even crossover we take the 0th element and every other// one after that from the mother.  The 1st and every other come from the// father.  For odd crossover, we do just the opposite.template <class T> int

⌨️ 快捷键说明

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