Add topology to IslandModel, sending messages mecanism, rewrite Bimap container
This commit is contained in:
parent
95b7b80f19
commit
b3f83717d6
10 changed files with 162 additions and 63 deletions
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue