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

📄 gademega.cpp

📁 遗传算法工具箱C++
💻 CPP
字号:
/* ----------------------------------------------------------------------------  gademe.C  mbwall 28jul94  Copyright (c) 1995-1996 Massachusetts Institute of Technology                          all rights reserved   Souce file for the deme-based genetic algorithm object.---------------------------------------------------------------------------- */#include "garandom.h"#include "GADemeGA.h"GAParameterList&GADemeGA::registerDefaultParameters(GAParameterList& p) {  GAGeneticAlgorithm::registerDefaultParameters(p);  p.add(gaNnPopulations, gaSNnPopulations, GAParameter::INT, &gaDefNPop);  p.add(gaNnMigration, gaSNnMigration, GAParameter::INT, &gaDefNMig);  return p;}GADemeGA::GADemeGA(const GAGenome& c) : GAGeneticAlgorithm(c) {  npop = gaDefNPop;  params.add(gaNnPopulations, gaSNnPopulations, GAParameter::INT, &npop);  nmig = gaDefNMig;  params.add(gaNnMigration, gaSNnMigration, GAParameter::INT, &nmig);  unsigned int nr = pop->size()/2;  nrepl = new int [npop];  deme = new GAPopulation* [npop];  pstats = new GAStatistics [npop];  tmppop = new GAPopulation(c, nr);  for(unsigned int i=0; i<npop; i++) {    nrepl[i] = nr;    deme[i] = new GAPopulation(*pop);  }}GADemeGA::GADemeGA(const GAPopulation& p) : GAGeneticAlgorithm(p) {  if(p.size() < 1) {    GAErr(GA_LOC, className(), "GADemeGA(GAPopulation&)", gaErrNoIndividuals);    pop = 0; nrepl = 0; tmppop = 0; pstats = 0;  }  else {    npop = gaDefNPop;    params.add(gaNnPopulations, gaSNnPopulations, GAParameter::INT, &npop);    nmig = gaDefNMig;    params.add(gaNnMigration, gaSNnMigration, GAParameter::INT, &nmig);    unsigned int nr = pop->size()/2;    nrepl = new int [npop];    deme = new GAPopulation* [npop];    pstats = new GAStatistics [npop];    tmppop = new GAPopulation(p.individual(0), nr);        for(unsigned int i=0; i<npop; i++) {      nrepl[i] = nr;      deme[i] = new GAPopulation(p);    }  }}GADemeGA::GADemeGA(const GADemeGA& orig) : GAGeneticAlgorithm(orig) {  deme = 0; nrepl = 0; tmppop = 0; pstats = 0;  copy(orig);}GADemeGA::~GADemeGA(){  for(unsigned int i=0; i<npop; i++)    delete deme[i];  delete [] deme;  delete [] nrepl;  delete [] pstats;  delete tmppop;}GADemeGA&GADemeGA::operator=(const GADemeGA& orig){  if(&orig != this) copy(orig);   return *this;}voidGADemeGA::copy(const GAGeneticAlgorithm& g){  GAGeneticAlgorithm::copy(g);  const GADemeGA& ga = DYN_CAST(const GADemeGA&,g);  unsigned int i;  for(i=0; i<npop; i++)    delete deme[i];  delete [] deme;  delete [] nrepl;  delete [] pstats;  nmig = ga.nmig;  npop = ga.npop;  nrepl = new int [npop];  deme = new GAPopulation* [npop];  memcpy(nrepl, ga.nrepl, npop * sizeof(int));  for(i=0; i<npop; i++)     deme[i]->copy(*(ga.deme[i]));  tmppop->copy(*(ga.tmppop));    pstats = new GAStatistics[npop];  for(i=0; i<npop; i++)    pstats[i] = ga.pstats[i];}// We make sure that the replacement pop is always at least one individual.  If// the percentage replacement is specified then we use that to determine the// size of the tmp pop.  Otherwise we use the absolute number of individuals.// If we're using absolute number then we don't have to resize the tmp pop.intGADemeGA::setptr(const char* name, const void* value){  int status = GAGeneticAlgorithm::setptr(name, value);  if(strcmp(name, gaNnPopulations) == 0 ||	  strcmp(name, gaSNnPopulations) == 0){    nPopulations(*((int*)value));    status = 0;  }  else if(strcmp(name, gaNnMigration) == 0 ||	  strcmp(name, gaSNnMigration) == 0){    nMigration(*((int*)value));    status = 0;  }  return status;}intGADemeGA::get(const char* name, void* value) const {  int status = GAGeneticAlgorithm::get(name, value);  if(strcmp(name, gaNnPopulations) == 0 || 	  strcmp(name, gaSNnPopulations) == 0){    *((int*)value) = npop;    status = 0;  }  else if(strcmp(name, gaNnMigration) == 0 || 	  strcmp(name, gaSNnMigration) == 0){    *((int*)value) = nmig;    status = 0;  }  return status;}void GADemeGA::objectiveFunction(int i, GAGenome::Evaluator f){  if(i == ALL)    for(unsigned int ii=0; ii<npop; ii++)      for(int jj=0; jj<deme[ii]->size(); jj++)	deme[ii]->individual(jj).evaluator(f);  else    for(int jj=0; jj<deme[i]->size(); jj++)      deme[i]->individual(jj).evaluator(f);}voidGADemeGA::objectiveData(int i, const GAEvalData& v){  if(i == ALL)    for(unsigned int ii=0; ii<npop; ii++)      for(int jj=0; jj<deme[ii]->size(); jj++)	deme[ii]->individual(jj).evalData(v);  else    for(int jj=0; jj<deme[i]->size(); jj++)      deme[i]->individual(jj).evalData(v);}const GAPopulation&GADemeGA::population(int i, const GAPopulation& p) {  if(i == ALL)    for(unsigned int ii=0; ii<npop; ii++)      *deme[ii] = p;  else    *deme[i] = p;  return *deme[((i==ALL) ? 0 : i)];}intGADemeGA::populationSize(int i, unsigned int value){  if(value < 1){    GAErr(GA_LOC, className(), "populationSize", gaErrBadPopSize);    value = 1;  }  if(i == ALL)    for(unsigned int ii=0; ii<npop; ii++)      deme[ii]->size(value);  else    deme[i]->size(value);  return value;}intGADemeGA::nReplacement(int i, unsigned int value){  if(i == ALL) {    for(unsigned int ii=0; ii<npop; ii++){      if(value > (unsigned int)deme[ii]->size()) 	GAErr(GA_LOC, className(), "nReplacement", gaErrBadPRepl);      else {	params.set(gaNnReplacement, (unsigned int)value);	nrepl[ii] = value;      }    }  }  else {    if(value > (unsigned int)deme[i]->size())      GAErr(GA_LOC, className(), "nReplacement", gaErrBadNRepl);    else      nrepl[i] = value;  }  if((unsigned int)(tmppop->size()) < value) {    tmppop->size(value);  }  return value;}GAScalingScheme& GADemeGA::scaling(int i, const GAScalingScheme & s){  if(i == ALL)    for(unsigned int ii=0; ii<npop; ii++)      deme[ii]->scaling(s);  else    deme[i]->scaling(s);  return deme[((i==ALL) ? 0 : i)]->scaling();}GASelectionScheme&GADemeGA::selector(int i, const GASelectionScheme& s){  if(i == ALL)    for(unsigned int ii=0; ii<npop; ii++)      deme[ii]->selector(s);  else    deme[i]->selector(s);  return deme[((i==ALL) ? 0 : i)]->selector();}int GADemeGA::nMigration(unsigned int n) {  params.set(gaNnMigration, (unsigned int)n);  return nmig = n;}// change the number of populations.  try affect the evolution as little as// possible in the process, so set things to sane values where we can.intGADemeGA::nPopulations(unsigned int n) {  if(n < 1 || n == npop) return npop;  if(n < npop) {    for(unsigned int i=n; i<npop; i++)      delete deme[i];    GAPopulation** ptmp = deme;    deme = new GAPopulation* [n];    memcpy(deme, ptmp, n * sizeof(GAPopulation*));    delete [] ptmp;    GAStatistics* stmp = pstats;    pstats = new GAStatistics[n];    for(unsigned int j=0; j<n; j++)      pstats[j] = stmp[j];    delete [] stmp;    int* rtmp = nrepl;    nrepl = new int[n];    memcpy(nrepl, rtmp, n * sizeof(int));    delete [] rtmp;    npop = n;  }  else {    GAPopulation** ptmp = deme;    deme = new GAPopulation* [n];    memcpy(deme, ptmp, npop * sizeof(GAPopulation*));    delete [] ptmp;    for(unsigned int i=npop; i<n; i++)      deme[i] = new GAPopulation(*deme[GARandomInt(0,npop-1)]);    GAStatistics* stmp = pstats;    pstats = new GAStatistics[n];    for(unsigned int j=0; j<npop; j++)      pstats[j] = stmp[j];    delete [] stmp;    int* rtmp = nrepl;    nrepl = new int[n];    memcpy(nrepl, rtmp, npop * sizeof(int));    for(unsigned int k=npop; k<n; k++)      nrepl[k] = nrepl[0];        npop = n;  }  params.set(gaNnPopulations, (unsigned int)n);  pop->size(npop);  return npop;}intGADemeGA::minimaxi(int m) {   if(m == MINIMIZE){    tmppop->order(GAPopulation::LOW_IS_BEST);    for(unsigned int i=0; i<npop; i++)      deme[i]->order(GAPopulation::LOW_IS_BEST);  }  else{    tmppop->order(GAPopulation::HIGH_IS_BEST);    for(unsigned int i=0; i<npop; i++)      deme[i]->order(GAPopulation::HIGH_IS_BEST);  }  return GAGeneticAlgorithm::minimaxi(m);}// We only use the sexual mating, so only check for that one.  Initialize each// of the popultions and set stats appropriately.voidGADemeGA::initialize(unsigned int seed) {  GARandomSeed(seed);  for(unsigned int i=0; i<npop; i++) {    deme[i]->initialize();    deme[i]->evaluate(gaTrue);    pstats[i].reset(*deme[i]);    pop->individual(i).copy(deme[i]->best());  }  pop->touch();  stats.reset(*pop);  if(!scross) GAErr(GA_LOC, className(), "initialize", gaErrNoSexualMating);}// To evolve the genetic algorithm, we loop through all of our populations and// evolve each one of them.  Then allow the migrator to do its thing.  Assumes// that the tmp pop is at least as big as the largest nrepl that we'll use.  // The master population maintains the best n individuals from each of the// populations, and it is based on those that we keep the statistics for the// entire genetic algorithm run.voidGADemeGA::step() {  int i, mut, c1, c2;  GAGenome *mom, *dad;  float pc;  if(!scross) pc = 0.0;  else        pc = pCrossover();  for(unsigned int ii=0; ii<npop; ii++) {    for(i=0; i<nrepl[ii]-1; i+=2){	// takes care of odd population      mom = &(deme[ii]->select());       dad = &(deme[ii]->select());      pstats[ii].numsel += 2;      c1 = c2 = 0;      if(GAFlipCoin(pc)){	pstats[ii].numcro += (*scross)(*mom, *dad, &tmppop->individual(i), 				       &tmppop->individual(i+1));	c1 = c2 = 1;      }      else{	tmppop->individual( i ).copy(*mom);	tmppop->individual(i+1).copy(*dad);      }      pstats[ii].nummut += (mut=tmppop->individual( i ).mutate(pMutation()));      if(mut > 0) c1 = 1;      pstats[ii].nummut += (mut=tmppop->individual(i+1).mutate(pMutation()));      if(mut > 0) c2 = 1;      pstats[ii].numeval += c1 + c2;    }    if(nrepl[ii] % 2 != 0){	// do the remaining population member      mom = &(deme[ii]->select());       dad = &(deme[ii]->select());       pstats[ii].numsel += 2;      c1 = 0;      if(GAFlipCoin(pc)){	pstats[ii].numcro += 	  (*scross)(*mom, *dad, &tmppop->individual(i), (GAGenome*)0);	c1 = 1;      }      else{	if(GARandomBit()) tmppop->individual(i).copy(*mom);	else              tmppop->individual(i).copy(*dad);      }      pstats[ii].nummut += (mut=tmppop->individual(i).mutate(pMutation()));      if(mut > 0) c1 = 1;      pstats[ii].numeval += c1;    }    for(i=0; i<nrepl[ii]; i++)      deme[ii]->add(&tmppop->individual(i));    deme[ii]->evaluate();    deme[ii]->scale();    for(i=0; i<nrepl[ii]; i++)      tmppop->replace(deme[ii]->remove(GAPopulation::WORST,				       GAPopulation::SCALED), i);        pstats[ii].numrep += nrepl[ii];  }  migrate();  for(unsigned int jj=0; jj<npop; jj++) {    deme[jj]->evaluate();    pstats[jj].update(*deme[jj]);  }  stats.numsel = stats.numcro = stats.nummut = stats.numrep = stats.numeval=0;  for(unsigned int kk=0; kk<npop; kk++) {    pop->individual(kk).copy(deme[kk]->best());    stats.numsel += pstats[kk].numsel;    stats.numcro += pstats[kk].numcro;    stats.nummut += pstats[kk].nummut;    stats.numrep += pstats[kk].numrep;    stats.numeval += pstats[kk].numeval;  }  pop->touch();  stats.update(*pop);  for(unsigned int ll=0; ll<npop; ll++)    stats.numpeval += pstats[ll].numpeval;}// This implementation uses an island model for parallel populations in which// each population migrates a certain number of individuals to its nearest// neighbor (I've heard of this referred to as the 'stepping-stone' model).//   In this implementation we migrate the best individuals only.  This assumes// that all populations have at least nmig individuals (we don't do any checks// for conflicts).voidGADemeGA::migrate() {  GAGenome **ind;  ind = new GAGenome* [nmig];  unsigned int j;  for(j=0; j<nmig; j++)     ind[j] = &(deme[0]->individual(j));  for(unsigned int i=1; i<npop; i++) {    for(j=0; j<nmig; j++)       ind[j] = deme[i]->replace(ind[j], j);  }  for(j=0; j<nmig; j++)     deme[0]->replace(ind[j], j);  delete [] ind;}

⌨️ 快捷键说明

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