//! \mainpage Creating a simple ParadisEO-PEO Evolutionary Algorithm //! //! \section structure Introduction //! //! One of the first steps in designing an evolutionary algorithm using the ParadisEO-PEO framework //! consists in having a clear overview of the implemented algorithm. A brief pseudo-code description is offered //! bellow - the entire source code for the ParadisEO-PEO evolutionary algorithm is defined in the peoEA.h //! header file. The main elements to be considered when building an evolutionary algorithm are the transformation //! operators, i.e. crossover and mutation, the evaluation function, the continuation criterion and the selection //! and replacement strategy. //! //! //! //! //! //! //! //! //!
do {    
         select( population, offsprings );   // select the offsprings from the current population
         transform( offsprings );   // crossover and mutation operators are applied on the selected offsprings
         evaluate( offsprings );   // evaluation step of the resulting offsprings
         replace( population, offsprings );   // replace the individuals in the current population whith individuals from the offspring population, according to a specified replacement strategy
} while ( eaCheckpointContinue( population ) );   // checkpoint operators are applied on the current population
//! //! The peoEA class offers an elementary evolutionary algorithm implementation. The peoEA class has the underlying structure //! for including parallel evaluation and parallel transformation operators, migration operators etc. Although there is //! no restriction on using the algorithms provided by the EO framework, no parallelism is provided - the EO implementation is exclusively sequential. //!
//! //! \section requirements Requirements //! //! You should have already installed the ParadisEO-PEO package - this requires several additional packages which should be already //! included in the provided archive. The installation script has to be launched in order to configure and compile all the required //! components. At the end of the installation phase you should end up having a directory tree resembling the following: //! //!
     ... //!
     paradiseo-mo //!
     paradiseo-moeo //!
     paradiseo-peo //!
            docs //!
            examples //!
                   lesson1 //!
                   lesson2 //!
                   ... //!
                   shared //!
                   ... //!
            src //!
            ... //!
     ... //!
//!
//! //! The source-code for this tutorial may be found in the paradiseo-peo/examples/lesson1 directory, in the main.cpp file. //! We strongly encourage creating a backup copy of the file if you consider modifying the source code. For a complete reference on the //! TSP-related classes and definitions please refer to the files under the paradiseo-peo/examples/shared. After the installation //! phase you should end up having an tspExample executable file in the paradiseo-peo/examples/lesson1 directory. //! We will discuss testing and launching aspects later in the tutorial. //! //! You are supposed to be familiar with working in C/C++ (with an extensive use of templates) and you should have at least an introductory //! background in working with the EO framework. //! //!
//! NOTE: All the presented examples have as case study the Traveling Salesman Problem (TSP). All the presented tutorials rely //! on a common shared source code defining transformation operators, //! evaluation functions, etc. for the TSP problem. For a complete understanding of the presented tutorials please take your time for //! consulting and for studying the additional underlying defined classes. //!

//! //! \section problemDef Problem Definition and Representation //! //! As we are not directly concerned with the Traveling Salesman Problem, and to some extent out of scope, no in depth details are offered //! for the TSP. The problem requires finding the shortest path connecting a given set of cities, while visiting each of //! the specified cities only once and returning to the startpoint city. The problem is known to be NP-complete, i.e. no polynomial //! time algorithm exists for solving the problem in exact manner. //! //! The construction of a ParadisEO-PEO evolutionary algorithm requires following a few simple steps - please take your time to study the signature //! of the peoEA constructor: //! //! //! //! //!
//!      peoEA( //!
            eoContinue< EOT >& __cont, //!
            peoPopEval< EOT >& __pop_eval, //!
            eoSelect< EOT >& __select, //!
            peoTransform< EOT >& __trans, //!
            eoReplacement< EOT >& __replace //!
     ); //!
//! \image html peoEA.png //!
//! //! A few remarks have to be made: while most of the parameters are passed as EO-specific types, the evaluation and the transformation objects have to be //! derived from the ParadisEO-PEO peoPopEval and peoTransform classes. Derived classes like the peoParaPopEval and peoParaSGATransform classes allow //! for parallel evaluation of the population and parallel transformation operators, respectively. Wrappers are provided thus allowing to make use //! of the EO classes. //! //! In the followings, the main required elements for building an evolutionary algorithm are enumerated. For complete details regarding the //! implementation aspects of each of the components, please refer to the common shared source code. //! Each of the bellow referred header files may be found in the pardiseo-peo/examples/shared directory. //! //!
    //!
  1. representation - the first decision to be taken concerns the representation of the individuals. You may create your //! own representation or you may use/derive one of the predefined classes of the EO framework.
    //! //! For our case study, the TSP, each city is defined as a Node in the node.h header file - in fact an unsigned value defined //! as typedef unsigned Node. Moreover, each individual (of the evolutionary algorithm) is represented as a Route object, a vector of Node objects, in //! the route.h header file - typedef eoVector< int, Node > Route. The definition of the Route object implies two //! elements: (1) a route is a vector of nodes, and (2) the fitness is an integer value (please refer to the eoVector //! definition in the EO framework). //! //! In addition you should also take a look in the route_init.h header file which includes the RouteInit class, defined for //! initializing in random manner Route objects. //!
  2. //!
  3. evaluation function - having a representation model, an evaluation object has to be defined, implementing a specific //! fitness function. The designed class has to be derived (directly or indirectly) from the peoPopEval class - you have the choice of //! using peoSeqPopEval or peoParaPopEval for sequential and parallel evaluation, respectively. These classes act as wrappers requiring //! the specification of an EO evaluation object derived from the eoEvalFunc class - please refer to their respective documentation.
    //! //! The fitness function for our TSP case study is implemented in the route_eval.h header file. The class is derived from the eoEvalFunc //! EO class, being defined as class RouteEval : public eoEvalFunc< Route >. //!
  4. //!
  5. transformation operators - in order to assure the evolution of the initial population, transformation operators have to be defined. //! Depending on your problem, you may specify quadruple operators (two input individuals, two output resulting individuals), i.e. crossover operators, //! binary operators (one input individual and one output resulting individual), i.e. mutation operators, or combination of both types. As for the //! evaluation function, the signature of the peoEA constructor requires specifying a peoTransform derived object as transformation operator. //! //! The transform operators, crossover and mutation, for the herein presented example are defined in the order_xover.h and the city_swap.h //! header files, respectively. //!
  6. //!
  7. continuation criterion - the evolutionary algorithm evolves in an iterative manner; a continuation criterion has to be specified. //! One of the most common and simplest options considers a maximum number of generations. It is your choice whether to use //! a predefined EO class for specifying the continuation criterion or using a custom defined class. In the later case you have to //! make sure that your class derives the eoContinue class.
    //!
  8. //!
  9. selection strategy - at each iteration a set of individuals are selected for applying the transform operators, in order //! to obtain the offspring population. As the specified parameter has to be derived from the eoSelect it is your option of whether using //! the EO provided selection strategies or implementing your own, as long as it inherits the eoSelect class. //! //! For our example we chose to use the eoRankingSelect strategy, provided in the EO framework. //!
  10. //!
  11. replacement strategy - once the offspring population is obtained, the offsprings have to be integrated back into the initial //! population, according to a given strategy. For custom defined strategies you have to inherit the eoReplacement EO class. We chose to //! use an eoPlusReplacement as strategy (please review the EO documentation for details on the different strategies available). //!
  12. //!
//!
//! //! \section example A simple example for constructing a peoEA object //! //! The source code for this example may be found in the main.cpp file, under the paradiseo-peo/examples/lesson1 directory. Please make sure you //! At this point you have two options: (a) you can just follow the example without touching the main.cpp or, (b) you can start from scratch, //! following the presented steps, in which case you are required make a backup copy of the main.cpp file and replace the original file with an //! empty one. //! //!
    //!
  1. include the necessary header files - as we will be using Route objects, we have to include the files //! which define the Route type, the initializing functor and the evaluation functions. Furthermore, in order to make use of //! transform operators, we require having the headers which define the crossover and the mutation operators. //! All these files may be found in the shared directory that we mentioned in the beginning. At this point you //! should have something like the following:
    //! //!
    //!		##include "route.h"
    //!		##include "route_init.h"
    //!		##include "route_eval.h"
    //!		
    //!		##include "order_xover.h"
    //!		##include "city_swap.h"
    //!		
    //! In addition we require having the paradiseo header file, in order to use the ParadisEO-PEO features, and a header specific //! for our problem, dealing with processing command-line parameters - the param.h header file. The complete picture at this point //! with all the required header files is as follows:
    //! //!
    //!		##include "route.h"
    //!		##include "route_init.h"
    //!		##include "route_eval.h"
    //!		
    //!		##include "order_xover.h"
    //!		##include "city_swap.h"
    //!
    //!		##include "param.h"
    //!
    //!		##include <paradiseo>
    //!		
    //! NOTE: the paradiseo header file is in fact a "super-header" - it includes all the esential ParadisEO-PEO header files. //! It is at at your choice if you want use the paradiseo header file or to explicitly include different header files, //! like the peoEA.h header file, for example. //! //!
  2. //!
  3. define problem specific parameters - in our case we have to specify how many individuals we want to have in our population, the number //! of generations for the evolutionary algorithm to iterate and the probabilities associated with the crossover and mutation operators.
    //! //!
    //!		##include "route.h"
    //!		##include "route_init.h"
    //!		##include "route_eval.h"
    //!		
    //!		##include "order_xover.h"
    //!		##include "city_swap.h"
    //!
    //!		##include "param.h"
    //!
    //!		##include <paradiseo>
    //!
    //!
    //!		##define POP_SIZE 10
    //!		##define NUM_GEN 100
    //!		##define CROSS_RATE 1.0
    //!		##define MUT_RATE 0.01
    //!		
    //!
  4. //!
  5. construct the skeleton of a simple ParadisEO-PEO program - the main function including the code for initializing the ParadisEO-PEO //! environment, for loading problem data and for shutting down the ParadisEO-PEO environment. From this point on we will make //! abstraction of the previous part referring only to the main function.
    //! //!
    //!		...
    //!		
    //!		int main( int __argc, char** __argv ) {
    //!		
    //!			// initializing the ParadisEO-PEO environment
    //!			peo :: init( __argc, __argv );
    //!		
    //!			// processing the command line specified parameters
    //!			loadParameters( __argc, __argv );
    //!		
    //!
    //!			// EVOLUTIONARY ALGORITHM TO BE DEFINED
    //!
    //!		
    //!			peo :: run( );
    //!			peo :: finalize( );
    //!			// shutting down the ParadisEO-PEO environment
    //!		
    //!			return 0;
    //!		}
    //!		
    //!
  6. //!
  7. initialization functors, evaluation function and transform operators - basically we only need to create instances for each of the //! enumerated objects, to be passed later as parameters for higher-level components of the evolutionary algorithm.
    //! //!
    //!		RouteInit route_init;	// random init object - creates random Route objects
    //!		RouteEval full_eval;	// evaluator object - offers a fitness value for a specified Route object
    //!
    //!		OrderXover crossover;	// crossover operator - creates two offsprings out of two specified parents
    //!		CitySwap mutation;	// mutation operator - randomly mutates one gene for a specified individual
    //!		
    //!
  8. //!
  9. construct the components of the evolutionary algorithm - each of the components that has to be passed as parameter to the //! peoEA constructor has to be defined along with the associated parameters. Except for the requirement to provide the //! appropriate objects (for example, a peoPopEval derived object must be specified for the evaluation functor), there is no strict //! path to follow. It is your option what elements to mix, depending on your problem - we aimed for simplicity in our example. //! //! //!
    //!		eoPop< Route > population( POP_SIZE, route_init );	// initial population for the algorithm having POP_SIZE individuals
    //!		peoSeqPopEval< Route > eaPopEval( full_eval );		// evaluator object - to be applied at each iteration on the entire population
    //!		
    //! //!
    //!		eoGenContinue< Route > eaCont( NUM_GEN );		// continuation criterion - the algorithm will iterate for NUM_GEN generations
    //!		eoCheckPoint< Route > eaCheckpointContinue( eaCont );	// checkpoint object - verify at each iteration if the continuation criterion is met
    //!		
    //! //!
    //!		eoRankingSelect< Route > selectionStrategy;		// selection strategy - applied at each iteration for selecting parent individuals
    //!		eoSelectNumber< Route > eaSelect( selectionStrategy, POP_SIZE ); // selection object - POP_SIZE individuals are selected at each iteration
    //!		
    //! //!
    //!		// transform operator - includes the crossover and the mutation operators with a specified associated rate
    //!		eoSGATransform< Route > transform( crossover, CROSS_RATE, mutation, MUT_RATE );
    //!		peoSeqTransform< Route > eaTransform( transform );	// ParadisEO transform operator (please remark the peo prefix) - wraps an e EO transform object
    //!		
    //! //!
    //!		eoPlusReplacement< Route > eaReplace;			// replacement strategy - for replacing the initial population with offspring individuals
    //!		
    //!
  10. //!
  11. evolutionary algorithm - having defined all the previous components, we are ready for instanciating an evolutionary algorithm. //! In the end we have to associate a population with the algorithm, which will serve as the initial population, to be iteratively evolved. //! //!
    //!		peoEA< Route > eaAlg( eaCheckpointContinue, eaPopEval, eaSelect, eaTransform, eaReplace );
    //!
    //!		eaAlg( population );	// specifying the initial population for the algorithm, to be iteratively evolved
    //!		
    //!
  12. //!
//! //! If you have not missed any of the enumerated points, your program should be like the following: //! //!
//! ##include "route.h"
//! ##include "route_init.h"
//! ##include "route_eval.h"
//! 
//! ##include "order_xover.h"
//! ##include "city_swap.h"
//! 
//! ##include "param.h"
//! 
//! ##include 
//! 
//! 
//! ##define POP_SIZE 10
//! ##define NUM_GEN 100
//! ##define CROSS_RATE 1.0
//! ##define MUT_RATE 0.01
//! 
//! 
//! int main( int __argc, char** __argv ) {
//! 
//! 	// initializing the ParadisEO-PEO environment
//! 	peo :: init( __argc, __argv );
//! 
//! 
//! 	// processing the command line specified parameters
//! 	loadParameters( __argc, __argv );
//! 
//! 
//! 	// init, eval operators, EA operators -------------------------------------------------------------------------------------------------------------
//! 
//! 	RouteInit route_init;	// random init object - creates random Route objects
//! 	RouteEval full_eval;	// evaluator object - offers a fitness value for a specified Route object
//! 
//! 	OrderXover crossover;	// crossover operator - creates two offsprings out of two specified parents
//! 	CitySwap mutation;	// mutation operator - randomly mutates one gene for a specified individual
//! 	// ------------------------------------------------------------------------------------------------------------------------------------------------
//! 
//! 
//! 	// evolutionary algorithm components --------------------------------------------------------------------------------------------------------------
//! 
//! 	eoPop< Route > population( POP_SIZE, route_init );	// initial population for the algorithm having POP_SIZE individuals
//! 	peoSeqPopEval< Route > eaPopEval( full_eval );		// evaluator object - to be applied at each iteration on the entire population
//! 
//! 	eoGenContinue< Route > eaCont( NUM_GEN );		// continuation criterion - the algorithm will iterate for NUM_GEN generations
//! 	eoCheckPoint< Route > eaCheckpointContinue( eaCont );	// checkpoint object - verify at each iteration if the continuation criterion is met
//! 
//! 	eoRankingSelect< Route > selectionStrategy;		// selection strategy - applied at each iteration for selecting parent individuals
//! 	eoSelectNumber< Route > eaSelect( selectionStrategy, POP_SIZE ); // selection object - POP_SIZE individuals are selected at each iteration
//! 
//! 	// transform operator - includes the crossover and the mutation operators with a specified associated rate
//! 	eoSGATransform< Route > transform( crossover, CROSS_RATE, mutation, MUT_RATE );
//! 	peoSeqTransform< Route > eaTransform( transform );	// ParadisEO transform operator (please remark the peo prefix) - wraps an e EO transform object
//! 
//! 	eoPlusReplacement< Route > eaReplace;			// replacement strategy - for replacing the initial population with offspring individuals
//! 	// ------------------------------------------------------------------------------------------------------------------------------------------------
//! 
//! 
//! 	// ParadisEO-PEO evolutionary algorithm -----------------------------------------------------------------------------------------------------------
//! 
//! 	peoEA< Route > eaAlg( eaCheckpointContinue, eaPopEval, eaSelect, eaTransform, eaReplace );
//! 	
//! 	eaAlg( population );	// specifying the initial population for the algorithm, to be iteratively evolved
//! 	// ------------------------------------------------------------------------------------------------------------------------------------------------
//! 
//! 
//! 	peo :: run( );
//! 	peo :: finalize( );
//! 	// shutting down the ParadisEO-PEO environment
//! 
//! 	return 0;
//! }
//! 
//! //! //! \section testing Compilation and Execution //! //! First, please make sure that you followed all the previous steps in defining the evolutionary algorithm. Your file should be called main.cpp - please //! make sure you do not rename the file (we will be using a pre-built makefile, thus you are required not to change the file names). Please make sure you //! are in the paradiseo-peo/examples/lesson1 directory - you should open a console and you should change your current directory to the one of Lesson1. //! //! Compilation: being in the paradiseo-peo/examples/lesson1 directory, you have to type make. As a result the main.cpp file //! will be compiled and you should obtain an executable file called tspExample. If you have errors, please verify any of the followings: //! //! //! //! NOTE: in order to successfully compile your program you should already have installed an MPI distribution in your system. //! //! Execution: the execution of a ParadisEO-PEO program requires having already created an environment for launching MPI programs. For MPICH-2, //! for example, this requires starting a ring of daemons. The implementation that we provided as an example is sequential and includes no parallelism - we //! will see in the end how to include also parallelism. Executing a parallel program requires specifying a mapping of resources, in order to assing different //! algorithms to different machines, define worker machines etc. This mapping is defined by an XML file called schema.xml, which, for our case, has //! the following structure: //! //!
//!	
//!	
//!	
//!		
//!			
//!			
//!			
//!			
//!			1
//!			
//!			
//!			
//!			
//!			
//!			
//!		
//!	
//! 
//! //! Not going into details, the XML file presented above describes a mapping which includes four nodes, the first one having the role of scheduler, //! the second one being the node on which the evolutionary algorithm is actually executed and the third and the fourth ones being slave nodes. Overall //! the mapping says that we will be launching four processes, out of which only one will be executing the evolutionary algorithm. The other node entries //! in the XML file have no real functionality as we have no parallelism in our program - the entries were created for you convenience, in order to provide //! a smooth transition to creating a parallel program. //! //! Launching the program may be different, depending on your MPI distribution - for MPICH-2, in a console, in the paradiseo-peo/examples/lesson1 //! directory you have to type the following command: //! //! mpiexec -n 4 ./tspExample @lesson.param //! //! NOTE: the "-n 4" indicates the number of processes to be launched. The last argument, "@lesson.param", indicates a file which specifies different //! application specific parameters (the mapping file to be used, for example, whether to use logging or not, etc). //! //! The result of your execution should be similar to the following: //!
//! 	Loading '../data/eil101.tsp'.
//! 	NAME: eil101.
//! 	COMMENT: 101-city problem (Christofides/Eilon).
//! 	TYPE: TSP.
//! 	DIMENSION: 101.
//! 	EDGE_WEIGHT_TYPE: EUC_2D.
//! 	Loading '../data/eil101.tsp'.
//! 	NAME: eil101.
//! 	COMMENT: 101-city problem (Christofides/Eilon).
//! 	EOF.
//! 	TYPE: TSP.
//! 	DIMENSION: 101.
//! 	EDGE_WEIGHT_TYPE: EUC_2D.
//! 	EOF.
//! 	Loading '../data/eil101.tsp'.
//! 	NAME: eil101.
//! 	COMMENT: 101-city problem (Christofides/Eilon).
//! 	TYPE: TSP.
//! 	DIMENSION: 101.
//! 	EDGE_WEIGHT_TYPE: EUC_2D.
//! 	EOF.
//! 	Loading '../data/eil101.tsp'.
//! 	NAME: eil101.
//! 	COMMENT: 101-city problem (Christofides/Eilon).
//! 	TYPE: TSP.
//! 	DIMENSION: 101.
//! 	EDGE_WEIGHT_TYPE: EUC_2D.
//! 	EOF.
//! 	STOP in eoGenContinue: Reached maximum number of generations [100/100]
//!	
//! //! //! \section paraIntro Introducing parallelism //! //! Creating parallel programs with ParadisEO-PEO represents an easy task once you have the basic structure for your program. For experimentation, //! in the main.cpp file, replace the line //!
//!	peoSeqPopEval< Route > eaPopEval( full_eval );
//! 
//! with //!
//!	peoParaPopEval< Route > eaPopEval( full_eval );
//! 
//! The second line only tells that we would like to evaluate individuals in parallel - this is very interesting if you have a time consuming fitness //! evaluation function. If you take another look on the schema.xml XML file you will see the last two nodes being marked as slaves (the "num_workers" //! attribute - these nodes will be used for computing the fitness of the individuals. //! //! At this point you only have to recompile your program and to launch it again - as we are not using a time consuming fitness fitness function, the //! effects might not be visible - you may increase the number of individuals to experiment.