150 lines
4.4 KiB
C++
150 lines
4.4 KiB
C++
|
|
/*
|
|
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,
|
|
// solutions 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_
|