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

📄 gastatistics.c

📁 单目标遗传算法优化的经典例子c++源码
💻 C
📖 第 1 页 / 共 2 页
字号:
// $Header: /usr/people/mbwall/src/galib/ga/RCS/GAStatistics.C,v 1.4 1999/04/03 00:57:00 mbwall Exp $
/* ----------------------------------------------------------------------------
  statistics.C
  mbwall 28jul94
  Copyright (c) 1995 Massachusetts Institute of Technology 
                     all rights reserved

 DESCRIPTION:
  Definition of the statistics object.
---------------------------------------------------------------------------- */
#include <string.h>
#include <ga/gaerror.h>
#include <ga/GAStatistics.h>



// Default settings and their names.
int  gaDefNumBestGenomes   = 1;
int  gaDefScoreFrequency1  = 1;
int  gaDefScoreFrequency2  = 100;
int  gaDefFlushFrequency   = 0;
char gaDefScoreFilename[]  = "generations.dat";


GAStatistics::GAStatistics() {
  curgen = 0;
  numsel = numcro = nummut = numrep = numeval = numpeval = 0;
  maxever = minever = 0.0;
  on = offmax = offmin = 0.0;
  aveInit = maxInit = minInit = devInit = 0.0;
  divInit = -1.0;
  aveCur = maxCur = minCur = devCur = 0.0;
  divCur = -1.0;

  scoreFreq = gaDefScoreFrequency1;
  dodiv = gaFalse;		// default is do not calculate diversity

  nconv=0; Nconv = 10;
  cscore = new float[Nconv]; memset(cscore, 0, Nconv*sizeof(float));

  nscrs=0; Nscrs = gaDefFlushFrequency;
  gen = new int[Nscrs]; memset(gen, 0, Nscrs*sizeof(int));
  aveScore = new float[Nscrs]; memset(aveScore, 0, Nscrs*sizeof(float));
  maxScore = new float[Nscrs]; memset(maxScore, 0, Nscrs*sizeof(float));
  minScore = new float[Nscrs]; memset(minScore, 0, Nscrs*sizeof(float));
  devScore = new float[Nscrs]; memset(devScore, 0, Nscrs*sizeof(float));
  divScore = new float[Nscrs]; memset(divScore, 0, Nscrs*sizeof(float));
  scorefile = new char[strlen(gaDefScoreFilename)+1];
  strcpy(scorefile, gaDefScoreFilename);
  which = Maximum;

  boa = (GAPopulation *)0;
}
GAStatistics::GAStatistics(const GAStatistics & orig){
  cscore=(float *)0;
  gen=(int *)0;
  aveScore=(float *)0;
  maxScore=(float *)0;
  minScore=(float *)0;
  devScore=(float *)0;
  divScore=(float *)0;
  scorefile=(char *)0;
  boa=(GAPopulation *)0;
  copy(orig);
}
GAStatistics::~GAStatistics(){
  delete [] cscore;
  delete [] gen;
  delete [] aveScore;
  delete [] maxScore;
  delete [] minScore;
  delete [] devScore;
  delete [] divScore;
  delete [] scorefile;
  delete boa;
}
void 
GAStatistics::copy(const GAStatistics & orig){
  if(&orig == this) return;

  curgen = orig.curgen;
  numsel = orig.numsel;
  numcro = orig.numcro;
  nummut = orig.nummut;
  numrep = orig.numrep;
  numeval = orig.numeval;
  numpeval = orig.numpeval;
  maxever = orig.maxever;
  minever = orig.minever;
  on = orig.on;
  offmax = orig.offmax;
  offmin = orig.offmin;
  aveInit = orig.aveInit;
  maxInit = orig.maxInit;
  minInit = orig.minInit;
  devInit = orig.devInit;
  divInit = orig.divInit;
  aveCur = orig.aveCur;
  maxCur = orig.maxCur;
  minCur = orig.minCur;
  devCur = orig.devCur;
  divCur = orig.divCur;

  scoreFreq = orig.scoreFreq;
  dodiv = orig.dodiv;

  nconv=orig.nconv; Nconv=orig.Nconv;
  delete [] cscore;
  cscore = new float [Nconv]; memcpy(cscore, orig.cscore, Nconv*sizeof(float));

  nscrs=orig.nscrs; Nscrs=orig.Nscrs;
  delete [] gen;
  gen = new int [Nscrs];
  memcpy(gen, orig.gen, Nscrs*sizeof(int));
  delete [] aveScore;
  aveScore = new float [Nscrs];
  memcpy(aveScore, orig.aveScore, Nscrs*sizeof(float));
  delete [] maxScore;
  maxScore = new float [Nscrs];
  memcpy(maxScore, orig.maxScore, Nscrs*sizeof(float));
  delete [] minScore;
  minScore = new float [Nscrs];
  memcpy(minScore, orig.minScore, Nscrs*sizeof(float));
  delete [] devScore;
  devScore = new float [Nscrs];
  memcpy(devScore, orig.devScore, Nscrs*sizeof(float));
  delete [] divScore;
  divScore = new float [Nscrs];
  memcpy(divScore, orig.divScore, Nscrs*sizeof(float));

  delete [] scorefile;
  if(orig.scorefile){
    scorefile = new char [strlen(orig.scorefile)+1];
    strcpy(scorefile, orig.scorefile);
  }
  else scorefile = (char*)0;

  which = orig.which;

  delete boa;
  if(orig.boa) boa = orig.boa->clone();
}


