📄 gastatistics.c
字号:
// $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 + -