Perfect forwarding for identity conversion functions. Add heterogeneous test (to clean and improve)

This commit is contained in:
quemy 2012-12-03 23:22:22 +01:00
commit 5a4596862b
6 changed files with 233 additions and 15 deletions

View file

@ -51,7 +51,7 @@ The abstract island is used to manipulate island pointers wihout the knowledge o
@see smp::Island
*/
template<class EOT>
template<class bEOT>
class AIsland
{
public:
@ -61,9 +61,7 @@ public:
/**
* Check if there is population to receive
*/
virtual void setModel(IslandModel<EOT>* _model) = 0;
virtual void setModel(IslandModel<bEOT>* _model) = 0;
/**
* Check if there is population to receive or to emigrate
@ -73,7 +71,7 @@ public:
/**
* Update the island by adding population to send in the imigrants list.
*/
virtual void update(eoPop<EOT> _data) = 0;
virtual void update(eoPop<bEOT> _data) = 0;
/**
* Check if the algorithm is stopped.

View file

@ -29,7 +29,7 @@ Contact: paradiseo-help@lists.gforge.inria.fr
template<template <class> class EOAlgo, class EOT, class bEOT>
template<class... Args>
paradiseo::smp::Island<EOAlgo,EOT,bEOT>::Island(std::function<EOT(bEOT&)> _convertFromBase, std::function<bEOT(EOT&)> _convertToBase, eoPop<EOT>& _pop, IntPolicy<EOT>& _intPolicy, MigPolicy<EOT>& _migPolicy, Args&... args) :
paradiseo::smp::Island<EOAlgo,EOT,bEOT>::Island(std::function<EOT&&(bEOT&)> _convertFromBase, std::function<bEOT&&(EOT&)> _convertToBase, eoPop<EOT>& _pop, IntPolicy<EOT>& _intPolicy, MigPolicy<EOT>& _migPolicy, Args&... args) :
// The PPExpander looks for the continuator in the parameters pack.
// The private inheritance of ContWrapper wraps the continuator and add islandNotifier.
ContWrapper<EOT, bEOT>(Loop<Args...>().template findValue<eoContinue<EOT>>(args...), this),
@ -54,8 +54,8 @@ template<class... Args>
paradiseo::smp::Island<EOAlgo,EOT,bEOT>::Island(eoPop<EOT>& _pop, IntPolicy<EOT>& _intPolicy, MigPolicy<EOT>& _migPolicy, Args&... args) :
Island(
// Default conversion functions for homogeneous islands
[](bEOT& i) -> EOT { return (EOT)i; },
[](EOT& i) -> bEOT { return (bEOT)i; },
[](bEOT& i) -> EOT&& { return std::forward<EOT>(i); },
[](EOT& i) -> bEOT&& { return std::forward<bEOT>(i); },
_pop, _intPolicy, _migPolicy, args...)
{ }
@ -114,7 +114,7 @@ void paradiseo::smp::Island<EOAlgo,EOT,bEOT>::send(eoSelect<EOT>& _select)
for(auto& indi : migPop)
baseMigPop.push_back(convertToBase(indi));
std::cout << "On envoie de l'île : " << migPop << std::endl;
//std::cout << "On envoie de l'île : " << migPop << std::endl;
// Delete delivered messages
for(auto it = sentMessages.begin(); it != sentMessages.end(); it++)
@ -131,7 +131,7 @@ void paradiseo::smp::Island<EOAlgo,EOT,bEOT>::receive(void)
std::lock_guard<std::mutex> lock(this->m);
while (!listImigrants.empty())
{
std::cout << "On reçoit dans l'île : " << listImigrants.size() << std::endl;
//std::cout << "On reçoit dans l'île : " << listImigrants.size() << std::endl;
eoPop<bEOT> base_offspring = listImigrants.front();
// Convert objects from base to our objects type
@ -152,7 +152,7 @@ void paradiseo::smp::Island<EOAlgo,EOT,bEOT>::receive(void)
template<template <class> class EOAlgo, class EOT, class bEOT>
void paradiseo::smp::Island<EOAlgo,EOT,bEOT>::update(eoPop<bEOT> _data)
{
std::cout << "On update dans l'île" << std::endl;
//std::cout << "On update dans l'île" << std::endl;
std::lock_guard<std::mutex> lock(this->m);
listImigrants.push(_data);
}

View file

@ -75,7 +75,7 @@ public:
* @param args Parameters to construct the algorithm.
*/
template<class... Args>
Island(std::function<EOT(bEOT&)> _convertFromBase, std::function<bEOT(EOT&)> _convertToBase, eoPop<EOT>& pop, IntPolicy<EOT>& _intPolicy, MigPolicy<EOT>& _migPolicy, Args&... args);
Island(std::function<EOT&&(bEOT&)> _convertFromBase, std::function<bEOT&&(EOT&)> _convertToBase, eoPop<EOT>& pop, IntPolicy<EOT>& _intPolicy, MigPolicy<EOT>& _migPolicy, Args&... args);
/**
* Constructor
* @param _popSize Size of the algorithm population.

View file

@ -107,7 +107,7 @@ template<class EOT>
void paradiseo::smp::IslandModel<EOT>::update(eoPop<EOT> _data, AIsland<EOT>* _island)
{
std::lock_guard<std::mutex> lock(m);
std::cout << "Mediateur reçoit ! " << _data << std::endl;
//std::cout << "Mediateur reçoit ! " << _data << std::endl;
listEmigrants.push(std::pair<eoPop<EOT>,AIsland<EOT>*>(_data, _island));
}
@ -134,7 +134,7 @@ void paradiseo::smp::IslandModel<EOT>::send(void)
std::lock_guard<std::mutex> lock(m);
while (!listEmigrants.empty())
{
std::cout << "Mediator envoie ! " << listEmigrants.size() << std::endl;
//std::cout << "Mediator envoie ! " << listEmigrants.size() << std::endl;
// Get the neighbors
unsigned idFrom = table.getLeft()[listEmigrants.front().second];
std::vector<unsigned> neighbors = topo.getIdNeighbors(idFrom);

View file

@ -19,7 +19,7 @@ set (TEST_LIST
t-smpIsland
t-smpTopo
t-smpMI_Homogeneous
#t-smpMI_Heterogeneous
t-smpMI_Heterogeneous
)
######################################################################################

View file

@ -0,0 +1,220 @@
#include <smp>
#include <eo>
#include <ga.h>
#include "smpTestClass.h"
using namespace paradiseo::smp;
using namespace std;
typedef eoBit<double> Indi2; // A bitstring with fitness double
// Conversion functions
Indi2 fromBase(Indi& i, unsigned size)
{
// Dummy conversion. We just create a new Indi2
Indi2 v;
for (unsigned ivar=0; ivar<size; ivar++)
{
bool r = rng.flip(); // new value, random in {0,1}
v.push_back(r); // append that random value to v
}
std::cout << "Convert from base : " << v << std::endl;
return v;
}
Indi toBase(Indi2& i)
{
// Dummy conversion. We just create a new Indi
Indi v;
std::cout << "Convert to base : " << v << std::endl;
return v;
}
// EVAL
//-----------------------------------------------------------------------------
// a simple fitness function that computes the number of ones of a bitstring
// @param _Indi2 A biststring Indi2vidual
double binary_value(const Indi2 & _Indi2)
{
double sum = 0;
for (unsigned i = 0; i < _Indi2.size(); i++)
sum += _Indi2[i];
return sum;
}
// GENERAL
//-----------------------------------------------------------------------------
int main(void)
{
// PARAMETRES
// all parameters are hard-coded!
const unsigned int SEED = 42; // seed for random number generator
const unsigned int T_SIZE = 3; // size for tournament selection
const unsigned int VEC_SIZE = 16; // Number of bits in genotypes
const unsigned int POP_SIZE = 10; // Size of population
const unsigned int MAX_GEN = 10; // Maximum number of generation before STOP
const float CROSS_RATE = 0.8; // Crossover rate
const double P_MUT_PER_BIT = 0.01; // probability of bit-flip mutation
const float MUT_RATE = 1.0; // mutation rate
// GENERAL
//////////////////////////
// Random seed
//////////////////////////
//reproducible random seed: if you don't change SEED above,
// you'll aways get the same result, NOT a random run
rng.reseed(SEED);
// EVAL
/////////////////////////////
// Fitness function
////////////////////////////
// Evaluation: from a plain C++ fn to an EvalFunc Object
eoEvalFuncPtr<Indi2> eval( binary_value );
// INIT
////////////////////////////////
// Initilisation of population
////////////////////////////////
// declare the population
eoPop<Indi2> pop;
// fill it!
for (unsigned int igeno=0; igeno<POP_SIZE; igeno++)
{
Indi2 v; // void Indi2vidual, to be filled
for (unsigned ivar=0; ivar<VEC_SIZE; ivar++)
{
bool r = rng.flip(); // new value, random in {0,1}
v.push_back(r); // append that random value to v
}
eval(v); // evaluate it
pop.push_back(v); // and put it in the population
}
// ENGINE
/////////////////////////////////////
// selection and replacement
////////////////////////////////////
// SELECT
// The robust tournament selection
eoDetTournamentSelect<Indi2> select(T_SIZE); // T_SIZE in [2,POP_SIZE]
// REPLACE
// The simple GA evolution engine uses generational replacement
// so no replacement procedure is needed
// OPERATORS
//////////////////////////////////////
// The variation operators
//////////////////////////////////////
// CROSSOVER
// 1-point crossover for bitstring
eo1PtBitXover<Indi2> xover;
// MUTATION
// standard bit-flip mutation for bitstring
eoBitMutation<Indi2> mutation(P_MUT_PER_BIT);
// STOP
// CHECKPOINT
//////////////////////////////////////
// termination condition
/////////////////////////////////////
// stop after MAX_GEN generations
eoGenContinue<Indi2> continuator(MAX_GEN);
// GENERATION
/////////////////////////////////////////
// the algorithm
////////////////////////////////////////
// standard Generational GA requires as parameters
// selection, evaluation, crossover and mutation, stopping criterion
// // Emigration policy
// // // Element 1
eoPeriodicContinue<Indi2> criteria(1);
eoDetTournamentSelect<Indi2> selectOne(2);
eoSelectNumber<Indi2> who(selectOne, 1);
MigPolicy<Indi2> migPolicy;
migPolicy.push_back(PolicyElement<Indi2>(who, criteria));
// // Integration policy
eoPlusReplacement<Indi2> intPolicy;
// We bind conversion functions
auto frombase = std::bind(fromBase, std::placeholders::_1, VEC_SIZE);
auto tobase = std::bind(toBase, std::placeholders::_1);
Island<eoSGA,Indi2, Indi> gga(frombase, tobase, pop, intPolicy, migPolicy, select, xover, CROSS_RATE, mutation, MUT_RATE,
eval, continuator);
//////////////////////////////////////////////////////////////////
typedef struct {
unsigned popSize = 10;
unsigned tSize = 2;
double pCross = 0.8;
double pMut = 0.7;
unsigned maxGen = 10;
} Param;
Param param;
loadInstances("t-data.dat", n, bkv, a, b);
// Evaluation function
IndiEvalFunc plainEval;
// Init a solution
IndiInit chromInit;
// Define selection
eoDetTournamentSelect<Indi> selectOne2(param.tSize);
eoSelectPerc<Indi> select2(selectOne2);// by default rate==1
// Define operators for crossover and mutation
IndiXover Xover; // CROSSOVER
IndiSwapMutation mutationSwap; // MUTATION
// Encapsule in a tranform operator
eoSGATransform<Indi> transform(Xover, param.pCross, mutationSwap, param.pMut);
// Define replace operator
eoPlusReplacement<Indi> replace;
eoGenContinue<Indi> genCont(param.maxGen); // generation continuation
// Define population
eoPop<Indi> pop2(param.popSize, chromInit);
// Island 1
// // Emigration policy
// // // Element 1
eoPeriodicContinue<Indi> criteria2(1);
eoDetTournamentSelect<Indi> selectOne3(5);
eoSelectNumber<Indi> who2(selectOne3, 2);
MigPolicy<Indi> migPolicy2;
migPolicy2.push_back(PolicyElement<Indi>(who2, criteria2));
// // Integration policy
eoPlusReplacement<Indi> intPolicy2;
Island<eoEasyEA,Indi> test(pop2, intPolicy2, migPolicy2, genCont, plainEval, select2, transform, replace);
// Topology
Topology<Complete> topo;
IslandModel<Indi> model(topo);
model.add(test);
model.add(gga);
model();
cout << test.getPop() << endl;
cout << gga.getPop() << endl;
return 0;
}