Well, what do you know, major commit.

Changed the signature of eoMon, eoBin and eoQuadOp to return a bool,
without invalidating fitness. Added a set of invalidators to take over
that job (see for instance eoSGA and eoSGATransform how this can transparantly used)

Derived eoState from eoFunctorStore (for convenience, from a design perspective this may sound wrong)

Added a wrap_op function that does the wrapping for you (see eoOpContainer how this made this functor
exceedingly less hairy). Checked all the tests removed the eoGeneric*Op family (not needed anymore)
and of course changed all the operators to reflect the change (and found a few that didn't
invalidate the fitness, thus really pointing out the advantage of the current approach)
This commit is contained in:
maartenkeijzer 2001-02-14 10:35:26 +00:00
commit 3a9b5a0e7e
30 changed files with 651 additions and 564 deletions

View file

@ -10,11 +10,10 @@ DEPS = $(top_builddir)/src/libeo.a $(top_builddir)/src/utils/libeoutils.a
INCLUDES = -I$(top_builddir)/src INCLUDES = -I$(top_builddir)/src
LDADDS = $(top_builddir)/src/libeo.a $(top_builddir)/src/utils/libeoutils.a LDADDS = $(top_builddir)/src/libeo.a $(top_builddir)/src/utils/libeoutils.a
CXXFLAGS = -g
############################################################################### ###############################################################################
bin_PROGRAMS = gprop bin_PROGRAMS = gprop
############################################################################### ###############################################################################
gprop_SOURCES = gprop.cc gprop_SOURCES = gprop.cc

View file

@ -109,11 +109,11 @@ mlp::set trn_set, val_set, tst_set;
class eoChromMutation: public eoMonOp<Chrom> class eoChromMutation: public eoMonOp<Chrom>
{ {
public: public:
void operator()(Chrom& chrom) bool operator()(Chrom& chrom)
{ {
mse::net tmp(chrom); mse::net tmp(chrom);
tmp.train(trn_set, 10, 0, 0.001); tmp.train(trn_set, 10, 0, 0.001);
chrom.invalidate(); return true;
} }
}; };
@ -124,7 +124,7 @@ public:
class eoChromXover: public eoQuadOp<Chrom> class eoChromXover: public eoQuadOp<Chrom>
{ {
public: public:
void operator()(Chrom& chrom1, Chrom& chrom2) bool operator()(Chrom& chrom1, Chrom& chrom2)
{ {
chrom1.normalize(); chrom1.normalize();
chrom2.desaturate(); chrom2.desaturate();
@ -132,8 +132,8 @@ public:
mse::net tmp1(chrom1), tmp2(chrom2); mse::net tmp1(chrom1), tmp2(chrom2);
tmp1.train(trn_set, 100, 0, 0.001); tmp1.train(trn_set, 100, 0, 0.001);
tmp2.train(trn_set, 100, 0, 0.001); tmp2.train(trn_set, 100, 0, 0.001);
chrom1.invalidate();
chrom2.invalidate(); return true;
} }
}; };

View file

@ -116,7 +116,7 @@ void init_eoChromEvaluator(const unsigned& c, const unsigned& l, string s)
uniform_generator<int> color(0, num_colors); uniform_generator<int> color(0, num_colors);
generate(solution.begin(), solution.end(), color); generate(solution.begin(), solution.end(), color);
} }
solution.fitness(eoChromEvaluator(solution)); solution.fitness(eoChromEvaluator(solution));
} }
@ -143,14 +143,14 @@ public:
class eoChromMutation: public eoMonOp<Chrom> class eoChromMutation: public eoMonOp<Chrom>
{ {
// many operators in one :( // many operators in one :(
void operator()(Chrom& chrom) bool operator()(Chrom& chrom)
{ {
uniform_generator<unsigned> what(0, 2); uniform_generator<unsigned> what(0, 2);
uniform_generator<unsigned> position(0, chrom.size()); uniform_generator<unsigned> position(0, chrom.size());
switch(what()) switch(what())
{ {
case 0: case 0:
{ {
// mutation // mutation
uniform_generator<int> color(0, num_colors); uniform_generator<int> color(0, num_colors);
@ -171,7 +171,7 @@ class eoChromMutation: public eoMonOp<Chrom>
} }
} }
chrom.invalidate(); return true;
} }
}; };
@ -182,12 +182,11 @@ class eoChromMutation: public eoMonOp<Chrom>
class eoChromXover: public eoQuadOp<Chrom> class eoChromXover: public eoQuadOp<Chrom>
{ {
public: public:
void operator()(Chrom& chrom1, Chrom& chrom2) bool operator()(Chrom& chrom1, Chrom& chrom2)
{ {
uniform_generator<unsigned> position(0, chrom1.size()); uniform_generator<unsigned> position(0, chrom1.size());
swap_ranges(chrom1.begin(), chrom1.begin() + position(), chrom2.begin()); swap_ranges(chrom1.begin(), chrom1.begin() + position(), chrom2.begin());
chrom1.invalidate(); return true;
chrom2.invalidate();
} }
}; };
@ -195,6 +194,6 @@ public:
#endif // mastermind_h #endif // mastermind_h
// Local Variables: // Local Variables:
// mode:C++ // mode:C++
// End: // End:

View file

@ -8,7 +8,7 @@ SUBDIRS = es ga gp utils other
CPPFLAGS = -O2 CPPFLAGS = -O2
lib_LIBRARIES = libeo.a lib_LIBRARIES = libeo.a
libeo_a_SOURCES = eoPrintable.cpp eoPersistent.cpp eoFunctorStore.cpp libeo_a_SOURCES = eoPrintable.cpp eoPersistent.cpp eoFunctorStore.cpp
libeoincdir = $(includedir)/eo libeoincdir = $(includedir)/eo
libeoinc_HEADERS = eo EO.h apply.h eoAlgo.h eoBreed.h eoCombinedContinue.h eoContinue.h eoCounter.h eoDetSelect.h eoDetTournamentSelect.h eoEasyEA.h eoEvalFunc.h eoEvalFuncPtr.h eoFactory.h eoFitContinue.h eoFitnessScalingSelect.h eoFixedLength.h eoFunctor.h eoFunctorStore.h eoGenContinue.h eoGenericBinOp.h eoGenericMonOp.h eoGenericQuadOp.h eoInit.h eoMerge.h eoMergeReduce.h eoObject.h eoOp.h eoOpSelMason.h eoPersistent.h eoPop.h eoPrintable.h eoProportionalCombinedOp.h eoProportionalSelect.h eoRandomSelect.h eoRankingSelect.h eoReduce.h eoReduceMerge.h eoReplacement.h eoSGA.h eoSGATransform.h eoScalarFitness.h eoSelect.h eoSelectFactory.h eoSelectMany.h eoSelectNumber.h eoSelectOne.h eoSelectPerc.h eoSteadyFitContinue.h eoStochTournamentSelect.h eoSurviveAndDie.h eoTransform.h eoVariableLength.h eoVariableLengthCrossover.h eoVariableLengthMutation.h es.h ga.h libeoinc_HEADERS = eo EO.h apply.h eoAlgo.h eoBreed.h eoCombinedContinue.h eoContinue.h eoCounter.h eoDetSelect.h eoDetTournamentSelect.h eoEasyEA.h eoEvalFunc.h eoEvalFuncPtr.h eoFactory.h eoFitContinue.h eoFitnessScalingSelect.h eoFixedLength.h eoFunctor.h eoFunctorStore.h eoGenContinue.h eoInvalidateOps.h eoInit.h eoMerge.h eoMergeReduce.h eoObject.h eoOp.h eoOpSelMason.h eoPersistent.h eoPop.h eoPrintable.h eoProportionalCombinedOp.h eoProportionalSelect.h eoRandomSelect.h eoRankingSelect.h eoReduce.h eoReduceMerge.h eoReplacement.h eoSGA.h eoSGATransform.h eoScalarFitness.h eoSelect.h eoSelectFactory.h eoSelectMany.h eoSelectNumber.h eoSelectOne.h eoSelectPerc.h eoSteadyFitContinue.h eoStochTournamentSelect.h eoSurviveAndDie.h eoTransform.h eoVariableLength.h eoVariableLengthCrossover.h eoVariableLengthMutation.h es.h ga.h

View file

@ -196,7 +196,7 @@ template <class Procedure>
eoProcedureCounter<Procedure>& make_counter(eoFunctorBase::procedure_tag, Procedure& _proc, eoFunctorStore& store, std::string _name = "proc_counter") eoProcedureCounter<Procedure>& make_counter(eoFunctorBase::procedure_tag, Procedure& _proc, eoFunctorStore& store, std::string _name = "proc_counter")
{ {
eoProcedureCounter<Procedure>* result = new eoProcedureCounter<Procedure>(_proc, _name); eoProcedureCounter<Procedure>* result = new eoProcedureCounter<Procedure>(_proc, _name);
store.add(result); store.storeFunctor(result);
return *result; return *result;
} }
@ -204,7 +204,7 @@ template <class UnaryFunctor>
eoUnaryFunctorCounter<UnaryFunctor>& make_counter(eoFunctorBase::unary_function_tag, UnaryFunctor& _proc, eoFunctorStore& store, std::string _name = "uf_counter") eoUnaryFunctorCounter<UnaryFunctor>& make_counter(eoFunctorBase::unary_function_tag, UnaryFunctor& _proc, eoFunctorStore& store, std::string _name = "uf_counter")
{ {
eoUnaryFunctorCounter<UnaryFunctor>* result = new eoUnaryFunctorCounter<UnaryFunctor>(_proc, _name); eoUnaryFunctorCounter<UnaryFunctor>* result = new eoUnaryFunctorCounter<UnaryFunctor>(_proc, _name);
store.add(result); store.storeFunctor(result);
return *result; return *result;
} }
@ -212,7 +212,7 @@ template <class BinaryFunctor>
eoBinaryFunctorCounter<BinaryFunctor>& make_counter(eoFunctorBase::binary_function_tag, BinaryFunctor& _proc, eoFunctorStore& store, std::string _name = "uf_counter") eoBinaryFunctorCounter<BinaryFunctor>& make_counter(eoFunctorBase::binary_function_tag, BinaryFunctor& _proc, eoFunctorStore& store, std::string _name = "uf_counter")
{ {
eoBinaryFunctorCounter<BinaryFunctor>* result = new eoBinaryFunctorCounter<BinaryFunctor>(_proc, _name); eoBinaryFunctorCounter<BinaryFunctor>* result = new eoBinaryFunctorCounter<BinaryFunctor>(_proc, _name);
store.add(result); store.storeFunctor(result);
return *result; return *result;
} }

View file

@ -34,9 +34,9 @@ class eoFunctorBase;
/** /**
eoFunctorStore is a class that stores functors that are allocated on the eoFunctorStore is a class that stores functors that are allocated on the
heap. This class can be used in factories to store allocated memory for heap. This class can be used in factories to store allocated memory for
dynamically created functors. dynamically created functors.
*/ */
class eoFunctorStore class eoFunctorStore
{ {
public : public :
@ -45,13 +45,19 @@ class eoFunctorStore
~eoFunctorStore(); ~eoFunctorStore();
/// Add an eoFunctorBase to the store /// Add an eoFunctorBase to the store
void add(eoFunctorBase* r) { vec.push_back(r); } template <class Functor>
Functor& storeFunctor(Functor* r)
{
// If the compiler complains about the following line, check if you really are giving it a pointer to an eoFunctorBase derived object
vec.push_back(r);
return *r;
}
private : private :
/// no copying allowed /// no copying allowed
eoFunctorStore(const eoFunctorStore&); eoFunctorStore(const eoFunctorStore&);
/// no copying allowed /// no copying allowed
eoFunctorStore operator=(const eoFunctorStore&); eoFunctorStore operator=(const eoFunctorStore&);
std::vector<eoFunctorBase*> vec; std::vector<eoFunctorBase*> vec;

View file

@ -1,9 +1,9 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// eoGenOp.h // eoGenOp.h
// (c) Maarten Keijzer and Marc Schoenauer, 2001 // (c) Maarten Keijzer and Marc Schoenauer, 2001
/* /*
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -18,7 +18,7 @@
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: mkeijzer@dhi.dk Contact: mak@dhi.dk
Marc.Schoenauer@polytechnique.fr Marc.Schoenauer@polytechnique.fr
*/ */
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -28,7 +28,7 @@
#include <eoOp.h> #include <eoOp.h>
#include <eoPopulator.h> #include <eoPopulator.h>
#include <eoFunctorStore.h>
/** @name General variation operators /** @name General variation operators
@ -41,15 +41,22 @@ thanks to the friend class eoPopulator
/** The base class for General Operators /** The base class for General Operators
Subclass this operator is you want to define an operator that falls
outside of the eoMonOp, eoBinOp, eoQuadOp classification. The argument
the operator will receive is an eoPopulator, which is a wrapper around
the original population, is an instantiation of the next population and
has often a selection function embedded in it to select new individuals.
Note that the actual work is performed in the apply function.
*/ */
template <class EOT> template <class EOT>
class eoGenOp : public eoOp<EOT>, public eoUF<eoPopulator<EOT> &, void> class eoGenOp : public eoOp<EOT>, public eoUF<eoPopulator<EOT> &, void>
{ {
public : public :
/// Ctor that honors its superclass /// Ctor that honors its superclass
eoGenOp(): eoOp<EOT>( eoOp<EOT>::general ) {} eoGenOp(): eoOp<EOT>( eoOp<EOT>::general ) {}
virtual unsigned max_production(void) = 0; virtual unsigned max_production(void) = 0;
virtual string className() = 0; virtual string className() = 0;
void operator()(eoPopulator<EOT>& _pop) void operator()(eoPopulator<EOT>& _pop)
{ {
@ -57,6 +64,7 @@ class eoGenOp : public eoOp<EOT>, public eoUF<eoPopulator<EOT> &, void>
apply(_pop); apply(_pop);
} }
protected : protected :
/** the function that will do the work /** the function that will do the work
*/ */
@ -75,7 +83,8 @@ class eoMonGenOp : public eoGenOp<EOT>
void apply(eoPopulator<EOT>& _it) void apply(eoPopulator<EOT>& _it)
{ {
op(*_it); // look how simple if (op(*_it))
(*_it).invalidate(); // look how simple
} }
string className() {return op.className();} string className() {return op.className();}
@ -101,8 +110,9 @@ class eoBinGenOp : public eoGenOp<EOT>
{ {
EOT& a = *_pop; EOT& a = *_pop;
EOT& b = *++_pop; EOT& b = *++_pop;
op(a, b); if (op(a, b))
_pop.erase(); a.invalidate();
_pop.erase(); // erase the b from the next population
} }
string className() {return op.className();} string className() {return op.className();}
@ -115,17 +125,18 @@ template <class EOT>
class eoSelBinGenOp : public eoGenOp<EOT> class eoSelBinGenOp : public eoGenOp<EOT>
{ {
public: public:
eoSelBinGenOp(eoBinOp<EOT>& _op, eoSelectOne<EOT>& _sel) : eoSelBinGenOp(eoBinOp<EOT>& _op, eoSelectOne<EOT>& _sel) :
op(_op), sel(_sel) {} op(_op), sel(_sel) {}
unsigned max_production(void) { return 1; } unsigned max_production(void) { return 1; }
void apply(eoPopulator<EOT>& _pop) void apply(eoPopulator<EOT>& _pop)
{ // _pop.source() gets the original population, an eoVecOp can make use of this as well { // _pop.source() gets the original population, an eoVecOp can make use of this as well
op(*_pop, sel(_pop.source())); if (op(*_pop, sel(_pop.source())))
(*_pop).invalidate();
} }
string className() {return op.className();} string className() {return op.className();}
private : private :
eoBinOp<EOT>& op; eoBinOp<EOT>& op;
eoSelectOne<EOT>& sel; eoSelectOne<EOT>& sel;
@ -147,7 +158,11 @@ class eoQuadGenOp : public eoGenOp<EOT>
EOT& a = *_pop; EOT& a = *_pop;
EOT& b = *++_pop; EOT& b = *++_pop;
op(a, b); if(op(a, b))
{
a.invalidate();
b.invalidate();
}
} }
string className() {return op.className();} string className() {return op.className();}
@ -155,6 +170,41 @@ class eoQuadGenOp : public eoGenOp<EOT>
eoQuadOp<EOT>& op; eoQuadOp<EOT>& op;
}; };
/**
Factory function for automagically creating references to an
eoGenOp object. Useful when you are too lazy to figure out
which wrapper belongs to which operator. The memory allocated
in the wrapper will be stored in a eoFunctorStore (eoState derives from this).
Therefore the memory will only be freed when the eoFunctorStore is deleted.
Make very sure that you are not using these wrappers after this happens.
You can use this function 'wrap_op' in the following way. Suppose you've
created an eoQuadOp<EOT> called my_quad, and you want to feed it to an eoTransform
derived class that expects an eoGenOp<EOT>. If you have an eoState lying around
(which is generally a good idea) you can say:
eoDerivedTransform<EOT> trans(eoGenOp<EOT>::wrap_op(my_quad, state), ...);
And as long as your state is not destroyed (by going out of scope for example,
your 'trans' functor will be usefull.
As a final note, you can also enter an eoGenOp as the argument. It will
not allocate memory then. This to make it even easier to use the wrap_op function.
For an example of how this is used, check the eoOpContainer class.
@see eoOpContainer
*/
template <class EOT>
eoGenOp<EOT>& wrap_op(eoOp<EOT>& _op, eoFunctorStore& _store)
{
switch(_op.getType())
{
case eoOp<EOT>::unary : return _store.storeFunctor(new eoMonGenOp<EOT>(static_cast<eoMonOp<EOT>&>(_op)));
case eoOp<EOT>::binary : return _store.storeFunctor(new eoBinGenOp<EOT>(static_cast<eoBinOp<EOT>&>(_op)));
case eoOp<EOT>::quadratic : return _store.storeFunctor(new eoQuadGenOp<EOT>(static_cast<eoQuadOp<EOT>&>(_op)));
case eoOp<EOT>::general : return static_cast<eoGenOp<EOT>&>(_op);
}
}
#endif #endif

View file

@ -104,10 +104,11 @@ class eoInitAdaptor : public eoMonOp<EOT>
{ {
public : public :
eoInitAdaptor(eoInit<EOT>& _init) : init(_init) {} eoInitAdaptor(eoInit<EOT>& _init) : init(_init) {}
void operator()(EOT& _eot) bool operator()(EOT& _eot)
{ {
init(_eot); init(_eot);
return true;
} }
private : private :

118
eo/src/eoInvalidateOps.h Normal file
View file

@ -0,0 +1,118 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// eoInvalidateOps.h
// (c) Maarten Keijzer 2001
/*
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; either
version 2 of the License, or (at your option) any later version.
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
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mak@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifndef _eoInvalidateOps_h
#define _eoInvalidateOps_h
#include <eoOp.h>
/**
One of the invalidator operators. Use this one as a 'hat' on an operator
that is defined to work on a generic datatype. This functor will then check
the return type of the operator and invalidate the fitness of the individual.
This functor is used in algorithms that work with straight eoMonOp, eoBinOp
or eoQuadOp operators, for instance eoSGA. Note that eoGenOp derived operators
generally do invalidate the fitness of the objects they have changed.
*/
template <class EOT>
class eoInvalidateMonOp : public eoMonOp<EOT>
{
public:
eoInvalidateMonOp(eoMonOp<EOT>& _op) : op(_op) {}
bool operator()(EOT& _eo)
{
if (op(_eo))
_eo.invalidate();
return false; // we did change the thing, but it is already invalidated
}
private:
eoMonOp<EOT>& op;
};
/**
One of the invalidator operators. Use this one as a 'hat' on an operator
that is defined to work on a generic datatype. This functor will then check
the return type of the operator and invalidate the fitness of the individual.
This functor is used in algorithms that work with straight eoMonOp, eoBinOp
or eoQuadOp operators, for instance eoSGA. Note that eoGenOp derived operators
generally do invalidate the fitness of the objects they have changed.
*/
template <class EOT>
class eoInvalidateBinOp : public eoBinOp<EOT>
{
public:
eoInvalidateBinOp(eoBinOp<EOT>& _op) : op(_op) {}
bool operator()(EOT& _eo, const EOT& _eo2)
{
if (op(_eo, _eo2))
_eo.invalidate();
return false; // we did change the thing, but it is already invalidated
}
private:
eoBinOp<EOT>& op;
};
/**
One of the invalidator operators. Use this one as a 'hat' on an operator
that is defined to work on a generic datatype. This functor will then check
the return type of the operator and invalidate the fitness of the individual.
This functor is used in algorithms that work with straight eoMonOp, eoBinOp
or eoQuadOp operators, for instance eoSGA. Note that eoGenOp derived operators
generally do invalidate the fitness of the objects they have changed.
*/
template <class EOT>
class eoInvalidateQuadOp : public eoQuadOp<EOT>
{
public:
eoInvalidateQuadOp(eoQuadOp<EOT>& _op) : op(_op) {}
bool operator()(EOT& _eo1, EOT& _eo2)
{
if (op(_eo1, _eo2))
{
_eo1.invalidate();
_eo2.invalidate();
}
return false; // we did change the thing, but it is already invalidated
}
private:
eoQuadOp<EOT>& op;
};
#endif

View file

@ -29,23 +29,23 @@
#include <eoFunctor.h> #include <eoFunctor.h>
#include <utils/eoRNG.h> #include <utils/eoRNG.h>
/** /**
\defgroup operators \defgroup Operators
Genetic Operators are used for various purposes Genetic Operators are used for various purposes
*/ */
/** @name Genetic operators /** @name Genetic operators
What is a genetic algorithm without genetic operators? What is a genetic algorithm without genetic operators?
There is a genetic operator hierarchy, with eoOp as father and There is a genetic operator hierarchy, with eoOp as father and
eoMonOp (monary or unary operator), eoBinOp and eoQuadOp (binary operators) eoMonOp (monary or unary operator), eoBinOp and eoQuadOp (binary operators)
and eoGenOp (any number of inputs and outputs, see eoGenOp.h) and eoGenOp (any number of inputs and outputs, see eoGenOp.h)
as subclasses. as subclasses.
Nobody should subclass eoOp, you should subclass eoGenOp, eoBinOp, eoQuadOp Nobody should subclass eoOp, you should subclass eoGenOp, eoBinOp, eoQuadOp
or eoMonOp, those are the ones actually used here. or eoMonOp, those are the ones actually used here.
#eoOp#s are only printable objects, so if you want to build them #eoOp#s are only printable objects, so if you want to build them
from a file, it has to be done in another class, namely factories. from a file, it has to be done in another class, namely factories.
Each hierarchy of #eoOp#s should have its own factory, which know Each hierarchy of #eoOp#s should have its own factory, which know
how to build them from a description in a file. how to build them from a description in a file.
@author GeNeura Team, Marten Keijzer and Marc Schoenauer @author GeNeura Team, Marten Keijzer and Marc Schoenauer
@ -55,10 +55,13 @@ how to build them from a description in a file.
/** Abstract data types for EO operators. /** Abstract data types for EO operators.
* Genetic operators act on chromosomes, changing them. The type to Genetic operators act on chromosomes, changing them.
* instantiate them should be an eoObject, but in any case, they are The type to use them on is problem specific. If your genotype
* type-specific; each kind of evolvable object can have its own operators is a vector<bool>, there are operators that work specifically
*/ on vector<bool>, but you might also find that generic operators
working on vector<T> are what you need.
*/
template<class EOType> template<class EOType>
class eoOp class eoOp
@ -88,9 +91,13 @@ private:
OpType opType; OpType opType;
}; };
/** eoMonOp is the monary operator: genetic operator that takes only one EO */ /**
eoMonOp is the monary operator: genetic operator that takes only one EO.
When defining your own, make sure that you return a boolean value
indicating that you have changed the content.
*/
template <class EOType> template <class EOType>
class eoMonOp: public eoOp<EOType>, public eoUF<EOType&, void> class eoMonOp: public eoOp<EOType>, public eoUF<EOType&, bool>
{ {
public: public:
/// Ctor /// Ctor
@ -100,11 +107,13 @@ public:
}; };
/** Binary genetic operator: subclasses eoOp, and defines basically the /** Binary genetic operator: subclasses eoOp, and defines basically the
* operator() with two operands, only the first one can be modified * operator() with two operands, only the first one can be modified
When defining your own, make sure that you return a boolean value
indicating that you have changed the content.
*/ */
template<class EOType> template<class EOType>
class eoBinOp: public eoOp<EOType>, public eoBF<EOType&, const EOType&, void> class eoBinOp: public eoOp<EOType>, public eoBF<EOType&, const EOType&, bool>
{ {
public: public:
/// Ctor /// Ctor
@ -113,11 +122,13 @@ public:
virtual string className() const {return "eoBinOp";}; virtual string className() const {return "eoBinOp";};
}; };
/** Quad genetic operator: subclasses eoOp, and defines basically the /** Quad genetic operator: subclasses eoOp, and defines basically the
operator() with two operands, both can be modified. operator() with two operands, both can be modified.
When defining your own, make sure that you return a boolean value
indicating that you have changed the content.
*/ */
template<class EOType> template<class EOType>
class eoQuadOp: public eoOp<EOType>, public eoBF<EOType&, EOType&, void> { class eoQuadOp: public eoOp<EOType>, public eoBF<EOType&, EOType&, bool> {
public: public:
/// Ctor /// Ctor
eoQuadOp() eoQuadOp()
@ -138,15 +149,15 @@ public:
/** Operator() simply calls embedded quadOp operator() with dummy second arg /** Operator() simply calls embedded quadOp operator() with dummy second arg
*/ */
void operator()(EOT & _eo1, const EOT & _eo2) bool operator()(EOT & _eo1, const EOT & _eo2)
{ {
EOT eoTmp = _eo2; // a copy that can be modified EOT eoTmp = _eo2; // a copy that can be modified
// if the embedded eoQuadOp is not symmetrical, // if the embedded eoQuadOp is not symmetrical,
// the result might be biased - hence the flip ... // the result might be biased - hence the flip ...
if (eo::rng.flip(0.5)) if (eo::rng.flip(0.5))
quadOp(_eo1, eoTmp); // both are modified - that's all return quadOp(_eo1, eoTmp); // both are modified - that's all
else else
quadOp(eoTmp, _eo1); // both are modified - that's all return quadOp(eoTmp, _eo1); // both are modified - that's all
} }
private: private:

View file

@ -1,9 +1,9 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// eoOpContainer.h // eoOpContainer.h
// (c) Maarten Keijzer and Marc Schoenauer, 2001 // (c) Maarten Keijzer and Marc Schoenauer, 2001
/* /*
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -29,13 +29,13 @@
#include <eoGenOp.h> #include <eoGenOp.h>
/** eoOpContainer is a base class for the sequential and proportional selectors /** eoOpContainer is a base class for the sequential and proportional selectors
* It takes care of wrapping the other operators, * It takes care of wrapping the other operators,
* and deleting stuff that it has allocated * and deleting stuff that it has allocated
* *
* Warning: all operators are added together with a rate (double) * Warning: all operators are added together with a rate (double)
* However, the meaning of this rate will be different in * However, the meaning of this rate will be different in
* the differnet instances of eoOpContainer: * the differnet instances of eoOpContainer:
* an ***absolute*** probability in the sequential version, and * an ***absolute*** probability in the sequential version, and
* a ***relative*** weight in the proportional version * a ***relative*** weight in the proportional version
*/ */
template <class EOT> template <class EOT>
@ -43,15 +43,11 @@ class eoOpContainer : public eoGenOp<EOT>
{ {
public : public :
/** Ctor: nothing much to do */ /** Ctor: nothing much to do */
eoOpContainer() : max_to_produce(0) {} eoOpContainer() : max_to_produce(2) {}
/** Dtor: delete all the GenOps created when wrapping simple ops /** Dtor: delete all the GenOps created when wrapping simple ops
*/ */
virtual ~eoOpContainer(void) virtual ~eoOpContainer(void) {}
{
for (unsigned i = 0; i < owned_genops.size(); ++i)
delete owned_genops[i];
}
/** for memory management (doesn't have to be very precise */ /** for memory management (doesn't have to be very precise */
virtual unsigned max_production(void) virtual unsigned max_production(void)
@ -59,57 +55,16 @@ class eoOpContainer : public eoGenOp<EOT>
return max_to_produce; return max_to_produce;
} }
/** wraps then add a simple eoMonOp */ /**
void add(eoMonOp<EOT>& _op, double _rate) Add an operator to the container, also give it a rate
(sidenote, it's much less hairy since I added the wrap_op is used)
*/
void add(eoOp<EOT>& _op, double _rate)
{ {
owned_genops.push_back(new eoMonGenOp<EOT>(_op)); ops.push_back(&wrap_op<EOT>(_op, store));
ops.push_back(owned_genops.back());
rates.push_back(_rate); rates.push_back(_rate);
max_to_produce = max(max_to_produce,ops.back()->max_production());
max_to_produce = max(max_to_produce,unsigned(1));
}
/** wraps then add a simple eoBinOp
* First case, no selector
*/
void add(eoBinOp<EOT>& _op, double _rate)
{
owned_genops.push_back(new eoBinGenOp<EOT>(_op));
ops.push_back(owned_genops.back());
rates.push_back(_rate);
max_to_produce = max(max_to_produce,unsigned(1));
}
/** wraps then add a simple eoBinOp
* Second case: a sepecific selector
*/
void add(eoBinOp<EOT>& _op, eoSelectOne<EOT> & _sel, double _rate)
{
owned_genops.push_back(new eoSelBinGenOp<EOT>(_op, _sel));
ops.push_back(owned_genops.back());
rates.push_back(_rate);
max_to_produce = max(max_to_produce,unsigned(1));
}
/** wraps then add a simple eoQuadOp */
void add(eoQuadOp<EOT>& _op, double _rate)
{
owned_genops.push_back(new eoQuadGenOp<EOT>(_op));
ops.push_back(owned_genops.back());
rates.push_back(_rate);
max_to_produce = max(max_to_produce,unsigned(2));
}
/** can add any GenOp */
void add(eoGenOp<EOT>& _op, double _rate)
{
ops.push_back(&_op);
rates.push_back(_rate);
max_to_produce = max(max_to_produce,_op.max_production());
} }
virtual string className() = 0; virtual string className() = 0;
@ -120,7 +75,7 @@ class eoOpContainer : public eoGenOp<EOT>
vector<eoGenOp<EOT>*> ops; vector<eoGenOp<EOT>*> ops;
private : private :
vector<eoGenOp<EOT>*> owned_genops; eoFunctorStore store;
unsigned max_to_produce; unsigned max_to_produce;
}; };

View file

@ -28,19 +28,16 @@
#include <eoPrintable.h> #include <eoPrintable.h>
#include <eoFunctor.h> #include <eoFunctor.h>
#include <eoOp.h> #include <eoOp.h>
#include <eoGenericMonOp.h>
#include <eoGenericBinOp.h>
#include <eoGenericQuadOp.h>
#include <utils/eoRNG.h> #include <utils/eoRNG.h>
/** /**
\defgroup PropCombined operators \defgroup PropCombined operators
Combination of same-type Genetic Operators - Proportional choice Combination of same-type Genetic Operators - Proportional choice
*/ */
/** @name PropCombined Genetic operators /** @name PropCombined Genetic operators
This files contains the classes eoPropCombinedXXXOp (XXX in {Mon, Bin, Quad}) This files contains the classes eoPropCombinedXXXOp (XXX in {Mon, Bin, Quad})
that allow to use more than a single operator of a specific class that allow to use more than a single operator of a specific class
into an algorithm, chosing by a roulette wheel based on user-defined rates into an algorithm, chosing by a roulette wheel based on user-defined rates
@author Marc Schoenauer @author Marc Schoenauer
@ -52,7 +49,7 @@ into an algorithm, chosing by a roulette wheel based on user-defined rates
//// combined MonOp //// combined MonOp
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
/** eoMonOp is the monary operator: genetic operator that takes only one EO /** eoMonOp is the monary operator: genetic operator that takes only one EO
* now accepts generic operators * now accepts generic operators
*/ */
@ -63,35 +60,16 @@ class eoPropCombinedMonOp: public eoMonOp<EOT>
public: public:
/// Ctor from a "true" operator /// Ctor from a "true" operator
eoPropCombinedMonOp(eoMonOp<EOT> & _first, const double _rate) eoPropCombinedMonOp(eoMonOp<EOT> & _first, const double _rate)
{ {
ops.push_back(&_first); ops.push_back(&_first);
rates.push_back(_rate);
}
/// Ctor from a generic operator
eoPropCombinedMonOp(eoGenericMonOp<EOT> & _first, const double _rate)
{
eoGeneric2TrueMonOp<EOT> *trueFirst =
new eoGeneric2TrueMonOp<EOT>(_first);
ops.push_back(trueFirst);
rates.push_back(_rate); rates.push_back(_rate);
} }
virtual string className() const { return "eoPropCombinedMonOp"; } virtual string className() const { return "eoPropCombinedMonOp"; }
virtual void add(eoMonOp<EOT> & _op, const double _rate, bool _verbose=false) virtual void add(eoMonOp<EOT> & _op, const double _rate, bool _verbose=false)
{ {
ops.push_back(&_op); ops.push_back(&_op);
rates.push_back(_rate);
// compute the relative rates in percent - to warn the user!
if (_verbose)
printOn(cout);
}
virtual void add(eoGenericMonOp<EOT> & _op, const double _rate, bool _verbose=false)
{
eoGeneric2TrueMonOp<EOT> *trueOp = new eoGeneric2TrueMonOp<EOT>(_op);
ops.push_back(trueOp);
rates.push_back(_rate); rates.push_back(_rate);
// compute the relative rates in percent - to warn the user! // compute the relative rates in percent - to warn the user!
if (_verbose) if (_verbose)
@ -110,10 +88,10 @@ public:
_os << ops[i]->className() << " with rate " << 100*rates[i]/total << " %\n"; _os << ops[i]->className() << " with rate " << 100*rates[i]/total << " %\n";
} }
virtual void operator()(EOT & _indi) virtual bool operator()(EOT & _indi)
{ {
unsigned what = rng.roulette_wheel(rates); // choose one op unsigned what = rng.roulette_wheel(rates); // choose one op
(*ops[what])(_indi); // apply it return (*ops[what])(_indi); // apply it
} }
protected: protected:
std::vector<eoMonOp<EOT>*> ops; std::vector<eoMonOp<EOT>*> ops;
@ -124,7 +102,7 @@ std::vector<double> rates;
//// combined BinOp //// combined BinOp
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
/** COmbined Binary genetic operator: /** COmbined Binary genetic operator:
* operator() has two operands, only the first one can be modified * operator() has two operands, only the first one can be modified
*/ */
template <class EOT> template <class EOT>
@ -133,16 +111,16 @@ class eoPropCombinedBinOp: public eoBinOp<EOT>
public: public:
/// Ctor /// Ctor
eoPropCombinedBinOp(eoBinOp<EOT> & _first, const double _rate) eoPropCombinedBinOp(eoBinOp<EOT> & _first, const double _rate)
{ {
ops.push_back(&_first); ops.push_back(&_first);
rates.push_back(_rate); rates.push_back(_rate);
} }
virtual string className() const { return "eoPropCombinedBinOp"; } virtual string className() const { return "eoPropCombinedBinOp"; }
virtual void add(eoBinOp<EOT> & _op, const double _rate, bool _verbose=false) virtual void add(eoBinOp<EOT> & _op, const double _rate, bool _verbose=false)
{ {
ops.push_back(&_op); ops.push_back(&_op);
rates.push_back(_rate); rates.push_back(_rate);
// compute the relative rates in percent - to warn the user! // compute the relative rates in percent - to warn the user!
if (_verbose) if (_verbose)
@ -160,7 +138,7 @@ virtual void add(eoBinOp<EOT> & _op, const double _rate, bool _verbose=false)
virtual void operator()(EOT & _indi1, const EOT & _indi2) virtual void operator()(EOT & _indi1, const EOT & _indi2)
{ {
unsigned what = rng.roulette_wheel(rates); // choose one op index unsigned what = rng.roulette_wheel(rates); // choose one op index
(*ops[what])(_indi1, _indi2); // apply it return (*ops[what])(_indi1, _indi2); // apply it
} }
private: private:
std::vector<eoBinOp<EOT>*> ops; std::vector<eoBinOp<EOT>*> ops;
@ -172,13 +150,13 @@ std::vector<double> rates;
//// combined QuadOp //// combined QuadOp
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
/** Quad genetic operator: subclasses eoOp, and defines basically the /** Quad genetic operator: subclasses eoOp, and defines basically the
operator() with two operands, both can be modified. operator() with two operands, both can be modified.
*/ */
/** Combined quad genetic operator: /** Combined quad genetic operator:
* operator() has two operands, both can be modified * operator() has two operands, both can be modified
* generic operators are now allowed: there are imbedded into * generic operators are now allowed: there are imbedded into
* the corresponding "true" operator * the corresponding "true" operator
*/ */
template <class EOT> template <class EOT>
@ -187,17 +165,8 @@ class eoPropCombinedQuadOp: public eoQuadOp<EOT>
public: public:
/// Ctor from a true operator /// Ctor from a true operator
eoPropCombinedQuadOp(eoQuadOp<EOT> & _first, const double _rate) eoPropCombinedQuadOp(eoQuadOp<EOT> & _first, const double _rate)
{ {
ops.push_back(&_first); ops.push_back(&_first);
rates.push_back(_rate);
}
/// Ctor from a generic operator
eoPropCombinedQuadOp(eoGenericQuadOp<EOT> & _first, const double _rate)
{
eoGeneric2TrueQuadOp<EOT> *trueFirst =
new eoGeneric2TrueQuadOp<EOT>(_first);
ops.push_back(trueFirst);
rates.push_back(_rate); rates.push_back(_rate);
} }
@ -205,19 +174,8 @@ virtual string className() const { return "eoPropCombinedQuadOp"; }
// addition of a true operator // addition of a true operator
virtual void add(eoQuadOp<EOT> & _op, const double _rate, bool _verbose=false) virtual void add(eoQuadOp<EOT> & _op, const double _rate, bool _verbose=false)
{ {
ops.push_back(&_op); ops.push_back(&_op);
rates.push_back(_rate);
// compute the relative rates in percent - to warn the user!
if (_verbose)
printOn(cout);
}
// addition of a generic operator
virtual void add(eoGenericQuadOp<EOT> & _op, const double _rate, bool _verbose=false)
{
eoGeneric2TrueQuadOp<EOT> *trueOp = new eoGeneric2TrueQuadOp<EOT>(_op);
ops.push_back(trueOp);
rates.push_back(_rate); rates.push_back(_rate);
// compute the relative rates in percent - to warn the user! // compute the relative rates in percent - to warn the user!
if (_verbose) if (_verbose)
@ -236,10 +194,10 @@ virtual void add(eoGenericQuadOp<EOT> & _op, const double _rate, bool _verbose=f
_os << ops[i]->className() << " with rate " << 100*rates[i]/total << " %\n"; _os << ops[i]->className() << " with rate " << 100*rates[i]/total << " %\n";
} }
virtual void operator()(EOT & _indi1, EOT & _indi2) virtual bool operator()(EOT & _indi1, EOT & _indi2)
{ {
unsigned what = rng.roulette_wheel(rates); // choose one op index unsigned what = rng.roulette_wheel(rates); // choose one op index
(*ops[what])(_indi1, _indi2); // apply it return (*ops[what])(_indi1, _indi2); // apply it
} }
private: private:
std::vector<eoQuadOp<EOT>*> ops; std::vector<eoQuadOp<EOT>*> ops;
@ -247,6 +205,6 @@ std::vector<double> rates;
}; };
// for General Ops, it's another story - see eoGOpSelector // for General Ops, it's another story -
#endif #endif

View file

@ -27,7 +27,7 @@
#ifndef _eoSGA_h #ifndef _eoSGA_h
#define _eoSGA_h #define _eoSGA_h
#include <eoOp.h> #include <eoInvalidateOps.h>
#include <eoContinue.h> #include <eoContinue.h>
#include <eoPop.h> #include <eoPop.h>
#include <eoSelectOne.h> #include <eoSelectOne.h>
@ -36,13 +36,13 @@
#include <eoAlgo.h> #include <eoAlgo.h>
#include <apply.h> #include <apply.h>
/** The Simple Genetic Algorithm, following Holland and Goldberg /** The Simple Genetic Algorithm, following Holland and Goldberg
* Needs a selector (class eoSelectOne) a crossover (eoQuad, * Needs a selector (class eoSelectOne) a crossover (eoQuad,
* i.e. a 2->2 operator) and a mutation with their respective rates, * i.e. a 2->2 operator) and a mutation with their respective rates,
* of course an evaluation function (eoEvalFunc) and a continuator * of course an evaluation function (eoEvalFunc) and a continuator
* (eoContinue) which gives the stopping criterion. Performs full * (eoContinue) which gives the stopping criterion. Performs full
* generational replacement. * generational replacement.
*/ */
template <class EOT> template <class EOT>
class eoSGA : public eoAlgo<EOT> class eoSGA : public eoAlgo<EOT>
@ -57,8 +57,8 @@ public :
eoMonOp<EOT>& _mutate, float _mrate, eoMonOp<EOT>& _mutate, float _mrate,
eoEvalFunc<EOT>& _eval, eoEvalFunc<EOT>& _eval,
eoContinue<EOT>& _cont) eoContinue<EOT>& _cont)
: cont(_cont), : cont(_cont),
mutate(_mutate), mutate(_mutate),
mutationRate(_mrate), mutationRate(_mrate),
cross(_cross), cross(_cross),
crossoverRate(_crate), crossoverRate(_crate),
@ -68,42 +68,44 @@ public :
void operator()(eoPop<EOT>& _pop) void operator()(eoPop<EOT>& _pop)
{ {
eoPop<EOT> offspring; eoPop<EOT> offspring;
do do
{ {
select(_pop, offspring); select(_pop, offspring);
unsigned i; unsigned i;
for (i=0; i<_pop.size()/2; i++) for (i=0; i<_pop.size()/2; i++)
{ {
if ( rng.flip(crossoverRate) ) if ( rng.flip(crossoverRate) )
{ {
// this crossover generates 2 offspring from two parents // this crossover generates 2 offspring from two parents
cross(offspring[2*i], offspring[2*i+1]); cross(offspring[2*i], offspring[2*i+1]);
} }
} }
for (i=0; i < _pop.size(); i++) for (i=0; i < _pop.size(); i++)
{ {
if (rng.flip(mutationRate) ) if (rng.flip(mutationRate) )
{ {
mutate(offspring[i]); mutate(offspring[i]);
} }
} }
_pop.swap(offspring); _pop.swap(offspring);
apply<EOT>(eval, _pop); apply<EOT>(eval, _pop);
} while (cont(_pop)); } while (cont(_pop));
} }
private : private :
eoContinue<EOT>& cont; eoContinue<EOT>& cont;
eoMonOp<EOT>& mutate; /// eoInvalidateMonOp invalidates the embedded operator
eoInvalidateMonOp<EOT> mutate;
float mutationRate; float mutationRate;
eoQuadOp<EOT>& cross; // eoInvalidateQuadOp invalidates the embedded operator
eoInvalidateQuadOp<EOT> cross;
float crossoverRate; float crossoverRate;
eoSelectPerc<EOT> select; eoSelectPerc<EOT> select;
eoEvalFunc<EOT>& eval; eoEvalFunc<EOT>& eval;

