Add topology to IslandModel, sending messages mecanism, rewrite Bimap container

This commit is contained in:
quemy 2012-11-24 15:26:11 +01:00
commit b3f83717d6
10 changed files with 162 additions and 63 deletions

View file

@ -79,12 +79,19 @@ public:
*/ */
virtual void check(void) = 0; virtual void check(void) = 0;
/**
* Update the island by adding population to send in the imigrants list.
*/
virtual void update(eoPop<EOT> _data) = 0;
/** /**
* Check if the algorithm is stopped. * Check if the algorithm is stopped.
* @return true if stopped * @return true if stopped
*/ */
virtual bool isStopped(void) = 0; virtual bool isStopped(void) const = 0;
protected:
std::mutex m;
}; };
} }

View file

@ -40,7 +40,7 @@ namespace smp
/** Bimap /** Bimap
Bidirectional map in order to create a bijection between islands and vertices. Bidirectional map in order to create a bijection between islands and vertices.
A and B objects are stocked in two std::set, then if you would avoid instances duplications, A and B objects are stocked in two std::map, then if you would like to avoid instances duplications,
template A and B with pointers. template A and B with pointers.
**/ **/
@ -50,43 +50,45 @@ class Bimap
public: public:
/** /**
* Add a relation * Add a relation
* @param workersNb the number of workers * @param A right key
* @param args... list of parameters according to the constructor of your algorithm * @param B left key
*/ */
void add(A a, B b) void add(A& a, B& b)
{ {
ASet.insert(a); rightAssociation[a] = b;
BSet.insert(b); leftAssociation[b] = a;
rightAssociation[&a] = &b;
leftAssociation[&b] = &a; std::cout << "DUMP" << std::endl;
for(auto i : rightAssociation)
std::cout << i.first << "------" << i.second << std::endl;
for(auto i : leftAssociation)
std::cout << i.first << "------" << i.second << std::endl;
std::cout << "END DUMP" << std::endl;
} }
std::map<A,B> getRight() const
B& getRight(A const a)
{ {
return *rightAssociation[&a]; return rightAssociation;
} }
A& getLeft(B const b) std::map<B,A> getLeft() const
{ {
return *leftAssociation[&b]; return leftAssociation;
} }
unsigned size() unsigned size() const
{ {
return ASet.size(); return leftAssociation.size();
} }
bool empty() bool empty() const
{ {
return ASet.empty(); return leftAssociation.empty();
} }
protected: protected:
std::set<A> ASet; std::map<A,B> rightAssociation;
std::set<B> BSet; std::map<B,A> leftAssociation;
std::map<A*,B*> rightAssociation;
std::map<B*,A*> leftAssociation;
}; };
} }

View file

@ -66,12 +66,6 @@ void paradiseo::smp::Island<EOAlgo,EOT>::setModel(IslandModel<EOT>* _model)
model = _model; model = _model;
} }
template<template <class> class EOAlgo, class EOT>
void paradiseo::smp::Island<EOAlgo,EOT>::update(eoPop<EOT>& _data)
{
listImigrants.push_back(&_data);
}
template<template <class> class EOAlgo, class EOT> template<template <class> class EOAlgo, class EOT>
eoPop<EOT>& paradiseo::smp::Island<EOAlgo,EOT>::getPop() eoPop<EOT>& paradiseo::smp::Island<EOAlgo,EOT>::getPop()
{ {
@ -94,7 +88,7 @@ void paradiseo::smp::Island<EOAlgo,EOT>::check()
} }
template<template <class> class EOAlgo, class EOT> template<template <class> class EOAlgo, class EOT>
bool paradiseo::smp::Island<EOAlgo,EOT>::isStopped(void) bool paradiseo::smp::Island<EOAlgo,EOT>::isStopped(void) const
{ {
return (bool)stopped; return (bool)stopped;
} }
@ -119,16 +113,39 @@ void paradiseo::smp::Island<EOAlgo,EOT>::send(eoSelect<EOT>& _select)
template<template <class> class EOAlgo, class EOT> template<template <class> class EOAlgo, class EOT>
void paradiseo::smp::Island<EOAlgo,EOT>::receive(void) void paradiseo::smp::Island<EOAlgo,EOT>::receive(void)
{ {
std::lock_guard<std::mutex> lock(this->m);
if(!listImigrants.empty()) {
std::cout << "______________________________________________" << std::endl;
std::cout << "Ile : " << this << std::endl;
std::cout << "Pop avant : " << std::endl << pop << std::endl;
while (!listImigrants.empty()) while (!listImigrants.empty())
{ {
eoPop<EOT> offspring = *(listImigrants.front());
eoPop<EOT> offspring = listImigrants.front();
// Evaluate objects to integrate // Evaluate objects to integrate
std::cout << "Evaluation des individus : " << std::endl;
for(auto& indi : offspring) for(auto& indi : offspring)
{
eval(indi); eval(indi);
std::cout << indi << std::endl;
}
//std::cout << "Ile " << this << " recoit : " << std::endl;
//std::cout << offspring << std::endl;
intPolicy(pop, offspring); intPolicy(pop, offspring);
listImigrants.pop(); listImigrants.pop();
} }
std::cout << "Pop après : " << std::endl << pop << std::endl;
std::cout << "______________________________________________" << std::endl;
}
} }
template<template <class> class EOAlgo, class EOT>
void paradiseo::smp::Island<EOAlgo,EOT>::update(eoPop<EOT> _data)
{
std::lock_guard<std::mutex> lock(this->m);
listImigrants.push(_data);
}

View file

@ -81,12 +81,6 @@ public:
*/ */
virtual void setModel(IslandModel<EOT>* _model); virtual void setModel(IslandModel<EOT>* _model);
/**
* Update the list of imigrants.
* @param _data Elements to integrate in the main population.
*/
void update(eoPop<EOT>& _data);
/** /**
* Return a reference to the island population. * Return a reference to the island population.
* @return Reference to the island population * @return Reference to the island population
@ -98,11 +92,17 @@ public:
*/ */
virtual void check(void); virtual void check(void);
/**
* Update the list of imigrants.
* @param _data Elements to integrate in the main population.
*/
void update(eoPop<EOT> _data);
/** /**
* Check if the algorithm is stopped. * Check if the algorithm is stopped.
* @return true if stopped * @return true if stopped
*/ */
virtual bool isStopped(void); virtual bool isStopped(void) const;
protected: protected:
@ -121,7 +121,7 @@ protected:
eoEvalFunc<EOT>& eval; eoEvalFunc<EOT>& eval;
eoPop<EOT> pop; eoPop<EOT> pop;
EOAlgo<EOT> algo; EOAlgo<EOT> algo;
std::queue<eoPop<EOT>*> listImigrants; std::queue<eoPop<EOT>> listImigrants;
IntPolicy<EOT>& intPolicy; IntPolicy<EOT>& intPolicy;
MigPolicy<EOT>& migPolicy; MigPolicy<EOT>& migPolicy;
std::atomic<bool> stopped; std::atomic<bool> stopped;

View file

