?? ex8.cpp
字號(hào):
/* ---------------------------------------------------------------------------- ex8.C mbwall 14jan95 Copyright 1995-1996 Massachusetts Institute of Technology DESCRIPTION: Example program for the list genome. This example containsthe code to run a genetic algorithm with a list genome. This program illustrates how to specialize member functions of the template classes. Here we specialize the default write() method so that we getthe contents of the nodes rather than the pointers to the node contents. Youcan specialize most functions of a template class (as long as they are notinlined). The objective function for this example returns both positive and negativevalues, depending on the genome it is evaluting. So the example also shows howto use the sigma truncation scaling method to handle the mixed scores.---------------------------------------------------------------------------- */#include <stdio.h>#include <stdlib.h>#include <ga/ga.h>#include <ga/std_stream.h>#define cout STD_COUT#define ostream STD_OSTREAM// Objective function and initializer declarations.float objective(GAGenome &);void ListInitializer(GAGenome &);intmain(int argc, char *argv[]){ cout << "Example 8\n\n"; cout << "This program runs a steady-state GA whose objective function\n"; cout << "tries to maximize the size of the list and tries to make lists\n"; cout << "that contain the number 101 in the nodes. The lists contain\n"; cout << "ints in the nodes.\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 i=1; i<argc; i++) { if(strcmp(argv[i++],"seed") == 0) GARandomSeed((unsigned int)atoi(argv[i])); }// Create the initial genome for the genetic algorithm to use. Set the// initializer and mutation before we make the genetic algorithm. GAListGenome<int> genome(objective); genome.initializer(ListInitializer);// genome.mutator(GAListGenome<int>::SwapMutator); genome.mutator(GAListGenome<int>::DestructiveMutator);// Now that we have a genome, we use it to create our GA. After creating the// GA we set the parameters and tell the GA to use sigma truncation scaling// rather than the default (linear scaling). Set the crossover to single// point crossover. The genetic algorithm handles crossover since genomes// don't know about other genomes. We could set the crossover on the genome// if we wanted - either way will work. GASteadyStateGA ga(genome); GASigmaTruncationScaling scale; ga.scaling(scale); ga.crossover(GAListGenome<int>::OnePointCrossover);// Set the default parameters we want to use, then check the command line for// other arguments that might modify these. ga.set(gaNpopulationSize, 40); // population size ga.set(gaNpCrossover, 0.6); // probability of crossover ga.set(gaNpMutation, 0.05); // probability of mutation ga.set(gaNnGenerations, 50); // number of generations ga.set(gaNscoreFrequency, 1); // how often to record scores ga.set(gaNflushFrequency, 10); // how often to dump scores to file ga.set(gaNselectScores, // which scores should we track? GAStatistics::Maximum|GAStatistics::Minimum|GAStatistics::Mean); ga.set(gaNscoreFilename, "bog.dat"); ga.parameters(argc, argv);// Evolve the genetic algorithm then dump out the results of the run. ga.evolve(); genome = ga.statistics().bestIndividual();// cout << "the ga generated the list:\n" << genome << "\n"; cout << "the list contains " << genome.size() << " nodes\n"; cout << "the ga used the parameters:\n" << ga.parameters() << "\n"; return 0;} /* ----------------------------------------------------------------------------Objective function There is no limit to the size of a list (only the memory you have on yourcomputer). This objective function tries to build a list that contains thenumber 101 in all of its nodes. If we don't put some control on this objectivethen the list will grow without bound. So we dampen it a bit with a penalty for large size. However, this will make the score go negative, so we must usea scaling object that allows negative objective scores. We could get lists with no contents, so we have to check for that. Just makesure that head has contents. If it does, then the rest of the genome will. When we access the node contents we have to dereference the member functions.For example, we do *chrom.head() not chrom.head(). This is because the memberfunctions return a pointer to the node's contents, not the actual contents.---------------------------------------------------------------------------- */floatobjective(GAGenome & c){ GAListGenome<int> & genome = (GAListGenome<int> &)c; int count=0; if(!genome.head()) return 0; count = (*genome.head() == 101) ? 1 : 0; // move to head of the list for(int i=1; i<genome.size(); i++) count += (*genome.next() == 101) ? 1 : 0; // check each element of the list return 5*count - genome.size();}/* ----------------------------------------------------------------------------Here is the initializer for our genomes. It builds a list of n items of typeint. Notice that we first destroy any list that is already in the genome before we do our initialization. This is so that the genomes can be re-used.When you re-run a GA, it does not destroy the individuals in the population - it reuses them. Thus, the initializer must make sure that the genome is cleaned up before it tries to initialize it.---------------------------------------------------------------------------- */voidListInitializer(GAGenome & c){ GAListGenome<int> &child=(GAListGenome<int> &)c; while(child.head()) child.destroy(); // destroy any pre-existing list int n=75; child.insert(100,GAListBASE::HEAD); for(int i=0; i<n; i++) child.insert(i+100); 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.template<> intGAListGenome<int>::write(ostream & os) const{ int *cur, *head; GAListIter<int> tmpiter(*this); if((head=tmpiter.head()) != NULL) os << *head << " "; for(cur=tmpiter.next(); cur && cur != head; cur=tmpiter.next()) os << *cur << " "; return os.fail() ? 1 : 0;}// force instantiations for compilers that do not do auto instantiation// for some compilers (e.g. metrowerks) this must come after any// specializations or you will get 'multiply-defined errors when you compile.#if !defined(GALIB_USE_AUTO_INST)#include <ga/GAList.C>#include <ga/GAListGenome.C>GALIB_INSTANTIATION_PREFIX GAList<int>;GALIB_INSTANTIATION_PREFIX GAListGenome<int>;#endif
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -