/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- The above line is usefulin Emacs-like editors */ /* Template for creating a new representation in EO ================================================ This is the template main file. It includes all other files that have been generated by the script create.sh so it is the only file to compile. In case you want to build up a separate library for your new Evolving Object, you'll need some work - follow what's done in the src/ga dir, used in the main file BitEA in tutorial/Lesson4 dir. Or you can wait until we do it :-) */ // Miscilaneous include and declaration #include using namespace std; // eo general include #include "eo" // the real bounds (not yet in general eo include) #include "utils/eoRealVectorBounds.h" // include here whatever specific files for your representation // Basically, this should include at least the following /** definition of representation: * class eoMyStruct MUST derive from EO for some fitness */ #include "eoMyStruct.h" /** definition of initilizqtion: * class eoMyStructInit MUST derive from eoInit */ #include "eoMyStructInit.h" /** definition of evaluation: * class eoMyStructEvalFunc MUST derive from eoEvalFunc * and should test for validity before doing any computation * see tutorial/Templates/evalFunc.tmpl */ #include "eoMyStructEvalFunc.h" /** definitions of operators: write as many classes as types of operators * and include them here. In this simple example, * one crossover (2->2) and one mutation (1->1) operators are used */ #include "eoMyStructQuadCrossover.h" #include "eoMyStructMutation.h" // GENOTYPE eoMyStruct ***MUST*** be templatized over the fitness //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* // START fitness type: double or eoMaximizingFitness if you are maximizing // eoMinimizingFitness if you are minimizing typedef eoMinimizingFitness MyFitT ; // type of fitness // END fitness type //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* // Then define your EO objects using that fitness type typedef eoMyStruct Indi; // ***MUST*** derive from EO // Use existing modules to define representation independent routines // how to initialize the population // it IS representation independent if an eoInit is given #include eoPop& make_pop(eoParser& _parser, eoState& _state, eoInit & _init) { return do_make_pop(_parser, _state, _init); } // the stopping criterion #include eoContinue& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter & _eval) { return do_make_continue(_parser, _state, _eval); } // outputs (stats, population dumps, ...) #include eoCheckPoint& make_checkpoint(eoParser& _parser, eoState& _state, eoEvalFuncCounter& _eval, eoContinue& _continue) { return do_make_checkpoint(_parser, _state, _eval, _continue); } // evolution engine (selection and replacement) #include eoAlgo& make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc& _eval, eoContinue& _continue, eoGenOp& _op) { return do_make_algo_scalar(_parser, _state, _eval, _continue, _op); } // simple call to the algo. stays there for consistency reasons // no template for that one #include // the instanciating fitnesses #include void run_ea(eoAlgo& _ga, eoPop& _pop) { do_run(_ga, _pop); } // checks for help demand, and writes the status file // and make_help; in libutils void make_help(eoParser & _parser); // now use all of the above, + representation dependent things int main(int argc, char* argv[]) { try { eoParser parser(argc, argv); // for user-parameter reading eoState state; // keeps all things allocated // The fitness ////////////// eoMyStructEvalFunc plainEval/* (varType _anyVariable) */; // turn that object into an evaluation counter eoEvalFuncCounter eval(plainEval); // a genotype initializer eoMyStructInit init; // or, if you need some parameters, you might as well // - write a constructor of the eoMyStructInit that uses a parser // - call it from here: // eoMyStructInit init(parser); // Build the variation operator (any seq/prop construct) // here, a simple example with only 1 crossover (2->2, a QuadOp) and // one mutation, is given. // Hints to have choice among multiple crossovers and mutations are given // A (first) crossover (possibly use the parser in its Ctor) eoMyStructQuadCrossover cross /* (eoParser parser) */; // IF MORE THAN ONE: // read its relative rate in the combination // double cross1Rate = parser.createParam(1.0, "cross1Rate", "Relative rate for crossover 1", '1', "Variation Operators").value(); // create the combined operator with the first one (rename it cross1 !!!) // eoPropCombinedQuadOp cross(cross1, cross1Rate); // and as many as you want the following way: // 1- write the new class by mimicking eoMyStructQuadCrossover.h // 2- include that file here together with eoMyStructQuadCrossover above // 3- uncomment and duplicate the following lines: // // eoMyStructSecondCrossover cross2(eoParser parser); // double cross2Rate = parser.createParam(1.0, "cross2Rate", "Relative rate for crossover 2", '2', "Variation Operators").value(); // cross.add(cross2, cross2Rate); // NOTE: if you want some gentle output, the last one shoudl be like // cross.add(cross, crossXXXRate, true); /////////////// Same thing for MUTATION // a (first) mutation (possibly use the parser in its Ctor) eoMyStructMutation mut /* (eoParser parser) */; // IF MORE THAN ONE: // read its relative rate in the combination // double mut1Rate = parser.createParam(1.0, "mut1Rate", "Relative rate for mutation 1", '1', "Variation Operators").value(); // create the combined operator with the first one (rename it cross1 !!!) // eoPropCombinedMonOp mut(mut1, mut1Rate); // and as many as you want the following way: // 1- write the new class by mimicking eoMyStructMutation.h // 2- include that file here together with eoMyStructMutation above // 3- uncomment and duplicate the following lines: // // eoMyStructSecondMutation mut2(eoParser parser); // double mut2Rate = parser.createParam(1.0, "mut2Rate", "Relative rate for mutation 2", '2', "Variation Operators").value(); // mut.add(mut2, mut2Rate); // NOTE: if you want some gentle output, the last one shoudl be like // mut.add(mut, mutXXXRate, true); // now encapsulate your crossover(s) and mutation(s) into an eoGeneralOp // so you can fully benefit of the existing evolution engines // First read the individual level parameters double pCross = parser.createParam(0.6, "pCross", "Probability of Crossover", 'C', "Variation Operators" ).value(); // minimum check if ( (pCross < 0) || (pCross > 1) ) throw runtime_error("Invalid pCross"); double pMut = parser.createParam(0.1, "pMut", "Probability of Mutation", 'M', "Variation Operators" ).value(); // minimum check if ( (pMut < 0) || (pMut > 1) ) throw runtime_error("Invalid pMut"); // now create the generalOp eoSGAGenOp op(cross, pCross, mut, pMut); //// Now the representation-independent things // // YOU SHOULD NOT NEED TO MODIFY ANYTHING BEYOND THIS POINT // unless you want to add specific statistics to the checkpoint ////////////////////////////////////////////// // initialize the population // yes, this is representation indepedent once you have an eoInit eoPop& pop = make_pop(parser, state, init); // stopping criteria eoContinue & term = make_continue(parser, state, eval); // output eoCheckPoint & checkpoint = make_checkpoint(parser, state, eval, term); // algorithm (need the operator!) eoAlgo& ga = make_algo_scalar(parser, state, eval, checkpoint, op); ///// End of construction of the algorithm ///////////////////////////////////////// // to be called AFTER all parameters have been read!!! make_help(parser); //// GO /////// // evaluate intial population AFTER help and status in case it takes time apply(eval, pop); // if you want to print it out // cout << "Initial Population\n"; // pop.sortedPrintOn(cout); // cout << endl; run_ea(ga, pop); // run the ga cout << "Final Population\n"; pop.sortedPrintOn(cout); cout << endl; } catch(exception& e) { cout << e.what() << endl; } return 0; }