@ -27,51 +27,99 @@ ParadisEO WebSite : http://paradiseo.gforge.inria.fr
Contact: paradiseo-help@lists.gforge.inria.fr Contact: paradiseo-help@lists.gforge.inria.fr
*/ */
template<class EOT>
paradiseo::smp::IslandModel<EOT>::IslandModel(AbstractTopology& _topo) :
topo(_topo)
{ }
template<class EOT> template<class EOT>
void paradiseo::smp::IslandModel<EOT>::add(AIsland<EOT>& _island) void paradiseo::smp::IslandModel<EOT>::add(AIsland<EOT>& _island)
{ {
static unsigned i = 0; islands.push_back(&_island);
islands[i] = &_island; islands.back()->setModel(this);
islands[i]->setModel(this);
i++;
} }
template<class EOT> template<class EOT>
void paradiseo::smp::IslandModel<EOT>::operator()() void paradiseo::smp::IslandModel<EOT>::operator()()
{ {
std::vector<Thread> threads(islands.size()); std::vector<std::thread> threads(islands.size());
// Construct topology according to the number of islands
topo.construct(islands.size());
// Create table
table = createTable(topo, islands);
// Lauching threads
unsigned i = 0; unsigned i = 0;
for(auto it : islands) for(auto it : islands)
{ {
threads[i].start(&AIsland<EOT>::operator(), it.second); threads[i] = std::thread(&AIsland<EOT>::operator(), it);
i++; i++;
} }
unsigned workingThread = islands.size(); unsigned workingThread = islands.size();
while(workingThread > 0) while(workingThread > 0)
{ {
// Count working islands
workingThread = islands.size(); workingThread = islands.size();
for(auto& it : islands) for(auto& it : islands)
if(it.second->isStopped()) if(it->isStopped())
workingThread--; workingThread--;
// Check reception
send();
std::this_thread::sleep_for(std::chrono::nanoseconds(10)); std::this_thread::sleep_for(std::chrono::nanoseconds(10));
} }
for(auto& thread : threads) for(auto& thread : threads)
thread.join(); thread.join();
for(auto& message : sentMessages)
message.join();
} }
template<class EOT> template<class EOT>
void paradiseo::smp::IslandModel<EOT>::update(eoPop<EOT> _data, AIsland<EOT>* _island) void paradiseo::smp::IslandModel<EOT>::update(eoPop<EOT> _data, AIsland<EOT>* _island)
{ {
std::cout << "Pop reçue par le médiateur" << std::endl; std::lock_guard<std::mutex> lock(m);
std::lock_guard<std::mutex> lock(this->m); //std::cout << "Pop reçue par le médiateur depuis " << _island << std::endl;
//std::cout << _data << std::endl;
std::cout << _data << std::endl;
listEmigrants.push(std::pair<eoPop<EOT>,AIsland<EOT>*>(_data, _island)); listEmigrants.push(std::pair<eoPop<EOT>,AIsland<EOT>*>(_data, _island));
} }
template<class EOT>
void paradiseo::smp::IslandModel<EOT>::send(void)
{
std::lock_guard<std::mutex> lock(m);
while (!listEmigrants.empty())
{
std::cout << "Le mediateur va envoyer de " << listEmigrants.front().second << " qui est " << table.getLeft()[listEmigrants.front().second] << std::endl;
unsigned id = table.getLeft()[listEmigrants.front().second];
std::vector<unsigned> neighbors = topo.getIdNeighbors(id);
eoPop<EOT> migPop = listEmigrants.front().first;
for (unsigned neighbor : neighbors)
{
std::cout << "On envoie à " << neighbor << std::endl;
sentMessages.push_back(std::thread(&AIsland<EOT>::update, table.getRight()[neighbor], migPop));
}
listEmigrants.pop();
}
}
template<class EOT>
Bimap<unsigned, AIsland<EOT>*> paradiseo::smp::IslandModel<EOT>::createTable(AbstractTopology& _topo, std::vector<AIsland<EOT>*>& _islands)
{
Bimap<unsigned, AIsland<EOT>*> table;
unsigned islandId = 0;
for(auto it : islands)
{
table.add(islandId, it);
islandId++;
}
return table;
}

View file

