fix eoAlgoFoundry management of numeric parameters
- Use a variant to avoid implicit casting to integer when selecting with brace-initialization. - Add more doc around parameter forges.
This commit is contained in:
parent
3a6236594e
commit
02eb0e967d
11 changed files with 393 additions and 163 deletions
|
|
@ -16,8 +16,6 @@
|
|||
* ParadisEO algorithmic grammar definition.
|
||||
*****************************************************************************/
|
||||
|
||||
// using Particle = eoRealParticle<eoMaximizingFitness>;
|
||||
using Ints = eoInt<eoMaximizingFitnessT<int>, size_t>;
|
||||
using Bits = eoBit<eoMaximizingFitnessT<int>, int>;
|
||||
|
||||
// by enumerating candidate operators and their parameters.
|
||||
|
|
@ -341,7 +339,7 @@ int main(int argc, char* argv[])
|
|||
"problem", "Problem ID",
|
||||
'p', "Problem", /*required=*/true);
|
||||
const size_t problem = problem_p.value();
|
||||
assert(0 <= problem and problem < benchmark.size());
|
||||
assert(problem < benchmark.size());
|
||||
|
||||
// const size_t dimension = parser.getORcreateParam<size_t>(1000,
|
||||
// "dimension", "Dimension size",
|
||||
|
|
@ -624,7 +622,7 @@ int main(int argc, char* argv[])
|
|||
eoInitFixedLength<Bits> onemax_init(/*bitstring size=*/dimension, bgen);
|
||||
auto& foundry = make_foundry(store, onemax_init, eval_count, max_evals, generations, max_target);
|
||||
|
||||
Ints encoded_algo(foundry.size());
|
||||
eoAlgoFoundry<Bits>::Encodings encoded_algo(foundry.size());
|
||||
|
||||
encoded_algo[foundry.crossover_rates .index()] = crossover_rate;
|
||||
encoded_algo[foundry.crossover_selectors .index()] = crossover_selector;
|
||||
|
|
@ -641,16 +639,6 @@ int main(int argc, char* argv[])
|
|||
foundry.select(encoded_algo);
|
||||
std::clog << foundry.name() << std::endl;
|
||||
|
||||
// // Evaluation of a forged encoded_algo on the sub-problem
|
||||
// eoEvalFoundryFastGA<Ints, Bits> eval_foundry(
|
||||
// foundry, pop_size,
|
||||
// onemax_init, onemax_eval,
|
||||
// /*penalization=*/ dimension, // Worst case penalization.
|
||||
// /*normalized=*/ false); // Use direct integer encoding.
|
||||
//
|
||||
// // Actually instanciate and run the algorithm.
|
||||
// eval_foundry(encoded_algo);
|
||||
|
||||
/*****************************************************************************
|
||||
* Run and output results.
|
||||
*****************************************************************************/
|
||||
|
|
@ -661,7 +649,7 @@ int main(int argc, char* argv[])
|
|||
onemax_eval(pop,pop);
|
||||
foundry(pop); // Actually run the selected algorithm.
|
||||
|
||||
} catch(eoMaxEvalException e) {
|
||||
} catch(eoMaxEvalException & e) {
|
||||
eo::log << eo::debug << "Reached maximum evaluations: " << eval_count.getValue() << " / " << max_evals << std::endl;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
© 2020 Thales group
|
||||
© 2022 Institut Pasteur
|
||||
|
||||
Authors:
|
||||
Johann Dreo <johann.dreo@thalesgroup.com>
|
||||
|
|
@ -24,6 +25,7 @@
|
|||
#define _eoAlgoFoundry_H_
|
||||
|
||||
#include <vector>
|
||||
#include <variant>
|
||||
|
||||
/** A vector of eoForge which hold an index.
|
||||
*
|
||||
|
|
@ -36,13 +38,13 @@
|
|||
* which takes the class name as template and its constructor's parameters
|
||||
* as arguments. For example:
|
||||
* @code
|
||||
* eoOperatorFoundry< eoSelectOne<EOT> > selectors;
|
||||
* selectors.add< eoStochTournamentSelect<EOT> >( 0.5 );
|
||||
* eoOperatorFoundry< eoSelectOne<EOT> > selectors;
|
||||
* selectors.add< eoStochTournamentSelect<EOT> >( 0.5 );
|
||||
* @endcode
|
||||
*
|
||||
* @warning If the managed constructor takes a reference YOU SHOULD ABSOLUTELY wrap it
|
||||
* in a `std::ref` when using `add` or `setup`, or it will silently be passed as a copy,
|
||||
* which would effectively disable any link between operators.
|
||||
* in a `std::ref` when using `add` or `setup`, or it will silently be passed as a copy,
|
||||
* which would effectively disable any link between operators.
|
||||
*
|
||||
* @ingroup Core
|
||||
* @ingroup Foundry
|
||||
|
|
@ -51,11 +53,18 @@ template<class Itf>
|
|||
class eoOperatorFoundry : public eoForgeVector< Itf >
|
||||
{
|
||||
public:
|
||||
/** Constructor
|
||||
*
|
||||
* @param encoding_index The slot position in the encodings, at which this operator is held.
|
||||
* @param always_reinstantiate If false, will enable cache for the forges in this container.
|
||||
*/
|
||||
eoOperatorFoundry(size_t encoding_index, bool always_reinstantiate = true ) :
|
||||
eoForgeVector<Itf>(always_reinstantiate),
|
||||
_index(encoding_index)
|
||||
{ }
|
||||
|
||||
/** Returns the slot index at which this is registered.
|
||||
*/
|
||||
size_t index() const { return _index; }
|
||||
|
||||
protected:
|
||||
|
|
@ -63,6 +72,24 @@ class eoOperatorFoundry : public eoForgeVector< Itf >
|
|||
size_t _index;
|
||||
};
|
||||
|
||||
|
||||
/** A vector of eoForge which hold a scalar numeric value.
|
||||
*
|
||||
* To be used in conjunction with a subclass of an eoAlgoFoundry,
|
||||
* where it can hold a range of parameter values
|
||||
* and hold the link to the encoding. @see eoAlgoFoundryEA
|
||||
*
|
||||
* As with eoForgeScalar, managed parameters
|
||||
* are represented through a [min,max] range.
|
||||
*
|
||||
* For example:
|
||||
* @code
|
||||
* eoParameterFoundry< double > proba(0.0, 1.0);
|
||||
* @endcode
|
||||
*
|
||||
* @ingroup Core
|
||||
* @ingroup Foundry
|
||||
*/
|
||||
template<class Itf>
|
||||
class eoParameterFoundry : public eoForgeScalar< Itf >
|
||||
{
|
||||
|
|
@ -70,11 +97,26 @@ class eoParameterFoundry : public eoForgeScalar< Itf >
|
|||
"eoParameterFoundry should only be used on arithmetic types (i.e. integer or floating point types)");
|
||||
|
||||
public:
|
||||
/** Underlying type of the parameter.
|
||||
*
|
||||
* @note: You probably only want to use either `double` or `size_t`.
|
||||
* @see eoAlgoFoundry
|
||||
*/
|
||||
using Type = Itf;
|
||||
|
||||
/** Constructor
|
||||
*
|
||||
* @param encoding_index The slot position in the encodings, at which this parameter is held.
|
||||
* @param min Minimium possible value.
|
||||
* @param max Maximum possible value.
|
||||
*/
|
||||
eoParameterFoundry(size_t encoding_index, Itf min, Itf max) :
|
||||
eoForgeScalar<Itf>(min, max),
|
||||
_index(encoding_index)
|
||||
{ }
|
||||
|
||||
/** Returns the slot index at which this is registered.
|
||||
*/
|
||||
size_t index() const { return _index; }
|
||||
|
||||
protected:
|
||||
|
|
@ -84,48 +126,54 @@ class eoParameterFoundry : public eoForgeScalar< Itf >
|
|||
|
||||
/** Interface of a Foundry: a class that instantiate an eoAlgo on-the-fly, given a choice of its operators.
|
||||
*
|
||||
* The chosen operators are encoded in a vector of indices.
|
||||
* The chosen operators are encoded in a vector of numbers.
|
||||
*
|
||||
* The foundry subclass should first be set up with sets of operators of the same interface,
|
||||
* held within an eoOperatorFoundry member.
|
||||
* @code
|
||||
* eoOperatorFoundry< eoSelectOne<EOT> > selectors;
|
||||
* eoOperatorFoundry< eoSelectOne<EOT> > selectors;
|
||||
* @endcode
|
||||
*
|
||||
* In a second step, the operators to be used should be selected
|
||||
* by indicating their index, just like if the foundry was an array:
|
||||
* @code
|
||||
* foundry.select({0, 1, 2});
|
||||
* // ^ ^ ^
|
||||
* // | | |
|
||||
* // | | + 3d operator
|
||||
* // | + 2d operator
|
||||
* // + 1st operator
|
||||
* foundry.select({size_t{0}, size_t{1}, size_t{2}});
|
||||
* // ^ ^ ^
|
||||
* // | | |
|
||||
* // | | + 3d operator
|
||||
* // | + 2d operator
|
||||
* // + 1st operator
|
||||
* @endcode
|
||||
*
|
||||
* If you don't (want to) recall the order of the operators in the encoding,
|
||||
* you can use the `index()` member of eoOperatorFoundry, for example:
|
||||
* @code
|
||||
* foundry.at(foundry.continuators.index()) = 2; // select the third continuator
|
||||
* foundry.at(foundry.continuators.index()) = size_t{2}; // select the third continuator
|
||||
* @endcode
|
||||
*
|
||||
* Now, you must implement the foundry just like any eoAlgo, by using the eoPop interface:
|
||||
* @code
|
||||
* foundry(pop);
|
||||
* foundry(pop);
|
||||
* @encode
|
||||
* It will instantiate the needed operators (only) and the algorithm itself on-the-fly,
|
||||
* and then run it.
|
||||
*
|
||||
* @note: The "encoding" which represent the selected options, figuring the actual meta-algorithm,
|
||||
* is a vector of `std::variant`, which can hold either a `size_t` or a `double`.
|
||||
* The first one is used to indicate the index of an operator class
|
||||
* *or* a parameter which is a size.
|
||||
* The second is used to store numerical parameters values.
|
||||
*
|
||||
* @note: Thanks to the underlying eoOperatorFoundry, not all the added operators are instantiated.
|
||||
* Every instantiation is deferred upon actual use. That way, you can still reconfigure them
|
||||
* at any time with `eoForgeOperator::setup`, for example:
|
||||
* @code
|
||||
* foundry.selector.at(0).setup(0.5); // using constructor's arguments
|
||||
* @endcode
|
||||
* Every instantiation is deferred upon actual use. That way, you can still reconfigure them
|
||||
* at any time with `eoForgeOperator::setup`, for example:
|
||||
* @code
|
||||
* foundry.selector.at(0).setup(0.5); // using constructor's arguments
|
||||
* @endcode
|
||||
*
|
||||
* @warning If the managed constructor takes a reference YOU SHOULD ABSOLUTELY wrap it
|
||||
* in a `std::ref` when using `add` or `setup`, or it will silently be passed as a copy,
|
||||
* which would effectively disable any link between operators.
|
||||
* in a `std::ref` when using `add` or `setup`, or it will silently be passed as a copy,
|
||||
* which would effectively disable any link between operators.
|
||||
*
|
||||
* @ingroup Core
|
||||
* @ingroup Foundry
|
||||
|
|
@ -135,30 +183,104 @@ template<class EOT>
|
|||
class eoAlgoFoundry : public eoAlgo<EOT>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
// We could use `std::any` instead of a variant,
|
||||
// but this would be more prone to errors from the end user, at the end.
|
||||
// Either the encoding is an index (of the operator within the list of instances)
|
||||
// either it's a real-valued parameter,
|
||||
// either it's a size.
|
||||
// So there's no need for more types (AFAIK).
|
||||
|
||||
/** The type use to represent a selected option in the meta-algorithm.
|
||||
*
|
||||
* This can figure, either:
|
||||
* - the index of an operator in the list of possible ones,
|
||||
* - the actual value of a numeric paramater,
|
||||
* - the value of a parameter which is a size.
|
||||
*/
|
||||
eoAlgoFoundry( size_t nb_operators ) :
|
||||
_size(nb_operators),
|
||||
_encoding(_size,0)
|
||||
using Encoding = std::variant<size_t, double>;
|
||||
|
||||
/** The type use to store all selected options.
|
||||
*/
|
||||
using Encodings = std::vector<Encoding>;
|
||||
|
||||
/** Constructor.
|
||||
*
|
||||
* @param nb_slots Number of operators or parameters that are assembled to make an algorithm.
|
||||
*/
|
||||
eoAlgoFoundry( size_t nb_slots ) :
|
||||
_size(nb_slots)
|
||||
{ }
|
||||
|
||||
/** Select indices of all the operators.
|
||||
*
|
||||
* i.e. Select an algorithm to instantiate.
|
||||
*
|
||||
* @note: You need to indicate the type of each item
|
||||
* if you want to call this with a brace-initialized vector.
|
||||
*
|
||||
* For example:
|
||||
* @code
|
||||
* foundry.select({ size_t{1}, double{0.5}, size_t{3} });
|
||||
* @endcode
|
||||
*
|
||||
* Or you can initialize the vector first:
|
||||
* @code
|
||||
* double crossover_rate = 0.5;
|
||||
* size_t crossover_oper = 3;
|
||||
* eoAlgoFoundry<EOT>::Encodings encoded_algo(foundry.size());
|
||||
* encoded_algo[foundry.crossover_rates.index()] = crossover_rate;
|
||||
* encoded_algo[foundry.crossover_opers.index()] = crossover_oper;
|
||||
* @encdoe
|
||||
*/
|
||||
void select( std::vector<size_t> encoding )
|
||||
void select( Encodings encodings )
|
||||
{
|
||||
assert(encoding.size() == _encoding.size());
|
||||
_encoding = encoding;
|
||||
assert(encodings.size() == _size);
|
||||
_encodings = encodings;
|
||||
}
|
||||
|
||||
/** Access to the index of the currently selected operator.
|
||||
/** Access to the encoding of the currently selected operator.
|
||||
*
|
||||
* @warning: This returns a `std::variant`, which you should `std::get<T>`.
|
||||
*
|
||||
* For example:
|
||||
* @code
|
||||
* size_t opera_id = std::get<size_t>(foundry.at(2));
|
||||
* double param_id = std::get<double>(foundry.at(3));
|
||||
* @endcode
|
||||
*
|
||||
* @note: You can use rank, value or len to have automatic casting.
|
||||
*/
|
||||
size_t& at(size_t i)
|
||||
Encoding & at(size_t i)
|
||||
{
|
||||
return _encoding.at(i);
|
||||
return _encodings.at(i);
|
||||
}
|
||||
|
||||
/** Access to the currently selected ID of an operator.
|
||||
*/
|
||||
template<class OP>
|
||||
size_t rank(const OP& op)
|
||||
{
|
||||
return std::get<size_t>( at(op.index()) );
|
||||
}
|
||||
|
||||
/** Access to the currently selected value of a numeric parameter.
|
||||
*/
|
||||
template<class OP>
|
||||
double value(const OP& param)
|
||||
{
|
||||
return std::get<double>( at(param.index()) );
|
||||
}
|
||||
|
||||
/** Access to the currently selected value of a unsigned integer parameter.
|
||||
*/
|
||||
template<class OP>
|
||||
size_t len(const OP& param)
|
||||
{
|
||||
return std::get<size_t>( at(param.index()) );
|
||||
}
|
||||
|
||||
/** Returns the number of slots that makes this algorithm.
|
||||
*/
|
||||
size_t size() const
|
||||
{
|
||||
return _size;
|
||||
|
|
@ -166,14 +288,14 @@ class eoAlgoFoundry : public eoAlgo<EOT>
|
|||
|
||||
/** Return the underlying encoding vector.
|
||||
*/
|
||||
std::vector<size_t> encoding() const
|
||||
Encodings encodings() const
|
||||
{
|
||||
return _encoding;
|
||||
return _encodings;
|
||||
}
|
||||
|
||||
protected:
|
||||
const size_t _size;
|
||||
std::vector<size_t> _encoding;
|
||||
std::vector<Encoding> _encodings;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -15,9 +15,10 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
© 2020 Thales group
|
||||
© 2022 Institut Pasteur
|
||||
|
||||
Authors:
|
||||
Johann Dreo <johann.dreo@thalesgroup.com>
|
||||
Johann Dreo <johann@dreo.fr>
|
||||
*/
|
||||
|
||||
#ifndef _eoAlgoFoundryEA_H_
|
||||
|
|
@ -36,7 +37,7 @@
|
|||
* which takes the class name as template and its constructor's parameters
|
||||
* as arguments. For example:
|
||||
* @code
|
||||
* foundry.selectors.add< eoStochTournamentSelect<EOT> >( 0.5 );
|
||||
* foundry.selectors.add< eoStochTournamentSelect<EOT> >( 0.5 );
|
||||
* @endcode
|
||||
*
|
||||
* @warning If the constructor takes a reference YOU SHOULD ABSOLUTELY wrap it
|
||||
|
|
@ -46,12 +47,12 @@
|
|||
* In a second step, the operators to be used should be selected
|
||||
* by indicating their index, just like the foundry was a array of five elements:
|
||||
* @code
|
||||
* foundry = {0, 1, 2, 0, 3};
|
||||
* // ^ ^ ^ ^ ^ replacement
|
||||
* // | | | + selection
|
||||
* // | | + mutation
|
||||
* // | + crossover
|
||||
* // + continue
|
||||
* foundry = {size_t{0}, size_t{1}, size_t{2}, size_t{0}, size_t{3}};
|
||||
* // ^ ^ ^ ^ ^ replacement
|
||||
* // | | | + selection
|
||||
* // | | + mutation
|
||||
* // | + crossover
|
||||
* // + continue
|
||||
* @endcode
|
||||
*
|
||||
* @note: by default, the firsts of the five operators are selected.
|
||||
|
|
@ -59,12 +60,12 @@
|
|||
* If you don't (want to) recall the order of the operators in the encoding,
|
||||
* you can use the `index()` member, for example:
|
||||
* @code
|
||||
* foundry.at(foundry.continuators.index()) = 2; // select the third continuator
|
||||
* foundry.at(foundry.continuators.index()) = size_t{2}; // select the third continuator
|
||||
* @endcode
|
||||
*
|
||||
* Now, you can call the fourdry just like any eoAlgo, by passing it an eoPop:
|
||||
* @code
|
||||
* foundry(pop);
|
||||
* foundry(pop);
|
||||
* @encode
|
||||
* It will instantiate the needed operators (only) and the algorithm itself on-the-fly,
|
||||
* and then run it.
|
||||
|
|
@ -73,7 +74,7 @@
|
|||
* Every instantiation is deferred upon actual use. That way, you can still reconfigure them
|
||||
* at any time with `eoForgeOperator::setup`, for example:
|
||||
* @code
|
||||
* foundry.selector.at(0).setup(0.5); // using constructor's arguments
|
||||
* foundry.selectors.at(0).setup(0.5); // using constructor's arguments
|
||||
* @endcode
|
||||
*
|
||||
* @ingroup Foundry
|
||||
|
|
@ -111,11 +112,11 @@ class eoAlgoFoundryEA : public eoAlgoFoundry<EOT>
|
|||
*/
|
||||
void operator()(eoPop<EOT>& pop)
|
||||
{
|
||||
assert(continuators.size() > 0); assert(this->at(continuators.index()) < continuators.size());
|
||||
assert( crossovers.size() > 0); assert(this->at( crossovers.index()) < crossovers.size());
|
||||
assert( mutations.size() > 0); assert(this->at( mutations.index()) < mutations.size());
|
||||
assert( selectors.size() > 0); assert(this->at( selectors.index()) < selectors.size());
|
||||
assert(replacements.size() > 0); assert(this->at(replacements.index()) < replacements.size());
|
||||
assert(continuators.size() > 0); assert(this->rank(continuators) < continuators.size());
|
||||
assert( crossovers.size() > 0); assert(this->rank( crossovers) < crossovers.size());
|
||||
assert( mutations.size() > 0); assert(this->rank( mutations) < mutations.size());
|
||||
assert( selectors.size() > 0); assert(this->rank( selectors) < selectors.size());
|
||||
assert(replacements.size() > 0); assert(this->rank(replacements) < replacements.size());
|
||||
|
||||
eoSequentialOp<EOT> variator;
|
||||
variator.add(this->crossover(), 1.0);
|
||||
|
|
@ -140,11 +141,11 @@ class eoAlgoFoundryEA : public eoAlgoFoundry<EOT>
|
|||
std::string name()
|
||||
{
|
||||
std::ostringstream name;
|
||||
name << this->at(continuators.index()) << " (" << this->continuator().className() << ") + ";
|
||||
name << this->at(crossovers.index()) << " (" << this->crossover().className() << ") + ";
|
||||
name << this->at(mutations.index()) << " (" << this->mutation().className() << ") + ";
|
||||
name << this->at(selectors.index()) << " (" << this->selector().className() << ") + ";
|
||||
name << this->at(replacements.index()) << " (" << this->replacement().className() << ")";
|
||||
name << this->continuator().className() << " [" << this->rank(continuators) << "] + ";
|
||||
name << this->crossover() .className() << " [" << this->rank(crossovers) << "] + ";
|
||||
name << this->mutation() .className() << " [" << this->rank(mutations) << "] + ";
|
||||
name << this->selector() .className() << " [" << this->rank(selectors) << "] + ";
|
||||
name << this->replacement().className() << " [" << this->rank(replacements) << "]";
|
||||
return name.str();
|
||||
}
|
||||
|
||||
|
|
@ -153,34 +154,44 @@ class eoAlgoFoundryEA : public eoAlgoFoundry<EOT>
|
|||
const size_t _max_gen;
|
||||
|
||||
public:
|
||||
/** Currently selected continuator.
|
||||
*/
|
||||
eoContinue<EOT>& continuator()
|
||||
{
|
||||
assert(this->at(continuators.index()) < continuators.size());
|
||||
return continuators.instantiate(this->at(continuators.index()));
|
||||
assert(this->rank(continuators) < continuators.size());
|
||||
return continuators.instantiate(this->rank(continuators));
|
||||
}
|
||||
|
||||
/** Currently selected crossover.
|
||||
*/
|
||||
eoQuadOp<EOT>& crossover()
|
||||
{
|
||||
assert(this->at(crossovers.index()) < crossovers.size());
|
||||
return crossovers.instantiate(this->at(crossovers.index()));
|
||||
assert(this->rank(crossovers) < crossovers.size());
|
||||
return crossovers.instantiate(this->rank(crossovers));
|
||||
}
|
||||
|
||||
/** Currently selected mutation.
|
||||
*/
|
||||
eoMonOp<EOT>& mutation()
|
||||
{
|
||||
assert(this->at(mutations.index()) < mutations.size());
|
||||
return mutations.instantiate(this->at(mutations.index()));
|
||||
assert(this->rank(mutations) < mutations.size());
|
||||
return mutations.instantiate(this->rank(mutations));
|
||||
}
|
||||
|
||||
/** Currently selected selector.
|
||||
*/
|
||||
eoSelectOne<EOT>& selector()
|
||||
{
|
||||
assert(this->at(selectors.index()) < selectors.size());
|
||||
return selectors.instantiate(this->at(selectors.index()));
|
||||
assert(this->rank(selectors) < selectors.size());
|
||||
return selectors.instantiate(this->rank(selectors));
|
||||
}
|
||||
|
||||
/** Currently selected replacement.
|
||||
*/
|
||||
eoReplacement<EOT>& replacement()
|
||||
{
|
||||
assert(this->at(replacements.index()) < replacements.size());
|
||||
return replacements.instantiate(this->at(replacements.index()));
|
||||
assert(this->rank(replacements) < replacements.size());
|
||||
return replacements.instantiate(this->rank(replacements));
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -29,25 +29,37 @@
|
|||
|
||||
/** A class that assemble an eoFastGA on the fly, given a combination of available operators.
|
||||
*
|
||||
* The foundry should first be set up with sets of operators
|
||||
* The foundry should first be set up with sets of operators/parameters
|
||||
* for the main modules of a FastGA:
|
||||
* continuators, crossovers, mutations, selections, replacement operators, etc.
|
||||
* continuators, crossovers (and rate of call), mutations (and rate of call),
|
||||
* selections, replacement operators, offspring size, etc.
|
||||
*
|
||||
* This is done through public member variable's `add` method,
|
||||
* which takes the class name as template and its constructor's parameters
|
||||
* as arguments. For example:
|
||||
* @code
|
||||
* foundry.selectors.add< eoRandomSelect<EOT> >();
|
||||
* foundry.selectors.add< eoRandomSelect<EOT> >();
|
||||
* @endcode
|
||||
*
|
||||
* @warning If the constructor takes a reference YOU SHOULD ABSOLUTELY wrap it
|
||||
* in a `std::ref`, or it will silently be passed as a copy,
|
||||
* which would effectively disable any link with other operator(s).
|
||||
* in a `std::ref`, or it will silently be passed as a copy,
|
||||
* which would effectively disable any link with other operator(s).
|
||||
*
|
||||
* In a second step, the operators to be used should be selected
|
||||
* by indicating their index, passing an array of 10 elements:
|
||||
* by indicating their wanted index or value, passing an array of 10 elements:
|
||||
* @code
|
||||
* foundry.select({0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
|
||||
* foundry.select({
|
||||
* double{0.1}, // crossover rate
|
||||
* size_t{1}, // crossover selector
|
||||
* size_t{2}, // crossover
|
||||
* size_t{3}, // selector after crossover
|
||||
* double{0.4}, // mutation rate
|
||||
* size_t{5}, // mutation selector
|
||||
* size_t{6}, // mutation
|
||||
* size_t{7}, // replacement
|
||||
* size_t{8}, // continuator
|
||||
* size_t{9} // nb of offsprings
|
||||
* });
|
||||
* @endcode
|
||||
*
|
||||
* @note: by default, the firsts of the 10 operators are selected.
|
||||
|
|
@ -55,22 +67,22 @@
|
|||
* If you don't (want to) recall the order of the operators in the encoding,
|
||||
* you can use the `index()` member, for example:
|
||||
* @code
|
||||
* foundry.at(foundry.continuators.index()) = 2; // select the third continuator
|
||||
* foundry.at(foundry.continuators.index()) = size_t{2}; // select the third continuator
|
||||
* @endcode
|
||||
*
|
||||
* Now, you can call the foundry just like any eoAlgo, by passing it an eoPop:
|
||||
* @code
|
||||
* foundry(pop);
|
||||
* foundry(pop);
|
||||
* @encode
|
||||
* It will instantiate the needed operators (only) and the algorithm itself on-the-fly,
|
||||
* and then run it.
|
||||
*
|
||||
* @note: Thanks to the underlying eoOperatorFoundry, not all the added operators are instantiated.
|
||||
* Every instantiation is deferred upon actual use. That way, you can still reconfigure them
|
||||
* at any time with `eoForgeOperator::setup`, for example:
|
||||
* @code
|
||||
* foundry.selector.at(0).setup(0.5); // Will call constructor's arguments
|
||||
* @endcode
|
||||
* Every instantiation is deferred upon actual use. That way, you can still reconfigure them
|
||||
* at any time with `eoForgeOperator::setup`, for example:
|
||||
* @code
|
||||
* foundry.selector.at(0).setup(0.5); // Will call constructor's arguments
|
||||
* @endcode
|
||||
*
|
||||
* @ingroup Foundry
|
||||
* @ingroup Algorithms
|
||||
|
|
@ -111,31 +123,31 @@ class eoAlgoFoundryFastGA : public eoAlgoFoundry<EOT>
|
|||
public:
|
||||
|
||||
/* Operators containers @{ */
|
||||
eoParameterFoundry< double > crossover_rates;
|
||||
eoParameterFoundry< double > crossover_rates;
|
||||
eoOperatorFoundry< eoSelectOne<EOT> > crossover_selectors;
|
||||
eoOperatorFoundry< eoQuadOp<EOT> > crossovers;
|
||||
eoOperatorFoundry< eoSelectOne<EOT> > aftercross_selectors;
|
||||
|
||||
eoParameterFoundry< double > mutation_rates;
|
||||
eoParameterFoundry< double > mutation_rates;
|
||||
eoOperatorFoundry< eoSelectOne<EOT> > mutation_selectors;
|
||||
eoOperatorFoundry< eoMonOp<EOT> > mutations;
|
||||
|
||||
eoOperatorFoundry< eoReplacement<EOT> > replacements;
|
||||
eoOperatorFoundry< eoContinue<EOT> > continuators;
|
||||
eoParameterFoundry< size_t > offspring_sizes;
|
||||
eoParameterFoundry< size_t > offspring_sizes;
|
||||
/* @} */
|
||||
|
||||
/** instantiate and call the pre-selected algorithm.
|
||||
*/
|
||||
void operator()(eoPop<EOT>& pop)
|
||||
{
|
||||
assert( crossover_selectors.size() > 0); assert(this->at( crossover_selectors.index()) < crossover_selectors.size());
|
||||
assert( crossovers.size() > 0); assert(this->at( crossovers.index()) < crossovers.size());
|
||||
assert(aftercross_selectors.size() > 0); assert(this->at(aftercross_selectors.index()) < aftercross_selectors.size());
|
||||
assert( mutation_selectors.size() > 0); assert(this->at( mutation_selectors.index()) < mutation_selectors.size());
|
||||
assert( mutations.size() > 0); assert(this->at( mutations.index()) < mutations.size());
|
||||
assert( replacements.size() > 0); assert(this->at( replacements.index()) < replacements.size());
|
||||
assert( continuators.size() > 0); assert(this->at( continuators.index()) < continuators.size());
|
||||
assert( crossover_selectors.size() > 0); assert(this->rank( crossover_selectors) < crossover_selectors.size());
|
||||
assert( crossovers.size() > 0); assert(this->rank( crossovers) < crossovers.size());
|
||||
assert(aftercross_selectors.size() > 0); assert(this->rank(aftercross_selectors) < aftercross_selectors.size());
|
||||
assert( mutation_selectors.size() > 0); assert(this->rank( mutation_selectors) < mutation_selectors.size());
|
||||
assert( mutations.size() > 0); assert(this->rank( mutations) < mutations.size());
|
||||
assert( replacements.size() > 0); assert(this->rank( replacements) < replacements.size());
|
||||
assert( continuators.size() > 0); assert(this->rank( continuators) < continuators.size());
|
||||
|
||||
// Objective function calls counter
|
||||
eoEvalCounterThrowException<EOT> eval(_eval, _max_evals);
|
||||
|
|
@ -165,7 +177,7 @@ class eoAlgoFoundryFastGA : public eoAlgoFoundry<EOT>
|
|||
try {
|
||||
// restart(pop);
|
||||
algo(pop);
|
||||
} catch(eoMaxEvalException e) {
|
||||
} catch(eoMaxEvalException & e) {
|
||||
#ifndef NDEBUG
|
||||
eo::log << eo::debug << "Reached maximum evaluations: " << eval.getValue() << " / " << _max_evals << std::endl;
|
||||
#endif
|
||||
|
|
@ -181,17 +193,18 @@ class eoAlgoFoundryFastGA : public eoAlgoFoundry<EOT>
|
|||
std::string name()
|
||||
{
|
||||
std::ostringstream name;
|
||||
name << "crossover_rates: " << this->at( crossover_rates.index()) << " (" << this-> crossover_rate() << ") + ";
|
||||
name << "crossover_selectors: " << this->at( crossover_selectors.index()) << " (" << this-> crossover_selector().className() << ") + ";
|
||||
name << "aftercross_selector: " << this->at(aftercross_selectors.index()) << " (" << this->aftercross_selector().className() << ") + ";
|
||||
name << "crossovers: " << this->at( crossovers.index()) << " (" << this-> crossover().className() << ") + ";
|
||||
name << "mutation_rates: " << this->at( mutation_rates.index()) << " (" << this-> mutation_rate() << ") + ";
|
||||
name << "mutation_selectors: " << this->at( mutation_selectors.index()) << " (" << this-> mutation_selector().className() << ") + ";
|
||||
name << "mutations: " << this->at( mutations.index()) << " (" << this-> mutation().className() << ") + ";
|
||||
name << "replacements: " << this->at( replacements.index()) << " (" << this-> replacement().className() << ") + ";
|
||||
name << "continuators: " << this->at( continuators.index()) << " (" << this-> continuator().className() << ") + ";
|
||||
name << "offspring_sizes: " << this->at( offspring_sizes.index()) << " (" << this-> offspring_size() << ")";
|
||||
return name.str();
|
||||
name << "crossover_rate: " << this-> crossover_rate() << " + ";
|
||||
name << "crossover_selector: " << this-> crossover_selector().className() << " [" << this->rank( crossover_selectors) << "] + ";
|
||||
name << "aftercross_selector: " << this->aftercross_selector().className() << " [" << this->rank(aftercross_selectors) << "] + ";
|
||||
name << "crossover: " << this-> crossover().className() << " [" << this->rank( crossovers) << "] + ";
|
||||
name << "mutation_rate: " << this-> mutation_rate() << " + ";
|
||||
name << "mutation_selector: " << this-> mutation_selector().className() << " [" << this->rank( mutation_selectors) << "] + ";
|
||||
name << "mutation: " << this-> mutation().className() << " [" << this->rank( mutations) << "] + ";
|
||||
name << "replacement: " << this-> replacement().className() << " [" << this->rank( replacements) << "] + ";
|
||||
name << "continuator: " << this-> continuator().className() << " [" << this->rank( continuators) << "] + ";
|
||||
name << "offspring_size: " << this-> offspring_size() << "";
|
||||
|
||||
return name.str();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
@ -201,61 +214,97 @@ class eoAlgoFoundryFastGA : public eoAlgoFoundry<EOT>
|
|||
const size_t _max_restarts;
|
||||
|
||||
public:
|
||||
/** Currently selected continuator.
|
||||
*/
|
||||
eoContinue<EOT>& continuator()
|
||||
{
|
||||
assert(this->at(continuators.index()) < continuators.size());
|
||||
return continuators.instantiate(this->at(continuators.index()));
|
||||
const size_t r = this->rank(continuators);
|
||||
assert(r < continuators.size());
|
||||
return continuators.instantiate(r);
|
||||
}
|
||||
|
||||
/** Currently selected crossover_rate.
|
||||
*/
|
||||
double& crossover_rate()
|
||||
{
|
||||
return crossover_rates.instantiate(this->at(crossover_rates.index()));
|
||||
// We could have used `decltype(crossover_rates)::Type` instead of `double`, here,
|
||||
// but this is less readable and the type is declared just above,
|
||||
// so we are supposed to know it.
|
||||
const double val = this->value(crossover_rates);
|
||||
assert(crossover_rates.min() <= val and val <= crossover_rates.max());
|
||||
return crossover_rates.instantiate(val);
|
||||
}
|
||||
|
||||
/** Currently selected crossover.
|
||||
*/
|
||||
eoQuadOp<EOT>& crossover()
|
||||
{
|
||||
assert(this->at(crossovers.index()) < crossovers.size());
|
||||
return crossovers.instantiate(this->at(crossovers.index()));
|
||||
const size_t r = this->rank(crossovers);
|
||||
assert(r < crossovers.size());
|
||||
return crossovers.instantiate(r);
|
||||
}
|
||||
|
||||
/** Currently selected mutation_rate.
|
||||
*/
|
||||
double& mutation_rate()
|
||||
{
|
||||
return mutation_rates.instantiate(this->at(mutation_rates.index()));
|
||||
const double val = this->value(mutation_rates);
|
||||
assert(mutation_rates.min() <= val and val <= mutation_rates.max());
|
||||
return mutation_rates.instantiate(val);
|
||||
}
|
||||
|
||||
/** Currently selected mutation.
|
||||
*/
|
||||
eoMonOp<EOT>& mutation()
|
||||
{
|
||||
assert(this->at(mutations.index()) < mutations.size());
|
||||
return mutations.instantiate(this->at(mutations.index()));
|
||||
const size_t r = this->rank(mutations);
|
||||
assert(r < mutations.size());
|
||||
return mutations.instantiate(r);
|
||||
}
|
||||
|
||||
/** Currently selected crossover_selector.
|
||||
*/
|
||||
eoSelectOne<EOT>& crossover_selector()
|
||||
{
|
||||
assert(this->at(crossover_selectors.index()) < crossover_selectors.size());
|
||||
return crossover_selectors.instantiate(this->at(crossover_selectors.index()));
|
||||
const size_t r = this->rank(crossover_selectors);
|
||||
assert(r < crossover_selectors.size());
|
||||
return crossover_selectors.instantiate(r);
|
||||
}
|
||||
|
||||
/** Currently selected aftercross_selector.
|
||||
*/
|
||||
eoSelectOne<EOT>& aftercross_selector()
|
||||
{
|
||||
assert(this->at(aftercross_selectors.index()) < aftercross_selectors.size());
|
||||
return aftercross_selectors.instantiate(this->at(aftercross_selectors.index()));
|
||||
const size_t r = this->rank(aftercross_selectors);
|
||||
assert(r < aftercross_selectors.size());
|
||||
return aftercross_selectors.instantiate(r);
|
||||
}
|
||||
|
||||
/** Currently selected mutation_selector.
|
||||
*/
|
||||
eoSelectOne<EOT>& mutation_selector()
|
||||
{
|
||||
assert(this->at(mutation_selectors.index()) < mutation_selectors.size());
|
||||
return mutation_selectors.instantiate(this->at(mutation_selectors.index()));
|
||||
const size_t r = this->rank(mutation_selectors);
|
||||
assert(r < mutation_selectors.size());
|
||||
return mutation_selectors.instantiate(r);
|
||||
}
|
||||
|
||||
/** Currently selected offspring_size.
|
||||
*/
|
||||
size_t& offspring_size()
|
||||
{
|
||||
return offspring_sizes.instantiate(this->at(offspring_sizes.index()));
|
||||
const size_t val = this->len(offspring_sizes);
|
||||
assert(offspring_sizes.min() <= val and val <= offspring_sizes.max());
|
||||
return offspring_sizes.instantiate(val);
|
||||
}
|
||||
|
||||
/** Currently selected replacement.
|
||||
*/
|
||||
eoReplacement<EOT>& replacement()
|
||||
{
|
||||
assert(this->at(replacements.index()) < replacements.size());
|
||||
return replacements.instantiate(this->at(replacements.index()));
|
||||
const size_t r = this->rank(replacements);
|
||||
assert(r < replacements.size());
|
||||
return replacements.instantiate(r);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,9 +15,10 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
© 2020 Thales group
|
||||
© 2022 Institut Pasteur
|
||||
|
||||
Authors:
|
||||
Johann Dreo <johann.dreo@thalesgroup.com>
|
||||
Johann Dreo <johann@dreo.fr>
|
||||
*/
|
||||
|
||||
#ifndef _eoEvalFoundryEA_H_
|
||||
|
|
@ -90,7 +91,7 @@ public:
|
|||
* auto& cont = foundry.continuator(); // Get the configured operator
|
||||
* @encode
|
||||
*/
|
||||
std::vector<size_t> decode( const EOT& sol ) const
|
||||
typename eoAlgoFoundry<SUB>::Encodings decode( const EOT& sol ) const
|
||||
{
|
||||
// // Denormalize
|
||||
// size_t cont = static_cast<size_t>(std::ceil( sol[i_cont] * _foundry.continuators.size() ));
|
||||
|
|
@ -125,18 +126,18 @@ public:
|
|||
_subpb_eval(pop,pop);
|
||||
|
||||
auto config = decode(sol);
|
||||
double cont = config[i_cont];
|
||||
double cros = config[i_cros];
|
||||
double muta = config[i_muta];
|
||||
double sele = config[i_sele];
|
||||
double repl = config[i_repl];
|
||||
size_t cont = std::get<size_t>(config[i_cont]);
|
||||
size_t cros = std::get<size_t>(config[i_cros]);
|
||||
size_t muta = std::get<size_t>(config[i_muta]);
|
||||
size_t sele = std::get<size_t>(config[i_sele]);
|
||||
size_t repl = std::get<size_t>(config[i_repl]);
|
||||
|
||||
if(
|
||||
0 <= cont and cont < _foundry.continuators.size()
|
||||
and 0 <= cros and cros < _foundry.crossovers .size()
|
||||
and 0 <= muta and muta < _foundry.mutations .size()
|
||||
and 0 <= sele and sele < _foundry.selectors .size()
|
||||
and 0 <= repl and repl < _foundry.replacements.size()
|
||||
cont < _foundry.continuators.size()
|
||||
and cros < _foundry.crossovers .size()
|
||||
and muta < _foundry.mutations .size()
|
||||
and sele < _foundry.selectors .size()
|
||||
and repl < _foundry.replacements.size()
|
||||
) {
|
||||
_foundry.select(config);
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,11 @@
|
|||
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
|
||||
|
||||
© 2022 Institut Pasteur
|
||||
|
||||
Authors:
|
||||
Johann Dreo <johann@dreo.fr>
|
||||
*/
|
||||
|
||||
#ifndef _eoFastGA_H_
|
||||
|
|
@ -116,6 +121,11 @@ public:
|
|||
eoPop<EOT> crossed;
|
||||
crossed.push_back(sol1);
|
||||
crossed.push_back(sol2);
|
||||
|
||||
// The aftercross selector may need fitness,
|
||||
// so we evaluate those two solutions, if needed.
|
||||
_pop_eval(crossed,crossed);
|
||||
|
||||
_select_aftercross.setup(crossed);
|
||||
EOT sol3 = _select_aftercross(crossed);
|
||||
|
||||
|
|
|
|||
|
|
@ -15,9 +15,10 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
© 2020 Thales group
|
||||
© 2022 Institut Pasteur
|
||||
|
||||
Authors:
|
||||
Johann Dreo <johann.dreo@thalesgroup.com>
|
||||
Johann Dreo <johann@dreo.fr>
|
||||
*/
|
||||
|
||||
#ifndef _eoForge_H_
|
||||
|
|
@ -185,7 +186,7 @@ class eoForgeOperator<Itf,Op> : public eoForgeInterface<Itf>
|
|||
Itf* _instantiated;
|
||||
};
|
||||
|
||||
/** A vector holding an operator with deferred instantiation at a given index.
|
||||
/** A vector holding an operator (with deferred instantiation) at a given index.
|
||||
*
|
||||
* @note You can actually store several instances of the same class,
|
||||
* with different parametrization (or not).
|
||||
|
|
@ -319,18 +320,41 @@ class eoForgeVector : public std::vector<eoForgeInterface<Itf>*>
|
|||
bool _no_cache;
|
||||
};
|
||||
|
||||
/** A range holding a parameter value at a given index.
|
||||
*
|
||||
* This is essential a scalar numerical parameter, with bounds check
|
||||
* and an interface similar to an eoForgeVector.
|
||||
*
|
||||
* @note Contrary to eoForgeVector, this does not store a set of possible values.
|
||||
*
|
||||
* @code
|
||||
eoForgeScalar<double> factories(0.0, 1.0);
|
||||
|
||||
// Actually instantiate.
|
||||
double param = factories.instantiate(0.5);
|
||||
* @endcode
|
||||
*
|
||||
* @ingroup Foundry
|
||||
*/
|
||||
template<class Itf>
|
||||
class eoForgeScalar
|
||||
{
|
||||
public:
|
||||
using Interface = Itf;
|
||||
|
||||
/** Constructor
|
||||
*
|
||||
* @param min Minimum possible value.
|
||||
* @param may Maximum possible value.
|
||||
*/
|
||||
eoForgeScalar(Itf min, Itf max) :
|
||||
_min(min),
|
||||
_max(max)
|
||||
{ }
|
||||
|
||||
/** Just return the same value, without managing any instantiation.
|
||||
*
|
||||
* Actually checks if value is in range.
|
||||
*/
|
||||
Itf& instantiate(double value)
|
||||
{
|
||||
|
|
@ -353,18 +377,24 @@ class eoForgeScalar
|
|||
Itf min() const { return _min; }
|
||||
Itf max() const { return _max; }
|
||||
|
||||
/** Set the minimum possible value.
|
||||
*/
|
||||
void min(Itf min)
|
||||
{
|
||||
assert(_min <= _max);
|
||||
_min = min;
|
||||
}
|
||||
|
||||
/** Set the maximum possible value.
|
||||
*/
|
||||
void max(Itf max)
|
||||
{
|
||||
assert(_max >= _min);
|
||||
_max = max;
|
||||
}
|
||||
|
||||
/** Set the possible range of values.
|
||||
*/
|
||||
void setup(Itf min, Itf max)
|
||||
{
|
||||
_min = min;
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ typedef unsigned long uint32_t;
|
|||
#include "../eoObject.h"
|
||||
|
||||
|
||||
|
||||
/** Random Number Generator
|
||||
|
||||
@class eoRng eoRNG.h utils/eoRNG.h
|
||||
|
|
|
|||
|
|
@ -77,14 +77,13 @@ int main(int /*argc*/, char** /*argv*/)
|
|||
pop.append(pop_size, init);
|
||||
eval(pop,pop);
|
||||
|
||||
foundry.at(foundry.continuators.index()) = i_cont;
|
||||
foundry.at(foundry.crossovers.index()) = i_cross;
|
||||
foundry.at(foundry.mutations.index()) = i_mut;
|
||||
foundry.at(foundry.selectors.index()) = i_sel;
|
||||
foundry.at(foundry.replacements.index()) = i_rep;
|
||||
|
||||
// Or, if you know the order.
|
||||
foundry.select({i_cont, i_cross, i_mut, i_sel, i_rep});
|
||||
foundry.select({
|
||||
size_t{i_cont},
|
||||
size_t{i_cross},
|
||||
size_t{i_mut},
|
||||
size_t{i_sel},
|
||||
size_t{i_rep}
|
||||
});
|
||||
|
||||
// Actually perform a search
|
||||
foundry(pop);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ int main(int /*argc*/, char** /*argv*/)
|
|||
using EOT = eoBit<double>;
|
||||
|
||||
oneMaxEval<EOT> eval;
|
||||
eoPopLoopEval<EOT> popeval(eval);
|
||||
|
||||
eoBooleanGenerator gen(0.5);
|
||||
eoInitFixedLength<EOT> init(dim, gen);
|
||||
|
|
@ -76,6 +77,8 @@ int main(int /*argc*/, char** /*argv*/)
|
|||
;
|
||||
std::clog << n << " possible algorithms instances." << std::endl;
|
||||
|
||||
std::clog << "Running everything (this may take time)..." << std::endl;
|
||||
|
||||
EOT best_sol;
|
||||
std::string best_algo = "";
|
||||
|
||||
|
|
@ -91,15 +94,20 @@ int main(int /*argc*/, char** /*argv*/)
|
|||
|
||||
eoPop<EOT> pop;
|
||||
pop.append(pop_size, init);
|
||||
popeval(pop,pop);
|
||||
|
||||
// FIXME put the parameters in the test?
|
||||
foundry.select({
|
||||
i_crossselect,
|
||||
i_cross,
|
||||
i_aftercrosel,
|
||||
i_mutselect,
|
||||
i_mut,
|
||||
i_rep,
|
||||
i_cont
|
||||
double{0.5}, // crossover_rate
|
||||
size_t{i_crossselect},
|
||||
size_t{i_cross},
|
||||
size_t{i_aftercrosel},
|
||||
double{0.5}, // mutation_rate
|
||||
size_t{i_mutselect},
|
||||
size_t{i_mut},
|
||||
size_t{i_rep},
|
||||
size_t{i_cont},
|
||||
size_t{pop_size} // offspring_size
|
||||
});
|
||||
|
||||
// Actually perform a search
|
||||
|
|
|
|||
|
|
@ -99,7 +99,18 @@ int main(int /*argc*/, char** /*argv*/)
|
|||
pop.append(5,init);
|
||||
::apply(onemax_eval,pop);
|
||||
|
||||
foundry.select({0,0,0,0,0,0/*,0,0*/});
|
||||
foundry.select({
|
||||
/*crossover_rates */ double{0.8},
|
||||
/*crossover_selectors */ size_t{0},
|
||||
/*crossovers */ size_t{0},
|
||||
/*aftercross_selectors*/ size_t{0},
|
||||
/*mutation_rates */ double{0.9},
|
||||
/*mutation_selectors */ size_t{0},
|
||||
/*mutations */ size_t{0},
|
||||
/*replacements */ size_t{0},
|
||||
/*continuators */ size_t{0},
|
||||
/*offspring_sizes */ size_t{1},
|
||||
});
|
||||
foundry(pop);
|
||||
|
||||
std::cout << "Done" << std::endl;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue