first example of automatic algorithm assembling

- add "Forges" tools, to wrap several operator with deferred
instanciation.
- add t-forge-algo to show how to enumerate several algorithms instances
from a common grammar and several alternative operators.
- add several missing className().
This commit is contained in:
Johann Dreo 2020-03-27 15:59:49 +01:00
commit 30c99f290f
14 changed files with 407 additions and 3 deletions

View file

@ -158,6 +158,8 @@
#include "other/external_eo"
#include "eoCounter.h"
#include "eoForge.h"
//-----------------------------------------------------------------------------
// to be continued ...

View file

@ -42,7 +42,8 @@
@ingroup Selectors
*/
template <class EOT> class eoDetTournamentSelect: public eoSelectOne<EOT>
template <class EOT>
class eoDetTournamentSelect: public eoSelectOne<EOT>
{
public:
/* (Default) Constructor -
@ -66,6 +67,8 @@ template <class EOT> class eoDetTournamentSelect: public eoSelectOne<EOT>
private:
unsigned tSize;
public:
virtual std::string className() const {return "eoDetTournamentSelect";}
};
//-----------------------------------------------------------------------------

201
eo/src/eoForge.h Normal file
View file

@ -0,0 +1,201 @@
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation;
version 2 of the License.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
© 2020 Thales group
Authors:
Johann Dreo <johann.dreo@thalesgroup.com>
*/
#ifndef _eoForge_H_
#define _eoForge_H_
#include <memory>
#include <map>
#include <any>
#include <string>
#include <tuple>
/** Interface for a "Forge": a class that can defer instanciation of EO's operator.
*
* This interface only declares an `instanciate` method,
* in order to be able to make containers of factories (@see eoForgeOperator).
*
* @ingroup Core
* @defgroup Forge Wrap and defer operators' instanciations.
* @ingroup Forge
*/
template<class Itf>
class eoForgeInterface
{
public:
virtual Itf& instanciate() = 0;
virtual ~eoForgeInterface() {}
};
/** This "Forge" can defer the instanciation of an EO's operator.
*
* It allows to decouple the constructor's parameters setup from its actual call.
* You can declare a parametrized operator at a given time,
* then actually instanciate it (with the given interface) at another time.
*
* This allows for creating containers of pre-parametrized operators (@see eoForgeMap or @see eoForgeVector).
*
* @code
eoForgeOperator<eoselect<EOT>,eoRankMuSelect<EOT>> forge(mu);
// ^ desired ^ to-be-instanciated ^ operator's
// interface operator parameters
// Actual instanciation:
eoSelect<EOT>& select = forge.instanciate();
* @endcode
*
* @ingroup Forge
*/
template<class Itf, class Op, typename... Args>
class eoForgeOperator : public eoForgeInterface<Itf>
{
public:
eoForgeOperator(Args&&... args) :
_args(std::forward<Args>(args)...)
{ }
Itf& instanciate()
{
return *(constructor(_args));
}
virtual ~eoForgeOperator() {}
protected:
std::tuple<Args...> _args;
private:
template <int... Idx>
struct index {};
template <int N, int... Idx>
struct gen_seq : gen_seq<N - 1, N - 1, Idx...> {};
template <int... Idx>
struct gen_seq<0, Idx...> : index<Idx...> {};
template <typename... Ts, int... Idx>
Op* constructor(std::tuple<Ts...>& args, index<Idx...>)
{
Op* p_op = new Op(std::get<Idx>(args)...);
return p_op;
}
template <typename... Ts>
Op* constructor(std::tuple<Ts...>& args)
{
return constructor(args, gen_seq<sizeof...(Ts)>{});
}
};
/** A map holding an operator with deferred instanciation at a given key.
*
* @note You can actually store several instances of the same class,
* with different parametrization (or not).
*
* @code
eoForgeMap<eoSelect<EOT>> named_factories;
// Capture constructor's parameters and defer instanciation.
named_factories.add<eoRankMuSelect<EOT>>("RMS", 1);
named_factories.setup<eoRankMuSelect<EOT>>("RMS", 5); // Edit
// Actually instanciate.
eoSelect<EOT>& op = named_factories.instanciate("RMS");
// Call.
op();
* @endcode
*
* @ingroup Forge
*/
template<class Itf>
class eoForgeMap : public std::map<std::string, std::shared_ptr<eoForgeInterface<Itf>> >
{
public:
template<class Op, typename... Args>
void setup(std::string key, Args&&... args)
{
auto opf = std::make_shared< eoForgeOperator<Itf,Op,Args...> >(std::forward<Args>(args)...);
(*this)[key] = opf;
}
template<class Op, typename... Args>
void add(std::string key, Args&&... args)
{
setup<Op>(key, std::forward<Args>(args)...);
}
Itf& instanciate(std::string key)
{
return this->at(key)->instanciate();
}
};
/** A vector holding an operator with deferred instanciation at a given index.
*
* @note You can actually store several instances of the same class,
* with different parametrization (or not).
*
* @code
eoForgeVector<eoSelect<EOT>> named_factories;
// Capture constructor's parameters and defer instanciation.
named_factories.add<eoRankMuSelect<EOT>>(1);
named_factories.setup<eoRankMuSelect<EOT>>(0, 5); // Edit
// Actually instanciate.
eoSelect<EOT>& op = named_factories.instanciate("RMS");
// Call.
op();
* @endcode
*
* @ingroup Forge
*/
template<class Itf>
class eoForgeVector : public std::vector<std::shared_ptr<eoForgeInterface<Itf>> >
{
public:
template<class Op, typename... Args>
void add(Args&&... args)
{
auto opf = std::make_shared< eoForgeOperator<Itf,Op,Args...> >(std::forward<Args>(args)...);
this->push_back(opf);
}
template<class Op, typename... Args>
void setup(size_t index, Args&&... args)
{
auto opf = std::make_shared< eoForgeOperator<Itf,Op,Args...> >(std::forward<Args>(args)...);
this->at(index) = opf;
}
Itf& instanciate(size_t index)
{
return this->at(index)->instanciate();
}
};
#endif // _eoForge_H_

View file

@ -59,6 +59,8 @@ public :
struct unary_function_tag {};
/// tag to identify a binary function in compile time function selection @see functor_category
struct binary_function_tag {};
virtual std::string className() const { return "unknown";}
};
/** @example t-eoFunctor.cpp
*/