// Update the genomes in the 'best of all' population to reflect any 
// changes made to the current population.  We just grab the genomes with
// the highest scores from the current population, and if they are higher than
// those of the genomes in the boa population, they get copied.  Note that
// the bigger the boa array, the bigger your running performance hit because
// we have to look through all of the boa to figure out which are better than
// those in the population.  The fastest way to use the boa is to keep only 
// one genome in the boa population.  A flag of 'True' will reset the boa
// population so that it is filled with the best of the current population.
//   Unfortunately it could take a long time to update the boa array using the
// copy method.  We'd like to simply keep pointers to the best genomes, but
// the genomes change from generation to generation, so we can't depend on
// that.
//   Notice that keeping boa is useful even for overlapping populations.  The
// boa keeps individuals that are different from each other - the overlapping
// population may not.  However, keeping boa is most useful for populations
// with little overlap.
//   When we check to see if a potentially better member is already in our
// best-of-all population, we use the operator== comparator not the genome
// comparator to do the comparison.
void
GAStatistics::
updateBestIndividual(const GAPopulation & pop, GABoolean flag){
  if(boa == (GAPopulation *)0 || boa->size() == 0) return; // do nothing
  if(pop.order() != boa->order()) boa->order(pop.order());

  if(flag == gaTrue){		// reset the BOA array
    int j=0;
    for(int i=0; i<boa->size(); i++){
      boa->best(i).copy(pop.best(j));
      if(j < pop.size()-1) j++;
    }
    return;
  }

  if(boa->size() == 1){		// there's only one boa so replace it with bop
    if(boa->order() == GAPopulation::HIGH_IS_BEST &&
       pop.best().score() > boa->best().score())
      boa->best().copy(pop.best());
    if(boa->order() == GAPopulation::LOW_IS_BEST &&
       pop.best().score() < boa->best().score())
      boa->best().copy(pop.best());
  }
  else{
    int i=0, j, k;
    if(boa->order() == GAPopulation::HIGH_IS_BEST) {
      while(i < pop.size() && pop.best(i).score() > boa->worst().score()){
	for(k=0;
	    pop.best(i).score() < boa->best(k).score() && k < boa->size();
	    k++);
	for(j=k; j<boa->size(); j++){
	  if(pop.best(i) == boa->best(j)) break;
	  if(pop.best(i).score() > boa->best(j).score()){
	    boa->worst().copy(pop.best(i));        // replace worst individual
	    boa->sort(gaTrue, GAPopulation::RAW);  // re-sort the population
	    break;
	  }
	}
	i++;
      }
    }
    if(boa->order() == GAPopulation::LOW_IS_BEST) {
      while(i < pop.size() && pop.best(i).score() < boa->worst().score()){
	for(k=0;
	    pop.best(i).score() > boa->best(k).score() && k < boa->size();
	    k++);
	for(j=k; j<boa->size(); j++){
	  if(pop.best(i) == boa->best(j)) break;
	  if(pop.best(i).score() < boa->best(j).score()){
	    boa->worst().copy(pop.best(i));        // replace worst individual
	    boa->sort(gaTrue, GAPopulation::RAW);  // re-sort the population
	    break;
	  }
	}
	i++;
      }
    }
  }
  return;
}


