📄 ex2.c
字号:
/* ----------------------------------------------------------------------------
ex2.C
mbwall 28jul94
Copyright (c) 1995-1996 Massachusetts Institute of Technology
DESCRIPTION:
Example program for the SimpleGA class and Bin2DecGenome class. This
program generates randomly a series of numbers then tries to match those
values in a binary-to-decimal genome. We use a simple GA (with linear
scaled fitness selection and non-steady-state population generation) and
binary-to-decimal, 1D genomes. We also use the userData argument to the
objective function.
---------------------------------------------------------------------------- */
#include <stdio.h>
#include <iostream.h>
#include <fstream.h>
#include <math.h>
#include <ga/GASimpleGA.h>
#include <ga/GABin2DecGenome.h>
float Objective(GAGenome &);
int
main(int argc, char **argv)
{
cout << "Example 2\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.\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.
int popsize = 25;
int ngen = 100;
float pmut = 0.01;
float pcross = 0.6;
// 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 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};
int i;
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 see what we got.
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. We pass the objective function to create the genome. We
// also use the user data function in the genome to keep track of our
// target values.
GABin2DecGenome genome(map, Objective, (void *)target);
// Now create the GA using the genome, set the parameters, and run it.
GASimpleGA ga(genome);
ga.populationSize(popsize);
ga.nGenerations(ngen);
ga.pMutation(pmut);
ga.pCrossover(pcross);
ga.scoreFilename("bog.dat");
ga.flushFrequency(50); // dump scores to disk every 50th generation
ga.evolve(seed);
// Dump the results of the GA to the screen. We print out first what a random
// genome looks like (so we get a bit of a feel for how hard it is for the
// GA to find the right values) then we print out the best genome that the
// GA was able to find.
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();
// We could print out the genome directly, like this:
// cout << genome << "\n";
cout << "best of generation data are in 'bog.dat'\n";
// 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 - the
// default scaling method for SimpleGA), 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& g)
{
GABin2DecGenome & genome = (GABin2DecGenome &)g;
float *sequence = (float *)g.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 + -