View file

@ -80,6 +80,8 @@ class eoPlusReplacement : public eoMergeReduce<EOT>
private :
eoPlus<EOT> plus;
eoTruncate<EOT> truncate;
public:
virtual std::string className() const {return "eoPlusReplacement";}
};
/**
@ -103,6 +105,8 @@ class eoCommaReplacement : public eoMergeReduce<EOT>
private :
eoNoElitism<EOT> no_elite;
eoTruncate<EOT> truncate;
public:
virtual std::string className() const {return "eoCommaReplacement";}
};
/**

View file

@ -42,7 +42,8 @@
@ingroup Selectors
*/
template <class EOT> class eoProportionalSelect: public eoSelectOne<EOT>
template <class EOT>
class eoProportionalSelect: public eoSelectOne<EOT>
{
public:
/// Sanity check
@ -80,6 +81,8 @@ private :
typedef std::vector<typename EOT::Fitness> FitVec;
FitVec cumulative;
public:
virtual std::string className() const {return "eoProportionalSelect";}
};
/** @example t-eoRoulette.cpp
*/

View file

@ -86,6 +86,8 @@ class eoSSGAWorseReplacement : public eoReduceMerge<EOT>
private :
eoLinearTruncate<EOT> truncate;
eoPlus<EOT> plus;
public:
virtual std::string className() const {return "eoSSGAWorseReplacement";}
};
/**
@ -101,6 +103,8 @@ class eoSSGADetTournamentReplacement : public eoReduceMerge<EOT>
private :
eoDetTournamentTruncate<EOT> truncate;
eoPlus<EOT> plus;
public:
virtual std::string className() const {return "eoSSGADetTournamentReplacement";}
};
/** SSGA stochastic tournament replacement. Is an eoReduceMerge.
@ -118,6 +122,8 @@ class eoSSGAStochTournamentReplacement : public eoReduceMerge<EOT>
private :
eoStochTournamentTruncate<EOT> truncate;
eoPlus<EOT> plus;
public:
virtual std::string className() const {return "eoSSGAStochTournamentReplacement";}
};
/** @} */

View file

@ -89,6 +89,8 @@ class eoGenerationalReplacement : public eoReplacement<EOT>
{
_parents.swap(_offspring);
}
public:
virtual std::string className() const {return "eoGenerationalReplacement ";}
};
/**
@ -123,6 +125,8 @@ public :
}
private:
eoReplacement<EOT> & replace;
public:
virtual std::string className() const {return "eoWeakElitistReplacement ";}
};
#endif

View file

@ -84,6 +84,8 @@ private:
bool ordered;
unsigned current;
std::vector<const EOT*> eoPters;
public:
virtual std::string className() const {return "eoSequentialSelect";}
};

View file

@ -36,7 +36,8 @@
@ingroup Selectors
*/
template <class EOT> class eoStochTournamentSelect: public eoSelectOne<EOT>
template <class EOT>
class eoStochTournamentSelect: public eoSelectOne<EOT>
{
public:
@ -62,6 +63,8 @@ template <class EOT> class eoStochTournamentSelect: public eoSelectOne<EOT>
private:
double Trate;
public:
virtual std::string className() const {return "eoStochTournamentSelect";}
};
#endif