diff --git a/smp/src/abstractIsland.h b/smp/src/abstractIsland.h index 9ecbf7216..ef48bd0f5 100644 --- a/smp/src/abstractIsland.h +++ b/smp/src/abstractIsland.h @@ -78,6 +78,8 @@ public: * @return true if stopped */ virtual bool isStopped(void) const = 0; + + virtual void receive(void) = 0; protected: std::mutex m; diff --git a/smp/src/island.h b/smp/src/island.h index 42b5ee3ac..947f28089 100644 --- a/smp/src/island.h +++ b/smp/src/island.h @@ -121,6 +121,11 @@ public: */ virtual bool isStopped(void) const; + /** + * Check if there is population to receive + */ + virtual void receive(void); + protected: /** @@ -129,11 +134,6 @@ protected: */ virtual void send(eoSelect& _select); - /** - * Check if there is population to receive - */ - virtual void receive(void); - eoEvalFunc& eval; eoPop& pop; EOAlgo algo; diff --git a/smp/src/islandModel.cpp b/smp/src/islandModel.cpp index c2eb4e00b..4ed72f4fd 100644 --- a/smp/src/islandModel.cpp +++ b/smp/src/islandModel.cpp @@ -48,18 +48,12 @@ void paradiseo::smp::IslandModel::operator()() { running = true; + // INIT PART + // Create topology, table and initialize islands + initModel(); + std::vector threads(islands.size()); - - // Preparing islands - for(auto& it : islands) - it.second = true; // Indicate islands are running - - // Construct topology according to the number of islands - topo.construct(islands.size()); - - // Create table - table = createTable(); - + // Launching threads unsigned i = 0; for(auto it : islands) @@ -68,14 +62,15 @@ void paradiseo::smp::IslandModel::operator()() i++; } - // + // Lambda function in order to know the number of working islands std::function workingIslands = [this]() -> int { return (int)std::count_if(std::begin(islands), std::end(islands), [](std::pair*, bool>& i) -> bool { return i.second; } ); }; - + + // SCHEDULING PART while(workingIslands() > 0) { // Count working islands @@ -93,13 +88,32 @@ void paradiseo::smp::IslandModel::operator()() std::this_thread::sleep_for(std::chrono::nanoseconds(10)); } - + + // ENDING PART + // Wait the end of algorithms for(auto& thread : threads) thread.join(); + // Send last population + while(!listEmigrants.empty()) + send(); + + // Wait the end of messages sending for(auto& message : sentMessages) message.join(); + // Force last integration + i = 0; + for(auto it : islands) + { + threads[i] = std::thread(&AIsland::receive, it.first); + i++; + } + + // Wait the end of the last integration + for(auto& thread : threads) + thread.join(); + running = false; } @@ -120,6 +134,7 @@ void paradiseo::smp::IslandModel::setTopology(AbstractTopology& _topo) // If we change when the algorithm is running, we need to recontruct the topo if(running) { + std::cout << "Changing topology" << std::endl; topo.construct(islands.size()); // If we change the topology during the algorithm, we need to isolate stopped islands for(auto it : islands) @@ -132,7 +147,7 @@ template void paradiseo::smp::IslandModel::send(void) { std::lock_guard lock(m); - while (!listEmigrants.empty()) + if (!listEmigrants.empty()) { //std::cout << "Mediator envoie ! " << listEmigrants.size() << std::endl; // Get the neighbors @@ -148,6 +163,26 @@ void paradiseo::smp::IslandModel::send(void) } } +template +bool paradiseo::smp::IslandModel::isRunning() const +{ + return (bool)running; +} + +template +void paradiseo::smp::IslandModel::initModel(void) +{ + // Preparing islands + for(auto& it : islands) + it.second = true; // Indicate islands are active + + // Construct topology according to the number of islands + topo.construct(islands.size()); + + // Create table + table = createTable(); +} + template Bimap*> paradiseo::smp::IslandModel::createTable() { @@ -161,9 +196,3 @@ Bimap*> paradiseo::smp::IslandModel::createTable() return table; } - -template -bool paradiseo::smp::IslandModel::isRunning() const -{ - return (bool)running; -} diff --git a/smp/src/islandModel.h b/smp/src/islandModel.h index e56080543..d7a495545 100644 --- a/smp/src/islandModel.h +++ b/smp/src/islandModel.h @@ -91,6 +91,11 @@ protected: */ void send(void); + /** + * Initialize islands, topology and table before starting the model + */ + void initModel(void); + Bimap*> createTable(); std::queue,AIsland*>> listEmigrants; diff --git a/smp/test/t-smpMI_Heterogeneous.cpp b/smp/test/t-smpMI_Heterogeneous.cpp index d304ab5b4..09f59bdfe 100644 --- a/smp/test/t-smpMI_Heterogeneous.cpp +++ b/smp/test/t-smpMI_Heterogeneous.cpp @@ -1,3 +1,5 @@ +// TODO : Un vrai test, propre, qui veut dire quelque chose :) + #include #include #include diff --git a/smp/test/t-smpMI_Homogeneous.cpp b/smp/test/t-smpMI_Homogeneous.cpp index 3d5e63354..f67a3fc4b 100644 --- a/smp/test/t-smpMI_Homogeneous.cpp +++ b/smp/test/t-smpMI_Homogeneous.cpp @@ -8,107 +8,108 @@ using namespace std; int main(void) { + // Defining parameters typedef struct { - unsigned popSize = 10; + unsigned popSize = 1000; unsigned tSize = 2; double pCross = 0.8; double pMut = 0.7; - unsigned maxGen = 10; + unsigned maxGen = 1000; } Param; Param param; + // Fixing the seed rng.reseed(42); + // Load instance loadInstances("t-data.dat", n, bkv, a, b); - // Evaluation function + //Common part to all islands IndiEvalFunc plainEval; - - // Init a solution IndiInit chromInit; - - // Define selection eoDetTournamentSelect selectOne(param.tSize); eoSelectPerc select(selectOne);// by default rate==1 - - // Define operators for crossover and mutation IndiXover Xover; // CROSSOVER IndiSwapMutation mutationSwap; // MUTATION - - // Encapsule in a tranform operator eoSGATransform transform(Xover, param.pCross, mutationSwap, param.pMut); - - // Define replace operator eoPlusReplacement replace; - - eoGenContinue genCont(param.maxGen+100); // generation continuation - eoGenContinue genCont_2(param.maxGen); // generation continuation - eoGenContinue genCont_3(param.maxGen); // generation continuation - // Define population + // ISLAND 1 + // // Algorithm part + eoGenContinue genCont(param.maxGen+100); eoPop pop(param.popSize, chromInit); + // // Emigration policy + // // // Element 1 + eoPeriodicContinue criteria(5); + eoDetTournamentSelect selectOne1(20); + eoSelectNumber who(selectOne1, 3); + + MigPolicy migPolicy; + migPolicy.push_back(PolicyElement(who, criteria)); + + // // Integration policy + eoPlusReplacement intPolicy; + + Island test(pop, intPolicy, migPolicy, genCont, plainEval, select, transform, replace); + + // ISLAND 1 + // // Algorithm part + eoGenContinue genCont_2(param.maxGen); // generation continuation + eoPop pop2(30, chromInit); + // // Emigration policy + // // // Element 1 + eoPeriodicContinue criteria_2(5); + eoDetTournamentSelect selectOne_2(25); + eoSelectNumber who_2(selectOne_2, 5); + + MigPolicy migPolicy_2; + migPolicy_2.push_back(PolicyElement(who_2, criteria_2)); + + // // Integration policy + eoPlusReplacement intPolicy_2; + + Island test2(pop2, intPolicy_2, migPolicy_2, genCont_2, plainEval, select, transform, replace); + + // Island 3 + // // Algorithm part + eoGenContinue genCont_3(param.maxGen); + eoPop pop3(30, chromInit); + // // Emigration policy + // // // Element 1 + eoPeriodicContinue criteria_3(10); + eoDetTournamentSelect selectOne_3(15); + eoSelectNumber who_3(selectOne_3, 1); + + MigPolicy migPolicy_3; + migPolicy.push_back(PolicyElement(who_3, criteria_3)); + + // // Integration policy + eoPlusReplacement intPolicy_3; + + Island test3(pop3, intPolicy_3, migPolicy_3, genCont_3, plainEval, select, transform, replace); + try { - // Island 1 - // // Emigration policy - // // // Element 1 - eoPeriodicContinue criteria(5); - eoDetTournamentSelect selectOne(20); - eoSelectNumber who(selectOne, 3); - - MigPolicy migPolicy; - migPolicy.push_back(PolicyElement(who, criteria)); - - // // Integration policy - eoPlusReplacement intPolicy; - - eoPop pop(param.popSize, chromInit); - - Island test(pop, intPolicy, migPolicy, genCont, plainEval, select, transform, replace); - - // Island 2 - // // Emigration policy - // // // Element 1 - eoPeriodicContinue criteria_2(5); - eoDetTournamentSelect selectOne_2(25); - eoSelectNumber who_2(selectOne_2, 5); - - MigPolicy migPolicy_2; - migPolicy_2.push_back(PolicyElement(who_2, criteria_2)); - - // // Integration policy - eoPlusReplacement intPolicy_2; - - eoPop pop2(30, chromInit); - Island test2(pop2, intPolicy_2, migPolicy_2, genCont_2, plainEval, select, transform, replace); - - // Island 3 - // // Emigration policy - // // // Element 1 - eoPeriodicContinue criteria_3(10); - eoDetTournamentSelect selectOne_3(15); - eoSelectNumber who_3(selectOne_3, 1); - - MigPolicy migPolicy_3; - migPolicy.push_back(PolicyElement(who_3, criteria_3)); - - // // Integration policy - eoPlusReplacement intPolicy_3; - - eoPop pop3(30, chromInit); - Island test3(pop3, intPolicy_3, migPolicy_3, genCont_3, plainEval, select, transform, replace); - - // Topology + // Topologies Topology topo; + Topology topo2; IslandModel model(topo); model.add(test); model.add(test2); model.add(test3); - model(); + std::thread t = std::thread(&IslandModel::operator(), &model); + + // Change topology after 1s of computation + std::chrono::milliseconds dura(1000); + std::this_thread::sleep_for( dura ); + + model.setTopology(topo2); + + t.join(); cout << test.getPop() << endl; cout << test2.getPop() << endl;