📄 gastatistics.c
字号:
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;
}
// Set the score info to the appropriate values. Update the score count.
void
GAStatistics::setScore(const GAPopulation& pop){
aveCur = pop.ave();
maxCur = pop.max();
minCur = pop.min();
devCur = pop.dev();
divCur = ((dodiv == gaTrue) ? pop.div() : (float)-1.0);
if(Nscrs == 0) return;
gen[nscrs] = curgen;
aveScore[nscrs] = aveCur;
maxScore[nscrs] = maxCur;
minScore[nscrs] = minCur;
devScore[nscrs] = devCur;
divScore[nscrs] = divCur;
nscrs++;
}
// For recording the convergence we have to keep a running list of the past N
// best scores. We just keep looping around and around the array of past
// scores. nconv keeps track of which one is the current one. The current
// item is thus nconv%Nconv. The oldest is nconv%Nconv+1 or 0.
void
GAStatistics::setConvergence(float s){
nconv++;
cscore[nconv%Nconv] = s;
}
// When a new number of gens to conv is specified, keep all the data that we
// can in the transfer. Make sure we do it in the right order! Then just
// continue on as before.
// If someone passes us a zero then we set to 1.
int
GAStatistics::nConvergence(unsigned int n){
if(n == 0) n = 1;
float *tmp = cscore;
cscore = new float[n];
if(Nconv < n){
if(nconv < Nconv){
memcpy(cscore, tmp, (nconv+1) * sizeof(float));
}
else{
memcpy(&(cscore[Nconv-(nconv%Nconv)-1]), tmp,
((nconv%Nconv)+1) * sizeof(float));
memcpy(cscore, &(tmp[(nconv%Nconv)+1]),
(Nconv-(nconv%Nconv)-1) * sizeof(float));
}
}
else{
if(nconv < n){
memcpy(cscore, tmp, (nconv+1) * sizeof(float));
}
else{
if((nconv % Nconv) + 1 < n){
memcpy(&(cscore[n-(nconv%Nconv)-1]), tmp,
((nconv%Nconv)+1) * sizeof(float));
memcpy(cscore, &(tmp[Nconv-(1+n-(nconv%Nconv))]), sizeof(float));
}
else{
memcpy(cscore, &(tmp[1+(nconv%Nconv)-n]), n * sizeof(float));
}
}
}
Nconv = n;
delete [] tmp;
return Nconv;
}
int
GAStatistics::nBestGenomes(const GAGenome& genome, unsigned int n){
if(n == 0){
delete boa;
boa = (GAPopulation*)0;
}
else if(boa == (GAPopulation*)0){
boa = new GAPopulation(genome, n);
}
else {
boa->size(n);
}
return n;
}
const GAGenome &
GAStatistics::bestIndividual(unsigned int n) const {
if(boa == 0 || (int)n >= boa->size()){
GAErr(GA_LOC, "GAStatistics", "bestIndividual", gaErrBadPopIndex);
n = 0;
}
return boa->best(n); // this will crash if no boa
}
// Adjust the scores buffers to match the specified amount. If someone
// specifies zero then we don't keep the scores, so set all to NULL.
int
GAStatistics::flushFrequency(unsigned int freq){
if(freq == 0){
if(nscrs > 0) flushScores();
resizeScores(freq);
}
else if(freq > Nscrs){
resizeScores(freq);
}
else if(freq < Nscrs){
if(nscrs > freq) flushScores();
resizeScores(freq);
}
Nscrs = freq;
return freq;
}
// Resize the scores vectors to the specified amount. Copy any scores that
// exist.
void
GAStatistics::resizeScores(unsigned int n){
int *tmpi;
float *tmpf;
if(n == 0){
delete [] gen;
gen = (int*)0;
delete [] aveScore;
aveScore = (float*)0;
delete [] maxScore;
maxScore = (float*)0;
delete [] minScore;
minScore = (float*)0;
delete [] devScore;
devScore = (float*)0;
delete [] divScore;
divScore = (float*)0;
nscrs = n;
}
else{
tmpi = gen;
gen = new int [n];
memcpy(gen, tmpi, (n < Nscrs ? n : Nscrs)*sizeof(int));
delete [] tmpi;
tmpf = aveScore;
aveScore = new float [n];
memcpy(aveScore, tmpf, (n < Nscrs ? n : Nscrs)*sizeof(float));
delete [] tmpf;
tmpf = maxScore;
maxScore = new float [n];
memcpy(maxScore, tmpf, (n < Nscrs ? n : Nscrs)*sizeof(float));
delete [] tmpf;
tmpf = minScore;
minScore = new float [n];
memcpy(minScore, tmpf, (n < Nscrs ? n : Nscrs)*sizeof(float));
delete [] tmpf;
tmpf = devScore;
devScore = new float [n];
memcpy(devScore, tmpf, (n < Nscrs ? n : Nscrs)*sizeof(float));
delete [] tmpf;
tmpf = divScore;
divScore = new float [n];
memcpy(divScore, tmpf, (n < Nscrs ? n : Nscrs)*sizeof(float));
delete [] tmpf;
if(nscrs > n) nscrs = n;
}
Nscrs = n;
}
// Write the current scores to file. If this is the first chunk (ie gen[0]
// is 0) then we create a new file. Otherwise we append to an existing file.
// We give no notice that we're overwriting the existing file!!
void
GAStatistics::writeScores(){
if(!scorefile) return;
#ifndef NO_STREAMS
ofstream outfile(scorefile, ((gen[0] == 0) ?
(ios::out | ios::trunc) :
(ios::out | ios::app)));
// should be done this way, but SGI systems (and others?) don't do it right...
// if(! outfile.is_open()){
if(outfile.fail()){
GAErr(GA_LOC, "GAStatistics", "writeScores", gaErrWriteError, scorefile);
return;
}
scores(outfile, which);
outfile.close();
#endif
}
#ifndef NO_STREAMS
int
GAStatistics::write(const char* filename) const {
ofstream outfile(filename, (ios::out | ios::trunc));
// should be done this way, but SGI systems (and others?) don't do it right...
// if(! outfile.is_open()){
if(outfile.fail()){
GAErr(GA_LOC, "GAStatistics", "write", gaErrWriteError, filename);
return 1;
}
write(outfile);
outfile.close();
return 0;
}
int
GAStatistics::write(ostream & os) const {
os << curgen << "\t# current generation\n";
os << convergence() << "\t# current convergence\n";
os << numsel << "\t# number of selections since initialization\n";
os << numcro << "\t# number of crossovers since initialization\n";
os << nummut << "\t# number of mutations since initialization\n";
os << numrep << "\t# number of replacements since initialization\n";
os << numeval << "\t# number of genome evaluations since initialization\n";
os << numpeval << "\t# number of population evaluations since initialization\n";
os << maxever << "\t# maximum score since initialization\n";
os << minever << "\t# minimum score since initialization\n";
os << on << "\t# average of all scores ('on-line' performance)\n";
os << offmax << "\t# average of maximum scores ('off-line' performance)\n";
os << offmin << "\t# average of minimum scores ('off-line' performance)\n";
os << "\n";
os << aveInit << "\t# mean score in initial population\n";
os << maxInit << "\t# maximum score in initial population\n";
os << minInit << "\t# minimum score in initial population\n";
os << devInit << "\t# standard deviation of initial population\n";
os <<divInit<<"\t# diversity of initial population (0=identical,-1=unset)\n";
os << "\n";
os << aveCur << "\t# mean score in current population\n";
os << maxCur << "\t# maximum score in current population\n";
os << minCur << "\t# minimum score in current population\n";
os << devCur << "\t# standard deviation of current population\n";
os << divCur<<"\t# diversity of current population (0=identical,-1=unset)\n";
os << "\n";
os << Nconv << "\t# how far back to look for convergence\n";
os << scoreFreq << "\t# how often to record scores\n";
os << Nscrs << "\t# how often to write scores to file\n";
os << scorefile << "\t# name of file to which scores are written\n";
return 0;
}
// You can specify the data that you want to dump out when you call this
// routine, or you can just let it use the selection from the object. If you
// specify a data set, that will be used rather than the 'which' in the object.
int
GAStatistics::scores(const char* filename, int w){
ofstream outfile(filename, (ios::out | ios::trunc));
// should be done this way, but SGI systems (and others?) don't do it right...
// if(! outfile.is_open()){
if(outfile.fail()){
GAErr(GA_LOC, "GAStatistics", "scores", gaErrWriteError, filename);
return 1;
}
scores(outfile, w);
outfile.close();
return 0;
}
int
GAStatistics::scores(ostream & os, int w){
if(w == NoScores) w = which;
for(unsigned int i=0; i<nscrs; i++){
os << gen[i];
if(w & Mean) os << "\t" << aveScore[i];
if(w & Maximum) os << "\t" << maxScore[i];
if(w & Minimum) os << "\t" << minScore[i];
if(w & Deviation) os << "\t" << devScore[i];
if(w & Diversity) os << "\t" << divScore[i];
os << "\n";
}
return 0;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -