📄 ex15.c
字号:
/* ----------------------------------------------------------------------------
ex15.C
mbwall 28jul94
Copyright (c) 1995-1996 Massachusetts Institute of Technology
DESCRIPTION:
This example nearly identical to example 2, but it uses convergence as the
stopping criterion for the GA rather than number-of-generations.
---------------------------------------------------------------------------- */
#include <stdio.h>
#include <iostream.h>
#include <fstream.h>
#include <math.h>
#include <ga/ga.h>
float objective(GAGenome &);
int
main(int argc, char **argv)
{
cout << "Example 15\n\n";
cout << "This program generates a sequence of random numbers then uses\n";
cout << "a simple GA and binary-to-decimal genome to match the\n";
cout << "sequence. It uses the convergence of the best-of-generation\n";
cout << "as the criterion for when to stop.\n\n";
// See if we've been given a seed to use (for testing purposes). When you
// specify a random seed, the evolution will be exactly the same each time
// you use that seed number.
unsigned int seed = 0;
for(int ii=1; ii<argc; ii++) {
if(strcmp(argv[ii++],"seed") == 0) {
seed = atoi(argv[ii]);
}
}
// Declare variables for the GA parameters and set them to some default values.
// When we use convergence as the completion measure we have to specify both
// a convergence value (larger means more converged) and a number-of-gen
// which specifies how many generations back to look to calculate the
// convergence. The number of generations back defaults to 20, so you do not
// have to set that if you don't want to.
int popsize = 30;
float pmut = 0.01;
float pcross = 0.6;
float pconv = 0.99; // threshhold for when we have converged
int nconv = 50; // how many generations back to look
// Generate a sequence of random numbers using the values in the min and max
// arrays. We also set one of them to integer value to show how you can get
// explicit integer representations by choosing your number of bits
// appropriately.
GARandomSeed(seed);
int i;
int n=7;
float *target = new float[n];
float min[] = {0, 0, 3, -5, 100, 0.001, 0};
float max[] = {1, 100, 3, -2, 100000, 0.010, 7};
for(i=0; i<n; i++)
target[i] = GARandomFloat(min[i], max[i]);
target[6] = GARandomInt((int)min[6], (int)max[6]);
// Print out the sequence to be sure we got the right one.
cout << "input sequence:\n";
for(i=0; i<n; i++){
cout.width(10);
cout << target[i] << " ";
}
cout << "\n"; cout.flush();
// Create a phenotype then fill it with the phenotypes we will need to map to
// the values we read from the file. The arguments to the add() method of a
// Bin2Dec phenotype are (1) number of bits, (2) min value, and (3) max value.
// The phenotype maps a floating-point number onto the number of bits that
// you designate. Here we just make everything use 8 bits and use the max and
// min that were used to generate the target values. You can experiment with
// the number of bits and max/min values in order to make the GA work better
// or worse.
GABin2DecPhenotype map;
for(i=0; i<n; i++)
map.add(8, min[i], max[i]);
// Create the template genome using the phenotype map we just made. The
// GA will use this genome to clone the population that it uses to do the
// evolution.
GABin2DecGenome genome(map, objective, (void *)target);
// Now create the GA using the genome and run it.
GASteadyStateGA ga(genome);
ga.scoreFrequency(1);
ga.flushFrequency(50);
ga.scoreFilename("bog.dat");
ga.populationSize(popsize);
ga.pMutation(pmut);
ga.pCrossover(pcross);
ga.pConvergence(pconv);
ga.nConvergence(nconv);
ga.terminator(GAGeneticAlgorithm::TerminateUponConvergence);
ga.evolve();
// Dump the results of the GA to the screen.
genome.initialize();
cout << "random values in the genome:\n";;
for(i=0; i<map.nPhenotypes(); i++){
cout.width(10); cout << genome.phenotype(i) << " ";
}
cout << "\n";
genome = ga.statistics().bestIndividual();
cout << "the ga generated:\n";
for(i=0; i<map.nPhenotypes(); i++){
cout.width(10); cout << genome.phenotype(i) << " ";
}
cout << "\n\n"; cout.flush();
// Clean up by freeing the memory we allocated.
delete [] target;
return 0;
}
// For this objective function we try to match the values in the array of float
// that is passed to us as userData. If the values in the genome map to
// values that are close, we return a better score. We are limited to positive
// values for the objective value (because we're using linear scaling), so we
// take the reciprocal of the absolute value of the difference between the
// value from the phenotype and the value in the sequence.
float
objective(GAGenome & c)
{
GABin2DecGenome & genome = (GABin2DecGenome &)c;
float *sequence = (float *)c.userData();
float value=genome.nPhenotypes();
for(int i=0; i<genome.nPhenotypes(); i++)
value += 1.0 / (1.0 + fabs(genome.phenotype(i) - sequence[i]));
return(value);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -