diff --git a/trunk/paradiseo-peo/examples/lesson1/doclsn.h b/trunk/paradiseo-peo/examples/lesson1/doclsn.h index 146ffc0cf..544edc583 100644 --- a/trunk/paradiseo-peo/examples/lesson1/doclsn.h +++ b/trunk/paradiseo-peo/examples/lesson1/doclsn.h @@ -2,7 +2,7 @@ //! //! \section structure Introduction //! -//! One of the first steps in designing an evolutionary algorihtm using the ParadisEO-PEO framework +//! 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 @@ -47,10 +47,13 @@ //!
//! //! The source-code for this tutorial may be found in the paradiseo-peo/examples/lesson1 directory, in the main.cpp file. -//! 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 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 @@ -91,7 +94,7 @@ //! //! 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 refered header files may be found in the pardiseo-peo/examples/shared directory. +//! 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 @@ -115,11 +118,11 @@ //! EO class, being defined as class RouteEval : public eoEvalFunc< Route >. //!
  2. //!
  3. transformation operators - in order to assure the evolution of the initial population, transformation operators have to be defined. -//! Depending on your prolem, you may specify quadruple operators (two input individuals, two output resulting individuals), i.e. crossover operators, +//! 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 presended example are defined in the order_xover.h and the city_swap.h +//! 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. //!
  4. //!
  5. continuation criterion - the evolutionary algorithm evolves in an iterative manner; a continuation criterion has to be specified. @@ -128,7 +131,7 @@ //! make sure that your class derives the eoContinue class.
    //!
  6. //!
  7. 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 whehter using +//! 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. @@ -142,25 +145,354 @@ //! //! \section example A simple example for constructing a peoEA object //! -//! -//! -//! -//! -//! -//! -//! -//! -//! -//! -//! -//! -//! -//! -//! -//! -//! -//! -//! -//! -//! -//!
    ...    
    eoPop< EOT > population( POP_SIZE, popInitializer );   // creation of a population with POP_SIZE individuals - the popInitializer is a functor to be called for each individual
       
    eoGenContinue< EOT > eaCont( NUM_GEN );   // number of generations for the evolutionary algorithm
    eoCheckPoint< EOT > eaCheckpointContinue( eaCont );   // checkpoint incorporating the continuation criterion - startpoint for adding other checkpoint objects
       
    peoSeqPopEval< EOT > eaPopEval( evalFunction );   // sequential evaluation functor wrapper - evalFunction represents the actual evaluation functor
       
    eoRankingSelect< EOT > selectionStrategy;   // selection strategy for creating the offspring population - a simple ranking selection in this case
    eoSelectNumber< EOT > eaSelect( selectionStrategy, POP_SIZE );   // the number of individuals to be selected for creating the offspring population
    eoRankingSelect< EOT > selectionStrategy;   // selection strategy for creating the offspring population - a simple ranking selection in this case
       
    eoSGATransform< EOT > transform( crossover, CROSS_RATE, mutation, MUT_RATE );   // transformation operator - crossover and mutation operators with their associated probabilities
    peoSeqTransform< EOT > eaTransform( transform );   // ParadisEO specific sequential operator - a parallel version may be specified in the same manner
       
    eoPlusReplacement< EOT > eaReplace;   // replacement strategy - for integrating the offspring resulting individuals in the initial population
       
    peoEA< EOT > eaAlg( eaCheckpointContinue, eaPopEval, eaSelect, eaTransform, eaReplace );   // ParadisEO evolutionary algorithm integrating the above defined objects
    eaAlg( population );   // specifying the initial population for the algorithm
    ...    
    \ No newline at end of file +//! 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. +//! +//!
        +//!
      • an initial population has to be specified; the constructor accepts the specification of an initializing object. Further, +//! an evaluation object is required - the peoEA constructor requires a peoPopEval derived class. +//!
      • +//!
      +//!
      +//!		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
      +//!		
      +//!
        +//!
      • the evolutionary algorithm continues to iterate till a continuation criterion is not met. For our case we consider +//! a fixed number of generations. The continuation criterion has to be specified as a checkpoint object, thus requiring +//! the creation of an eoCheckPoint object in addition. +//!
      • +//!
      +//!
      +//!		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
      +//!		
      +//!
        +//!
      • selection strategy - we are required to specify a selection strategy for extracting individuals out of the parent +//! population; in addition the number of individuals to be selected has to be specified. +//!
      • +//!
      +//!
      +//!		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
      +//!		
      +//!
        +//!
      • transformation operators - we have to integrate the crossover and the mutation functors into an object which may be passed +//! as a parameter when creating the peoEA object. The constructor of peoEA requires a peoTransform derived +//! object. Associated probabilities have to be specified also. +//!
      • +//!
      +//!
      +//!		// 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
      +//!		
      +//!
        +//!
      • replacement strategy - required for defining the way for integrating the resulting offsprings into the initial population. +//! At your option whether you would like to chose one of the predefined replacement strategies that come with the EO framework +//! or if you want to define your own. +//!
      • +//!
      +//!
      +//!		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. diff --git a/trunk/paradiseo-peo/examples/lesson1/lesson.param b/trunk/paradiseo-peo/examples/lesson1/lesson.param new file mode 100644 index 000000000..3caca8ccf --- /dev/null +++ b/trunk/paradiseo-peo/examples/lesson1/lesson.param @@ -0,0 +1,12 @@ +## miscallenous parameters + +--debug=false + +## deployment schema + +--schema=schema.xml + +## parameters + +--inst=../data/eil101.tsp + diff --git a/trunk/paradiseo-peo/examples/lesson1/main.cpp b/trunk/paradiseo-peo/examples/lesson1/main.cpp index b99376b63..0658fa813 100644 --- a/trunk/paradiseo-peo/examples/lesson1/main.cpp +++ b/trunk/paradiseo-peo/examples/lesson1/main.cpp @@ -6,8 +6,6 @@ Contact: paradiseo-help@lists.gforge.inria.fr */ -#include "param.h" - #include "route.h" #include "route_init.h" #include "route_eval.h" @@ -15,6 +13,8 @@ #include "order_xover.h" #include "city_swap.h" +#include "param.h" + #include diff --git a/trunk/paradiseo-peo/examples/lesson1/schema.xml b/trunk/paradiseo-peo/examples/lesson1/schema.xml new file mode 100644 index 000000000..3edea1488 --- /dev/null +++ b/trunk/paradiseo-peo/examples/lesson1/schema.xml @@ -0,0 +1,18 @@ + + + + + + + + + 1 + + + + + + + + + diff --git a/trunk/paradiseo-peo/examples/lesson2/lesson.param b/trunk/paradiseo-peo/examples/lesson2/lesson.param new file mode 100644 index 000000000..3caca8ccf --- /dev/null +++ b/trunk/paradiseo-peo/examples/lesson2/lesson.param @@ -0,0 +1,12 @@ +## miscallenous parameters + +--debug=false + +## deployment schema + +--schema=schema.xml + +## parameters + +--inst=../data/eil101.tsp + diff --git a/trunk/paradiseo-peo/examples/lesson2/schema.xml b/trunk/paradiseo-peo/examples/lesson2/schema.xml new file mode 100644 index 000000000..3edea1488 --- /dev/null +++ b/trunk/paradiseo-peo/examples/lesson2/schema.xml @@ -0,0 +1,18 @@ + + + + + + + + + 1 + + + + + + + + +