View file

@ -3,7 +3,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// eoSGA.h // eoSGA.h
// (c) Marc.Schoenauer 2000 - Maarten Keijzer 2000 // (c) Marc.Schoenauer 2000 - Maarten Keijzer 2000
/* /*
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -27,7 +27,7 @@
#ifndef _eoSGATransform_h #ifndef _eoSGATransform_h
#define _eoSGATransform_h #define _eoSGATransform_h
#include <eoOp.h> #include <eoInvalidateOps.h>
#include <eoPop.h> #include <eoPop.h>
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -148,16 +148,16 @@ template<class EOT> class eoDynSGATransform : public eoTransform<EOT>
}; };
// accessors - mainly for EASEA // accessors - mainly for EASEA
double & PCrossHandle() { return crossoverProba;} double & PCrossHandle() { return crossoverProba;}
double & PMutHandle() { return mutationProba;} double & PMutHandle() { return mutationProba;}
private: private:
// difference with eoSGATransform: the operator probabilities // difference with eoSGATransform: the operator probabilities
// they can be passed by reference or by value. // they can be passed by reference or by value.
// hence we need here to use a reference, and to eventually store a value // hence we need here to use a reference, and to eventually store a value
eoQuadOp<EOT>& cross; eoInvalidateQuadOp<EOT> cross;
double crossoverProbaHolder; // the value, used only if ctor gets a value double crossoverProbaHolder; // the value, used only if ctor gets a value
double& crossoverProba; // the reference, to be used in operator() double& crossoverProba; // the reference, to be used in operator()
eoMonOp<EOT>& mutate; eoInvalidateMonOp<EOT> mutate;
double mutationProbaHolder; // the value, used only if ctor gets a value double mutationProbaHolder; // the value, used only if ctor gets a value
double& mutationProba; // the reference, to be used in operator() double& mutationProba; // the reference, to be used in operator()
}; };

View file

@ -29,13 +29,12 @@
#include <eoFunctor.h> #include <eoFunctor.h>
#include <eoVariableLength.h> #include <eoVariableLength.h>
#include <eoGenericBinOp.h> #include <eoOp.h>
#include <eoGenericQuadOp.h>
/** /**
Base classes for generic crossovers on variable length chromosomes. Base classes for generic crossovers on variable length chromosomes.
Basically, they exchange genes - we need some matching information to apply Basically, they exchange genes - we need some matching information to apply
atom crossover atom crossover
*/ */
@ -79,17 +78,17 @@ private:
*/ */
template <class EOT> template <class EOT>
class eoVlAtomExchangeQuadOp : public eoGenericQuadOp<EOT> class eoVlAtomExchangeQuadOp : public eoQuadOp<EOT>
{ {
public : public :
typedef typename EOT::AtomType AtomType; typedef typename EOT::AtomType AtomType;
// default ctor: requires bounds on number of genes + a rate // default ctor: requires bounds on number of genes + a rate
eoVlAtomExchangeQuadOp(unsigned _Min, unsigned _Max, eoVlAtomExchangeQuadOp(unsigned _Min, unsigned _Max,
eoAtomExchange<AtomType>& _atomExchange): eoAtomExchange<AtomType>& _atomExchange):
Min(_Min), Max(_Max), atomExchange(_atomExchange) {} Min(_Min), Max(_Max), atomExchange(_atomExchange) {}
bool operator()(EOT & _eo1, EOT & _eo2) bool operator()(EOT & _eo1, EOT & _eo2)
{ {
EOT tmp1, tmp2; // empty individuals EOT tmp1, tmp2; // empty individuals
@ -116,8 +115,8 @@ public :
i1++; i1++;
} }
index++; index++;
} while ( ( (i1<Min) || (i2<Min) || } while ( ( (i1<Min) || (i2<Min) ||
(i1>Max) || (i2>Max) ) (i1>Max) || (i2>Max) )
&& (index<10000) ); && (index<10000) );
if (index >= 10000) if (index >= 10000)
{ {
@ -157,21 +156,21 @@ private:
A very primitive version, that does no verification at all!!! A very primitive version, that does no verification at all!!!
NEEDS to be improved - but no time now :-((( NEEDS to be improved - but no time now :-(((
Especially, if both guys have maximal size, it will take a lot of time Especially, if both guys have maximal size, it will take a lot of time
to generate 2 offspring that both are not oversized!!! to generate 2 offspring that both are not oversized!!!
Also, we should first check for identical atoms, and copy them to the Also, we should first check for identical atoms, and copy them to the
offspring, and only after that exchange the other ones (Radcliffe's RRR). offspring, and only after that exchange the other ones (Radcliffe's RRR).
*/ */
template <class EOT> template <class EOT>
class eoVlUniformQuadOp : public eoGenericQuadOp<EOT> class eoVlUniformQuadOp : public eoQuadOp<EOT>
{ {
public : public :
typedef typename EOT::AtomType AtomType; typedef typename EOT::AtomType AtomType;
// default ctor: requires bounds on number of genes + a rate // default ctor: requires bounds on number of genes + a rate
eoVlUniformQuadOp(unsigned _Min, unsigned _Max, double _rate=0.5) : eoVlUniformQuadOp(unsigned _Min, unsigned _Max, double _rate=0.5) :
Min(_Min), Max(_Max), rate(_rate) {} Min(_Min), Max(_Max), rate(_rate) {}
bool operator()(EOT & _eo1, EOT & _eo2) bool operator()(EOT & _eo1, EOT & _eo2)
{ {
unsigned i; unsigned i;
@ -194,7 +193,7 @@ public :
tmp2.push_back(_eo2[i]); tmp2.push_back(_eo2[i]);
} }
index++; index++;
} while ( ( (tmp1.size()<Min) || (tmp2.size()<Min) || } while ( ( (tmp1.size()<Min) || (tmp2.size()<Min) ||
(tmp1.size()>Max) || (tmp2.size()>Max) ) (tmp1.size()>Max) || (tmp2.size()>Max) )
&& (index<10000) ); && (index<10000) );
if (index >= 10000) if (index >= 10000)
@ -218,21 +217,21 @@ private:
A very primitive version, that does no verification at all!!! A very primitive version, that does no verification at all!!!
NEEDS to be improved - but no time now :-((( NEEDS to be improved - but no time now :-(((
Especially, if both guys have maximal size, it will take some time Especially, if both guys have maximal size, it will take some time
to generate even 1 offspring that is not oversized!!! to generate even 1 offspring that is not oversized!!!
Also, we should first check for identical atoms, and copy them to the Also, we should first check for identical atoms, and copy them to the
offspring, and only after that exchange the other ones (Radcliffe's RRR). offspring, and only after that exchange the other ones (Radcliffe's RRR).
*/ */
template <class EOT> template <class EOT>
class eoVlUniformBinOp : public eoGenericBinOp<EOT> class eoVlUniformBinOp : public eoBinOp<EOT>
{ {
public : public :
typedef typename EOT::AtomType AtomType; typedef typename EOT::AtomType AtomType;
// default ctor: requires bounds on number of genes + a rate // default ctor: requires bounds on number of genes + a rate
eoVlUniformBinOp(unsigned _Min, unsigned _Max, double _rate=0.5) : eoVlUniformBinOp(unsigned _Min, unsigned _Max, double _rate=0.5) :
Min(_Min), Max(_Max), rate(_rate) {} Min(_Min), Max(_Max), rate(_rate) {}
bool operator()(EOT & _eo1, const EOT & _eo2) bool operator()(EOT & _eo1, const EOT & _eo2)
{ {
unsigned i; unsigned i;
@ -248,7 +247,7 @@ public :
tmpIsTwo = false; tmpIsTwo = false;
} }
else else
tmpIsOne=false; tmpIsOne=false;
// we should look for _eo1[i] inside _eo2 and erase it there if found! // we should look for _eo1[i] inside _eo2 and erase it there if found!
} }
for (i=0; i<_eo2.size(); i++) for (i=0; i<_eo2.size(); i++)

View file

@ -3,7 +3,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// eoVariableLengthMutation.h // eoVariableLengthMutation.h
// (c) GeNeura Team, 2000 - EEAAX 1999 - Maarten Keijzer 2000 // (c) GeNeura Team, 2000 - EEAAX 1999 - Maarten Keijzer 2000
/* /*
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -29,10 +29,10 @@
#include <eoFunctor.h> #include <eoFunctor.h>
#include <eoVariableLength.h> #include <eoVariableLength.h>
#include <eoGenericMonOp.h> #include <eoOp.h>
/** /**
Base classes for generic mutations on variable length chromosomes. Base classes for generic mutations on variable length chromosomes.
THey all require a generic mutation for their simple genes THey all require a generic mutation for their simple genes
*/ */
@ -40,16 +40,16 @@ THey all require a generic mutation for their simple genes
/** THis ones applies its atomic mutation to all the genes /** THis ones applies its atomic mutation to all the genes
*/ */
template <class EOT> template <class EOT>
class eoVlAllMutation : public eoGenericMonOp<EOT> class eoVlAllMutation : public eoMonOp<EOT>
{ {
public : public :
typedef typename EOT::AtomType AtomType; typedef typename EOT::AtomType AtomType;
// default ctor: requires an Atom mutation // default ctor: requires an Atom mutation
eoVlAllMutation(eoGenericMonOp<AtomType> & _atomMutation) : eoVlAllMutation(eoMonOp<AtomType> & _atomMutation) :
atomMutation(_atomMutation) {} atomMutation(_atomMutation) {}
bool operator()(EOT & _eo) bool operator()(EOT & _eo)
{ {
bool modified=false; bool modified=false;
@ -61,23 +61,23 @@ public :
return modified; return modified;
} }
private: private:
eoGenericMonOp<AtomType> & atomMutation; eoMonOp<AtomType> & atomMutation;
}; };
/** This ones applies its atomic mutation to a fixed /** This ones applies its atomic mutation to a fixed
number of genes (1 by default) number of genes (1 by default)
*/ */
template <class EOT> template <class EOT>
class eoVlKMutation : public eoGenericMonOp<EOT> class eoVlKMutation : public eoMonOp<EOT>
{ {
public : public :
typedef typename EOT::AtomType AtomType; typedef typename EOT::AtomType AtomType;
// default ctor: requires an Atom mutation // default ctor: requires an Atom mutation
eoVlKMutation(eoGenericMonOp<AtomType> & _atomMutation, unsigned _nb=1) : eoVlKMutation(eoMonOp<AtomType> & _atomMutation, unsigned _nb=1) :
nb(_nb), atomMutation(_atomMutation) {} nb(_nb), atomMutation(_atomMutation) {}
bool operator()(EOT & _eo) bool operator()(EOT & _eo)
{ {
bool modified=false; bool modified=false;
@ -91,7 +91,7 @@ public :
} }
private: private:
unsigned nb; unsigned nb;
eoGenericMonOp<AtomType> & atomMutation; eoMonOp<AtomType> & atomMutation;
}; };
/** Addition of a gene /** Addition of a gene
@ -99,20 +99,20 @@ private:
order-dependent and order-independent order-dependent and order-independent
*/ */
template <class EOT> template <class EOT>
class eoVlAddMutation : public eoGenericMonOp<EOT> class eoVlAddMutation : public eoMonOp<EOT>
{ {
public : public :
typedef typename EOT::AtomType AtomType; typedef typename EOT::AtomType AtomType;
/** default ctor /** default ctor
* @param nMax max number of atoms * @param nMax max number of atoms
* @param _atomInit an Atom initializer * @param _atomInit an Atom initializer
*/ */
eoVlAddMutation(unsigned _nMax, eoInit<AtomType> & _atomInit) : eoVlAddMutation(unsigned _nMax, eoInit<AtomType> & _atomInit) :
nMax(_nMax), atomInit(_atomInit) {} nMax(_nMax), atomInit(_atomInit) {}
bool operator()(EOT & _eo) bool operator()(EOT & _eo)
{ {
if (_eo.size() >= nMax) if (_eo.size() >= nMax)
@ -150,27 +150,27 @@ public:
can of course be applied to both order-dependent and order-independent can of course be applied to both order-dependent and order-independent
*/ */
template <class EOT> template <class EOT>
class eoVlDelMutation : public eoGenericMonOp<EOT> class eoVlDelMutation : public eoMonOp<EOT>
{ {
public : public :
typedef typename EOT::AtomType AtomType; typedef typename EOT::AtomType AtomType;
/** ctor with an external gene chooser /** ctor with an external gene chooser
* @param nMin min number of atoms t oleave in the individual * @param nMin min number of atoms t oleave in the individual
* @param _geneChooser an eoGeneCHooser to choose which one to delete * @param _geneChooser an eoGeneCHooser to choose which one to delete
*/ */
eoVlDelMutation(unsigned _nMin, eoGeneDelChooser<EOT> & _chooser) : eoVlDelMutation(unsigned _nMin, eoGeneDelChooser<EOT> & _chooser) :
nMin(_nMin), uChooser(), chooser(_chooser) {} nMin(_nMin), uChooser(), chooser(_chooser) {}
/** ctor with unifirm gebe chooser /** ctor with unifirm gebe chooser
* @param nMin min number of atoms t oleave in the individual * @param nMin min number of atoms t oleave in the individual
*/ */
eoVlDelMutation(unsigned _nMin) : eoVlDelMutation(unsigned _nMin) :
nMin(_nMin), uChooser(), chooser(uChooser) {} nMin(_nMin), uChooser(), chooser(uChooser) {}
bool operator()(EOT & _eo) bool operator()(EOT & _eo)
{ {
if (_eo.size() <= nMin) if (_eo.size() <= nMin)

View file

@ -80,22 +80,22 @@ public:
/// needed virtual dtor /// needed virtual dtor
virtual ~eoEsMutate() {}; virtual ~eoEsMutate() {};
/** Inherited from eoObject /** Inherited from eoObject
@see eoObject @see eoObject
*/ */
virtual string className() const {return "eoESMutate";}; virtual string className() const {return "eoESMutate";};
/** /**
Mutate eoEsSimple Mutate eoEsSimple
*/ */
virtual void operator()( eoEsSimple<FitT>& _eo) virtual bool operator()( eoEsSimple<FitT>& _eo)
{ {
_eo.stdev *= exp(TauLcl * rng.normal()); _eo.stdev *= exp(TauLcl * rng.normal());
if (_eo.stdev < stdev_eps) if (_eo.stdev < stdev_eps)
_eo.stdev = stdev_eps; _eo.stdev = stdev_eps;
// now apply to all // now apply to all
for (unsigned i = 0; i < _eo.size(); ++i) for (unsigned i = 0; i < _eo.size(); ++i)
@ -104,40 +104,40 @@ public:
} }
bounds.foldsInBounds(_eo); bounds.foldsInBounds(_eo);
_eo.invalidate(); return true;
} }
/// mutations - standard and correlated /// mutations - standard and correlated
// ========= // =========
/* /*
* Standard mutation of object variables and standard * Standard mutation of object variables and standard
* deviations in ESs. * deviations in ESs.
* If there are fewer different standard deviations available * If there are fewer different standard deviations available
* than the dimension of the objective function requires, the * than the dimension of the objective function requires, the
* last standard deviation is responsible for ALL remaining * last standard deviation is responsible for ALL remaining
* object variables. * object variables.
* Schwefel 1977: Numerische Optimierung von Computer-Modellen * Schwefel 1977: Numerische Optimierung von Computer-Modellen
* mittels der Evolutionsstrategie, pp. 165 ff. * mittels der Evolutionsstrategie, pp. 165 ff.
*/ */
virtual void operator()( eoEsStdev<FitT>& _eo ) virtual bool operator()( eoEsStdev<FitT>& _eo )
{ {
double global = exp(TauGlb * rng.normal()); double global = exp(TauGlb * rng.normal());
for (unsigned i = 0; i < _eo.size(); i++) for (unsigned i = 0; i < _eo.size(); i++)
{ {
double stdev = _eo.stdevs[i]; double stdev = _eo.stdevs[i];
stdev *= global * exp(TauLcl * rng.normal()); stdev *= global * exp(TauLcl * rng.normal());
if (stdev < stdev_eps) if (stdev < stdev_eps)
stdev = stdev_eps; stdev = stdev_eps;
_eo.stdevs[i] = stdev; _eo.stdevs[i] = stdev;
_eo[i] += stdev * rng.normal(); _eo[i] += stdev * rng.normal();
} }
bounds.foldsInBounds(_eo); bounds.foldsInBounds(_eo);
_eo.invalidate(); return true;
} }
/* /*
@ -148,43 +148,43 @@ public:
* G. Rudolph: Globale Optimierung mit parallelen Evolutions- * G. Rudolph: Globale Optimierung mit parallelen Evolutions-
* strategien, Diploma Thesis, University of Dortmund, 1990 * strategien, Diploma Thesis, University of Dortmund, 1990
*/ */
// Code from Thomas Baeck // Code from Thomas Baeck
virtual void operator()( eoEsFull<FitT> & _eo ) virtual bool operator()( eoEsFull<FitT> & _eo )
{ {
/* /*
* First: mutate standard deviations (as above). * First: mutate standard deviations (as above).
*/ */
double global = exp(TauGlb * rng.normal()); double global = exp(TauGlb * rng.normal());
unsigned i; unsigned i;
for (i = 0; i < _eo.size(); i++) for (i = 0; i < _eo.size(); i++)
{ {
double stdev = _eo.stdevs[i]; double stdev = _eo.stdevs[i];
stdev *= global * exp(TauLcl * rng.normal()); stdev *= global * exp(TauLcl * rng.normal());
if (stdev < stdev_eps) if (stdev < stdev_eps)
stdev = stdev_eps; stdev = stdev_eps;
_eo.stdevs[i] = stdev; _eo.stdevs[i] = stdev;
} }
/* /*
* Mutate rotation angles. * Mutate rotation angles.
*/ */
for (i = 0; i < _eo.correlations.size(); i++) for (i = 0; i < _eo.correlations.size(); i++)
{ {
_eo.correlations[i] += TauBeta * rng.normal(); _eo.correlations[i] += TauBeta * rng.normal();
if ( fabs(_eo.correlations[i]) > M_PI ) if ( fabs(_eo.correlations[i]) > M_PI )
{ {
_eo.correlations[i] -= M_PI * (int) (_eo.correlations[i]/M_PI) ; _eo.correlations[i] -= M_PI * (int) (_eo.correlations[i]/M_PI) ;
} }
} }
/* /*
* Perform correlated mutations. * Perform correlated mutations.
*/ */
@ -192,17 +192,17 @@ public:
double d1,d2, S, C; double d1,d2, S, C;
vector<double> VarStp(_eo.size()); vector<double> VarStp(_eo.size());
for (i = 0; i < _eo.size(); i++) for (i = 0; i < _eo.size(); i++)
VarStp[i] = _eo.stdevs[i] * rng.normal(); VarStp[i] = _eo.stdevs[i] * rng.normal();
unsigned nq = _eo.correlations.size() - 1; unsigned nq = _eo.correlations.size() - 1;
for (k = 0; k < _eo.size()-1; k++) for (k = 0; k < _eo.size()-1; k++)
{ {
n1 = _eo.size() - k - 1; n1 = _eo.size() - k - 1;
n2 = _eo.size() - 1; n2 = _eo.size() - 1;
for (i = 0; i < k; i++) for (i = 0; i < k; i++)
{ {
d1 = VarStp[n1]; d1 = VarStp[n1];
d2 = VarStp[n2]; d2 = VarStp[n2];
@ -214,13 +214,13 @@ public:
nq--; nq--;
} }
} }
for (i = 0; i < _eo.size(); i++) for (i = 0; i < _eo.size(); i++)
_eo[i] += VarStp[i]; _eo[i] += VarStp[i];
bounds.foldsInBounds(_eo); bounds.foldsInBounds(_eo);
_eo.invalidate(); return true;
} }
private : private :
@ -243,14 +243,14 @@ public:
TauLcl /= sqrt( 2.0 * sqrt( (double)size ) ); TauLcl /= sqrt( 2.0 * sqrt( (double)size ) );
TauGlb /= sqrt( 2.0 * ( (double) size ) ); TauGlb /= sqrt( 2.0 * ( (double) size ) );
} }
void init(eoEsFull<FitT>, eoEsMutationInit& _init) void init(eoEsFull<FitT>, eoEsMutationInit& _init)
{ {
init(eoEsStdev<FitT>(), _init); init(eoEsStdev<FitT>(), _init);
TauBeta = _init.TauBeta(); TauBeta = _init.TauBeta();
} }
// the data // the data
//========= //=========
double TauLcl; /* Local factor for mutation of std deviations */ double TauLcl; /* Local factor for mutation of std deviations */
double TauGlb; /* Global factor for mutation of std deviations */ double TauGlb; /* Global factor for mutation of std deviations */

View file

@ -33,10 +33,10 @@
/** /**
\ingroup EvolutionStrategies \ingroup EvolutionStrategies
Crossover for Evolutionary strategie style representation, Crossover for Evolutionary strategie style representation,
supporting co-evolving standard deviations. supporting co-evolving standard deviations.
Simply calls a crossover for the object variables, Simply calls a crossover for the object variables,
and a crossover for teh StdDev and a crossover for teh StdDev
*/ */
@ -44,26 +44,30 @@ template <class EOT>
class eoEsStdevXOver : public eoQuadOp<EOT> class eoEsStdevXOver : public eoQuadOp<EOT>
{ {
public : public :
eoEsStdevXOver(eoGenericQuadOp<vector<double> > & _objectXOver, eoEsStdevXOver(eoQuadOp<vector<double> > & _objectXOver,
eoGenericQuadOp<vector<double> > & _stdDevXOver) : eoQuadOp<vector<double> > & _stdDevXOver) :
objectXOver(_objectXOver), stdDevXOver(_stdDevXOver) {} objectXOver(_objectXOver), stdDevXOver(_stdDevXOver) {}
std::string className(void) const { return "eoEsStdevXOver"; } std::string className(void) const { return "eoEsStdevXOver"; }
void operator()(EOT & _eo1, EOT & _eo2) bool operator()(EOT & _eo1, EOT & _eo2)
{ {
bool objectChanged = objectXOver(_eo1, _eo2); // as vector<double> bool objectChanged = objectXOver(_eo1, _eo2); // as vector<double>
bool stdDevChanged = stdDevXOver(_eo1.stdevs, _eo2.stdevs); bool stdDevChanged = stdDevXOver(_eo1.stdevs, _eo2.stdevs);
/// Marc, I didn't change it, but if only the stdev has changed,
/// doesn't that mean that the fitness is stil valid. Maarten
if ( objectChanged || stdDevChanged ) if ( objectChanged || stdDevChanged )
{ {
_eo1.invalidate(); return true;
_eo2.invalidate();
} }
return false;
} }
private: private:
eoGenericQuadOp<vector<double> > & objectXOver; eoQuadOp<vector<double> > & objectXOver;
eoGenericQuadOp<vector<double> > & stdDevXOver; eoQuadOp<vector<double> > & stdDevXOver;
}; };
/* A question: it seems it really makes no difference to have /* A question: it seems it really makes no difference to have

View file

@ -31,27 +31,26 @@
in eoRealOp.h. in eoRealOp.h.
So they can be used when part of the genotype is a vector<double> ... So they can be used when part of the genotype is a vector<double> ...
In the long run, they should replace completely the operators from eoRealOp In the long run, they should replace completely the operators from eoRealOp
when all constructs using eoOp will be able to use the corresponding when all constructs using eoOp will be able to use the corresponding
eoGenericOp - as it is already done in eoProportinoalCombinedOp eoGenericOp - as it is already done in eoProportinoalCombinedOp
MS January 25. 2001 MS January 25. 2001
*/ */
#include <algorithm> // swap_ranges #include <algorithm> // swap_ranges
#include <utils/eoRNG.h> #include <utils/eoRNG.h>
#include <eoGenericMonOp.h> #include <eoOp.h>
#include <eoGenericQuadOp.h>
#include <es/eoRealBounds.h> #include <es/eoRealBounds.h>
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** eoUniformMutation --> changes all values of the vector /** eoUniformMutation --> changes all values of the vector
by uniform choice with range epsilon by uniform choice with range epsilon
with probability p_change per variable with probability p_change per variable
\class eoUniformMutation eoRealOp.h Tutorial/eoRealOp.h \class eoUniformMutation eoRealOp.h Tutorial/eoRealOp.h
\ingroup parameteric \ingroup parameteric
*/ */
template<class EOT> class eoGenericUniformMutation: public eoGenericMonOp<EOT> template<class EOT> class eoGenericUniformMutation: public eoMonOp<EOT>
{ {
public: public:
/** /**
@ -61,8 +60,8 @@ template<class EOT> class eoGenericUniformMutation: public eoGenericMonOp<EOT>
* @param _epsilon the range for uniform nutation * @param _epsilon the range for uniform nutation
* @param _p_change the probability to change a given coordinate * @param _p_change the probability to change a given coordinate
*/ */
eoGenericUniformMutation(const double& _epsilon, eoGenericUniformMutation(const double& _epsilon,
const double& _p_change = 1.0): const double& _p_change = 1.0):
bounds(eoDummyVectorNoBounds), epsilon(_epsilon), p_change(_p_change) {} bounds(eoDummyVectorNoBounds), epsilon(_epsilon), p_change(_p_change) {}
/** /**
@ -71,23 +70,23 @@ template<class EOT> class eoGenericUniformMutation: public eoGenericMonOp<EOT>
* @param _epsilon the range for uniform nutation * @param _epsilon the range for uniform nutation
* @param _p_change the probability to change a given coordinate * @param _p_change the probability to change a given coordinate
*/ */
eoGenericUniformMutation(eoRealVectorBounds & _bounds, eoGenericUniformMutation(eoRealVectorBounds & _bounds,
const double& _epsilon, const double& _p_change = 1.0): const double& _epsilon, const double& _p_change = 1.0):
bounds(_bounds), epsilon(_epsilon), p_change(_p_change) {} bounds(_bounds), epsilon(_epsilon), p_change(_p_change) {}
/// The class name. /// The class name.
string className() const { return "eoGenericUniformMutation"; } string className() const { return "eoGenericUniformMutation"; }
/** /**
* Do it! * Do it!
* @param _eo The cromosome undergoing the mutation * @param _eo The cromosome undergoing the mutation
*/ */
bool operator()(EOT& _eo) bool operator()(EOT& _eo)
{ {
bool hasChanged=false; bool hasChanged=false;
for (unsigned lieu=0; lieu<_eo.size(); lieu++) for (unsigned lieu=0; lieu<_eo.size(); lieu++)
{ {
if (rng.flip(p_change)) if (rng.flip(p_change))
{ {
// check the bounds // check the bounds
double emin = _eo[lieu]-epsilon; double emin = _eo[lieu]-epsilon;
@ -104,21 +103,21 @@ template<class EOT> class eoGenericUniformMutation: public eoGenericMonOp<EOT>
return true; return true;
return false; return false;
} }
private: private:
eoRealVectorBounds & bounds; eoRealVectorBounds & bounds;
double epsilon; double epsilon;
double p_change; double p_change;
}; };
/** eoDetUniformMutation --> changes exactly k values of the vector /** eoDetUniformMutation --> changes exactly k values of the vector
by uniform choice with range epsilon by uniform choice with range epsilon
\class eoDetUniformMutation eoRealOp.h Tutorial/eoRealOp.h \class eoDetUniformMutation eoRealOp.h Tutorial/eoRealOp.h
\ingroup parameteric \ingroup parameteric
*/ */
template<class EOT> class eoGenericDetUniformMutation: template<class EOT> class eoGenericDetUniformMutation:
public eoGenericMonOp<EOT> public eoMonOp<EOT>
{ {
public: public:
/** /**
@ -126,8 +125,8 @@ template<class EOT> class eoGenericDetUniformMutation:
* @param _epsilon the range for uniform nutation * @param _epsilon the range for uniform nutation
* @param number of coordinate to modify * @param number of coordinate to modify
*/ */
eoGenericDetUniformMutation(const double& _epsilon, eoGenericDetUniformMutation(const double& _epsilon,
const unsigned& _no = 1): const unsigned& _no = 1):
bounds(eoDummyVectorNoBounds), epsilon(_epsilon), no(_no) {} bounds(eoDummyVectorNoBounds), epsilon(_epsilon), no(_no) {}
/** /**
@ -136,18 +135,18 @@ template<class EOT> class eoGenericDetUniformMutation:
* @param _epsilon the range for uniform nutation * @param _epsilon the range for uniform nutation
* @param number of coordinate to modify * @param number of coordinate to modify
*/ */
eoGenericDetUniformMutation(eoRealVectorBounds & _bounds, eoGenericDetUniformMutation(eoRealVectorBounds & _bounds,
const double& _epsilon, const unsigned& _no = 1): const double& _epsilon, const unsigned& _no = 1):
bounds(_bounds), epsilon(_epsilon), no(_no) {} bounds(_bounds), epsilon(_epsilon), no(_no) {}
/// The class name. /// The class name.
string className() const { return "eoGenericDetUniformMutation"; } string className() const { return "eoGenericDetUniformMutation"; }
/** /**
* Do it! * Do it!
* @param _eo The cromosome undergoing the mutation * @param _eo The cromosome undergoing the mutation
*/ */
bool operator()(EOT& _eo) bool operator()(EOT& _eo)
{ {
for (unsigned i=0; i<no; i++) for (unsigned i=0; i<no; i++)
{ {
@ -175,37 +174,37 @@ private:
// two arithmetical crossovers // two arithmetical crossovers
/** eoSegmentCrossover --> uniform choice in segment /** eoSegmentCrossover --> uniform choice in segment
== arithmetical with same value along all coordinates == arithmetical with same value along all coordinates
\class eoSegmentCrossover eoRealOp.h Tutorial/eoRealOp.h \class eoSegmentCrossover eoRealOp.h Tutorial/eoRealOp.h
\ingroup parameteric \ingroup parameteric
*/ */
template<class EOT> class eoGenericSegmentCrossover: public eoGenericQuadOp<EOT> template<class EOT> class eoGenericSegmentCrossover: public eoQuadOp<EOT>
{ {
public: public:
/** /**
* (Default) Constructor. * (Default) Constructor.
* The bounds are initialized with the global object that says: no bounds. * The bounds are initialized with the global object that says: no bounds.
* *
* @param _alphaMin the amount of exploration OUTSIDE the parents * @param _alphaMin the amount of exploration OUTSIDE the parents
* as in BLX-alpha notation (Eshelman and Schaffer) * as in BLX-alpha notation (Eshelman and Schaffer)
* 0 == contractive application * 0 == contractive application
* Must be positive * Must be positive
*/ */
eoGenericSegmentCrossover(const double& _alpha = 0.0) : eoGenericSegmentCrossover(const double& _alpha = 0.0) :
bounds(eoDummyVectorNoBounds), alpha(_alpha), range(1+2*_alpha) {} bounds(eoDummyVectorNoBounds), alpha(_alpha), range(1+2*_alpha) {}
/** /**
* Constructor with bounds * Constructor with bounds
* @param _bounds an eoRealVectorBounds that contains the bounds * @param _bounds an eoRealVectorBounds that contains the bounds
* @param _alphaMin the amount of exploration OUTSIDE the parents * @param _alphaMin the amount of exploration OUTSIDE the parents
* as in BLX-alpha notation (Eshelman and Schaffer) * as in BLX-alpha notation (Eshelman and Schaffer)
* 0 == contractive application * 0 == contractive application
* Must be positive * Must be positive
*/ */
eoGenericSegmentCrossover(eoRealVectorBounds & _bounds, eoGenericSegmentCrossover(eoRealVectorBounds & _bounds,
const double& _alpha = 0.0) : const double& _alpha = 0.0) :
bounds(_bounds), alpha(_alpha), range(1+2*_alpha) {} bounds(_bounds), alpha(_alpha), range(1+2*_alpha) {}
/// The class name. /// The class name.
@ -216,12 +215,12 @@ template<class EOT> class eoGenericSegmentCrossover: public eoGenericQuadOp<EOT>
* @param _eo1 The first parent * @param _eo1 The first parent
* @param _eo2 The first parent * @param _eo2 The first parent
*/ */
bool operator()(EOT& _eo1, EOT& _eo2) bool operator()(EOT& _eo1, EOT& _eo2)
{ {
unsigned i; unsigned i;
double r1, r2, fact; double r1, r2, fact;
double alphaMin = -alpha; double alphaMin = -alpha;
double alphaMax = 1+alpha; double alphaMax = 1+alpha;
if ( (alpha == 0.0) || bounds.hasNoBoundAtAll() ) // no check to perform if ( (alpha == 0.0) || bounds.hasNoBoundAtAll() ) // no check to perform
fact = -alpha + rng.uniform(range); // in [-alpha,1+alpha) fact = -alpha + rng.uniform(range); // in [-alpha,1+alpha)
else // look for the bounds for fact else // look for the bounds for fact
@ -238,7 +237,7 @@ template<class EOT> class eoGenericSegmentCrossover: public eoGenericQuadOp<EOT>
{ {
alphaMin = max(alphaMin, (bounds.minimum(i)-rmin)/length); alphaMin = max(alphaMin, (bounds.minimum(i)-rmin)/length);
alphaMin = max(alphaMin, (rmax-bounds.maximum(i))/length); alphaMin = max(alphaMin, (rmax-bounds.maximum(i))/length);
} }
if (bounds.isMaxBounded(i)) if (bounds.isMaxBounded(i))
{ {
alphaMax = min(alphaMax, (bounds.maximum(i)-rmin)/length); alphaMax = min(alphaMax, (bounds.maximum(i)-rmin)/length);
@ -264,28 +263,28 @@ protected:
double alpha; double alpha;
double range; // == 1+2*alpha double range; // == 1+2*alpha
}; };
/** eoArithmeticCrossover --> uniform choice in hypercube /** eoArithmeticCrossover --> uniform choice in hypercube
== arithmetical with different values for each coordinate == arithmetical with different values for each coordinate
\class eoArithmeticCrossover eoRealOp.h Tutorial/eoRealOp.h \class eoArithmeticCrossover eoRealOp.h Tutorial/eoRealOp.h
\ingroup parameteric \ingroup parameteric
*/ */
template<class EOT> class eoGenericArithmeticCrossover: template<class EOT> class eoGenericArithmeticCrossover:
public eoGenericQuadOp<EOT> public eoQuadOp<EOT>
{ {
public: public:
/** /**
* (Default) Constructor. * (Default) Constructor.
* The bounds are initialized with the global object that says: no bounds. * The bounds are initialized with the global object that says: no bounds.
* *
* @param _alphaMin the amount of exploration OUTSIDE the parents * @param _alphaMin the amount of exploration OUTSIDE the parents
* as in BLX-alpha notation (Eshelman and Schaffer) * as in BLX-alpha notation (Eshelman and Schaffer)
* 0 == contractive application * 0 == contractive application
* Must be positive * Must be positive
*/ */
eoGenericArithmeticCrossover(const double& _alpha = 0.0): eoGenericArithmeticCrossover(const double& _alpha = 0.0):
bounds(eoDummyVectorNoBounds), alpha(_alpha), range(1+2*_alpha) bounds(eoDummyVectorNoBounds), alpha(_alpha), range(1+2*_alpha)
{ {
if (_alpha < 0) if (_alpha < 0)
throw runtime_error("BLX coefficient should be positive"); throw runtime_error("BLX coefficient should be positive");
@ -294,14 +293,14 @@ template<class EOT> class eoGenericArithmeticCrossover:
/** /**
* Constructor with bounds * Constructor with bounds
* @param _bounds an eoRealVectorBounds that contains the bounds * @param _bounds an eoRealVectorBounds that contains the bounds
* @param _alphaMin the amount of exploration OUTSIDE the parents * @param _alphaMin the amount of exploration OUTSIDE the parents
* as in BLX-alpha notation (Eshelman and Schaffer) * as in BLX-alpha notation (Eshelman and Schaffer)
* 0 == contractive application * 0 == contractive application
* Must be positive * Must be positive
*/ */
eoGenericArithmeticCrossover(eoRealVectorBounds & _bounds, eoGenericArithmeticCrossover(eoRealVectorBounds & _bounds,
const double& _alpha = 0.0): const double& _alpha = 0.0):
bounds(_bounds), alpha(_alpha), range(1+2*_alpha) bounds(_bounds), alpha(_alpha), range(1+2*_alpha)
{ {
if (_alpha < 0) if (_alpha < 0)
throw runtime_error("BLX coefficient should be positive"); throw runtime_error("BLX coefficient should be positive");
@ -315,7 +314,7 @@ template<class EOT> class eoGenericArithmeticCrossover:
* @param _eo1 The first parent * @param _eo1 The first parent
* @param _eo2 The first parent * @param _eo2 The first parent
*/ */
bool operator()(EOT& _eo1, EOT& _eo2) bool operator()(EOT& _eo1, EOT& _eo2)
{ {
unsigned i; unsigned i;
double r1, r2, fact; double r1, r2, fact;
@ -344,7 +343,7 @@ template<class EOT> class eoGenericArithmeticCrossover:
{ {
alphaMin = max(alphaMin, (bounds.minimum(i)-rmin)/length); alphaMin = max(alphaMin, (bounds.minimum(i)-rmin)/length);
alphaMin = max(alphaMin, (rmax-bounds.maximum(i))/length); alphaMin = max(alphaMin, (rmax-bounds.maximum(i))/length);
} }
if (bounds.isMaxBounded(i)) if (bounds.isMaxBounded(i))
{ {
alphaMax = min(alphaMax, (bounds.maximum(i)-rmin)/length); alphaMax = min(alphaMax, (bounds.maximum(i)-rmin)/length);
@ -363,14 +362,14 @@ protected:
double alpha; double alpha;
double range; // == 1+2*alphaMin double range; // == 1+2*alphaMin
}; };
/** eoRealUxOver --> Uniform crossover, also termed intermediate crossover /** eoRealUxOver --> Uniform crossover, also termed intermediate crossover
\class eoRealUxOver eoRealOp.h Tutorial/eoRealOp.h \class eoRealUxOver eoRealOp.h Tutorial/eoRealOp.h
\ingroup parameteric \ingroup parameteric
*/ */
template<class EOT> class eoGenericRealUxOver: public eoGenericQuadOp<EOT> template<class EOT> class eoGenericRealUxOver: public eoQuadOp<EOT>
{ {
public: public:
/** /**
@ -378,7 +377,7 @@ template<class EOT> class eoGenericRealUxOver: public eoGenericQuadOp<EOT>
* @param _preference bias in the choice (usually, no bias == 0.5) * @param _preference bias in the choice (usually, no bias == 0.5)
*/ */
eoGenericRealUxOver(double _preference = 0.5): preference(_preference) eoGenericRealUxOver(double _preference = 0.5): preference(_preference)
{ {
if ( (_preference <= 0.0) || (_preference >= 1.0) ) if ( (_preference <= 0.0) || (_preference >= 1.0) )
runtime_error("UxOver --> invalid preference"); runtime_error("UxOver --> invalid preference");
} }
@ -392,10 +391,10 @@ template<class EOT> class eoGenericRealUxOver: public eoGenericQuadOp<EOT>
* @param _eo2 The second parent * @param _eo2 The second parent
* @runtime_error if sizes don't match * @runtime_error if sizes don't match
*/ */
bool operator()(EOT& _eo1, EOT& _eo2) bool operator()(EOT& _eo1, EOT& _eo2)
{ {
if ( _eo1.size() != _eo2.size()) if ( _eo1.size() != _eo2.size())
runtime_error("eoRealUxOver --> chromosomes sizes don't match" ); runtime_error("eoRealUxOver --> chromosomes sizes don't match" );
bool changed = false; bool changed = false;
for (unsigned int i=0; i<_eo1.size(); i++) for (unsigned int i=0; i<_eo1.size(); i++)
{ {
@ -415,7 +414,7 @@ template<class EOT> class eoGenericRealUxOver: public eoGenericQuadOp<EOT>
private: private:
double preference; double preference;
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//@} //@}

View file

@ -41,7 +41,7 @@
* to enable dynamic mutations (see eoOenFithMutation below). * to enable dynamic mutations (see eoOenFithMutation below).
* *
* As for the bounds, the values are here folded back into the bounds. * As for the bounds, the values are here folded back into the bounds.
* The other possiblity would be to iterate until we fall inside the bounds - * The other possiblity would be to iterate until we fall inside the bounds -
* but this sometimes takes a long time!!! * but this sometimes takes a long time!!!
*/ */
@ -55,7 +55,7 @@ template<class EOT> class eoNormalMutation: public eoMonOp<EOT>
* @param _sigma the range for uniform nutation * @param _sigma the range for uniform nutation
* @param _p_change the probability to change a given coordinate * @param _p_change the probability to change a given coordinate
*/ */
eoNormalMutation(double & _sigma, const double& _p_change = 1.0): eoNormalMutation(double & _sigma, const double& _p_change = 1.0):
sigma(_sigma), bounds(eoDummyVectorNoBounds), p_change(_p_change) {} sigma(_sigma), bounds(eoDummyVectorNoBounds), p_change(_p_change) {}
/** /**
@ -64,33 +64,32 @@ template<class EOT> class eoNormalMutation: public eoMonOp<EOT>
* @param _sigma the range for uniform nutation * @param _sigma the range for uniform nutation
* @param _p_change the probability to change a given coordinate * @param _p_change the probability to change a given coordinate
*/ */
eoNormalMutation(eoRealVectorBounds & _bounds, eoNormalMutation(eoRealVectorBounds & _bounds,
double & _sigma, const double& _p_change = 1.0): double & _sigma, const double& _p_change = 1.0):
sigma(_sigma), bounds(_bounds), p_change(_p_change) {} sigma(_sigma), bounds(_bounds), p_change(_p_change) {}
/// The class name. /// The class name.
string className() const { return "eoNormalMutation"; } string className() const { return "eoNormalMutation"; }
/** /**
* Do it! * Do it!
* @param _eo The cromosome undergoing the mutation * @param _eo The cromosome undergoing the mutation
*/ */
void operator()(EOT& _eo) bool operator()(EOT& _eo)
{ {
bool hasChanged=false; bool hasChanged=false;
for (unsigned lieu=0; lieu<_eo.size(); lieu++) for (unsigned lieu=0; lieu<_eo.size(); lieu++)
{ {
if (rng.flip(p_change)) if (rng.flip(p_change))
{ {
_eo[lieu] += sigma*rng.normal(); _eo[lieu] += sigma*rng.normal();
bounds.foldsInBounds(lieu, _eo[lieu]); bounds.foldsInBounds(lieu, _eo[lieu]);
hasChanged = true; hasChanged = true;
} }
} }
if (hasChanged) return hasChanged;
_eo.invalidate();
} }
protected: protected:
double & sigma; double & sigma;
private: private:
@ -98,9 +97,9 @@ private:
double p_change; double p_change;
}; };
/** the dynamic version: just say it is updatable - /** the dynamic version: just say it is updatable -
* and write the update() method! * and write the update() method!
* here the 1 fifth rule: count the proportion of successful mutations, and * here the 1 fifth rule: count the proportion of successful mutations, and
* increase sigma if more than threshold (1/5 !) * increase sigma if more than threshold (1/5 !)
*/ */

View file

@ -35,8 +35,8 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** eoUniformMutation --> changes all values of the vector /** eoUniformMutation --> changes all values of the vector
by uniform choice with range epsilon by uniform choice with range epsilon
with probability p_change per variable with probability p_change per variable
\class eoUniformMutation eoRealOp.h Tutorial/eoRealOp.h \class eoUniformMutation eoRealOp.h Tutorial/eoRealOp.h
\ingroup parameteric \ingroup parameteric
@ -52,7 +52,7 @@ template<class EOT> class eoUniformMutation: public eoMonOp<EOT>
* @param _epsilon the range for uniform nutation * @param _epsilon the range for uniform nutation
* @param _p_change the probability to change a given coordinate * @param _p_change the probability to change a given coordinate
*/ */
eoUniformMutation(const double& _epsilon, const double& _p_change = 1.0): eoUniformMutation(const double& _epsilon, const double& _p_change = 1.0):
bounds(eoDummyVectorNoBounds), epsilon(_epsilon), p_change(_p_change) {} bounds(eoDummyVectorNoBounds), epsilon(_epsilon), p_change(_p_change) {}
/** /**
@ -61,23 +61,23 @@ template<class EOT> class eoUniformMutation: public eoMonOp<EOT>
* @param _epsilon the range for uniform nutation * @param _epsilon the range for uniform nutation
* @param _p_change the probability to change a given coordinate * @param _p_change the probability to change a given coordinate
*/ */
eoUniformMutation(eoRealVectorBounds & _bounds, eoUniformMutation(eoRealVectorBounds & _bounds,
const double& _epsilon, const double& _p_change = 1.0): const double& _epsilon, const double& _p_change = 1.0):
bounds(_bounds), epsilon(_epsilon), p_change(_p_change) {} bounds(_bounds), epsilon(_epsilon), p_change(_p_change) {}
/// The class name. /// The class name.
string className() const { return "eoUniformMutation"; } string className() const { return "eoUniformMutation"; }
/** /**
* Do it! * Do it!
* @param _eo The cromosome undergoing the mutation * @param _eo The cromosome undergoing the mutation
*/ */
void operator()(EOT& _eo) bool operator()(EOT& _eo)
{ {
bool hasChanged=false; bool hasChanged=false;
for (unsigned lieu=0; lieu<_eo.size(); lieu++) for (unsigned lieu=0; lieu<_eo.size(); lieu++)
{ {
if (rng.flip(p_change)) if (rng.flip(p_change))
{ {
// check the bounds // check the bounds
double emin = _eo[lieu]-epsilon; double emin = _eo[lieu]-epsilon;
@ -90,18 +90,17 @@ template<class EOT> class eoUniformMutation: public eoMonOp<EOT>
hasChanged = true; hasChanged = true;
} }
} }
if (hasChanged) return hasChanged;
_eo.invalidate();
} }
private: private:
eoRealVectorBounds & bounds; eoRealVectorBounds & bounds;
double epsilon; double epsilon;
double p_change; double p_change;
}; };
/** eoDetUniformMutation --> changes exactly k values of the vector /** eoDetUniformMutation --> changes exactly k values of the vector
by uniform choice with range epsilon by uniform choice with range epsilon
\class eoDetUniformMutation eoRealOp.h Tutorial/eoRealOp.h \class eoDetUniformMutation eoRealOp.h Tutorial/eoRealOp.h
\ingroup parameteric \ingroup parameteric
*/ */
@ -114,7 +113,7 @@ template<class EOT> class eoDetUniformMutation: public eoMonOp<EOT>
* @param _epsilon the range for uniform nutation * @param _epsilon the range for uniform nutation
* @param number of coordinate to modify * @param number of coordinate to modify
*/ */
eoDetUniformMutation(const double& _epsilon, const unsigned& _no = 1): eoDetUniformMutation(const double& _epsilon, const unsigned& _no = 1):
bounds(eoDummyVectorNoBounds), epsilon(_epsilon), no(_no) {} bounds(eoDummyVectorNoBounds), epsilon(_epsilon), no(_no) {}
/** /**
@ -134,12 +133,11 @@ template<class EOT> class eoDetUniformMutation: public eoMonOp<EOT>
* Do it! * Do it!
* @param _eo The cromosome undergoing the mutation * @param _eo The cromosome undergoing the mutation
*/ */
void operator()(EOT& _eo) bool operator()(EOT& _eo)
{ {
_eo.invalidate();
for (unsigned i=0; i<no; i++) for (unsigned i=0; i<no; i++)
{ {
unsigned lieu = rng.random(_eo.size()); unsigned lieu = rng.random(_eo.size());
// actually, we should test that we don't re-modify same variable! // actually, we should test that we don't re-modify same variable!
// check the bounds // check the bounds
@ -150,7 +148,9 @@ template<class EOT> class eoDetUniformMutation: public eoMonOp<EOT>
if (bounds.isMaxBounded(lieu)) if (bounds.isMaxBounded(lieu))
emax = min(bounds.maximum(lieu), emax); emax = min(bounds.maximum(lieu), emax);
_eo[lieu] = emin + (emax-emin)*rng.uniform(); _eo[lieu] = emin + (emax-emin)*rng.uniform();
} }
return true;
} }
private: private:
@ -162,7 +162,7 @@ private:
// two arithmetical crossovers // two arithmetical crossovers
/** eoSegmentCrossover --> uniform choice in segment /** eoSegmentCrossover --> uniform choice in segment
== arithmetical with same value along all coordinates == arithmetical with same value along all coordinates
\class eoSegmentCrossover eoRealOp.h Tutorial/eoRealOp.h \class eoSegmentCrossover eoRealOp.h Tutorial/eoRealOp.h
\ingroup parameteric \ingroup parameteric
@ -175,12 +175,12 @@ template<class EOT> class eoSegmentCrossover: public eoQuadOp<EOT>
* (Default) Constructor. * (Default) Constructor.
* The bounds are initialized with the global object that says: no bounds. * The bounds are initialized with the global object that says: no bounds.
* *
* @param _alphaMin the amount of exploration OUTSIDE the parents * @param _alphaMin the amount of exploration OUTSIDE the parents
* as in BLX-alpha notation (Eshelman and Schaffer) * as in BLX-alpha notation (Eshelman and Schaffer)
* 0 == contractive application * 0 == contractive application
* Must be positive * Must be positive
*/ */
eoSegmentCrossover(const double& _alpha = 0.0) : eoSegmentCrossover(const double& _alpha = 0.0) :
bounds(eoDummyVectorNoBounds), alpha(_alpha), range(1+2*_alpha) {} bounds(eoDummyVectorNoBounds), alpha(_alpha), range(1+2*_alpha) {}
/** /**
@ -203,12 +203,12 @@ template<class EOT> class eoSegmentCrossover: public eoQuadOp<EOT>
* @param _eo1 The first parent * @param _eo1 The first parent
* @param _eo2 The first parent * @param _eo2 The first parent
*/ */
void operator()(EOT& _eo1, EOT& _eo2) bool operator()(EOT& _eo1, EOT& _eo2)
{ {
unsigned i; unsigned i;
double r1, r2, fact; double r1, r2, fact;
double alphaMin = -alpha; double alphaMin = -alpha;
double alphaMax = 1+alpha; double alphaMax = 1+alpha;
if (alpha == 0.0) // no check to perform if (alpha == 0.0) // no check to perform
fact = -alpha + rng.uniform(range); // in [-alpha,1+alpha) fact = -alpha + rng.uniform(range); // in [-alpha,1+alpha)
else // look for the bounds for fact else // look for the bounds for fact
@ -225,7 +225,7 @@ template<class EOT> class eoSegmentCrossover: public eoQuadOp<EOT>
{ {
alphaMin = max(alphaMin, (bounds.minimum(i)-rmin)/length); alphaMin = max(alphaMin, (bounds.minimum(i)-rmin)/length);
alphaMin = max(alphaMin, (rmax-bounds.maximum(i))/length); alphaMin = max(alphaMin, (rmax-bounds.maximum(i))/length);
} }
if (bounds.isMaxBounded(i)) if (bounds.isMaxBounded(i))
{ {
alphaMax = min(alphaMax, (bounds.maximum(i)-rmin)/length); alphaMax = min(alphaMax, (bounds.maximum(i)-rmin)/length);
@ -243,8 +243,7 @@ template<class EOT> class eoSegmentCrossover: public eoQuadOp<EOT>
_eo1[i] = fact * r1 + (1-fact) * r2; _eo1[i] = fact * r1 + (1-fact) * r2;
_eo2[i] = (1-fact) * r1 + fact * r2; _eo2[i] = (1-fact) * r1 + fact * r2;
} }
_eo1.invalidate(); // shoudl test if fact was 0 or 1 :-))) return true; // shoudl test if fact was 0 or 1 :-)))
_eo2.invalidate();
} }
protected: protected:
@ -252,8 +251,8 @@ protected:
double alpha; double alpha;
double range; // == 1+2*alpha double range; // == 1+2*alpha
}; };
/** eoArithmeticCrossover --> uniform choice in hypercube /** eoArithmeticCrossover --> uniform choice in hypercube
== arithmetical with different values for each coordinate == arithmetical with different values for each coordinate
\class eoArithmeticCrossover eoRealOp.h Tutorial/eoRealOp.h \class eoArithmeticCrossover eoRealOp.h Tutorial/eoRealOp.h
\ingroup parameteric \ingroup parameteric
@ -266,13 +265,13 @@ template<class EOT> class eoArithmeticCrossover: public eoQuadOp<EOT>
* (Default) Constructor. * (Default) Constructor.
* The bounds are initialized with the global object that says: no bounds. * The bounds are initialized with the global object that says: no bounds.
* *
* @param _alphaMin the amount of exploration OUTSIDE the parents * @param _alphaMin the amount of exploration OUTSIDE the parents
* as in BLX-alpha notation (Eshelman and Schaffer) * as in BLX-alpha notation (Eshelman and Schaffer)
* 0 == contractive application * 0 == contractive application
* Must be positive * Must be positive
*/ */
eoArithmeticCrossover(const double& _alpha = 0.0): eoArithmeticCrossover(const double& _alpha = 0.0):
bounds(eoDummyVectorNoBounds), alpha(_alpha), range(1+2*_alpha) bounds(eoDummyVectorNoBounds), alpha(_alpha), range(1+2*_alpha)
{ {
if (_alpha < 0) if (_alpha < 0)
throw runtime_error("BLX coefficient should be positive"); throw runtime_error("BLX coefficient should be positive");
@ -302,7 +301,7 @@ template<class EOT> class eoArithmeticCrossover: public eoQuadOp<EOT>
* @param _eo1 The first parent * @param _eo1 The first parent
* @param _eo2 The first parent * @param _eo2 The first parent
*/ */
void operator()(EOT& _eo1, EOT& _eo2) bool operator()(EOT& _eo1, EOT& _eo2)
{ {
unsigned i; unsigned i;
double r1, r2, fact; double r1, r2, fact;
@ -331,7 +330,7 @@ template<class EOT> class eoArithmeticCrossover: public eoQuadOp<EOT>
{ {
alphaMin = max(alphaMin, (bounds.minimum(i)-rmin)/length); alphaMin = max(alphaMin, (bounds.minimum(i)-rmin)/length);
alphaMin = max(alphaMin, (rmax-bounds.maximum(i))/length); alphaMin = max(alphaMin, (rmax-bounds.maximum(i))/length);
} }
if (bounds.isMaxBounded(i)) if (bounds.isMaxBounded(i))
{ {
alphaMax = min(alphaMax, (bounds.maximum(i)-rmin)/length); alphaMax = min(alphaMax, (bounds.maximum(i)-rmin)/length);
@ -342,16 +341,16 @@ template<class EOT> class eoArithmeticCrossover: public eoQuadOp<EOT>
_eo2[i] = (1-fact) * rmin + fact * rmax; _eo2[i] = (1-fact) * rmin + fact * rmax;
} }
} }
_eo1.invalidate();
_eo2.invalidate(); return true;
} }
protected: protected:
eoRealVectorBounds & bounds; eoRealVectorBounds & bounds;
double alpha; double alpha;
double range; // == 1+2*alphaMin double range; // == 1+2*alphaMin
}; };
/** eoRealUxOver --> Uniform crossover, also termed intermediate crossover /** eoRealUxOver --> Uniform crossover, also termed intermediate crossover
\class eoRealUxOver eoRealOp.h Tutorial/eoRealOp.h \class eoRealUxOver eoRealOp.h Tutorial/eoRealOp.h
@ -380,10 +379,10 @@ template<class EOT> class eoRealUxOver: public eoQuadOp<EOT>
* @param _eo2 The second parent * @param _eo2 The second parent
* @runtime_error if sizes don't match * @runtime_error if sizes don't match
*/ */
void operator()(EOT& _eo1, EOT& _eo2) bool operator()(EOT& _eo1, EOT& _eo2)
{ {
if ( _eo1.size() != _eo2.size()) if ( _eo1.size() != _eo2.size())
runtime_error("UxOver --> chromosomes sizes don't match" ); runtime_error("UxOver --> chromosomes sizes don't match" );
bool changed = false; bool changed = false;
for (unsigned int i=0; i<_eo1.size(); i++) for (unsigned int i=0; i<_eo1.size(); i++)
{ {
@ -396,11 +395,7 @@ template<class EOT> class eoRealUxOver: public eoQuadOp<EOT>
changed = true; changed = true;
} }
} }
if (changed) return changed;
{
_eo1.invalidate();
_eo2.invalidate();
}
} }
private: private:
float preference; float preference;

View file

@ -60,7 +60,7 @@
#include <ga/eoBit.h> #include <ga/eoBit.h>
/** eoBitFlip --> changes 1 bit /** eoBitFlip --> changes 1 bit
\class eoBitBitFlip eoBitOp.h ga/eoBitOp.h \class eoBitBitFlip eoBitOp.h ga/eoBitOp.h
\ingroup bitstring \ingroup bitstring
*/ */
@ -70,20 +70,20 @@ template<class Chrom> class eoOneBitFlip: public eoMonOp<Chrom>
public: public:
/// The class name. /// The class name.
string className() const { return "eoOneBitFlip"; } string className() const { return "eoOneBitFlip"; }
/** /**
* Change one bit. * Change one bit.
* @param chrom The cromosome which one bit is going to be changed. * @param chrom The cromosome which one bit is going to be changed.
*/ */
void operator()(Chrom& chrom) bool operator()(Chrom& chrom)
{ {
unsigned i = eo::rng.random(chrom.size()); unsigned i = eo::rng.random(chrom.size());
chrom[i] = (chrom[i]) ? false : true; chrom[i] = (chrom[i]) ? false : true;
chrom.invalidate(); return true;
} }
}; };
/** eoDetBitFlip --> changes exactly k bits /** eoDetBitFlip --> changes exactly k bits
\class eoDetBitFlip eoBitOp.h ga/eoBitOp.h \class eoDetBitFlip eoBitOp.h ga/eoBitOp.h
\ingroup bitstring \ingroup bitstring
*/ */
@ -100,12 +100,12 @@ template<class Chrom> class eoDetBitFlip: public eoMonOp<Chrom>
/// The class name. /// The class name.
string className() const { return "eoDetBitFlip"; } string className() const { return "eoDetBitFlip"; }
/** /**
* Change num_bit bits. * Change num_bit bits.
* @param chrom The cromosome which one bit is going to be changed. * @param chrom The cromosome which one bit is going to be changed.
*/ */
void operator()(Chrom& chrom) bool operator()(Chrom& chrom)
{ {
// does not check for duplicate: if someone volunteers .... // does not check for duplicate: if someone volunteers ....
for (unsigned k=0; k<num_bit; k++) for (unsigned k=0; k<num_bit; k++)
@ -113,14 +113,14 @@ template<class Chrom> class eoDetBitFlip: public eoMonOp<Chrom>
unsigned i = eo::rng.random(chrom.size()); unsigned i = eo::rng.random(chrom.size());
chrom[i] = (chrom[i]) ? false : true; chrom[i] = (chrom[i]) ? false : true;
} }
chrom.invalidate(); return true;
} }
private: private:
unsigned num_bit; unsigned num_bit;
}; };
/** eoBitMutation --> classical mutation /** eoBitMutation --> classical mutation
\class eoBitMutation eoBitOp.h ga/eoBitOp.h \class eoBitMutation eoBitOp.h ga/eoBitOp.h
\ingroup bitstring \ingroup bitstring
*/ */
@ -141,7 +141,7 @@ template<class Chrom> class eoBitMutation: public eoMonOp<Chrom>
* Mutate a chromosome. * Mutate a chromosome.
* @param chrom The chromosome to be mutated. * @param chrom The chromosome to be mutated.
*/ */
void operator()(Chrom& chrom) bool operator()(Chrom& chrom)
{ {
bool changed_something = false; bool changed_something = false;
for (unsigned i = 0; i < chrom.size(); i++) for (unsigned i = 0; i < chrom.size(); i++)
@ -151,16 +151,15 @@ template<class Chrom> class eoBitMutation: public eoMonOp<Chrom>
changed_something = true; changed_something = true;
} }
if (changed_something) return changed_something;
chrom.invalidate();
} }
private: private:
double rate; double rate;
}; };
/** eoBitInversion: inverts the bits of the chromosome between an interval /** eoBitInversion: inverts the bits of the chromosome between an interval
\class eoBitInversion eoBitOp.h ga/eoBitOp.h \class eoBitInversion eoBitOp.h ga/eoBitOp.h
\ingroup bitstring \ingroup bitstring
*/ */
@ -175,20 +174,20 @@ template<class Chrom> class eoBitInversion: public eoMonOp<Chrom>
* Inverts a range of bits in a binary chromosome. * Inverts a range of bits in a binary chromosome.
* @param chrom The chromosome whos bits are going to be inverted (a range). * @param chrom The chromosome whos bits are going to be inverted (a range).
*/ */
void operator()(Chrom& chrom) bool operator()(Chrom& chrom)
{ {
unsigned u1 = eo::rng.random(chrom.size() + 1) , u2; unsigned u1 = eo::rng.random(chrom.size() + 1) , u2;
do u2 = eo::rng.random(chrom.size() + 1); while (u1 == u2); do u2 = eo::rng.random(chrom.size() + 1); while (u1 == u2);
unsigned r1 = min(u1, u2), r2 = max(u1, u2); unsigned r1 = min(u1, u2), r2 = max(u1, u2);
reverse(chrom.begin() + r1, chrom.begin() + r2); reverse(chrom.begin() + r1, chrom.begin() + r2);
chrom.invalidate(); return true;
} }
}; };
/** eoBitNext --> next value when bitstring considered as binary value /** eoBitNext --> next value when bitstring considered as binary value
\class eoBitNext eoBitOp.h ga/eoBitOp.h \class eoBitNext eoBitOp.h ga/eoBitOp.h
\ingroup bitstring \ingroup bitstring
*/ */
@ -198,12 +197,12 @@ template<class Chrom> class eoBitNext: public eoMonOp<Chrom>
public: public:
/// The class name. /// The class name.
string className() const { return "eoBitNext"; } string className() const { return "eoBitNext"; }
/** /**
* Change the bit string x to be x+1. * Change the bit string x to be x+1.
* @param chrom The chromosome to be added one. * @param chrom The chromosome to be added one.
*/ */
void operator()(Chrom& chrom) bool operator()(Chrom& chrom)
{ {
for (int i = chrom.size() - 1; i >= 0; i--) for (int i = chrom.size() - 1; i >= 0; i--)
if (chrom[i]) if (chrom[i])
@ -217,12 +216,12 @@ template<class Chrom> class eoBitNext: public eoMonOp<Chrom>
break; break;
} }
chrom.invalidate(); return true;
} }
}; };
/** eoBitPrev --> previous value when bitstring treated as binary value /** eoBitPrev --> previous value when bitstring treated as binary value
\class eoBitPrev eoBitOp.h ga/eoBitOp.h \class eoBitPrev eoBitOp.h ga/eoBitOp.h
\ingroup bitstring \ingroup bitstring
*/ */
@ -232,12 +231,12 @@ template<class Chrom> class eoBitPrev: public eoMonOp<Chrom>
public: public:
/// The class name. /// The class name.
string className() const { return "eoBitPrev"; } string className() const { return "eoBitPrev"; }
/** /**
* Change the bit string x to be x-1. * Change the bit string x to be x-1.
* @param chrom The chromosome to be substracted one. * @param chrom The chromosome to be substracted one.
*/ */
void operator()(Chrom& chrom) bool operator()(Chrom& chrom)
{ {
for (int i = chrom.size() - 1; i >= 0; i--) for (int i = chrom.size() - 1; i >= 0; i--)
if (chrom[i]) if (chrom[i])
@ -249,14 +248,14 @@ template<class Chrom> class eoBitPrev: public eoMonOp<Chrom>
{ {
chrom[i] = 1; chrom[i] = 1;
continue; continue;
} }
chrom.invalidate(); return true;
} }
}; };
/** eo1PtBitXover --> classic 1-point crossover
/** eo1PtBitXover --> classic 1-point crossover
\class eo1PtBitCrossover eoBitOp.h ga/eoBitOp.h \class eo1PtBitCrossover eoBitOp.h ga/eoBitOp.h
\ingroup bitstring \ingroup bitstring
*/ */
@ -272,7 +271,7 @@ template<class Chrom> class eo1PtBitXover: public eoQuadOp<Chrom>
* @param chrom1 The first chromosome. * @param chrom1 The first chromosome.
* @param chrom2 The first chromosome. * @param chrom2 The first chromosome.
*/ */
void operator()(Chrom& chrom1, Chrom& chrom2) bool operator()(Chrom& chrom1, Chrom& chrom2)
{ {
unsigned site = eo::rng.random(min(chrom1.size(), chrom2.size())); unsigned site = eo::rng.random(min(chrom1.size(), chrom2.size()));
@ -280,15 +279,15 @@ template<class Chrom> class eo1PtBitXover: public eoQuadOp<Chrom>
{ {
swap_ranges(chrom1.begin(), chrom1.begin() + site, chrom2.begin()); swap_ranges(chrom1.begin(), chrom1.begin() + site, chrom2.begin());
chrom1.invalidate(); return true;
chrom2.invalidate();
} }
return false;
} }
}; };
/** eoUBitXover --> classic Uniform crossover
/** eoUBitXover --> classic Uniform crossover
\class eoUBitXover eoBitOp.h ga/eoBitOp.h \class eoUBitXover eoBitOp.h ga/eoBitOp.h
\ingroup bitstring \ingroup bitstring
*/ */
@ -298,7 +297,7 @@ template<class Chrom> class eoUBitXover: public eoQuadOp<Chrom>
public: public:
/// (Default) Constructor. /// (Default) Constructor.
eoUBitXover(const float& _preference = 0.5): preference(_preference) eoUBitXover(const float& _preference = 0.5): preference(_preference)
{ {
if ( (_preference <= 0.0) || (_preference >= 1.0) ) if ( (_preference <= 0.0) || (_preference >= 1.0) )
runtime_error("UxOver --> invalid preference"); runtime_error("UxOver --> invalid preference");
} }
@ -311,10 +310,10 @@ template<class Chrom> class eoUBitXover: public eoQuadOp<Chrom>
* @param chrom2 The first chromosome. * @param chrom2 The first chromosome.
* @runtime_error if sizes don't match * @runtime_error if sizes don't match
*/ */
void operator()(Chrom& chrom1, Chrom& chrom2) bool operator()(Chrom& chrom1, Chrom& chrom2)
{ {
if ( chrom1.size() != chrom2.size()) if ( chrom1.size() != chrom2.size())
runtime_error("UxOver --> chromosomes sizes don't match" ); runtime_error("UxOver --> chromosomes sizes don't match" );
bool changed = false; bool changed = false;
for (unsigned int i=0; i<chrom1.size(); i++) for (unsigned int i=0; i<chrom1.size(); i++)
{ {
@ -326,18 +325,14 @@ template<class Chrom> class eoUBitXover: public eoQuadOp<Chrom>
changed = true; changed = true;
} }
} }
if (changed) return changed;
{ }
chrom1.invalidate();
chrom2.invalidate();
}
}
private: private:
float preference; float preference;
}; };
/** eoNPtsBitXover --> n-point crossover
/** eoNPtsBitXover --> n-point crossover
\class eoNPtsBitXover eoBitOp.h ga/eoBitOp.h \class eoNPtsBitXover eoBitOp.h ga/eoBitOp.h
\ingroup bitstring \ingroup bitstring
*/ */
@ -347,29 +342,29 @@ template<class Chrom> class eoNPtsBitXover: public eoQuadOp<Chrom>
public: public:
/// (Default) Constructor. /// (Default) Constructor.
eoNPtsBitXover(const unsigned& _num_points = 2): num_points(_num_points) eoNPtsBitXover(const unsigned& _num_points = 2): num_points(_num_points)
{ {
if (num_points < 1) if (num_points < 1)
runtime_error("NxOver --> invalid number of points"); runtime_error("NxOver --> invalid number of points");
} }
/// The class name. /// The class name.
string className() const { return "eoNPtsBitXover"; } string className() const { return "eoNPtsBitXover"; }
/** /**
* n-point crossover for binary chromosomes. * n-point crossover for binary chromosomes.
* @param chrom1 The first chromosome. * @param chrom1 The first chromosome.
* @param chrom2 The first chromosome. * @param chrom2 The first chromosome.
*/ */
void operator()(Chrom& chrom1, Chrom& chrom2) bool operator()(Chrom& chrom1, Chrom& chrom2)
{ {
unsigned max_size = min(chrom1.size(), chrom2.size()); unsigned max_size = min(chrom1.size(), chrom2.size());
unsigned max_points = min(max_size - 1, num_points); unsigned max_points = min(max_size - 1, num_points);
vector<bool> points(max_size, false); vector<bool> points(max_size, false);
// select ranges of bits to swap // select ranges of bits to swap
do { do {
unsigned bit = eo::rng.random(max_size) + 1; unsigned bit = eo::rng.random(max_size) + 1;
if (points[bit]) if (points[bit])
continue; continue;
else else
@ -378,30 +373,29 @@ template<class Chrom> class eoNPtsBitXover: public eoQuadOp<Chrom>
max_points--; max_points--;
} }
} while (max_points); } while (max_points);
// swap bits between chromosomes // swap bits between chromosomes
bool change = false; bool change = false;
for (unsigned bit = 1; bit < points.size(); bit++) for (unsigned bit = 1; bit < points.size(); bit++)
{ {
if (points[bit]) if (points[bit])
change = !change; change = !change;
if (change) if (change)
swap(chrom1[bit], chrom2[bit]); swap(chrom1[bit], chrom2[bit]);
} }
chrom1.invalidate(); return true;
chrom2.invalidate();
} }
private: private:
unsigned num_points; unsigned num_points;
}; };
/** eoBitGxOver --> Npts crossover when bistring considered /** eoBitGxOver --> Npts crossover when bistring considered
as a string of binary-encoded genes (exchanges genes) as a string of binary-encoded genes (exchanges genes)
Is anybody still using it apart from historians ??? :-) Is anybody still using it apart from historians ??? :-)
\class eoBitGxOver eoBitOp.h ga/eoBitOp.h \class eoBitGxOver eoBitOp.h ga/eoBitOp.h
@ -412,28 +406,28 @@ template<class Chrom> class eoBitGxOver: public eoQuadOp<Chrom>
{ {
public: public:
/// Constructor. /// Constructor.
eoBitGxOver(const unsigned _gene_size, const unsigned _num_points = 2): eoBitGxOver(const unsigned _gene_size, const unsigned _num_points = 2):
gene_size(_gene_size), num_points(_num_points) gene_size(_gene_size), num_points(_num_points)
{ {
if (gene_size < 1) if (gene_size < 1)
runtime_error("GxOver --> invalid gene size"); runtime_error("GxOver --> invalid gene size");
if (num_points < 1) if (num_points < 1)
runtime_error("GxOver --> invalid number of points"); runtime_error("GxOver --> invalid number of points");
} }
/// The class name /// The class name
string className() const { return "eoBitGxOver"; } string className() const { return "eoBitGxOver"; }
/** /**
* Gene crossover for binary chromosomes. * Gene crossover for binary chromosomes.
* @param chrom1 The first chromosome. * @param chrom1 The first chromosome.
* @param chrom2 The first chromosome. * @param chrom2 The first chromosome.
*/ */
void operator()(Chrom& chrom1, Chrom& chrom2) bool operator()(Chrom& chrom1, Chrom& chrom2)
{ {
unsigned max_genes = min(chrom1.size(), chrom2.size()) / gene_size; unsigned max_genes = min(chrom1.size(), chrom2.size()) / gene_size;
unsigned cut_genes = min(max_genes, num_points); unsigned cut_genes = min(max_genes, num_points);
vector<bool> points(max_genes, false); vector<bool> points(max_genes, false);
// selects genes to swap // selects genes to swap
@ -454,11 +448,10 @@ template<class Chrom> class eoBitGxOver: public eoQuadOp<Chrom>
swap_ranges(chrom1.begin() + i * gene_size, swap_ranges(chrom1.begin() + i * gene_size,
chrom1.begin() + i * gene_size + gene_size, chrom1.begin() + i * gene_size + gene_size,
chrom2.begin() + i * gene_size); chrom2.begin() + i * gene_size);
chrom1.invalidate(); return true;
chrom2.invalidate();
} }
private: private:
unsigned gene_size; unsigned gene_size;
unsigned num_points; unsigned num_points;

View file

@ -148,7 +148,7 @@ private :
unsigned max_depth; unsigned max_depth;
std::vector<Node> initializor; std::vector<Node> initializor;
bool grow; bool grow;
}; };
template<class FType, class Node> template<class FType, class Node>
@ -165,7 +165,7 @@ public:
/// Dtor /// Dtor
virtual ~eoSubtreeXOver () {}; virtual ~eoSubtreeXOver () {};
void operator()(EoType & _eo1, EoType & _eo2 ) bool operator()(EoType & _eo1, EoType & _eo2 )
{ {
int i = rng.random(_eo1.size()); int i = rng.random(_eo1.size());
int j = rng.random(_eo2.size()); int j = rng.random(_eo2.size());
@ -173,26 +173,25 @@ public:
parse_tree<Node>::subtree tmp = _eo2[j]; parse_tree<Node>::subtree tmp = _eo2[j];
_eo1[i] = _eo2[j]; // insert subtree _eo1[i] = _eo2[j]; // insert subtree
_eo2[j]=tmp; _eo2[j]=tmp;
_eo1.pruneTree(max_length); _eo1.pruneTree(max_length);
_eo2.pruneTree(max_length); _eo2.pruneTree(max_length);
_eo1.invalidate(); return true;
_eo2.invalidate();
} }
unsigned max_length; unsigned max_length;
}; };
template<class FType, class Node> template<class FType, class Node>
class eoBranchMutation: public eoMonOp< eoParseTree<FType, Node> > class eoBranchMutation: public eoMonOp< eoParseTree<FType, Node> >
{ {
public: public:
typedef eoParseTree<FType, Node> EoType; typedef eoParseTree<FType, Node> EoType;
eoBranchMutation(eoInit<EoType>& _init, unsigned _max_length) eoBranchMutation(eoInit<EoType>& _init, unsigned _max_length)
: eoMonOp<EoType>(), max_length(_max_length), initializer(_init) : eoMonOp<EoType>(), max_length(_max_length), initializer(_init)
{}; {};
virtual string className() const { return "eoBranchMutation"; }; virtual string className() const { return "eoBranchMutation"; };
@ -200,26 +199,26 @@ public:
/// Dtor /// Dtor
virtual ~eoBranchMutation() {}; virtual ~eoBranchMutation() {};
void operator()(EoType& _eo1 ) bool operator()(EoType& _eo1 )
{ {
int i = rng.random(_eo1.size()); int i = rng.random(_eo1.size());
EoType eo2; EoType eo2;
initializer(eo2); initializer(eo2);
int j = rng.random(eo2.size()); int j = rng.random(eo2.size());
_eo1[i] = eo2[j]; // insert subtree _eo1[i] = eo2[j]; // insert subtree
_eo1.pruneTree(max_length); _eo1.pruneTree(max_length);
_eo1.invalidate(); return true;
} }
private : private :
unsigned max_length; unsigned max_length;
eoInit<EoType>& initializer; eoInit<EoType>& initializer;
}; };

View file

@ -46,13 +46,13 @@ class eoExternalInit : public eoInit<ExternalEO>
{ {
public : public :
eoExternalInit(External (*_init)(void)) : init(_init) {} eoExternalInit(External (*_init)(void)) : init(_init) {}
void operator()(ExternalEO& _eo) void operator()(ExternalEO& _eo)
{ {
_eo = (*init)(); _eo = (*init)();
_eo.invalidate(); _eo.invalidate();
} }
@ -76,7 +76,7 @@ class eoExternalEvalFunc : public eoEvalFunc<ExternalEO>
eoExternalEvalFunc(F (*_eval)(const External&)) : eval(_eval) {} eoExternalEvalFunc(F (*_eval)(const External&)) : eval(_eval) {}
void operator()(ExternalEO& eo) void operator()(ExternalEO& eo)
{ {
if (eo.invalid()) if (eo.invalid())
eo.fitness( (*eval)(eo) ); eo.fitness( (*eval)(eo) );
@ -93,8 +93,8 @@ class eoExternalEvalFunc : public eoEvalFunc<ExternalEO>
bool func(External&); bool func(External&);
Where External is the user defined struct or class. Where External is the user defined struct or class.
The function should return true when it changed something, false otherwise The function should return true when it changed something, false otherwise
*/ */
@ -105,10 +105,9 @@ class eoExternalMonOp : public eoMonOp<ExternalEO>
eoExternalMonOp(bool (*_mutate)(External&)) : mutate(_mutate) {} eoExternalMonOp(bool (*_mutate)(External&)) : mutate(_mutate) {}
void operator()(ExternalEO& eo) bool operator()(ExternalEO& eo)
{ {
if ((*mutate)(eo)) return (*mutate)(eo);
eo.invalidate();
} }
private : private :
@ -132,10 +131,9 @@ class eoExternalBinOp : public eoBinOp<ExternalEO>
eoExternalBinOp(bool (*_binop)(External&, const External&)) : binop(_binop) {} eoExternalBinOp(bool (*_binop)(External&, const External&)) : binop(_binop) {}
void operator()(ExternalEO& eo1, const ExternalEO& eo2) bool operator()(ExternalEO& eo1, const ExternalEO& eo2)
{ {
if ((*binop)(eo1, eo2)) return (*binop)(eo1, eo2);
eo1.invalidate();
} }
private : private :
@ -159,13 +157,9 @@ class eoExternalQuadOp : public eoQuadOp<ExternalEO>
eoExternalQuadOp(bool (*_quadop)(External&, External&)) : quadop(_quadop) {} eoExternalQuadOp(bool (*_quadop)(External&, External&)) : quadop(_quadop) {}
void operator()(ExternalEO& eo1, ExternalEO& eo2) bool operator()(ExternalEO& eo1, ExternalEO& eo2)
{ {
if ((*quadop)(eo1, eo2)) return (*quadop)(eo1, eo2);
{
eo1.invalidate();
eo2.invalidate();
}
} }
private : private :

View file

@ -38,11 +38,20 @@ class eoObject;
class eoPersistent; class eoPersistent;
/** /**
* eoState can be used to register derivants of eoPersistent. It will eoState can be used to register derivants of eoPersistent. It will
* then in turn implement the persistence framework through members load then in turn implement the persistence framework through members load
* and save, that will call readFrom and printOn for the registrated objects. and save, that will call readFrom and printOn for the registrated objects.
It is derived from eoFunctorStore, so that it also serves as a place where
all those nifty eo functors can be stored. This is useful in the case you
want to use one of the make_* functions. These functions generally take as their
last argument an eoFunctorStore (or a state) which is used to hold all dynamically
generated data. Note however, that unlike with eoPersistent derived classes, eoFunctorBase
derived classes are not saved or loaded. To govern the creation of functors,
command-line parameters (which can be stored) are needed.
*/ */
class eoState class eoState : public eoFunctorStore
{ {
public : public :
@ -68,12 +77,6 @@ public :
return static_cast<T&>(*ownedObjects.back()); return static_cast<T&>(*ownedObjects.back());
} }
void storeFunctor(eoFunctorBase* _functor)
{
// add it to the functorStore, fo
functorStore.add(_functor);
}
/** /**
* Loading error thrown when nothing seems to work. * Loading error thrown when nothing seems to work.
*/ */
@ -123,9 +126,6 @@ private :
std::vector<ObjectMap::iterator> creationOrder; std::vector<ObjectMap::iterator> creationOrder;
std::vector<eoPersistent*> ownedObjects; std::vector<eoPersistent*> ownedObjects;
// And a functor store to boot
eoFunctorStore functorStore;
// private copy and assignment as eoState is supposed to be unique // private copy and assignment as eoState is supposed to be unique
eoState(const eoState&); eoState(const eoState&);
eoState& operator=(const eoState&); eoState& operator=(const eoState&);

View file

@ -36,6 +36,9 @@ echo "Testing t-eofitness"
echo "Testing t-eoGA" echo "Testing t-eoGA"
./t-eoGA > t-eoGA.log ./t-eoGA > t-eoGA.log
echo "Testing t-eoGenOp"
./t-eoGenOp > t-eoGenOp.log
echo "Finished" echo "Finished"
#TODO test if an error occured #TODO test if an error occured

View file

@ -23,7 +23,7 @@
*/ */
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** test program for the general operator - millenium version! /** test program for the general operator - millenium version!
* uses dummy individuals * uses dummy individuals
*/ */
#include <eo> #include <eo>
@ -53,10 +53,11 @@ class monop : public eoMonOp<EOT>
{ {
public : public :
monop(char * _sig){sig=_sig;} monop(char * _sig){sig=_sig;}
void operator()(EOT& _eo) bool operator()(EOT& _eo)
{ {
_eo.s = sig + "(" + _eo.s + ")"; _eo.s = sig + "(" + _eo.s + ")";
_eo.fitness(_eo.fitness()+pSize); _eo.fitness(_eo.fitness()+pSize);
return false;
} }
string className() {return sig;} string className() {return sig;}
private: private:
@ -66,11 +67,12 @@ class monop : public eoMonOp<EOT>
class binop: public eoBinOp<EOT> class binop: public eoBinOp<EOT>
{ {
public : public :
void operator()(EOT& _eo1, const EOT& _eo2) bool operator()(EOT& _eo1, const EOT& _eo2)
{ {
_eo1.s = "bin(" + _eo1.s + "," + _eo2.s + ")"; _eo1.s = "bin(" + _eo1.s + "," + _eo2.s + ")";
double f= (_eo1.fitness()+_eo2.fitness()) * pSize; double f= (_eo1.fitness()+_eo2.fitness()) * pSize;
_eo1.fitness(_eo1.fitness()+f); _eo1.fitness(_eo1.fitness()+f);
return false;
} }
string className() {return "binop";} string className() {return "binop";}
}; };
@ -79,7 +81,7 @@ class quadop: public eoQuadOp<EOT>
{ {
public : public :
string className() {return "quadop";} string className() {return "quadop";}
void operator()(EOT& a, EOT& b) bool operator()(EOT& a, EOT& b)
{ {
EOT oi = a; EOT oi = a;
EOT oj = b; EOT oj = b;
@ -89,6 +91,7 @@ class quadop: public eoQuadOp<EOT>
double f= (a.fitness()+b.fitness()+2*pSize) * pSize; double f= (a.fitness()+b.fitness()+2*pSize) * pSize;
a.fitness(a.fitness()+f); a.fitness(a.fitness()+f);
b.fitness(b.fitness()+f); b.fitness(b.fitness()+f);
return false;
} }
}; };
// an eoQuadOp that does nothing // an eoQuadOp that does nothing
@ -96,7 +99,7 @@ class quadClone: public eoQuadOp<EOT>
{ {
public : public :
string className() {return "quadclone";} string className() {return "quadclone";}
void operator()(EOT& , EOT& ) {} bool operator()(EOT& , EOT& ) {return false;}
}; };
// User defined General Operator... adapted from Marc's example // User defined General Operator... adapted from Marc's example