// Use this method to update the statistics to account for the current
// population.  This routine increments the generation counter and assumes that
// the population that gets passed is the current population.
//   If we are supposed to flush the scores, then we dump them to the specified
// file.  If no flushing frequency has been specified then we don't record.
void
GAStatistics::update(const GAPopulation & pop){
  ++curgen;			// must do this first so no divide-by-zero
  if(scoreFreq > 0 && (curgen % scoreFreq == 0)) setScore(pop);
  if(Nscrs > 0 && nscrs >= Nscrs) flushScores();
  maxever = (pop.max() > maxever) ? pop.max() : maxever;
  minever = (pop.min() < minever) ? pop.min() : minever;
  float tmpval;
  tmpval = (on*(curgen-1) + pop.ave()) / curgen;
  on = tmpval;
  tmpval = (offmax*(curgen-1) + pop.max()) / curgen;
  offmax = tmpval;
  tmpval = (offmin*(curgen-1) + pop.min()) / curgen;
  offmin = tmpval;
  setConvergence((pop.order() == GAPopulation::HIGH_IS_BEST) ?
		 pop.max() : pop.min());
  updateBestIndividual(pop);
  numpeval = pop.nevals();
}


// Reset the GA's statistics based on the population.  To do this right you
// should initialize the population before you pass it to this routine.  If you
// don't, the stats will be based on a non-initialized population.
void
GAStatistics::reset(const GAPopulation & pop){
  curgen = 0;
  numsel = numcro = nummut = numrep = numeval = numpeval = 0;

  memset(gen, 0, Nscrs*sizeof(int));
  memset(aveScore, 0, Nscrs*sizeof(float));
  memset(maxScore, 0, Nscrs*sizeof(float));
  memset(minScore, 0, Nscrs*sizeof(float));
  memset(devScore, 0, Nscrs*sizeof(float));
  memset(divScore, 0, Nscrs*sizeof(float));
  nscrs = 0;
  setScore(pop);
  if(Nscrs > 0) flushScores();

  memset(cscore, 0, Nconv*sizeof(float));
  nconv = 0;			// should set to -1 then call setConv
  cscore[0] = 
    ((pop.order() == GAPopulation::HIGH_IS_BEST) ? pop.max() : pop.min());
//  cscore[0] = pop.max();
//  setConvergence(maxScore[0]);

  updateBestIndividual(pop, gaTrue);
  aveCur = aveInit = pop.ave();
  maxCur = maxInit = maxever = pop.max();
  minCur = minInit = minever = pop.min();
  devCur = devInit = pop.dev();
  divCur = divInit = ((dodiv == gaTrue) ? pop.div() : (float)-1.0);

  on = pop.ave();
  offmax = pop.max();
  offmin = pop.min();
  numpeval = pop.nevals();
  for(int i=0; i<pop.size(); i++)
    numeval += pop.individual(i).nevals();
}

void
GAStatistics::flushScores(){
  if(nscrs == 0) return;
  writeScores();

⌨️ 快捷键说明

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