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

📄 garealgenome.cpp

📁 遗传算法工具箱C++
💻 CPP
字号:
// $Header$/* ----------------------------------------------------------------------------  real.C  mbwall 11nov95  Copyright (c) 1995-1996 Massachusetts Institute of Technology                          all rights reserved DESCRIPTION:   Source file for the real number specialization of the array genome.---------------------------------------------------------------------------- */#include "GARealGenome.h"// We must also specialize the allele set so that the alleles are handled// properly.  Be sure to handle bounds correctly whether we are discretized// or continuous.  Handle the case where someone sets stupid bounds that // might cause an infinite loop for exclusive bounds.template <> floatGAAlleleSet<float>::allele() const {  float value = 0.0;  if(core->type == GAAllele::ENUMERATED)    value = core->a[GARandomInt(0, core->sz-1)];  else if(core->type == GAAllele::DISCRETIZED){    float n = (core->a[1] - core->a[0]) / core->a[2];    int m = (int)n;    if(core->lowerb == GAAllele::EXCLUSIVE) m -= 1;    if(core->upperb == GAAllele::EXCLUSIVE) m -= 1;    value = core->a[0] + GARandomInt(0,(int)m) * core->a[2];    if(core->lowerb == GAAllele::EXCLUSIVE) value += core->a[2];  }  else{    if(core->a[0] == core->a[1] &&        core->lowerb == GAAllele::EXCLUSIVE &&        core->upperb == GAAllele::EXCLUSIVE) {      value = core->a[0];    }    else {      do {	value = GARandomFloat(core->a[0], core->a[1]);      } while ((core->lowerb == GAAllele::EXCLUSIVE && value == core->a[0]) ||	       (core->upperb == GAAllele::EXCLUSIVE && value == core->a[1]));    }  }  return value;}// If someone asks for a discretized item that is beyond the bounds, give them// one of the bounds.  If they ask for allele item when there is no// discretization or enumeration, then error and return lower bound.template <> floatGAAlleleSet<float>::allele(unsigned int i) const {  float value = 0.0;  if(core->type == GAAllele::ENUMERATED)    value = core->a[i % core->sz];  else if(core->type == GAAllele::DISCRETIZED){    float n = (core->a[1] - core->a[0])/core->a[2];    unsigned int m = (unsigned int)n;            // what about bogus limits?    if(core->lowerb == GAAllele::EXCLUSIVE) m -= 1;    if(core->upperb == GAAllele::EXCLUSIVE) m -= 1;    if(i > m) i = (int)m;    value = core->a[0] + i*core->a[2];    if(core->lowerb == GAAllele::EXCLUSIVE) value += core->a[2];  }  else{    GAErr(GA_LOC, "GAAlleleSet", "allele", gaErrNoAlleleIndex);    value = core->a[0];  }  return value;}// now the specialization of the genome itself.template <> const char * GA1DArrayAlleleGenome<float>::className() const {return "GARealGenome";}template <> int GA1DArrayAlleleGenome<float>::classID() const {return GAID::FloatGenome;}template <> GA1DArrayAlleleGenome<float>::GA1DArrayAlleleGenome(unsigned int length, const GAAlleleSet<float> & s,		      GAGenome::Evaluator f, void * u) :GA1DArrayGenome<float>(length, f, u){  naset = 1;  aset = new GAAlleleSet<float>[1];  aset[0] = s;  initializer(DEFAULT_REAL_INITIALIZER);  mutator(DEFAULT_REAL_MUTATOR);  comparator(DEFAULT_REAL_COMPARATOR);  crossover(DEFAULT_REAL_CROSSOVER);}template <> GA1DArrayAlleleGenome<float>::GA1DArrayAlleleGenome(const GAAlleleSetArray<float> & sa,		      GAGenome::Evaluator f, void * u) :GA1DArrayGenome<float>(sa.size(), f, u){  naset = sa.size();  aset = new GAAlleleSet<float>[naset];  for(int i=0; i<naset; i++)    aset[i] = sa.set(i);  initializer(DEFAULT_REAL_INITIALIZER);  mutator(DEFAULT_REAL_MUTATOR);  comparator(DEFAULT_REAL_COMPARATOR);  crossover(DEFAULT_REAL_CROSSOVER);}template <> GA1DArrayAlleleGenome<float>::~GA1DArrayAlleleGenome(){  delete [] aset;}#ifdef GALIB_USE_STREAMS// The read specialization takes in each number and stuffs it into the array.template <> intGA1DArrayAlleleGenome<float>::read(STD_ISTREAM & is) {  unsigned int i=0;  float val;  do{    is >> val;    if(!is.fail()) gene(i++, val);  } while(!is.fail() && !is.eof() && i < nx);  if(is.eof() && i < nx){    GAErr(GA_LOC, className(), "read", gaErrUnexpectedEOF);    is.clear(STD_IOS_BADBIT | is.rdstate());    return 1;  }  return 0;}// No need to specialize the write method.#endif/* ----------------------------------------------------------------------------   Operator specializations---------------------------------------------------------------------------- */// The Gaussian mutator picks a new value based on a Gaussian distribution// around the current value.  We respect the bounds (if any).//*** need to figure out a way to make the stdev other than 1.0 int GARealGaussianMutator(GAGenome& g, float pmut){  GA1DArrayAlleleGenome<float> &child=    DYN_CAST(GA1DArrayAlleleGenome<float> &, g);  register int n, i;  if(pmut <= 0.0) return(0);  float nMut = pmut * (float)(child.length());  int length = child.length()-1;  if(nMut < 1.0){		// we have to do a flip test on each element    nMut = 0;    for(i=length; i>=0; i--){      float value = child.gene(i);      if(GAFlipCoin(pmut)){	if(child.alleleset(i).type() == GAAllele::ENUMERATED ||	   child.alleleset(i).type() == GAAllele::DISCRETIZED)	  value = child.alleleset(i).allele();	else if(child.alleleset(i).type() == GAAllele::BOUNDED){	  value += GAUnitGaussian();	  value = GAMax(child.alleleset(i).lower(), value);	  value = GAMin(child.alleleset(i).upper(), value);	}	child.gene(i, value);	nMut++;      }    }  }  else{				// only mutate the ones we need to    for(n=0; n<nMut; n++){      int idx = GARandomInt(0,length);      float value = child.gene(idx);      if(child.alleleset(idx).type() == GAAllele::ENUMERATED ||	 child.alleleset(idx).type() == GAAllele::DISCRETIZED)	value = child.alleleset(idx).allele();      else if(child.alleleset(idx).type() == GAAllele::BOUNDED){	value += GAUnitGaussian();	value = GAMax(child.alleleset(idx).lower(), value);	value = GAMin(child.alleleset(idx).upper(), value);      }      child.gene(idx, value);    }  }  return((int)nMut);}// Arithmetic crossover generates a new value that is the average of the parent// values.  Note that this means both children in a sexual crossover will be// identical.  If parents are not the same length, the extra elements are not// set!  You might want to add some noise to this so that both children are not// the same...int GARealArithmeticCrossover(const GAGenome& p1, const GAGenome& p2,			  GAGenome* c1, GAGenome* c2) {  const GA1DArrayGenome<float> &mom=    DYN_CAST(const GA1DArrayGenome<float> &, p1);  const GA1DArrayGenome<float> &dad=    DYN_CAST(const GA1DArrayGenome<float> &, p2);  int n=0;  if(c1 && c2){    GA1DArrayGenome<float> &sis=DYN_CAST(GA1DArrayGenome<float> &, *c1);    GA1DArrayGenome<float> &bro=DYN_CAST(GA1DArrayGenome<float> &, *c2);    int len = GAMax(mom.length(), dad.length());    for(int i=0; i<len; i++) {      sis.gene(i, 0.5 * (mom.gene(i) + dad.gene(i)));      bro.gene(i, 0.5 * (mom.gene(i) + dad.gene(i)));    }    n = 2;  }  else if(c1 || c2){    GA1DArrayGenome<float> &sis = (c1 ? 				   DYN_CAST(GA1DArrayGenome<float> &, *c1) : 				   DYN_CAST(GA1DArrayGenome<float> &, *c2));    int len = GAMax(mom.length(), dad.length());    for(int i=0; i<len; i++) {      sis.gene(i, 0.5 * (mom.gene(i) + dad.gene(i)));    }    n = 1;  }  return n;}// Blend crossover generates a new value based on the interval between parents.// We generate a uniform distribution based on the distance between parent// values, then choose the child value based upon that distribution.int GARealBlendCrossover(const GAGenome& p1, const GAGenome& p2,		     GAGenome* c1, GAGenome* c2) {  const GA1DArrayGenome<float> &mom=    DYN_CAST(const GA1DArrayGenome<float> &, p1);  const GA1DArrayGenome<float> &dad=    DYN_CAST(const GA1DArrayGenome<float> &, p2);  int n=0;  if(c1 && c2){    GA1DArrayGenome<float> &sis=DYN_CAST(GA1DArrayGenome<float> &, *c1);    GA1DArrayGenome<float> &bro=DYN_CAST(GA1DArrayGenome<float> &, *c2);    int len = GAMax(mom.length(), dad.length());    for(int i=0; i<len; i++) {      float dist = 0;      if(mom.gene(i) > dad.gene(i)) 	dist = mom.gene(i) - dad.gene(i);      else 	dist = dad.gene(i) - mom.gene(i);      float lo = (GAMin(mom.gene(i), dad.gene(i))) - 0.5*dist;      float hi = (GAMax(mom.gene(i), dad.gene(i))) + 0.5*dist;      sis.gene(i, GARandomFloat(lo, hi));      bro.gene(i, GARandomFloat(lo, hi));    }    n = 2;  }  else if(c1 || c2){    GA1DArrayGenome<float> &sis = (c1 ?				   DYN_CAST(GA1DArrayGenome<float> &, *c1) :				   DYN_CAST(GA1DArrayGenome<float> &, *c2));    int len = GAMax(mom.length(), dad.length());    for(int i=0; i<len; i++) {      float dist = 0;      if(mom.gene(i) > dad.gene(i)) 	dist = mom.gene(i) - dad.gene(i);      else 	dist = dad.gene(i) - mom.gene(i);      float lo = (GAMin(mom.gene(i), dad.gene(i))) - 0.5*dist;      float hi = (GAMax(mom.gene(i), dad.gene(i))) + 0.5*dist;      sis.gene(i, GARandomFloat(lo, hi));    }    n = 1;  }  return n;}// force instantiations of this genome type.//// These must be included _after_ the specializations because some compilers// get all wigged out about the declaration/specialization order.  Note that// some compilers require a syntax different than others when forcing the // instantiation (i.e. GNU wants the 'template class', borland does not).#ifndef GALIB_USE_AUTO_INST#include "GAAllele.cpp"#include "GA1DArrayGenome.cpp"#if defined(__BORLANDC__)#define GALIB_REALGENOME_TEMPLATE_PREFACE#else#define GALIB_REALGENOME_TEMPLATE_PREFACE template class#endifGALIB_REALGENOME_TEMPLATE_PREFACE GAAlleleSet<float>;GALIB_REALGENOME_TEMPLATE_PREFACE GAAlleleSetCore<float>;GALIB_REALGENOME_TEMPLATE_PREFACE GAAlleleSetArray<float>;GALIB_REALGENOME_TEMPLATE_PREFACE GAArray<float>;GALIB_REALGENOME_TEMPLATE_PREFACE GA1DArrayGenome<float>;GALIB_REALGENOME_TEMPLATE_PREFACE GA1DArrayAlleleGenome<float>;#endif

⌨️ 快捷键说明

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