feat: adds a FastGA algo, update the Foundry
This commit is contained in:
parent
367a8c8ab1
commit
40c80eda45
7 changed files with 467 additions and 70 deletions
|
|
@ -146,6 +146,7 @@
|
||||||
// Algorithms
|
// Algorithms
|
||||||
#include "eoEasyEA.h"
|
#include "eoEasyEA.h"
|
||||||
#include "eoSGA.h"
|
#include "eoSGA.h"
|
||||||
|
#include "eoFastGA.h"
|
||||||
// #include "eoEvolutionStrategy.h" removed for a while - until eoGenOp is done
|
// #include "eoEvolutionStrategy.h" removed for a while - until eoGenOp is done
|
||||||
#include "eoAlgoReset.h"
|
#include "eoAlgoReset.h"
|
||||||
#include "eoAlgoRestart.h"
|
#include "eoAlgoRestart.h"
|
||||||
|
|
|
||||||
|
|
@ -27,30 +27,30 @@
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
/** A class that assemble an eoEasyEA on the fly, given a combination of available operators.
|
/** 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
|
||||||
* for the main modules of an EA:
|
* for the main modules of a FastGA:
|
||||||
* continuators, crossovers, mutations, selection and replacement operators.
|
* continuators, crossovers, mutations, selections, replacement operators, etc.
|
||||||
*
|
*
|
||||||
* This is done through public member variable's `add` method,
|
* This is done through public member variable's `add` method,
|
||||||
* which takes the class name as template and its constructor's parameters
|
* which takes the class name as template and its constructor's parameters
|
||||||
* as arguments. For example:
|
* as arguments. For example:
|
||||||
* @code
|
* @code
|
||||||
* foundry.selectors.add< eoStochTournamentSelect<EOT> >( 0.5 );
|
* foundry.selectors.add< eoRandomSelect<EOT> >();
|
||||||
* @endcode
|
* @endcode
|
||||||
*
|
*
|
||||||
* @warning If the constructor takes a reference YOU SHOULD ABSOLUTELY wrap it
|
* @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,
|
* in a `std::ref`, or it will silently be passed as a copy,
|
||||||
* which would effectively disable any link between operators.
|
* which would effectively disable any link with other operator(s).
|
||||||
*
|
*
|
||||||
* In a second step, the operators to be used should be selected
|
* In a second step, the operators to be used should be selected
|
||||||
* by indicating their index, passing an array of eight elements:
|
* by indicating their index, passing an array of 10 elements:
|
||||||
* @code
|
* @code
|
||||||
* foundry.select({0, 1, 2, 3, 4, 5, 6, 7});
|
* foundry.select({0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
|
||||||
* @endcode
|
* @endcode
|
||||||
*
|
*
|
||||||
* @note: by default, the firsts of the eight operators are selected.
|
* @note: by default, the firsts of the 10 operators are selected.
|
||||||
*
|
*
|
||||||
* If you don't (want to) recall the order of the operators in the encoding,
|
* If you don't (want to) recall the order of the operators in the encoding,
|
||||||
* you can use the `index()` member, for example:
|
* you can use the `index()` member, for example:
|
||||||
|
|
@ -58,7 +58,7 @@
|
||||||
* foundry.at(foundry.continuators.index()) = 2; // select the third continuator
|
* foundry.at(foundry.continuators.index()) = 2; // select the third continuator
|
||||||
* @endcode
|
* @endcode
|
||||||
*
|
*
|
||||||
* Now, you can call the fourdry just like any eoAlgo, by passing it an eoPop:
|
* Now, you can call the foundry just like any eoAlgo, by passing it an eoPop:
|
||||||
* @code
|
* @code
|
||||||
* foundry(pop);
|
* foundry(pop);
|
||||||
* @encode
|
* @encode
|
||||||
|
|
@ -69,7 +69,7 @@
|
||||||
* Every instantiation is deferred upon actual use. That way, you can still reconfigure them
|
* Every instantiation is deferred upon actual use. That way, you can still reconfigure them
|
||||||
* at any time with `eoForgeOperator::setup`, for example:
|
* at any time with `eoForgeOperator::setup`, for example:
|
||||||
* @code
|
* @code
|
||||||
* foundry.selector.at(0).setup(0.5); // using constructor's arguments
|
* foundry.selector.at(0).setup(0.5); // Will call constructor's arguments
|
||||||
* @endcode
|
* @endcode
|
||||||
*
|
*
|
||||||
* @ingroup Foundry
|
* @ingroup Foundry
|
||||||
|
|
@ -88,15 +88,20 @@ class eoAlgoFoundryFastGA : public eoAlgoFoundry<EOT>
|
||||||
size_t max_evals = 10000,
|
size_t max_evals = 10000,
|
||||||
size_t max_restarts = std::numeric_limits<size_t>::max()
|
size_t max_restarts = std::numeric_limits<size_t>::max()
|
||||||
) :
|
) :
|
||||||
eoAlgoFoundry<EOT>(8),
|
eoAlgoFoundry<EOT>(10),
|
||||||
continuators(0, true), // Always re-instantiate continuators, because they hold a state.
|
|
||||||
crossover_rates(1, false),
|
crossover_rates(0, false),
|
||||||
|
crossover_selectors(1, false),
|
||||||
crossovers(2, false),
|
crossovers(2, false),
|
||||||
mutation_rates(3, false),
|
aftercross_selectors(3, false),
|
||||||
mutations(4, false),
|
|
||||||
selectors(5, false),
|
mutation_rates(4, false),
|
||||||
pop_sizes(6, false),
|
mutation_selectors(5, false),
|
||||||
|
mutations(6, false),
|
||||||
|
|
||||||
replacements(7, false),
|
replacements(7, false),
|
||||||
|
continuators(8, true), // Always re-instantiate continuators, because they hold a state.
|
||||||
|
pop_sizes(9, false),
|
||||||
_eval(eval),
|
_eval(eval),
|
||||||
_init(init),
|
_init(init),
|
||||||
_max_evals(max_evals),
|
_max_evals(max_evals),
|
||||||
|
|
@ -106,62 +111,53 @@ class eoAlgoFoundryFastGA : public eoAlgoFoundry<EOT>
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* Operators containers @{ */
|
/* Operators containers @{ */
|
||||||
eoOperatorFoundry< eoContinue<EOT> > continuators;
|
|
||||||
eoOperatorFoundry< double > crossover_rates;
|
eoOperatorFoundry< double > crossover_rates;
|
||||||
|
eoOperatorFoundry< eoSelectOne<EOT> > crossover_selectors;
|
||||||
eoOperatorFoundry< eoQuadOp<EOT> > crossovers;
|
eoOperatorFoundry< eoQuadOp<EOT> > crossovers;
|
||||||
|
eoOperatorFoundry< eoSelectOne<EOT> > aftercross_selectors;
|
||||||
|
|
||||||
eoOperatorFoundry< double > mutation_rates;
|
eoOperatorFoundry< double > mutation_rates;
|
||||||
|
eoOperatorFoundry< eoSelectOne<EOT> > mutation_selectors;
|
||||||
eoOperatorFoundry< eoMonOp<EOT> > mutations;
|
eoOperatorFoundry< eoMonOp<EOT> > mutations;
|
||||||
eoOperatorFoundry< eoSelectOne<EOT> > selectors;
|
|
||||||
eoOperatorFoundry< size_t > pop_sizes;
|
|
||||||
eoOperatorFoundry< eoReplacement<EOT> > replacements;
|
eoOperatorFoundry< eoReplacement<EOT> > replacements;
|
||||||
|
eoOperatorFoundry< eoContinue<EOT> > continuators;
|
||||||
|
eoOperatorFoundry< size_t > pop_sizes;
|
||||||
/* @} */
|
/* @} */
|
||||||
|
|
||||||
/** instantiate and call the pre-selected algorithm.
|
/** instantiate and call the pre-selected algorithm.
|
||||||
*/
|
*/
|
||||||
void operator()(eoPop<EOT>& pop)
|
void operator()(eoPop<EOT>& pop)
|
||||||
{
|
{
|
||||||
assert( continuators.size() > 0); assert(this->at( continuators.index()) < continuators.size());
|
assert( crossover_rates.size() > 0); assert(this->at( crossover_rates.index()) < crossover_rates.size());
|
||||||
assert(crossover_rates.size() > 0); assert(this->at(crossover_rates.index()) < crossover_rates.size());
|
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( crossovers.size() > 0); assert(this->at( crossovers.index()) < crossovers.size());
|
||||||
assert( mutation_rates.size() > 0); assert(this->at( mutation_rates.index()) < mutation_rates.size());
|
assert(aftercross_selectors.size() > 0); assert(this->at(aftercross_selectors.index()) < aftercross_selectors.size());
|
||||||
assert( mutations.size() > 0); assert(this->at( mutations.index()) < mutations.size());
|
assert( mutation_rates.size() > 0); assert(this->at( mutation_rates.index()) < mutation_rates.size());
|
||||||
assert( selectors.size() > 0); assert(this->at( selectors.index()) < selectors.size());
|
assert( mutation_selectors.size() > 0); assert(this->at( mutation_selectors.index()) < mutation_selectors.size());
|
||||||
assert( pop_sizes.size() > 0); assert(this->at( pop_sizes.index()) < pop_sizes.size());
|
assert( mutations.size() > 0); assert(this->at( mutations.index()) < mutations.size());
|
||||||
assert( replacements.size() > 0); assert(this->at( replacements.index()) < replacements.size());
|
assert( replacements.size() > 0); assert(this->at( replacements.index()) < replacements.size());
|
||||||
|
assert( continuators.size() > 0); assert(this->at( continuators.index()) < continuators.size());
|
||||||
// Crossover or clone
|
assert( pop_sizes.size() > 0); assert(this->at( pop_sizes.index()) < pop_sizes.size());
|
||||||
double cross_rate = this->crossover_rate();
|
|
||||||
eoProportionalOp<EOT> cross;
|
|
||||||
// Cross-over that produce only one offspring,
|
|
||||||
// made by wrapping the quad op (which produce 2 offsprings)
|
|
||||||
// in a bin op (which ignore the second offspring).
|
|
||||||
eoQuad2BinOp<EOT> single_cross(this->crossover());
|
|
||||||
cross.add(single_cross, cross_rate);
|
|
||||||
eoBinCloneOp<EOT> cross_clone;
|
|
||||||
cross.add(cross_clone, 1 - cross_rate); // Clone
|
|
||||||
|
|
||||||
// Mutation or clone
|
|
||||||
double mut_rate = this->mutation_rate();
|
|
||||||
eoProportionalOp<EOT> mut;
|
|
||||||
mut.add(this->mutation(), mut_rate);
|
|
||||||
eoMonCloneOp<EOT> mut_clone;
|
|
||||||
mut.add(mut_clone, 1 - mut_rate); // FIXME TBC
|
|
||||||
|
|
||||||
// Apply mutation after cross-over.
|
|
||||||
eoSequentialOp<EOT> variator;
|
|
||||||
variator.add(cross,1.0);
|
|
||||||
variator.add(mut,1.0);
|
|
||||||
|
|
||||||
// All variatiors
|
|
||||||
double lambda = this->pop_size();
|
|
||||||
eoGeneralBreeder<EOT> breeder(this->selector(), variator, lambda, /*as rate*/false);
|
|
||||||
|
|
||||||
// Objective function calls counter
|
// Objective function calls counter
|
||||||
eoEvalCounterThrowException<EOT> eval(_eval, _max_evals);
|
eoEvalCounterThrowException<EOT> eval(_eval, _max_evals);
|
||||||
eoPopLoopEval<EOT> pop_eval(eval);
|
eoPopLoopEval<EOT> pop_eval(eval);
|
||||||
|
|
||||||
// Algorithm itself
|
// Algorithm itself
|
||||||
eoEasyEA<EOT> algo = eoEasyEA<EOT>(this->continuator(), pop_eval, breeder, this->replacement());
|
eoFastGA<EOT> algo(
|
||||||
|
this->crossover_rate(),
|
||||||
|
this->crossover_selector(),
|
||||||
|
this->crossover(),
|
||||||
|
this->aftercross_selector(),
|
||||||
|
this->mutation_rate(),
|
||||||
|
this->mutation_selector(),
|
||||||
|
this->mutation(),
|
||||||
|
pop_eval,
|
||||||
|
this->replacement(),
|
||||||
|
this->continuator(),
|
||||||
|
this->pop_size()
|
||||||
|
);
|
||||||
|
|
||||||
// Restart wrapper
|
// Restart wrapper
|
||||||
eoAlgoPopReset<EOT> reset_pop(_init, pop_eval);
|
eoAlgoPopReset<EOT> reset_pop(_init, pop_eval);
|
||||||
|
|
@ -172,27 +168,27 @@ class eoAlgoFoundryFastGA : public eoAlgoFoundry<EOT>
|
||||||
restart(pop);
|
restart(pop);
|
||||||
} catch(eoMaxEvalException e) {
|
} catch(eoMaxEvalException e) {
|
||||||
// In case some solutions were not evaluated when max eval occured.
|
// In case some solutions were not evaluated when max eval occured.
|
||||||
|
// FIXME can this even be considered legal?
|
||||||
eoPopLoopEval<EOT> pop_last_eval(_eval);
|
eoPopLoopEval<EOT> pop_last_eval(_eval);
|
||||||
pop_last_eval(pop,pop);
|
pop_last_eval(pop,pop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return an approximate name of the selected algorithm.
|
/** Return an approximate name of the selected algorithm.
|
||||||
*
|
|
||||||
* @note: does not take into account parameters of the operators,
|
|
||||||
* only show class names.
|
|
||||||
*/
|
*/
|
||||||
std::string name()
|
std::string name()
|
||||||
{
|
{
|
||||||
std::ostringstream name;
|
std::ostringstream name;
|
||||||
name << this->at( continuators.index()) << " (" << this-> continuator().className() << ") + ";
|
name << this->at( crossover_rates.index()) << " (" << this-> crossover_rate() << ") + ";
|
||||||
name << this->at(crossover_rates.index()) << " (" << this->crossover_rate() << ") + ";
|
name << this->at( crossover_selectors.index()) << " (" << this-> crossover_selector().className() << ") + ";
|
||||||
name << this->at( crossovers.index()) << " (" << this-> crossover().className() << ") + ";
|
name << this->at(aftercross_selectors.index()) << " (" << this->aftercross_selector().className() << ") + ";
|
||||||
name << this->at( mutation_rates.index()) << " (" << this-> mutation_rate() << ") + ";
|
name << this->at( crossovers.index()) << " (" << this-> crossover().className() << ") + ";
|
||||||
name << this->at( mutations.index()) << " (" << this-> mutation().className() << ") + ";
|
name << this->at( mutation_rates.index()) << " (" << this-> mutation_rate() << ") + ";
|
||||||
name << this->at( selectors.index()) << " (" << this-> selector().className() << ") + ";
|
name << this->at( mutation_selectors.index()) << " (" << this-> mutation_selector().className() << ") + ";
|
||||||
name << this->at( pop_sizes.index()) << " (" << this-> pop_size() << ")";
|
name << this->at( mutations.index()) << " (" << this-> mutation().className() << ") + ";
|
||||||
name << this->at( replacements.index()) << " (" << this-> replacement().className() << ")";
|
name << this->at( replacements.index()) << " (" << this-> replacement().className() << ") + ";
|
||||||
|
name << this->at( continuators.index()) << " (" << this-> continuator().className() << ") + ";
|
||||||
|
name << this->at( pop_sizes.index()) << " (" << this-> pop_size() << ")";
|
||||||
return name.str();
|
return name.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -233,10 +229,22 @@ class eoAlgoFoundryFastGA : public eoAlgoFoundry<EOT>
|
||||||
return mutations.instantiate(this->at(mutations.index()));
|
return mutations.instantiate(this->at(mutations.index()));
|
||||||
}
|
}
|
||||||
|
|
||||||
eoSelectOne<EOT>& selector()
|
eoSelectOne<EOT>& crossover_selector()
|
||||||
{
|
{
|
||||||
assert(this->at(selectors.index()) < selectors.size());
|
assert(this->at(crossover_selectors.index()) < crossover_selectors.size());
|
||||||
return selectors.instantiate(this->at(selectors.index()));
|
return crossover_selectors.instantiate(this->at(crossover_selectors.index()));
|
||||||
|
}
|
||||||
|
|
||||||
|
eoSelectOne<EOT>& aftercross_selector()
|
||||||
|
{
|
||||||
|
assert(this->at(aftercross_selectors.index()) < aftercross_selectors.size());
|
||||||
|
return aftercross_selectors.instantiate(this->at(aftercross_selectors.index()));
|
||||||
|
}
|
||||||
|
|
||||||
|
eoSelectOne<EOT>& mutation_selector()
|
||||||
|
{
|
||||||
|
assert(this->at(mutation_selectors.index()) < mutation_selectors.size());
|
||||||
|
return mutation_selectors.instantiate(this->at(mutation_selectors.index()));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t& pop_size()
|
size_t& pop_size()
|
||||||
|
|
|
||||||
150
eo/src/eoFastGA.h
Normal file
150
eo/src/eoFastGA.h
Normal file
|
|
@ -0,0 +1,150 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _eoFastGA_H_
|
||||||
|
#define _eoFastGA_H_
|
||||||
|
|
||||||
|
/** The Fast Genetic Algorithm.
|
||||||
|
*
|
||||||
|
* @ingroup Algorithms
|
||||||
|
*/
|
||||||
|
template<class EOT>
|
||||||
|
class eoFastGA : public eoAlgo<EOT>
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
double _rate_crossover;
|
||||||
|
eoSelectOne<EOT>& _select_cross;
|
||||||
|
eoQuadOp<EOT>& _crossover;
|
||||||
|
eoSelectOne<EOT>& _select_aftercross;
|
||||||
|
|
||||||
|
double _rate_mutation;
|
||||||
|
eoSelectOne<EOT>& _select_mut;
|
||||||
|
eoMonOp<EOT>& _mutation;
|
||||||
|
|
||||||
|
eoPopEvalFunc<EOT>& _pop_eval;
|
||||||
|
eoReplacement<EOT>& _replace;
|
||||||
|
|
||||||
|
eoContinue<EOT>& _continuator;
|
||||||
|
|
||||||
|
double _offsprings_size;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
eoFastGA(
|
||||||
|
double rate_crossover,
|
||||||
|
eoSelectOne<EOT>& select_cross,
|
||||||
|
eoQuadOp<EOT>& crossover,
|
||||||
|
eoSelectOne<EOT>& select_aftercross,
|
||||||
|
double rate_mutation,
|
||||||
|
eoSelectOne<EOT>& select_mut,
|
||||||
|
eoMonOp<EOT>& mutation,
|
||||||
|
eoPopEvalFunc<EOT>& pop_eval,
|
||||||
|
eoReplacement<EOT>& replace,
|
||||||
|
eoContinue<EOT>& continuator,
|
||||||
|
double offsprings_size = 0
|
||||||
|
) :
|
||||||
|
_rate_crossover(rate_crossover),
|
||||||
|
_select_cross(select_cross),
|
||||||
|
_crossover(crossover),
|
||||||
|
_select_aftercross(select_aftercross),
|
||||||
|
_rate_mutation(rate_mutation),
|
||||||
|
_select_mut(select_mut),
|
||||||
|
_mutation(mutation),
|
||||||
|
_pop_eval(pop_eval),
|
||||||
|
_replace(replace),
|
||||||
|
_continuator(continuator),
|
||||||
|
_offsprings_size(offsprings_size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(eoPop<EOT>& pop)
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
assert(pop.size() > 0);
|
||||||
|
for(auto sol : pop) {
|
||||||
|
assert(not sol.invalid());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// Set lambda to the pop size
|
||||||
|
// if it was not set up at construction.
|
||||||
|
if(_offsprings_size == 0) {
|
||||||
|
_offsprings_size = pop.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
eoPop<EOT> offsprings;
|
||||||
|
|
||||||
|
for(size_t i=0; i < _offsprings_size; ++i) {
|
||||||
|
|
||||||
|
if(eo::rng.flip(_rate_crossover)) {
|
||||||
|
// Manual setup of eoSelectOne
|
||||||
|
// (usually they are setup in a
|
||||||
|
// wrapping eoSelect).
|
||||||
|
_select_cross.setup(pop);
|
||||||
|
|
||||||
|
// Copy of const ref solutions,
|
||||||
|
// because one alter them hereafter.
|
||||||
|
EOT sol1 = _select_cross(pop);
|
||||||
|
EOT sol2 = _select_cross(pop);
|
||||||
|
|
||||||
|
// If the operator returns true,
|
||||||
|
// olutions have been altered.
|
||||||
|
if(_crossover(sol1, sol2)) {
|
||||||
|
sol1.invalidate();
|
||||||
|
sol2.invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select one of the two solutions
|
||||||
|
// which have been crossed.
|
||||||
|
eoPop<EOT> crossed;
|
||||||
|
crossed.push_back(sol1);
|
||||||
|
crossed.push_back(sol2);
|
||||||
|
_select_aftercross.setup(crossed);
|
||||||
|
EOT sol3 = _select_aftercross(crossed);
|
||||||
|
|
||||||
|
// Additional mutation (X)OR the crossed/cloned solution.
|
||||||
|
if(eo::rng.flip(_rate_mutation)) {
|
||||||
|
if(_mutation(sol3)) {
|
||||||
|
sol3.invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offsprings.push_back(sol3);
|
||||||
|
|
||||||
|
} else { // If not crossing, always mutate.
|
||||||
|
_select_mut.setup(pop);
|
||||||
|
EOT sol3 = _select_mut(pop);
|
||||||
|
_mutation(sol3);
|
||||||
|
offsprings.push_back(sol3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(offsprings.size() == _offsprings_size);
|
||||||
|
|
||||||
|
_pop_eval(pop, offsprings);
|
||||||
|
_replace(pop, offsprings);
|
||||||
|
|
||||||
|
} while(_continuator(pop));
|
||||||
|
#ifndef NDEBUG
|
||||||
|
assert(pop.size() > 0);
|
||||||
|
for(auto sol : pop) {
|
||||||
|
assert(not sol.invalid());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _eoFastGA_H_
|
||||||
|
|
@ -76,8 +76,10 @@ set (TEST_LIST
|
||||||
t-algo-forged
|
t-algo-forged
|
||||||
t-algo-forged-search
|
t-algo-forged-search
|
||||||
t-FastGA
|
t-FastGA
|
||||||
|
t-eoFastGA
|
||||||
t-forge-FastGA
|
t-forge-FastGA
|
||||||
t-eoFoundryFastGA
|
t-eoFoundryFastGA
|
||||||
|
t-eoAlgoFoundryFastGA
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,20 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
|
||||||
147
eo/test/t-eoAlgoFoundryFastGA.cpp
Normal file
147
eo/test/t-eoAlgoFoundryFastGA.cpp
Normal file
|
|
@ -0,0 +1,147 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <eo>
|
||||||
|
#include <ga.h>
|
||||||
|
#include "../../problems/eval/oneMaxEval.h"
|
||||||
|
|
||||||
|
|
||||||
|
int main(int /*argc*/, char** /*argv*/)
|
||||||
|
{
|
||||||
|
size_t dim = 500;
|
||||||
|
size_t pop_size = 10;
|
||||||
|
|
||||||
|
eo::log << eo::setlevel(eo::warnings);
|
||||||
|
|
||||||
|
using EOT = eoBit<double>;
|
||||||
|
|
||||||
|
oneMaxEval<EOT> eval;
|
||||||
|
|
||||||
|
eoBooleanGenerator gen(0.5);
|
||||||
|
eoInitFixedLength<EOT> init(dim, gen);
|
||||||
|
|
||||||
|
eoAlgoFoundryFastGA<EOT> foundry(init, eval, pop_size*10);
|
||||||
|
|
||||||
|
/***** Variation rates *****/
|
||||||
|
for(double r = 0.0; r < 1.0; r+=0.1) {
|
||||||
|
foundry.crossover_rates.add<double>(r);
|
||||||
|
foundry. mutation_rates.add<double>(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Crossovers ****/
|
||||||
|
foundry.crossovers.add< eo1PtBitXover<EOT> >();
|
||||||
|
foundry.crossovers.add< eoUBitXover<EOT> >(0.5); // preference over 1
|
||||||
|
for(size_t i=1; i < 11; i+=4) {
|
||||||
|
foundry.crossovers.add< eoNPtsBitXover<EOT> >(i); // nb of points
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Mutations ****/
|
||||||
|
foundry.mutations.add< eoBitMutation<EOT> >(0.01); // proba of flipping one bit
|
||||||
|
for(size_t i=1; i < 11; i+=4) {
|
||||||
|
foundry.mutations.add< eoDetBitFlip<EOT> >(i); // mutate k bits
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Selectors *****/
|
||||||
|
for(eoOperatorFoundry<eoSelectOne<EOT>>& ops :
|
||||||
|
{std::ref(foundry.crossover_selectors),
|
||||||
|
std::ref(foundry.aftercross_selectors),
|
||||||
|
std::ref(foundry.mutation_selectors) }) {
|
||||||
|
|
||||||
|
ops.add< eoRandomSelect<EOT> >();
|
||||||
|
ops.add< eoStochTournamentSelect<EOT> >(0.5);
|
||||||
|
ops.add< eoSequentialSelect<EOT> >();
|
||||||
|
ops.add< eoProportionalSelect<EOT> >();
|
||||||
|
for(size_t i=2; i < 10; i+=4) {
|
||||||
|
ops.add< eoDetTournamentSelect<EOT> >(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Replacements ****/
|
||||||
|
foundry.replacements.add< eoCommaReplacement<EOT> >();
|
||||||
|
foundry.replacements.add< eoPlusReplacement<EOT> >();
|
||||||
|
foundry.replacements.add< eoSSGAWorseReplacement<EOT> >();
|
||||||
|
foundry.replacements.add< eoSSGAStochTournamentReplacement<EOT> >(0.51);
|
||||||
|
for(size_t i=2; i < 10; i+=4) {
|
||||||
|
foundry.replacements.add< eoSSGADetTournamentReplacement<EOT> >(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Continuators ****/
|
||||||
|
for(size_t i=10; i < 30; i+=10 ) {
|
||||||
|
foundry.continuators.add< eoSteadyFitContinue<EOT> >(10,i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Offspring population size *****/
|
||||||
|
foundry.pop_sizes.add<size_t>(0); // 0 = same as parent pop
|
||||||
|
// for(size_t s = pop_size; s < 2*pop_size; s+=pop_size/10) {
|
||||||
|
// foundry.pop_sizes.add<size_t>(s);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
size_t n =
|
||||||
|
foundry.crossover_rates.size()
|
||||||
|
* foundry.crossover_selectors.size()
|
||||||
|
* foundry.crossovers.size()
|
||||||
|
* foundry.aftercross_selectors.size()
|
||||||
|
* foundry.mutation_rates.size()
|
||||||
|
* foundry.mutation_selectors.size()
|
||||||
|
* foundry.mutations.size()
|
||||||
|
* foundry.replacements.size()
|
||||||
|
* foundry.continuators.size()
|
||||||
|
* foundry.pop_sizes.size();
|
||||||
|
std::clog << n << " possible algorithms instances." << std::endl;
|
||||||
|
|
||||||
|
EOT best_sol;
|
||||||
|
std::string best_algo = "";
|
||||||
|
|
||||||
|
size_t i=0;
|
||||||
|
for(size_t i_crossrate = 0; i_crossrate < foundry.crossover_rates.size(); ++i_crossrate ) {
|
||||||
|
for(size_t i_crossselect = 0; i_crossselect < foundry.crossover_selectors.size(); ++i_crossselect ) {
|
||||||
|
for(size_t i_cross = 0; i_cross < foundry.crossovers.size(); ++i_cross ) {
|
||||||
|
for(size_t i_aftercrosel = 0; i_aftercrosel < foundry.aftercross_selectors.size(); ++i_aftercrosel ) {
|
||||||
|
for(size_t i_mutrate = 0; i_mutrate < foundry.mutation_rates.size(); ++i_mutrate ) {
|
||||||
|
for(size_t i_mutselect = 0; i_mutselect < foundry.mutation_selectors.size(); ++i_mutselect ) {
|
||||||
|
for(size_t i_mut = 0; i_mut < foundry.mutations.size(); ++i_mut ) {
|
||||||
|
for(size_t i_rep = 0; i_rep < foundry.replacements.size(); ++i_rep ) {
|
||||||
|
for(size_t i_cont = 0; i_cont < foundry.continuators.size(); ++i_cont ) {
|
||||||
|
for(size_t i_pop = 0; i_pop < foundry.pop_sizes.size(); ++i_pop ) {
|
||||||
|
std::clog << "\r" << i++ << "/" << n-1; std::clog.flush();
|
||||||
|
|
||||||
|
eoPop<EOT> pop;
|
||||||
|
pop.append(pop_size, init);
|
||||||
|
|
||||||
|
foundry.select({
|
||||||
|
i_crossrate,
|
||||||
|
i_crossselect,
|
||||||
|
i_cross,
|
||||||
|
i_aftercrosel,
|
||||||
|
i_mutrate,
|
||||||
|
i_mutselect,
|
||||||
|
i_mut,
|
||||||
|
i_rep,
|
||||||
|
i_cont,
|
||||||
|
i_pop
|
||||||
|
});
|
||||||
|
|
||||||
|
// Actually perform a search
|
||||||
|
foundry(pop);
|
||||||
|
|
||||||
|
if(best_sol.invalid()) {
|
||||||
|
best_sol = pop.best_element();
|
||||||
|
best_algo = foundry.name();
|
||||||
|
} else if(pop.best_element().fitness() > best_sol.fitness()) {
|
||||||
|
best_sol = pop.best_element();
|
||||||
|
best_algo = foundry.name();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << std::endl << "Best algo: " << best_algo << ", with " << best_sol << std::endl;
|
||||||
|
|
||||||
|
}
|
||||||
72
eo/test/t-eoFastGA.cpp
Normal file
72
eo/test/t-eoFastGA.cpp
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <eo>
|
||||||
|
#include <ga.h>
|
||||||
|
#include "../../problems/eval/oneMaxEval.h"
|
||||||
|
|
||||||
|
using EOT = eoBit<double>;
|
||||||
|
|
||||||
|
int main(int /*argc*/, char** /*argv*/)
|
||||||
|
{
|
||||||
|
size_t dim = 100;
|
||||||
|
size_t pop_size = 10;
|
||||||
|
|
||||||
|
oneMaxEval<EOT> evalfunc;
|
||||||
|
eoPopLoopEval<EOT> eval(evalfunc);
|
||||||
|
|
||||||
|
eoBooleanGenerator gen(0.5);
|
||||||
|
eoInitFixedLength<EOT> init(dim, gen);
|
||||||
|
|
||||||
|
double cross_rate = 0.5;
|
||||||
|
eoSequentialSelect<EOT> select_cross;
|
||||||
|
eoUBitXover<EOT> crossover;
|
||||||
|
eoRandomSelect<EOT> select_aftercross;
|
||||||
|
|
||||||
|
double mut_rate = 0.5;
|
||||||
|
eoSequentialSelect<EOT> select_mut;
|
||||||
|
eoStandardBitMutation<EOT> mutation(0.5);
|
||||||
|
|
||||||
|
eoPlusReplacement<EOT> replacement;
|
||||||
|
|
||||||
|
eoGenContinue<EOT> common_cont(dim*2);
|
||||||
|
eoCombinedContinue<EOT> gen_cont(common_cont);
|
||||||
|
|
||||||
|
eoFastGA<EOT> algo(
|
||||||
|
cross_rate,
|
||||||
|
select_cross,
|
||||||
|
crossover,
|
||||||
|
select_aftercross,
|
||||||
|
mut_rate,
|
||||||
|
select_mut,
|
||||||
|
mutation,
|
||||||
|
eval,
|
||||||
|
replacement,
|
||||||
|
common_cont
|
||||||
|
);
|
||||||
|
|
||||||
|
eoPop<EOT> pop;
|
||||||
|
pop.append(pop_size, init);
|
||||||
|
eval(pop,pop);
|
||||||
|
|
||||||
|
algo(pop);
|
||||||
|
|
||||||
|
std::cout << pop.best_element() << std::endl;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue