📄 ex11.c
字号:
/* ----------------------------------------------------------------------------
ex11.C
mbwall 13apr95
Copyright (c) 1995-1996 Massachusetts Institute of Technology
DESCRIPTION:
This example shows how to use an order-based list genome.
---------------------------------------------------------------------------- */
#include <stdio.h>
#include <stdlib.h>
#include <iostream.h>
#include <fstream.h>
#include <ga/ga.h>
// The objective function tells how good a genome is. The Initializer defines
// how the lists should be initialized.
float objective(GAGenome &);
void ListInitializer(GAGenome &);
int
main(int argc, char *argv[])
{
cout << "Example 11\n\n";
cout << "This program illustrates the use of order-based lists. The\n";
cout << "list in this problem contains 25 numbers, 0 to 24. It tries\n";
cout << "to put them in descending order from 24 to 0.\n\n";
cout.flush();
// 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.
for(int ii=1; ii<argc; ii++) {
if(strcmp(argv[ii++],"seed") == 0) {
GARandomSeed((unsigned int)atoi(argv[ii]));
}
}
// Set the default values of the parameters.
GAParameterList params;
GASteadyStateGA::registerDefaultParameters(params);
params.set(gaNpopulationSize, 30); // population size
params.set(gaNpCrossover, 0.6); // probability of crossover
params.set(gaNpMutation, 0.01); // probability of mutation
params.set(gaNnGenerations, 1000); // number of generations
params.set(gaNpReplacement, 0.5); // how much of pop to replace each gen
params.set(gaNscoreFrequency, 10); // how often to record scores
params.set(gaNnReplacement, 4); // how much of pop to replace each gen
params.set(gaNflushFrequency, 10); // how often to dump scores to file
params.set(gaNscoreFilename, "bog.dat");
// params.read("settings.txt"); // grab values from file first
params.parse(argc, argv, gaFalse); // parse command line for GAlib args
// Now create the GA and run it. We first create a genome with the
// operators we want. Since we're using a template genome, we must assign
// all three operators. We use the order-based crossover site when we assign
// the crossover operator.
GAListGenome<int> genome(objective);
genome.initializer(ListInitializer);
genome.mutator(GAListGenome<int>::SwapMutator);
// Now that we have our genome, we create the GA (it clones the genome to
// make all of the individuals for its populations). Set the parameters on
// the GA then let it evolve.
GASteadyStateGA ga(genome);
ga.crossover(GAListGenome<int>::PartialMatchCrossover);
ga.parameters(params);
ga.evolve();
// Assign the best that the GA found to our genome then print out the results.
genome = ga.statistics().bestIndividual();
cout << "the ga generated the following list (objective score is ";
cout << genome.score() << "):\n" << genome << "\n";
cout << "best of generation data are in '" << ga.scoreFilename() << "'\n";
cout << ga.parameters() << "\n";
// char *fn;
// ga.get(gaNscoreFilename, &fn);
// cout << "filename is '" << fn << "'\n";
return 0;
}
/* ----------------------------------------------------------------------------
Objective function
The objective function gives one point for every number in the correct
position. We're trying to get a sequence of numbers from n to 0 in descending
order.
---------------------------------------------------------------------------- */
float
objective(GAGenome & c)
{
GAListGenome<int> & genome = (GAListGenome<int> &)c;
float score = (*genome.head() == genome.size()-1); // move to head of list
for(int i=genome.size()-2; i>0; i--)
score += (*genome.next() == i); // cycle through list and look at nodes
return score;
}
/* ----------------------------------------------------------------------------
List Genome Operators
-------------------------------------------------------------------------------
The initializer creates a list with n elements in it and puts a unique digit
in each one. After we make the list, we scramble everything up.
---------------------------------------------------------------------------- */
void
ListInitializer(GAGenome & c)
{
GAListGenome<int> &child=(GAListGenome<int> &)c;
while(child.head()) child.destroy(); // destroy any pre-existing list
int n=25;
child.insert(0,GAListBASE::HEAD); // the head node contains a '0'
for(int i=1; i<n; i++)
child.insert(i); // each subsequent node contains a number
for(int j=0; j<n; j++)
child.swap(GARandomInt(0,n-1), GARandomInt(0,n-1));
}
// Here we specialize the write method for the List class. This lets us see
// exactly what we want (the default write method dumps out pointers to the
// data rather than the data contents).
// This routine prints out the contents of each element of the list,
// separated by a space. It does not put a newline at the end of the list.
// Notice that you can specialize ANY function of a template class, but
// some compilers are more finicky about how you do it than others. For the
// metrowerks compiler this specialization must come before the forced
// instantiation.
int
GAListGenome<int>::write(ostream & os) const
{
int *cur, *head;
GAListIter<int> tmpiter(*this);
if((head=tmpiter.head()) != 0) os << *head << " ";
for(cur=tmpiter.next(); cur && cur != head; cur=tmpiter.next())
os << *cur << " ";
return os.fail() ? 1 : 0;
}
// If your compiler does not do automatic instantiation (e.g. g++ 2.6.8),
// then define the NO_AUTO_INST directive.
#ifdef NO_AUTO_INST
#include <ga/GAList.C>
#include <ga/GAListGenome.C>
#if defined(__GNUG__)
template class GAList<int>;
template class GAListGenome<int>;
#else
GAList<int>;
GAListGenome<int>;
#endif
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -