00001 // "main.cpp" 00002 00003 // (c) OPAC Team, LIFL, January 2006 00004 00005 /* 00006 Contact: paradiseo-help@lists.gforge.inria.fr 00007 */ 00008 00009 #include <eo> 00010 #include <paradiseo> 00011 00012 #include <peoParallelAlgorithmWrapper.h> 00013 #include <peoSynchronousMultiStart.h> 00014 00015 00016 00017 #include "route.h" 00018 #include "route_init.h" 00019 #include "route_eval.h" 00020 00021 #include "order_xover.h" 00022 #include "city_swap.h" 00023 00024 #include "param.h" 00025 00026 00027 00028 00029 #include <mo.h> 00030 00031 #include <graph.h> 00032 #include <route.h> 00033 #include <route_eval.h> 00034 #include <route_init.h> 00035 00036 #include <two_opt.h> 00037 #include <two_opt_init.h> 00038 #include <two_opt_next.h> 00039 #include <two_opt_incr_eval.h> 00040 00041 00042 00043 #define RANDOM_POP_SIZE 30 00044 #define RANDOM_ITERATIONS 10 00045 00046 00047 #define POP_SIZE 10 00048 #define NUM_GEN 100 00049 #define CROSS_RATE 1.0 00050 #define MUT_RATE 0.01 00051 00052 #define NUMBER_OF_POPULATIONS 3 00053 00054 00055 00056 struct RandomExplorationAlgorithm { 00057 00058 RandomExplorationAlgorithm( peoPopEval< Route >& __popEval, peoSynchronousMultiStart< Route >& extParallelExecution ) 00059 : popEval( __popEval ), parallelExecution( extParallelExecution ) { 00060 } 00061 00062 00063 // the sequential algorithm to be executed in parallel by the wrapper 00064 void operator()() { 00065 00066 RouteInit route_init; // random init object - creates random Route objects 00067 RouteEval route_eval; 00068 eoPop< Route > population( RANDOM_POP_SIZE, route_init ); 00069 00070 popEval( population ); 00071 00072 00073 // executing HCs on the population in parallel 00074 parallelExecution( population ); 00075 00076 00077 00078 // just to show off :: HCs on a vector of Route objects 00079 { 00080 Route* rVect = new Route[ 5 ]; 00081 for ( unsigned int index = 0; index < 5; index++ ) { 00082 00083 route_init( rVect[ index ] ); route_eval( rVect[ index ] ); 00084 } 00085 00086 // applying the HCs on the vector of Route objects 00087 parallelExecution( rVect, rVect + 5 ); 00088 delete[] rVect; 00089 } 00090 00091 00092 00093 Route bestRoute = population.best_element(); 00094 00095 for ( unsigned int index = 0; index < RANDOM_ITERATIONS; index++ ) { 00096 00097 for ( unsigned int routeIndex = 0; routeIndex < RANDOM_POP_SIZE; routeIndex++ ) { 00098 00099 route_init( population[ routeIndex ] ); 00100 } 00101 00102 popEval( population ); 00103 00104 if ( fabs( population.best_element().fitness() ) < fabs( bestRoute.fitness() ) ) bestRoute = population.best_element(); 00105 00106 std::cout << "Random Iteration #" << index << "... [ " << bestRoute.fitness() << " ]" << std::flush << std::endl; 00107 } 00108 } 00109 00110 00111 peoPopEval< Route >& popEval; 00112 peoSynchronousMultiStart< Route >& parallelExecution; 00113 }; 00114 00115 00116 00117 00118 int main( int __argc, char** __argv ) { 00119 00120 srand( time(NULL) ); 00121 00122 00123 00124 // initializing the ParadisEO-PEO environment 00125 peo :: init( __argc, __argv ); 00126 00127 00128 // processing the command line specified parameters 00129 loadParameters( __argc, __argv ); 00130 00131 00132 00133 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 00134 // #1 An EO evolutionary algorithm to be executed in parallel with other algorithms (no parallel evaluation, no etc.). 00135 00136 // init, eval operators, EA operators ------------------------------------------------------------------------------------------------------------- 00137 RouteInit route_init; // random init object - creates random Route objects 00138 RouteEval full_eval; // evaluator object - offers a fitness value for a specified Route object 00139 00140 OrderXover crossover; // crossover operator - creates two offsprings out of two specified parents 00141 CitySwap mutation; // mutation operator - randomly mutates one gene for a specified individual 00142 // ------------------------------------------------------------------------------------------------------------------------------------------------ 00143 00144 00145 // evolutionary algorithm components -------------------------------------------------------------------------------------------------------------- 00146 00147 eoPop< Route > population( POP_SIZE, route_init ); // initial population for the algorithm having POP_SIZE individuals 00148 00149 eoGenContinue< Route > eaCont( NUM_GEN ); // continuation criterion - the algorithm will iterate for NUM_GEN generations 00150 eoCheckPoint< Route > eaCheckpointContinue( eaCont ); // checkpoint object - verify at each iteration if the continuation criterion is met 00151 00152 eoRankingSelect< Route > selectionStrategy; // selection strategy - applied at each iteration for selecting parent individuals 00153 eoSelectNumber< Route > eaSelect( selectionStrategy, POP_SIZE ); // selection object - POP_SIZE individuals are selected at each iteration 00154 00155 // transform operator - includes the crossover and the mutation operators with a specified associated rate 00156 eoSGATransform< Route > transform( crossover, CROSS_RATE, mutation, MUT_RATE ); 00157 00158 eoPlusReplacement< Route > eaReplace; // replacement strategy - for replacing the initial population with offspring individuals 00159 // ------------------------------------------------------------------------------------------------------------------------------------------------ 00160 00161 00162 00163 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00164 // SEQENTIAL ALGORITHM DEFINITION ----------------------------------------------------------------------------------------------------------------- 00165 eoEasyEA< Route > eaAlg( eaCheckpointContinue, full_eval, eaSelect, transform, eaReplace ); 00166 // SEQENTIAL ALGORITHM DEFINITION ----------------------------------------------------------------------------------------------------------------- 00167 00168 // SETTING UP THE PARALLEL WRAPPER ---------------------------------------------------------------------------------------------------------------- 00169 peoParallelAlgorithmWrapper parallelEAAlg( eaAlg, population ); // specifying the embedded algorithm and the algorithm input data 00170 // SETTING UP THE PARALLEL WRAPPER ---------------------------------------------------------------------------------------------------------------- 00171 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00172 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 00173 00174 00175 00176 00177 00178 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 00179 // #2 A MO hill climbing to be executed in parallel with other algorithms (no parallel evaluation, no etc.). 00180 00181 if ( getNodeRank() == 1 ) { 00182 00183 Graph::load( __argv [ 1 ] ); 00184 } 00185 00186 Route route; 00187 RouteInit init; init( route ); 00188 RouteEval full_evalHC; full_evalHC( route ); 00189 00190 if ( getNodeRank() == 1 ) { 00191 00192 std :: cout << "[From] " << route << std :: endl; 00193 } 00194 00195 00196 TwoOptInit two_opt_init; 00197 TwoOptNext two_opt_next; 00198 TwoOptIncrEval two_opt_incr_eval; 00199 00200 moBestImprSelect< TwoOpt > two_opt_select; 00201 00202 00203 00204 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00205 // SEQENTIAL ALGORITHM DEFINITION ----------------------------------------------------------------------------------------------------------------- 00206 moHC< TwoOpt > hill_climbing( two_opt_init, two_opt_next, two_opt_incr_eval, two_opt_select, full_evalHC ); 00207 // SEQENTIAL ALGORITHM DEFINITION ----------------------------------------------------------------------------------------------------------------- 00208 00209 // SETTING UP THE PARALLEL WRAPPER ---------------------------------------------------------------------------------------------------------------- 00210 peoParallelAlgorithmWrapper parallelHillClimbing( hill_climbing, route ); // specifying the embedded algorithm and the algorithm input data 00211 // SETTING UP THE PARALLEL WRAPPER ---------------------------------------------------------------------------------------------------------------- 00212 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00213 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 00214 00215 00216 00217 00218 00219 00220 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 00221 // #3 A user defined algorithm to be executed in parallel with other algorithms - parallel evaluation and synchronous 00222 // multi-start of several hill-climbing algorithms (inside the user defined algorithm)!!. 00223 00224 RouteEval full_evalRandom; 00225 peoParaPopEval< Route > randomParaEval( full_evalRandom ); 00226 00227 00228 peoSynchronousMultiStart< Route > parallelExecution( hill_climbing ); 00229 00230 RandomExplorationAlgorithm randomExplorationAlgorithm( randomParaEval, parallelExecution ); 00231 00232 00233 // SETTING UP THE PARALLEL WRAPPER ---------------------------------------------------------------------------------------------------------------- 00234 peoParallelAlgorithmWrapper parallelRandExp( randomExplorationAlgorithm ); // specifying the embedded algorithm - no input data in this case 00235 00236 randomParaEval.setOwner( parallelRandExp ); 00237 parallelExecution.setOwner( parallelRandExp ); 00238 // SETTING UP THE PARALLEL WRAPPER ---------------------------------------------------------------------------------------------------------------- 00239 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 00240 00241 00242 00243 00244 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 00245 // #4 Synchronous Multi-Start: several hill-climbing algorithms launched in parallel on different initial solutions 00246 00247 RouteInit ex_hc_route_init; // random init object - creates random Route objects 00248 RouteEval ex_hc_full_eval; // evaluator object - offers a fitness value for a specified Route object 00249 00250 eoPop< Route > ex_hc_population( POP_SIZE, ex_hc_route_init ); 00251 00252 for ( unsigned int index = 0; index < POP_SIZE; index++ ) { 00253 00254 ex_hc_full_eval( ex_hc_population[ index ] ); 00255 } 00256 00257 00258 // SETTING UP THE PARALLEL WRAPPER ---------------------------------------------------------------------------------------------------------------- 00259 peoSynchronousMultiStart< Route > ex_hc_parallelExecution( hill_climbing ); 00260 peoParallelAlgorithmWrapper ex_hc_parallel( ex_hc_parallelExecution, ex_hc_population ); // specifying the embedded algorithm - no input data in this case 00261 00262 ex_hc_parallelExecution.setOwner( ex_hc_parallel ); 00263 // SETTING UP THE PARALLEL WRAPPER ---------------------------------------------------------------------------------------------------------------- 00264 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 00265 00266 00267 00268 00269 00270 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 00271 // #5 Synchronous Multi-Start: Multiple EO evolutionary algorithms to be executed in parallel 00272 // (inside different processes, on different populations; no parallel evaluation, no etc.). 00273 00274 RouteInit ex_route_init; // random init object - creates random Route objects 00275 RouteEval ex_full_eval; // evaluator object - offers a fitness value for a specified Route object 00276 00277 std::vector< eoPop< Route > > ex_population; 00278 ex_population.resize( NUMBER_OF_POPULATIONS ); 00279 00280 for ( unsigned int indexPop = 0; indexPop < NUMBER_OF_POPULATIONS; indexPop++ ) { 00281 00282 ex_population[ indexPop ].resize( POP_SIZE ); 00283 00284 for ( unsigned int index = 0; index < POP_SIZE; index++ ) { 00285 00286 ex_route_init( ex_population[ indexPop ][ index ] ); 00287 ex_full_eval( ex_population[ indexPop ][ index ] ); 00288 } 00289 } 00290 00291 00292 // SETTING UP THE PARALLEL WRAPPER ---------------------------------------------------------------------------------------------------------------- 00293 peoSynchronousMultiStart< eoPop< Route > > ex_parallelExecution( eaAlg ); 00294 peoParallelAlgorithmWrapper ex_parallel( ex_parallelExecution, ex_population ); // specifying the embedded algorithm - no input data in this case 00295 00296 ex_parallelExecution.setOwner( ex_parallel ); 00297 // SETTING UP THE PARALLEL WRAPPER ---------------------------------------------------------------------------------------------------------------- 00298 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 00299 00300 00301 00302 00303 00304 00305 peo :: run( ); 00306 peo :: finalize( ); 00307 // shutting down the ParadisEO-PEO environment 00308 00309 00310 00311 // the algorithm is executed in the #1 rank process 00312 if ( getNodeRank() == 1 ) { 00313 00314 std :: cout << "[To] " << route << std :: endl << std::endl; 00315 00316 00317 std :: cout << "Synchronous Multi-Start HCs:" << std :: endl ; 00318 for ( unsigned int index = 0; index < POP_SIZE; index++ ) { 00319 00320 std::cout << ex_hc_population[ index ] << std::endl; 00321 } 00322 std::cout << std::endl << std::endl; 00323 00324 00325 std :: cout << "Synchronous Multi-Start EAs:" << std :: endl ; 00326 for ( unsigned int index = 0; index < NUMBER_OF_POPULATIONS; index++ ) { 00327 00328 std::cout << ex_population[ index ] << std::endl; 00329 } 00330 std::cout << std::endl << std::flush; 00331 00332 } 00333 00334 00335 00336 return 0; 00337 }