fix: refactor foundry to be more dynamic than static
- Remove size template in favor of dynamic container: allow using the generic interface. - Using `operator=` was inducing slicing.
This commit is contained in:
parent
78be884270
commit
11ff72bdd9
5 changed files with 56 additions and 55 deletions
|
|
@ -23,8 +23,7 @@
|
||||||
#ifndef _eoAlgoFoundry_H_
|
#ifndef _eoAlgoFoundry_H_
|
||||||
#define _eoAlgoFoundry_H_
|
#define _eoAlgoFoundry_H_
|
||||||
|
|
||||||
#include <array>
|
#include <vector>
|
||||||
#include <tuple>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -32,18 +31,23 @@
|
||||||
* @ingroup Foundry
|
* @ingroup Foundry
|
||||||
* @ingroup Algorithms
|
* @ingroup Algorithms
|
||||||
*/
|
*/
|
||||||
template<class EOT, unsigned NBOP>
|
template<class EOT>
|
||||||
class eoAlgoFoundry : public eoAlgo<EOT>
|
class eoAlgoFoundry : public eoAlgo<EOT>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const size_t dim = NBOP;
|
/**
|
||||||
|
|
||||||
/** The constructon only take an eval, because all other operators
|
|
||||||
* are stored in the public containers.
|
|
||||||
*/
|
*/
|
||||||
eoAlgoFoundry()
|
eoAlgoFoundry( size_t nb_operators ) :
|
||||||
|
_size(nb_operators),
|
||||||
|
_encoding(_size,0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/** Select indices of all the operators.
|
||||||
|
*/
|
||||||
|
void select( std::vector<size_t> encoding )
|
||||||
{
|
{
|
||||||
_encoding = { 0 }; // dim * 0
|
assert(encoding.size() == _encoding.size());
|
||||||
|
_encoding = encoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Access to the index of the currently selected operator.
|
/** Access to the index of the currently selected operator.
|
||||||
|
|
@ -53,15 +57,14 @@ class eoAlgoFoundry : public eoAlgo<EOT>
|
||||||
return _encoding.at(i);
|
return _encoding.at(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Select indices of all the operators.
|
size_t size() const
|
||||||
*/
|
|
||||||
void operator=( std::array<size_t,dim> a)
|
|
||||||
{
|
{
|
||||||
_encoding = a;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::array<size_t, dim> _encoding;
|
const size_t _size;
|
||||||
|
std::vector<size_t> _encoding;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,10 +76,20 @@
|
||||||
* @ingroup Algorithms
|
* @ingroup Algorithms
|
||||||
*/
|
*/
|
||||||
template<class EOT>
|
template<class EOT>
|
||||||
class eoAlgoFoundryEA : public eoAlgoFoundry<EOT,5>
|
class eoAlgoFoundryEA : public eoAlgoFoundry<EOT>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using eoAlgoFoundry<EOT,5>::dim;
|
/** The constructon only take an eval, because all other operators
|
||||||
|
* are stored in the public containers.
|
||||||
|
*/
|
||||||
|
eoAlgoFoundryEA( eoPopEvalFunc<EOT>& eval, size_t max_gen ) :
|
||||||
|
eoAlgoFoundry<EOT>(5),
|
||||||
|
index_of(),
|
||||||
|
_eval(eval),
|
||||||
|
_max_gen(max_gen)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
struct Indices
|
struct Indices
|
||||||
{
|
{
|
||||||
|
|
@ -93,17 +103,6 @@ class eoAlgoFoundryEA : public eoAlgoFoundry<EOT,5>
|
||||||
/** Helper for keeping track of the indices of the underlying encoding. */
|
/** Helper for keeping track of the indices of the underlying encoding. */
|
||||||
const Indices index_of;
|
const Indices index_of;
|
||||||
|
|
||||||
/** The constructon only take an eval, because all other operators
|
|
||||||
* are stored in the public containers.
|
|
||||||
*/
|
|
||||||
eoAlgoFoundryEA( eoPopEvalFunc<EOT>& eval, size_t max_gen ) :
|
|
||||||
index_of(),
|
|
||||||
_eval(eval),
|
|
||||||
_max_gen(max_gen)
|
|
||||||
{
|
|
||||||
_encoding = { 0 }; // dim * 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Operators containers @{ */
|
/* Operators containers @{ */
|
||||||
eoForgeVector< eoContinue<EOT> > continuators;
|
eoForgeVector< eoContinue<EOT> > continuators;
|
||||||
eoForgeVector< eoQuadOp<EOT> > crossovers;
|
eoForgeVector< eoQuadOp<EOT> > crossovers;
|
||||||
|
|
@ -116,11 +115,11 @@ class eoAlgoFoundryEA : public eoAlgoFoundry<EOT,5>
|
||||||
*/
|
*/
|
||||||
void operator()(eoPop<EOT>& pop)
|
void operator()(eoPop<EOT>& pop)
|
||||||
{
|
{
|
||||||
assert(continuators.size() > 0); assert(_encoding.at(index_of.continuators) < continuators.size());
|
assert(continuators.size() > 0); assert(this->at(index_of.continuators) < continuators.size());
|
||||||
assert( crossovers.size() > 0); assert(_encoding.at(index_of.crossovers) < crossovers.size());
|
assert( crossovers.size() > 0); assert(this->at(index_of.crossovers) < crossovers.size());
|
||||||
assert( mutations.size() > 0); assert(_encoding.at(index_of.mutations) < mutations.size());
|
assert( mutations.size() > 0); assert(this->at(index_of.mutations) < mutations.size());
|
||||||
assert( selectors.size() > 0); assert(_encoding.at(index_of.selectors) < selectors.size());
|
assert( selectors.size() > 0); assert(this->at(index_of.selectors) < selectors.size());
|
||||||
assert(replacements.size() > 0); assert(_encoding.at(index_of.replacements) < replacements.size());
|
assert(replacements.size() > 0); assert(this->at(index_of.replacements) < replacements.size());
|
||||||
|
|
||||||
eoSequentialOp<EOT> variator;
|
eoSequentialOp<EOT> variator;
|
||||||
variator.add(this->crossover(), 1.0);
|
variator.add(this->crossover(), 1.0);
|
||||||
|
|
@ -145,48 +144,47 @@ class eoAlgoFoundryEA : public eoAlgoFoundry<EOT,5>
|
||||||
std::string name()
|
std::string name()
|
||||||
{
|
{
|
||||||
std::ostringstream name;
|
std::ostringstream name;
|
||||||
name << _encoding.at(index_of.continuators) << " (" << this->continuator().className() << ") + ";
|
name << this->at(index_of.continuators) << " (" << this->continuator().className() << ") + ";
|
||||||
name << _encoding.at(index_of.crossovers) << " (" << this->crossover().className() << ") + ";
|
name << this->at(index_of.crossovers) << " (" << this->crossover().className() << ") + ";
|
||||||
name << _encoding.at(index_of.mutations) << " (" << this->mutation().className() << ") + ";
|
name << this->at(index_of.mutations) << " (" << this->mutation().className() << ") + ";
|
||||||
name << _encoding.at(index_of.selectors) << " (" << this->selector().className() << ") + ";
|
name << this->at(index_of.selectors) << " (" << this->selector().className() << ") + ";
|
||||||
name << _encoding.at(index_of.replacements) << " (" << this->replacement().className() << ")";
|
name << this->at(index_of.replacements) << " (" << this->replacement().className() << ")";
|
||||||
return name.str();
|
return name.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
eoPopEvalFunc<EOT>& _eval;
|
eoPopEvalFunc<EOT>& _eval;
|
||||||
const size_t _max_gen;
|
const size_t _max_gen;
|
||||||
std::array<size_t, dim> _encoding;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
eoContinue<EOT>& continuator()
|
eoContinue<EOT>& continuator()
|
||||||
{
|
{
|
||||||
assert(_encoding.at(index_of.continuators) < continuators.size());
|
assert(this->at(index_of.continuators) < continuators.size());
|
||||||
return continuators.instanciate(_encoding.at(index_of.continuators));
|
return continuators.instanciate(this->at(index_of.continuators));
|
||||||
}
|
}
|
||||||
|
|
||||||
eoQuadOp<EOT>& crossover()
|
eoQuadOp<EOT>& crossover()
|
||||||
{
|
{
|
||||||
assert(_encoding.at(index_of.crossovers) < crossovers.size());
|
assert(this->at(index_of.crossovers) < crossovers.size());
|
||||||
return crossovers.instanciate(_encoding.at(index_of.crossovers));
|
return crossovers.instanciate(this->at(index_of.crossovers));
|
||||||
}
|
}
|
||||||
|
|
||||||
eoMonOp<EOT>& mutation()
|
eoMonOp<EOT>& mutation()
|
||||||
{
|
{
|
||||||
assert(_encoding.at(index_of.mutations) < mutations.size());
|
assert(this->at(index_of.mutations) < mutations.size());
|
||||||
return mutations.instanciate(_encoding.at(index_of.mutations));
|
return mutations.instanciate(this->at(index_of.mutations));
|
||||||
}
|
}
|
||||||
|
|
||||||
eoSelectOne<EOT>& selector()
|
eoSelectOne<EOT>& selector()
|
||||||
{
|
{
|
||||||
assert(_encoding.at(index_of.selectors) < selectors.size());
|
assert(this->at(index_of.selectors) < selectors.size());
|
||||||
return selectors.instanciate(_encoding.at(index_of.selectors));
|
return selectors.instanciate(this->at(index_of.selectors));
|
||||||
}
|
}
|
||||||
|
|
||||||
eoReplacement<EOT>& replacement()
|
eoReplacement<EOT>& replacement()
|
||||||
{
|
{
|
||||||
assert(_encoding.at(index_of.replacements) < replacements.size());
|
assert(this->at(index_of.replacements) < replacements.size());
|
||||||
return replacements.instanciate(_encoding.at(index_of.replacements));
|
return replacements.instanciate(this->at(index_of.replacements));
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,8 @@ public:
|
||||||
static const size_t i_repl = eoAlgoFoundryEA<SUB>::Indices::replacements;
|
static const size_t i_repl = eoAlgoFoundryEA<SUB>::Indices::replacements;
|
||||||
|
|
||||||
/** Decode the high-level problem encoding as an array of indices.
|
/** Decode the high-level problem encoding as an array of indices.
|
||||||
|
*
|
||||||
|
* @note: If the EOT is an eoInt, this will be optimized out.
|
||||||
*
|
*
|
||||||
* May be useful for getting a solution back into an eoAlgoFoundryEA.
|
* May be useful for getting a solution back into an eoAlgoFoundryEA.
|
||||||
* @code
|
* @code
|
||||||
|
|
@ -80,7 +82,7 @@ public:
|
||||||
* auto& cont = foundry.continuator(); // Get the configured operator
|
* auto& cont = foundry.continuator(); // Get the configured operator
|
||||||
* @encode
|
* @encode
|
||||||
*/
|
*/
|
||||||
std::array<size_t,eoAlgoFoundryEA<SUB>::dim> decode( const EOT& sol )
|
std::vector<size_t> decode( const EOT& sol ) const
|
||||||
{
|
{
|
||||||
// Denormalize
|
// Denormalize
|
||||||
size_t cont = static_cast<size_t>(std::ceil( sol[i_cont] * _foundry.continuators.size() ));
|
size_t cont = static_cast<size_t>(std::ceil( sol[i_cont] * _foundry.continuators.size() ));
|
||||||
|
|
@ -121,7 +123,7 @@ public:
|
||||||
and 0 <= sele and sele < _foundry.selectors .size()
|
and 0 <= sele and sele < _foundry.selectors .size()
|
||||||
and 0 <= repl and repl < _foundry.replacements.size()
|
and 0 <= repl and repl < _foundry.replacements.size()
|
||||||
) {
|
) {
|
||||||
_foundry = config;
|
_foundry.select(config);
|
||||||
|
|
||||||
// Actually perform a search
|
// Actually perform a search
|
||||||
_foundry(pop);
|
_foundry(pop);
|
||||||
|
|
|
||||||
|
|
@ -65,10 +65,8 @@ eoAlgoFoundryEA<Bits>& make_foundry(eoFunctorStore& store, eoPopEvalFunc<Bits>&
|
||||||
|
|
||||||
// A basic PSO algorithm.
|
// A basic PSO algorithm.
|
||||||
std::pair< eoAlgo<Particle>*, eoPop<Particle>* >
|
std::pair< eoAlgo<Particle>*, eoPop<Particle>* >
|
||||||
make_pso(eoFunctorStore& store, eoEvalFunc<Particle>& eval_foundry)
|
make_pso(eoFunctorStore& store, eoEvalFoundryEA<Particle,Bits>& eval_foundry, size_t dim)
|
||||||
{
|
{
|
||||||
const size_t dim = eoAlgoFoundryEA<Bits>::dim;
|
|
||||||
|
|
||||||
auto& gen_pos = store.pack< eoUniformGenerator<double> >(0.1,0.9);
|
auto& gen_pos = store.pack< eoUniformGenerator<double> >(0.1,0.9);
|
||||||
auto& random_pos = store.pack< eoInitFixedLength<Particle> >(dim, gen_pos);
|
auto& random_pos = store.pack< eoInitFixedLength<Particle> >(dim, gen_pos);
|
||||||
|
|
||||||
|
|
@ -133,13 +131,13 @@ int main(int /*argc*/, char** /*argv*/)
|
||||||
|
|
||||||
eoAlgo<Particle>* pso;
|
eoAlgo<Particle>* pso;
|
||||||
eoPop<Particle>* pop_foundry;
|
eoPop<Particle>* pop_foundry;
|
||||||
std::tie(pso, pop_foundry) = make_pso(store, eval_foundry);
|
std::tie(pso, pop_foundry) = make_pso(store, eval_foundry, foundry.size());
|
||||||
|
|
||||||
// Perform the best algorithm configuration search.
|
// Perform the best algorithm configuration search.
|
||||||
(*pso)(*pop_foundry);
|
(*pso)(*pop_foundry);
|
||||||
|
|
||||||
// Print a glimpse of the best algorithm found.
|
// Print a glimpse of the best algorithm found.
|
||||||
foundry = eval_foundry.decode(pop_foundry->best_element());
|
foundry.select(eval_foundry.decode(pop_foundry->best_element()));
|
||||||
std::cout << "Best algorithm: " << foundry.name() << std::endl;
|
std::cout << "Best algorithm: " << foundry.name() << std::endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ int main(int /*argc*/, char** /*argv*/)
|
||||||
foundry.at(foundry.index_of.replacements) = i_rep;
|
foundry.at(foundry.index_of.replacements) = i_rep;
|
||||||
|
|
||||||
// Or, if you know the order.
|
// Or, if you know the order.
|
||||||
foundry = {i_cont, i_cross, i_mut, i_sel, i_rep};
|
foundry.select({i_cont, i_cross, i_mut, i_sel, i_rep});
|
||||||
|
|
||||||
// Actually perform a search
|
// Actually perform a search
|
||||||
foundry(pop);
|
foundry(pop);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue