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

@ -143,7 +143,7 @@ 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());
@ -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();
} }
}; };

View file

@ -11,4 +11,4 @@ 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

@ -45,7 +45,13 @@ 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 :

View file

@ -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,6 +41,13 @@ 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>
@ -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();}
@ -122,7 +132,8 @@ class eoSelBinGenOp : public eoGenOp<EOT>
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();}
@ -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

@ -105,9 +105,10 @@ 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,7 +29,7 @@
#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
*/ */
@ -55,9 +55,12 @@ 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>
@ -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
@ -102,9 +109,11 @@ 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
@ -115,9 +124,11 @@ public:
/** 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

@ -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
{
owned_genops.push_back(new eoMonGenOp<EOT>(_op));
ops.push_back(owned_genops.back());
rates.push_back(_rate);
max_to_produce = max(max_to_produce,unsigned(1)); (sidenote, it's much less hairy since I added the wrap_op is used)
}
/** wraps then add a simple eoBinOp
* First case, no selector
*/ */
void add(eoBinOp<EOT>& _op, double _rate) void add(eoOp<EOT>& _op, double _rate)
{ {
owned_genops.push_back(new eoBinGenOp<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
* 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,9 +28,6 @@
#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
@ -68,15 +65,6 @@ public:
rates.push_back(_rate); 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);
}
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)
@ -88,16 +76,6 @@ public:
printOn(cout); 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);
// compute the relative rates in percent - to warn the user!
if (_verbose)
printOn(cout);
}
// outputs the operators and percentages // outputs the operators and percentages
virtual void printOn(ostream & _os) virtual void printOn(ostream & _os)
{ {
@ -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;
@ -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;
@ -192,15 +170,6 @@ public:
rates.push_back(_rate); 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);
}
virtual string className() const { return "eoPropCombinedQuadOp"; } virtual string className() const { return "eoPropCombinedQuadOp"; }
// addition of a true operator // addition of a true operator
@ -213,17 +182,6 @@ virtual void add(eoQuadOp<EOT> & _op, const double _rate, bool _verbose=false)
printOn(cout); 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);
// compute the relative rates in percent - to warn the user!
if (_verbose)
printOn(cout);
}
// outputs the operators and percentages // outputs the operators and percentages
virtual void printOn(ostream & _os) virtual void printOn(ostream & _os)
{ {
@ -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>
@ -101,9 +101,11 @@ public :
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

@ -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>
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -154,10 +154,10 @@ 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,8 +29,7 @@
#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.
@ -79,7 +78,7 @@ private:
*/ */
template <class EOT> template <class EOT>
class eoVlAtomExchangeQuadOp : public eoGenericQuadOp<EOT> class eoVlAtomExchangeQuadOp : public eoQuadOp<EOT>
{ {
public : public :
@ -162,7 +161,7 @@ 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 :
@ -223,7 +222,7 @@ 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 :

View file

@ -29,7 +29,7 @@
#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.
@ -40,14 +40,14 @@ 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)
@ -61,21 +61,21 @@ 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)
@ -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,7 +99,7 @@ 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 :
@ -150,7 +150,7 @@ 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 :

View file

@ -89,7 +89,7 @@ public:
/** /**
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());
@ -104,7 +104,7 @@ public:
} }
bounds.foldsInBounds(_eo); bounds.foldsInBounds(_eo);
_eo.invalidate(); return true;
} }
/// mutations - standard and correlated /// mutations - standard and correlated
@ -120,7 +120,7 @@ public:
* 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++)
@ -137,7 +137,7 @@ public:
bounds.foldsInBounds(_eo); bounds.foldsInBounds(_eo);
_eo.invalidate(); return true;
} }
/* /*
@ -151,7 +151,7 @@ public:
// Code from Thomas Baeck // Code from Thomas Baeck
virtual void operator()( eoEsFull<FitT> & _eo ) virtual bool operator()( eoEsFull<FitT> & _eo )
{ {
/* /*
@ -220,7 +220,7 @@ public:
bounds.foldsInBounds(_eo); bounds.foldsInBounds(_eo);
_eo.invalidate(); return true;
} }
private : private :

View file

@ -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

@ -38,8 +38,7 @@ 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>
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -51,7 +50,7 @@ MS January 25. 2001
\ingroup parameteric \ingroup parameteric
*/ */
template<class EOT> class eoGenericUniformMutation: public eoGenericMonOp<EOT> template<class EOT> class eoGenericUniformMutation: public eoMonOp<EOT>
{ {
public: public:
/** /**
@ -118,7 +117,7 @@ private:
*/ */
template<class EOT> class eoGenericDetUniformMutation: template<class EOT> class eoGenericDetUniformMutation:
public eoGenericMonOp<EOT> public eoMonOp<EOT>
{ {
public: public:
/** /**
@ -181,7 +180,7 @@ private:
\ingroup parameteric \ingroup parameteric
*/ */
template<class EOT> class eoGenericSegmentCrossover: public eoGenericQuadOp<EOT> template<class EOT> class eoGenericSegmentCrossover: public eoQuadOp<EOT>
{ {
public: public:
/** /**
@ -272,7 +271,7 @@ protected:
*/ */
template<class EOT> class eoGenericArithmeticCrossover: template<class EOT> class eoGenericArithmeticCrossover:
public eoGenericQuadOp<EOT> public eoQuadOp<EOT>
{ {
public: public:
/** /**
@ -370,7 +369,7 @@ protected:
\ingroup parameteric \ingroup parameteric
*/ */
template<class EOT> class eoGenericRealUxOver: public eoGenericQuadOp<EOT> template<class EOT> class eoGenericRealUxOver: public eoQuadOp<EOT>
{ {
public: public:
/** /**

View file

@ -75,7 +75,7 @@ template<class EOT> class eoNormalMutation: 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)
{ {
bool hasChanged=false; bool hasChanged=false;
for (unsigned lieu=0; lieu<_eo.size(); lieu++) for (unsigned lieu=0; lieu<_eo.size(); lieu++)
@ -87,8 +87,7 @@ template<class EOT> class eoNormalMutation: public eoMonOp<EOT>
hasChanged = true; hasChanged = true;
} }
} }
if (hasChanged) return hasChanged;
_eo.invalidate();
} }
protected: protected:

View file

@ -72,7 +72,7 @@ template<class EOT> class eoUniformMutation: 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)
{ {
bool hasChanged=false; bool hasChanged=false;
for (unsigned lieu=0; lieu<_eo.size(); lieu++) for (unsigned lieu=0; lieu<_eo.size(); lieu++)
@ -90,8 +90,7 @@ template<class EOT> class eoUniformMutation: public eoMonOp<EOT>
hasChanged = true; hasChanged = true;
} }
} }
if (hasChanged) return hasChanged;
_eo.invalidate();
} }
private: private:
@ -134,9 +133,8 @@ 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());
@ -151,6 +149,8 @@ template<class EOT> class eoDetUniformMutation: public eoMonOp<EOT>
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:
@ -203,7 +203,7 @@ 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;
@ -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:
@ -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;
@ -342,8 +341,8 @@ 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:
@ -380,7 +379,7 @@ 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" );
@ -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

@ -75,11 +75,11 @@ template<class Chrom> class eoOneBitFlip: public eoMonOp<Chrom>
* 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;
} }
}; };
@ -105,7 +105,7 @@ template<class Chrom> class eoDetBitFlip: public eoMonOp<Chrom>
* 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,7 +113,7 @@ 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;
@ -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,8 +151,7 @@ template<class Chrom> class eoBitMutation: public eoMonOp<Chrom>
changed_something = true; changed_something = true;
} }
if (changed_something) return changed_something;
chrom.invalidate();
} }
private: private:
@ -175,7 +174,7 @@ 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;
@ -183,7 +182,7 @@ template<class Chrom> class eoBitInversion: public eoMonOp<Chrom>
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;
} }
}; };
@ -203,7 +202,7 @@ template<class Chrom> class eoBitNext: public eoMonOp<Chrom>
* 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,7 +216,7 @@ template<class Chrom> class eoBitNext: public eoMonOp<Chrom>
break; break;
} }
chrom.invalidate(); return true;
} }
}; };
@ -237,7 +236,7 @@ template<class Chrom> class eoBitPrev: public eoMonOp<Chrom>
* 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])
@ -251,7 +250,7 @@ template<class Chrom> class eoBitPrev: public eoMonOp<Chrom>
continue; continue;
} }
chrom.invalidate(); return true;
} }
}; };
@ -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()));
@ -281,9 +280,9 @@ 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;
} }
}; };
@ -311,7 +310,7 @@ 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" );
@ -326,11 +325,7 @@ 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;
@ -360,7 +355,7 @@ template<class Chrom> class eoNPtsBitXover: 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 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);
@ -391,8 +386,7 @@ template<class Chrom> class eoNPtsBitXover: public eoQuadOp<Chrom>
swap(chrom1[bit], chrom2[bit]); swap(chrom1[bit], chrom2[bit]);
} }
chrom1.invalidate(); return true;
chrom2.invalidate();
} }
private: private:
@ -429,7 +423,7 @@ template<class Chrom> class eoBitGxOver: 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 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);
@ -455,8 +449,7 @@ template<class Chrom> class eoBitGxOver: public eoQuadOp<Chrom>
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:

View file

@ -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());
@ -177,8 +177,7 @@ public:
_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;
@ -200,7 +199,7 @@ 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());
@ -213,7 +212,7 @@ public:
_eo1.pruneTree(max_length); _eo1.pruneTree(max_length);
_eo1.invalidate(); return true;
} }
private : private :

View file

@ -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

@ -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