@ -37,6 +37,7 @@ Contact: paradiseo-help@lists.gforge.inria.fr
#include <thread> #include <thread>
#include <bimap.h> #include <bimap.h>
#include <abstractIsland.h> #include <abstractIsland.h>
#include <topology/topology.h>
namespace paradiseo namespace paradiseo
{ {
@ -55,6 +56,8 @@ template<class EOT>
class IslandModel class IslandModel
{ {
public: public:
IslandModel(AbstractTopology& topo);
/** /**
* Add an island to the model. * Add an island to the model.
* @param _island Island to add. * @param _island Island to add.
@ -72,9 +75,19 @@ public:
void update(eoPop<EOT> _data, AIsland<EOT>* _island); void update(eoPop<EOT> _data, AIsland<EOT>* _island);
protected: protected:
/**
* Send population to islands
*/
void send(void);
Bimap<unsigned, AIsland<EOT>*> createTable(AbstractTopology& _topo, std::vector<AIsland<EOT>*>& _islands);
std::queue<std::pair<eoPop<EOT>,AIsland<EOT>*>> listEmigrants; std::queue<std::pair<eoPop<EOT>,AIsland<EOT>*>> listEmigrants;
Bimap<unsigned, unsigned> table; Bimap<unsigned, AIsland<EOT>*> table;
std::map<unsigned, AIsland<EOT>*> islands; std::vector<AIsland<EOT>*> islands;
AbstractTopology& topo;
std::vector<std::thread> sentMessages;
std::mutex m; std::mutex m;
}; };

View file

@ -40,4 +40,10 @@ Contact: paradiseo-help@lists.gforge.inria.fr
#include <policyElement.h> #include <policyElement.h>
#include <islandNotifier.h> #include <islandNotifier.h>
// Topologies
#include <topology/topology.h>
#include <topology/complete.h>
#include <topology/ring.h>
#include <topology/star.h>
#endif #endif

View file

@ -52,13 +52,13 @@ public :
* Return a vector containing the index of nearby nodes according to the topology * Return a vector containing the index of nearby nodes according to the topology
* @param idIsland index of the node of which you want the neighbors. * @param idIsland index of the node of which you want the neighbors.
*/ */
virtual std::vector<unsigned> getIdNeighbors(unsigned idIsland) const =0; virtual std::vector<unsigned> getIdNeighbors(unsigned idIsland) const = 0;
/** /**
* Construct or re-construct a topology with the given number of nodes. * Construct or re-construct a topology with the given number of nodes.
* @param nbIsland number of nodes for the topology * @param nbIsland number of nodes for the topology
*/ */
virtual void construct(unsigned nbIsland) =0; virtual void construct(unsigned nbIsland) = 0;
}; };
} }

View file

@ -27,6 +27,9 @@ ParadisEO WebSite : http://paradiseo.gforge.inria.fr
Contact: paradiseo-help@lists.gforge.inria.fr Contact: paradiseo-help@lists.gforge.inria.fr
*/ */
#ifndef TOPOLOGY_H_
#define TOPOLOGY_H_
#include <vector> #include <vector>
#include <topology/abstractTopology.h> #include <topology/abstractTopology.h>
@ -76,3 +79,5 @@ private :
} }
} }
#endif

View file

@ -9,11 +9,11 @@ using namespace std;
int main(void) int main(void)
{ {
typedef struct { typedef struct {
unsigned popSize = 100; unsigned popSize = 3;
unsigned tSize = 2; unsigned tSize = 2;
double pCross = 0.8; double pCross = 0.8;
double pMut = 0.7; double pMut = 0.7;
unsigned maxGen = 10000; unsigned maxGen = 10;
} Param; } Param;
Param param; Param param;
@ -77,12 +77,13 @@ int main(void)
// // Integration policy // // Integration policy
eoPlusReplacement<Indi> intPolicy_2; eoPlusReplacement<Indi> intPolicy_2;
Island<eoEasyEA,Indi> test2(param.popSize, chromInit, intPolicy_2, migPolicy_2, genCont_2, plainEval, select, transform, replace); Island<eoEasyEA,Indi> test2(param.popSize, chromInit, intPolicy_2, migPolicy_2, genCont_2, plainEval, select, transform, replace);
//test(); // Topology
Topology<Complete> topo;
IslandModel<Indi> model; IslandModel<Indi> model(topo);
model.add(test); model.add(test);
model.add(test2); model.add(test2);