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;
/**
* 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.
* @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
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.
**/
@ -50,43 +50,45 @@ class Bimap
public:
/**
* Add a relation
* @param workersNb the number of workers
* @param args... list of parameters according to the constructor of your algorithm
* @param A right key
* @param B left key
*/
void add(A a, B b)
void add(A& a, B& b)
{
ASet.insert(a);
BSet.insert(b);
rightAssociation[&a] = &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;
}
B& getRight(A const a)
std::map<A,B> getRight() const
{
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:
std::set<A> ASet;
std::set<B> BSet;
std::map<A*,B*> rightAssociation;
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;
}
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>
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>
bool paradiseo::smp::Island<EOAlgo,EOT>::isStopped(void)
bool paradiseo::smp::Island<EOAlgo,EOT>::isStopped(void) const
{
return (bool)stopped;
}
@ -119,16 +113,39 @@ void paradiseo::smp::Island<EOAlgo,EOT>::send(eoSelect<EOT>& _select)
template<template <class> class EOAlgo, class EOT>
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())
{
eoPop<EOT> offspring = *(listImigrants.front());
eoPop<EOT> offspring = listImigrants.front();
// Evaluate objects to integrate
std::cout << "Evaluation des individus : " << std::endl;
for(auto& indi : offspring)
{
eval(indi);
std::cout << indi << std::endl;
}
//std::cout << "Ile " << this << " recoit : " << std::endl;
//std::cout << offspring << std::endl;
intPolicy(pop, offspring);
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);
/**
* 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 Reference to the island population
@ -98,11 +92,17 @@ public:
*/
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.
* @return true if stopped
*/
virtual bool isStopped(void);
virtual bool isStopped(void) const;
protected:
@ -121,7 +121,7 @@ protected:
eoEvalFunc<EOT>& eval;
eoPop<EOT> pop;
EOAlgo<EOT> algo;
std::queue<eoPop<EOT>*> listImigrants;
std::queue<eoPop<EOT>> listImigrants;
IntPolicy<EOT>& intPolicy;
MigPolicy<EOT>& migPolicy;
std::atomic<bool> stopped;

View file

@ -27,51 +27,99 @@ ParadisEO WebSite : http://paradiseo.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>
void paradiseo::smp::IslandModel<EOT>::add(AIsland<EOT>& _island)
{
static unsigned i = 0;
islands[i] = &_island;
islands[i]->setModel(this);
i++;
islands.push_back(&_island);
islands.back()->setModel(this);
}
template<class EOT>
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;
for(auto it : islands)
{
threads[i].start(&AIsland<EOT>::operator(), it.second);
threads[i] = std::thread(&AIsland<EOT>::operator(), it);
i++;
}
unsigned workingThread = islands.size();
while(workingThread > 0)
{
// Count working islands
workingThread = islands.size();
for(auto& it : islands)
if(it.second->isStopped())
if(it->isStopped())
workingThread--;
// Check reception
send();
std::this_thread::sleep_for(std::chrono::nanoseconds(10));
}
for(auto& thread : threads)
thread.join();
for(auto& message : sentMessages)
message.join();
}
template<class EOT>
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(this->m);
std::cout << _data << std::endl;
std::lock_guard<std::mutex> lock(m);
//std::cout << "Pop reçue par le médiateur depuis " << _island << std::endl;
//std::cout << _data << std::endl;
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 <bimap.h>
#include <abstractIsland.h>
#include <topology/topology.h>
namespace paradiseo
{
@ -55,6 +56,8 @@ template<class EOT>
class IslandModel
{
public:
IslandModel(AbstractTopology& topo);
/**
* Add an island to the model.
* @param _island Island to add.
@ -72,9 +75,19 @@ public:
void update(eoPop<EOT> _data, AIsland<EOT>* _island);
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;
Bimap<unsigned, unsigned> table;
std::map<unsigned, AIsland<EOT>*> islands;
Bimap<unsigned, AIsland<EOT>*> table;
std::vector<AIsland<EOT>*> islands;
AbstractTopology& topo;
std::vector<std::thread> sentMessages;
std::mutex m;
};

View file

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

View file

@ -52,13 +52,13 @@ public :
* 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.
*/
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.
* @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
*/
#ifndef TOPOLOGY_H_
#define TOPOLOGY_H_
#include <vector>
#include <topology/abstractTopology.h>
@ -76,3 +79,5 @@ private :
}
}
#endif

View file

@ -9,11 +9,11 @@ using namespace std;
int main(void)
{
typedef struct {
unsigned popSize = 100;
unsigned popSize = 3;
unsigned tSize = 2;
double pCross = 0.8;
double pMut = 0.7;
unsigned maxGen = 10000;
unsigned maxGen = 10;
} Param;
Param param;
@ -77,12 +77,13 @@ int main(void)
// // Integration policy
eoPlusReplacement<Indi> intPolicy_2;
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(test2);