GOing to the generic operators: some additions (eoGeneric*)
and some modifications in eoFixedLength and eoVariableLength.
This commit is contained in:
parent
5f925a4c12
commit
4b2bb7f564
9 changed files with 788 additions and 15 deletions
|
|
@ -46,7 +46,17 @@ class eoFixedLength : public EO<FitT>, public std::vector<GeneType>
|
||||||
eoFixedLength(unsigned size = 0, GeneType value = GeneType()) : EO<FitT>(), std::vector<GeneType>(size, value)
|
eoFixedLength(unsigned size = 0, GeneType value = GeneType()) : EO<FitT>(), std::vector<GeneType>(size, value)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/// to avoid conflicts between EO::operator< and vector<double>::operator<
|
// we can't have a Ctor from a vector, it would create ambiguity
|
||||||
|
// with the copy Ctor
|
||||||
|
void value(std::vector<GeneType> _v)
|
||||||
|
{
|
||||||
|
if (_v.size() != size())
|
||||||
|
throw runtime_error("Wrong size in vector assignation in eoFixedLength");
|
||||||
|
copy(_v.begin(), _v.end(), begin());
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// to avoid conflicts between EO::operator< and vector<GeneType>::operator<
|
||||||
bool operator<(const eoFixedLength<FitT, GeneType>& _eo) const
|
bool operator<(const eoFixedLength<FitT, GeneType>& _eo) const
|
||||||
{
|
{
|
||||||
return EO<FitT>::operator<(_eo);
|
return EO<FitT>::operator<(_eo);
|
||||||
|
|
|
||||||
75
eo/src/eoGenericBinOp.h
Normal file
75
eo/src/eoGenericBinOp.h
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// eoGenericBinOp.h
|
||||||
|
// (c) GeNeura Team, 2000 - EEAAX 1999 - Maarten Keijzer 2000
|
||||||
|
/*
|
||||||
|
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 _eoGenericBinOp_h
|
||||||
|
#define _eoGenericBinOp_h
|
||||||
|
|
||||||
|
#include <eoOp.h>
|
||||||
|
|
||||||
|
/** Contains base classes for generic binary operators for eoFixedLength
|
||||||
|
and eoVariableLength (They also derive from the eoOp) as well as
|
||||||
|
the corresponding converters to actual Ops.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** eoGenericBinOp is the generic binary operator:
|
||||||
|
it takes two arguments, modifies the first one, and returns a boolean
|
||||||
|
indicating if the argument has actually been modified
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <class EOT>
|
||||||
|
class eoGenericBinOp: public eoOp<EOT>, public eoBF<EOT &, const EOT &, bool>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Ctor
|
||||||
|
eoGenericBinOp()
|
||||||
|
: eoOp<EOT>( eoOp<EOT>::binary ) {};
|
||||||
|
virtual string className() const {return "eoGenericBinOp";};
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Converter from eoGenericBinOp to eoBinOp
|
||||||
|
the only thinig to do is to transform the boolean into invalidation
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <class EOT>
|
||||||
|
class eoGeneric2TrueBinOp: public eoBinOp<EOT>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Ctor
|
||||||
|
eoGeneric2TrueBinOp(eoGenericBinOp<EOT> & _binOp)
|
||||||
|
: binOp( _binOp ) {};
|
||||||
|
virtual string className() const {return "eoGeneric2TrueBinOp";}
|
||||||
|
|
||||||
|
virtual void operator()(EOT & _eo1, const EOT & _eo2)
|
||||||
|
{
|
||||||
|
if (binOp(_eo1, _eo2))
|
||||||
|
_eo1.invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
eoGenericBinOp<EOT> & binOp;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
75
eo/src/eoGenericMonOp.h
Normal file
75
eo/src/eoGenericMonOp.h
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// eoGenericMonOp.h
|
||||||
|
// (c) GeNeura Team, 2000 - EEAAX 1999 - Maarten Keijzer 2000
|
||||||
|
/*
|
||||||
|
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 _eoGenericMonOp_h
|
||||||
|
#define _eoGenericMonOp_h
|
||||||
|
|
||||||
|
#include <eoOp.h>
|
||||||
|
|
||||||
|
/** Contains base classes for generic operators for eoFixedLength
|
||||||
|
and eoVariableLength (They also derive from the eoOp) as well as
|
||||||
|
the corresponding converters to actual Ops.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** eoGenericMonOp is the generic unary operator:
|
||||||
|
it takes one argument, and returns a boolean indicating if the argument
|
||||||
|
has been modified
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <class EOT>
|
||||||
|
class eoGenericMonOp: public eoOp<EOT>, public eoUF<EOT&, bool>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Ctor
|
||||||
|
eoGenericMonOp()
|
||||||
|
: eoOp<EOT>( eoOp<EOT>::unary ) {};
|
||||||
|
virtual string className() const {return "eoGenericMonOp";};
|
||||||
|
};
|
||||||
|
|
||||||
|
/** COnverter from eoGenericMonOp to eoMonOp
|
||||||
|
the only thinig to do is to transform the boolean into invalidation
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <class EOT>
|
||||||
|
class eoGeneric2TrueMonOp: public eoMonOp<EOT>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Ctor
|
||||||
|
eoGeneric2TrueMonOp(eoGenericMonOp<EOT> & _monOp)
|
||||||
|
: monOp( _monOp ) {};
|
||||||
|
virtual string className() const {return "eoGeneric2trueMonOp";}
|
||||||
|
|
||||||
|
virtual void operator()(EOT & _eo)
|
||||||
|
{
|
||||||
|
if (monOp(_eo))
|
||||||
|
_eo.invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
eoGenericMonOp<EOT> & monOp;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
83
eo/src/eoGenericQuadOp.h
Normal file
83
eo/src/eoGenericQuadOp.h
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// eoGenericQuadOp.h
|
||||||
|
// (c) GeNeura Team, 2000 - EEAAX 1999 - Maarten Keijzer 2000
|
||||||
|
/*
|
||||||
|
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 _eoGenericQuadOp_h
|
||||||
|
#define _eoGenericQuadOp_h
|
||||||
|
|
||||||
|
#include <eoOp.h>
|
||||||
|
|
||||||
|
/** Contains base classes for generic quadratic operators for eoFixedLength
|
||||||
|
and eoVariableLength (They also derive from the eoOp) as well as
|
||||||
|
the corresponding converters to actual Ops.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** eoGenericQuadOp is the generic quadratic operator:
|
||||||
|
it takes two arguments, modifies the first one, and returns a boolean
|
||||||
|
indicating if the arguments have actually been modified
|
||||||
|
|
||||||
|
WARNING: even if only 1 argument is modified, it should return true,
|
||||||
|
and both fitnesses will be invalidated. It is assumed that
|
||||||
|
quadratic operators do some exchange of genetic material, so
|
||||||
|
if one is modified, the other is, too!
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <class EOT>
|
||||||
|
class eoGenericQuadOp: public eoOp<EOT>, public eoBF<EOT &, EOT &, bool>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Ctor
|
||||||
|
eoGenericQuadOp()
|
||||||
|
: eoOp<EOT>( eoOp<EOT>::binary ) {};
|
||||||
|
virtual string className() const {return "eoGenericQuadOp";};
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Converter from eoGenericQuadOp to eoQuadOp
|
||||||
|
the only thinig to do is to transform the boolean into invalidation
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <class EOT>
|
||||||
|
class eoGeneric2TrueQuadOp: public eoQuadOp<EOT>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Ctor
|
||||||
|
eoGeneric2TrueQuadOp(eoGenericQuadOp<EOT> & _quadOp)
|
||||||
|
: quadOp( _quadOp ) {};
|
||||||
|
virtual string className() const {return "eoGeneric2TrueQuadOp";}
|
||||||
|
|
||||||
|
virtual void operator()(EOT & _eo1, EOT & _eo2)
|
||||||
|
{
|
||||||
|
if (quadOp(_eo1, _eo2))
|
||||||
|
{
|
||||||
|
_eo1.invalidate();
|
||||||
|
_eo2.invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
eoGenericQuadOp<EOT> & quadOp;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -105,6 +105,7 @@ public:
|
||||||
/** Quadratic genetic operator: subclasses eoOp, and defines basically the
|
/** Quadratic genetic operator: subclasses eoOp, and defines basically the
|
||||||
operator() with two operands, both can be modified.
|
operator() with two operands, both can be modified.
|
||||||
*/
|
*/
|
||||||
|
#define eoQuadraticOp eoQuadOp
|
||||||
|
|
||||||
template<class EOType>
|
template<class EOType>
|
||||||
class eoQuadraticOp: public eoOp<EOType>, public eoBF<EOType&, EOType&, void> {
|
class eoQuadraticOp: public eoOp<EOType>, public eoBF<EOType&, EOType&, void> {
|
||||||
|
|
@ -115,6 +116,29 @@ public:
|
||||||
virtual string className() const {return "eoQuadOp";};
|
virtual string className() const {return "eoQuadOp";};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Turning an eoBinOp into an eoQuadOp is generic:
|
||||||
|
template <class EOT>
|
||||||
|
class eoQuad2BinOp: public eoBinOp<EOT>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Ctor, from an eoQuadOp
|
||||||
|
eoQuad2BinOp(eoQuadOp<EOT> & _quadOp) : quadOp(_quadOp) {}
|
||||||
|
|
||||||
|
// Operator() simply calls embedded quadOp operator() with dummy second arg
|
||||||
|
void operator()(EOT & _eo1, const EOT & _eo2)
|
||||||
|
{
|
||||||
|
EOT eoTmp = _eo2; // a copy that can be modified
|
||||||
|
// if the embedded eoQuadOp is not symmetrical,
|
||||||
|
// the result might be biased - hence the flip ...
|
||||||
|
if (eo::rng.flip(0.5))
|
||||||
|
quadOp(_eo1, eoTmp); // both are modified - that's all
|
||||||
|
else
|
||||||
|
quadOp(eoTmp, _eo1); // both are modified - that's all
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
eoQuadOp<EOT> & quadOp;
|
||||||
|
};
|
||||||
|
|
||||||
// some forward declarations
|
// some forward declarations
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,15 +79,24 @@ class eoPop: public vector<EOT>, public eoObject, public eoPersistent
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** SAME Initialization task than init. ctor, but is NOT a constructor
|
/** appends random guys at end of pop.
|
||||||
|
Can be used to initialize it pop is empty
|
||||||
|
|
||||||
@param _popSize total population size
|
@param _popSize total population size
|
||||||
@param _chromInit Initialization routine, produces EO's, needs to be an eoInit
|
@param _chromInit Initialization routine, produces EO's, needs to be an eoInit
|
||||||
*/
|
*/
|
||||||
void append( unsigned _popSize, eoInit<EOT>& _chromInit )
|
void append( unsigned _newPopSize, eoInit<EOT>& _chromInit )
|
||||||
{
|
{
|
||||||
resize(size()+_popSize); // adjust the size
|
unsigned oldSize = size();
|
||||||
for ( unsigned i = 0; i < _popSize; i++ )
|
if (_newPopSize < oldSize)
|
||||||
|
{
|
||||||
|
throw runtime_error("New size smaller than old size in pop.append");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_newPopSize == oldSize)
|
||||||
|
return;
|
||||||
|
resize(_newPopSize); // adjust the size
|
||||||
|
for ( unsigned i = oldSize; i < _popSize; i++ )
|
||||||
{
|
{
|
||||||
_chromInit(operator[](i));
|
_chromInit(operator[](i));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,21 +27,34 @@
|
||||||
#ifndef _eoVariableLength_h
|
#ifndef _eoVariableLength_h
|
||||||
#define _eoVariableLength_h
|
#define _eoVariableLength_h
|
||||||
|
|
||||||
#include <list>
|
#include <vector>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Base class for variable length chromosomes. Derives from EO and list,
|
Base class for variable length chromosomes. Derives from EO and vector,
|
||||||
redirects the smaller than operator to EO (fitness based comparison),
|
redirects the smaller than operator to EO (fitness based comparison),
|
||||||
and implements the virtual functions printOn() and readFrom()
|
and implements the virtual functions printOn() and readFrom()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <class FitT, class GeneType>
|
template <class FitT, class GeneType>
|
||||||
class eoVariableLength : public EO<FitT>, public std::list<GeneType>
|
class eoVariableLength : public EO<FitT>, public std::vector<GeneType>
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
|
|
||||||
typedef GeneType AtomType;
|
typedef GeneType AtomType;
|
||||||
typedef std::list<GeneType> ContainerType;
|
typedef std::vector<GeneType> ContainerType;
|
||||||
|
|
||||||
|
// default ctor
|
||||||
|
eoVariableLength(unsigned size = 0, GeneType value = GeneType()) : EO<FitT>(), std::vector<GeneType>(size, value)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// we can't have a Ctor from a vector, it would create ambiguity
|
||||||
|
// with the copy Ctor
|
||||||
|
void value(std::vector<GeneType> _v)
|
||||||
|
{
|
||||||
|
resize(_v.size());
|
||||||
|
copy(_v.begin(), _v.end(), begin());
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
/// printing...
|
/// printing...
|
||||||
void printOn(ostream& os) const
|
void printOn(ostream& os) const
|
||||||
|
|
@ -51,7 +64,7 @@ class eoVariableLength : public EO<FitT>, public std::list<GeneType>
|
||||||
|
|
||||||
os << size() << ' ';
|
os << size() << ' ';
|
||||||
|
|
||||||
std::copy(begin(), end(), ostream_iterator<double>(os));
|
std::copy(begin(), end(), ostream_iterator<AtomType>(os, " "));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// reading...
|
/// reading...
|
||||||
|
|
@ -62,14 +75,14 @@ class eoVariableLength : public EO<FitT>, public std::list<GeneType>
|
||||||
unsigned sz;
|
unsigned sz;
|
||||||
is >> sz;
|
is >> sz;
|
||||||
|
|
||||||
resize(0);
|
resize(sz);
|
||||||
unsigned i;
|
unsigned i;
|
||||||
unsigned gene;
|
|
||||||
|
|
||||||
for (i = 0; i < sz; ++i)
|
for (i = 0; i < sz; ++i)
|
||||||
{
|
{
|
||||||
is >> gene;
|
AtomType atom;
|
||||||
push_back(gene);
|
is >> atom;
|
||||||
|
operator[](i) = atom;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -81,7 +94,7 @@ class eoVariableLength : public EO<FitT>, public std::list<GeneType>
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// to avoid conflicts between EO::operator< and vector<double>::operator<
|
/// to avoid conflicts between EO::operator< and vector<GeneType>::operator<
|
||||||
template <class FitT, class GeneType>
|
template <class FitT, class GeneType>
|
||||||
bool operator<(const eoVariableLength<FitT, GeneType>& _eo1, const eoVariableLength<FitT, GeneType>& _eo2)
|
bool operator<(const eoVariableLength<FitT, GeneType>& _eo1, const eoVariableLength<FitT, GeneType>& _eo2)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
294
eo/src/eoVariableLengthCrossover.h
Normal file
294
eo/src/eoVariableLengthCrossover.h
Normal file
|
|
@ -0,0 +1,294 @@
|
||||||
|
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// eoVariableLengthCrossover.h
|
||||||
|
// (c) GeNeura Team, 2000 - EEAAX 1999 - Maarten Keijzer 2000
|
||||||
|
/*
|
||||||
|
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 _eoVariableLengthCrossover_h
|
||||||
|
#define _eoVariableLengthCrossover_h
|
||||||
|
|
||||||
|
#include <eoFunctor.h>
|
||||||
|
#include <eoVariableLength.h>
|
||||||
|
#include <eoGenericBinOp.h>
|
||||||
|
#include <eoGenericQuadOp.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
Base classes for generic crossovers on variable length chromosomes.
|
||||||
|
|
||||||
|
Basically, they exchange genes - we need some matching information to apply
|
||||||
|
atom crossover
|
||||||
|
*/
|
||||||
|
|
||||||
|
//* A helper class for choosing which genes to exchange
|
||||||
|
template <class Atom>
|
||||||
|
class eoAtomExchange : public eoBF<unsigned, Atom &, bool>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// a function to initlialize - to be called before every crossover
|
||||||
|
virtual void randomize(unsigned int, unsigned int){}
|
||||||
|
};
|
||||||
|
|
||||||
|
//* Uniform crossover - well, not really for FixedLength
|
||||||
|
template <class Atom>
|
||||||
|
class eoUniformAtomExchange: public eoAtomExchange<Atom>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
eoUniformAtomExchange(double _rate=0.5):rate(_rate){}
|
||||||
|
|
||||||
|
// randomize: fill the mask: the exchange will be simulated first
|
||||||
|
// to see if sizes are OK, so it must be repeatable
|
||||||
|
void randomize(unsigned _size1, unsigned _size2)
|
||||||
|
{
|
||||||
|
mask.resize(_size1 + _size2);
|
||||||
|
for (unsigned i=0; i<_size1+_size2; i++)
|
||||||
|
mask[i]=eo::rng.flip(rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
// the operator() simply returns the mask booleans in turn
|
||||||
|
bool operator()(unsigned _i, Atom & )
|
||||||
|
{
|
||||||
|
return mask[_i];
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
double rate;
|
||||||
|
vector<bool> mask;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** Exchange Crossover using an AtomExchange
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <class EOT>
|
||||||
|
class eoVlAtomExchangeQuadOp : public eoGenericQuadOp<EOT>
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
|
||||||
|
typedef typename EOT::AtomType AtomType;
|
||||||
|
|
||||||
|
// default ctor: requires bounds on number of genes + a rate
|
||||||
|
eoVlAtomExchangeQuadOp(unsigned _Min, unsigned _Max,
|
||||||
|
eoAtomExchange<AtomType>& _atomExchange):
|
||||||
|
Min(_Min), Max(_Max), atomExchange(_atomExchange) {}
|
||||||
|
|
||||||
|
bool operator()(EOT & _eo1, EOT & _eo2)
|
||||||
|
{
|
||||||
|
EOT tmp1, tmp2; // empty individuals
|
||||||
|
unsigned index=0;
|
||||||
|
// main loop: until sizes are OK, do only simulated exchange
|
||||||
|
unsigned i, i1, i2;
|
||||||
|
do {
|
||||||
|
// "initialize the AtomExchange
|
||||||
|
atomExchange.randomize(_eo1.size(), _eo2.size());
|
||||||
|
// simulate crossover
|
||||||
|
i1=i2=0;
|
||||||
|
for (i=0; i<_eo1.size(); i++)
|
||||||
|
{
|
||||||
|
if (atomExchange(i, _eo1[i]))
|
||||||
|
i1++;
|
||||||
|
else
|
||||||
|
i2++;
|
||||||
|
}
|
||||||
|
for (i=0; i<_eo2.size(); i++)
|
||||||
|
{
|
||||||
|
if (atomExchange(i, _eo2[i]))
|
||||||
|
i2++;
|
||||||
|
else
|
||||||
|
i1++;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
} while ( ( (i1<Min) || (i2<Min) ||
|
||||||
|
(i1>Max) || (i2>Max) )
|
||||||
|
&& (index<10000) );
|
||||||
|
if (index >= 10000)
|
||||||
|
{
|
||||||
|
cout << "Warning: impossible to generate individual of the right size in 10000 trials\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// here we know we have the right sizes: do the actual exchange
|
||||||
|
for (i=0; i<_eo1.size(); i++)
|
||||||
|
{
|
||||||
|
if (atomExchange(i, _eo1[i]))
|
||||||
|
tmp1.push_back(_eo1[i]);
|
||||||
|
else
|
||||||
|
tmp2.push_back(_eo1[i]);
|
||||||
|
}
|
||||||
|
for (i=0; i<_eo2.size(); i++)
|
||||||
|
{
|
||||||
|
if (atomExchange(i, _eo2[i]))
|
||||||
|
tmp2.push_back(_eo2[i]);
|
||||||
|
else
|
||||||
|
tmp1.push_back(_eo2[i]);
|
||||||
|
}
|
||||||
|
// and put everything back in place
|
||||||
|
_eo1.swap(tmp1);
|
||||||
|
_eo2.swap(tmp2);
|
||||||
|
return true; // should we test that? Yes, but no time now
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
unsigned Min, Max;
|
||||||
|
eoAtomExchange<AtomType> & atomExchange;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Direct Uniform Exchange of genes (obsolete, already :-)
|
||||||
|
|
||||||
|
A very primitive version, that does no verification at all!!!
|
||||||
|
NEEDS to be improved - but no time now :-(((
|
||||||
|
Especially, if both guys have maximal size, it will take a lot of time
|
||||||
|
to generate 2 offspring that both are not oversized!!!
|
||||||
|
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).
|
||||||
|
*/
|
||||||
|
template <class EOT>
|
||||||
|
class eoVlUniformQuadOp : public eoGenericQuadOp<EOT>
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
|
||||||
|
typedef typename EOT::AtomType AtomType;
|
||||||
|
|
||||||
|
// default ctor: requires bounds on number of genes + a rate
|
||||||
|
eoVlUniformQuadOp(unsigned _Min, unsigned _Max, double _rate=0.5) :
|
||||||
|
Min(_Min), Max(_Max), rate(_rate) {}
|
||||||
|
|
||||||
|
bool operator()(EOT & _eo1, EOT & _eo2)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
EOT tmp1, tmp2;
|
||||||
|
unsigned index=0;
|
||||||
|
do {
|
||||||
|
for (i=0; i<_eo1.size(); i++)
|
||||||
|
{
|
||||||
|
if (eo::rng.flip(rate))
|
||||||
|
tmp1.push_back(_eo1[i]);
|
||||||
|
else
|
||||||
|
tmp2.push_back(_eo1[i]);
|
||||||
|
// here we should look for _eo1[i] inside _eo2 and erase it if found!
|
||||||
|
}
|
||||||
|
for (i=0; i<_eo2.size(); i++)
|
||||||
|
{
|
||||||
|
if (eo::rng.flip(rate))
|
||||||
|
tmp1.push_back(_eo2[i]);
|
||||||
|
else
|
||||||
|
tmp2.push_back(_eo2[i]);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
} while ( ( (tmp1.size()<Min) || (tmp2.size()<Min) ||
|
||||||
|
(tmp1.size()>Max) || (tmp2.size()>Max) )
|
||||||
|
&& (index<10000) );
|
||||||
|
if (index >= 10000)
|
||||||
|
{
|
||||||
|
cout << "Warning: impossible to generate individual of the right size in 10000 trials\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_eo1.swap(tmp1);
|
||||||
|
_eo2.swap(tmp2);
|
||||||
|
return true; // should we test that?
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
unsigned Min, Max;
|
||||||
|
double rate;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** Direct Uniform Exchange of genes for Variable Length, BINARY version
|
||||||
|
|
||||||
|
A very primitive version, that does no verification at all!!!
|
||||||
|
NEEDS to be improved - but no time now :-(((
|
||||||
|
Especially, if both guys have maximal size, it will take some time
|
||||||
|
to generate even 1 offspring that is not oversized!!!
|
||||||
|
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).
|
||||||
|
*/
|
||||||
|
template <class EOT>
|
||||||
|
class eoVlUniformBinOp : public eoGenericBinOp<EOT>
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
|
||||||
|
typedef typename EOT::AtomType AtomType;
|
||||||
|
|
||||||
|
// default ctor: requires bounds on number of genes + a rate
|
||||||
|
eoVlUniformBinOp(unsigned _Min, unsigned _Max, double _rate=0.5) :
|
||||||
|
Min(_Min), Max(_Max), rate(_rate) {}
|
||||||
|
|
||||||
|
bool operator()(EOT & _eo1, const EOT & _eo2)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
EOT tmp1;
|
||||||
|
bool tmpIsOne=true, tmpIsTwo=true;
|
||||||
|
unsigned index=0;
|
||||||
|
do {
|
||||||
|
for (i=0; i<_eo1.size(); i++)
|
||||||
|
{
|
||||||
|
if (eo::rng.flip(rate))
|
||||||
|
{
|
||||||
|
tmp1.push_back(_eo1[i]);
|
||||||
|
tmpIsTwo = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tmpIsOne=false;
|
||||||
|
// we should look for _eo1[i] inside _eo2 and erase it there if found!
|
||||||
|
}
|
||||||
|
for (i=0; i<_eo2.size(); i++)
|
||||||
|
{
|
||||||
|
if (! eo::rng.flip(rate))
|
||||||
|
{
|
||||||
|
tmp1.push_back(_eo2[i]);
|
||||||
|
tmpIsOne = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tmpIsTwo = false;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
} while ( ( (tmp1.size()<Min) || (tmp1.size()>Max) )
|
||||||
|
&& (index<10000) );
|
||||||
|
// this while condition is not optimal, as it may take some time
|
||||||
|
if (index >= 10000)
|
||||||
|
{
|
||||||
|
cout << "Warning: impossible to generate individual of the right size in 10000 trials\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_eo1.swap(tmp1);
|
||||||
|
if (tmpIsTwo)
|
||||||
|
{
|
||||||
|
// _eo1.fitness(_eo2.fitness()); NO FITNESS EXISTS HERE!
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (tmpIsOne) // already has the right fitness
|
||||||
|
{ // WRONG: NO FITNESS EXISTS HERE!
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true; // there were some modifications...
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned Min, Max;
|
||||||
|
double rate;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
190
eo/src/eoVariableLengthMutation.h
Normal file
190
eo/src/eoVariableLengthMutation.h
Normal file
|
|
@ -0,0 +1,190 @@
|
||||||
|
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// eoVariableLengthMutation.h
|
||||||
|
// (c) GeNeura Team, 2000 - EEAAX 1999 - Maarten Keijzer 2000
|
||||||
|
/*
|
||||||
|
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 _eoVariableLengthMutation_h
|
||||||
|
#define _eoVariableLengthMutation_h
|
||||||
|
|
||||||
|
#include <eoFunctor.h>
|
||||||
|
#include <eoVariableLength.h>
|
||||||
|
#include <eoGenericMonOp.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
Base classes for generic mutations on variable length chromosomes.
|
||||||
|
|
||||||
|
THey all require a generic mutation for their simple genes
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** THis ones applies its atomic mutation to all the genes
|
||||||
|
*/
|
||||||
|
template <class EOT>
|
||||||
|
class eoVlAllMutation : public eoGenericMonOp<EOT>
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
|
||||||
|
typedef typename EOT::AtomType AtomType;
|
||||||
|
|
||||||
|
// default ctor: requires an Atom mutation
|
||||||
|
eoVlAllMutation(eoGenericMonOp<AtomType> & _atomMutation) :
|
||||||
|
atomMutation(_atomMutation) {}
|
||||||
|
|
||||||
|
bool operator()(EOT & _eo)
|
||||||
|
{
|
||||||
|
bool modified=false;
|
||||||
|
for (unsigned i=0; i<_eo.size(); i++)
|
||||||
|
{
|
||||||
|
if (atomMutation(_eo[i]))
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
eoGenericMonOp<AtomType> & atomMutation;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** This ones applies its atomic mutation to a fixed
|
||||||
|
number of genes (1 by default)
|
||||||
|
*/
|
||||||
|
template <class EOT>
|
||||||
|
class eoVlKMutation : public eoGenericMonOp<EOT>
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
|
||||||
|
typedef typename EOT::AtomType AtomType;
|
||||||
|
|
||||||
|
// default ctor: requires an Atom mutation
|
||||||
|
eoVlKMutation(eoGenericMonOp<AtomType> & _atomMutation, unsigned _nb=1) :
|
||||||
|
nb(_nb), atomMutation(_atomMutation) {}
|
||||||
|
|
||||||
|
bool operator()(EOT & _eo)
|
||||||
|
{
|
||||||
|
bool modified=false;
|
||||||
|
for (unsigned k=0; k<nb; k++)
|
||||||
|
{
|
||||||
|
unsigned i = rng.random(_eo.size()); // we don't test for duplicates...
|
||||||
|
if (atomMutation(_eo[i]))
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
unsigned nb;
|
||||||
|
eoGenericMonOp<AtomType> & atomMutation;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Addition of a gene
|
||||||
|
Is inserted at a random position - so can be applied to both
|
||||||
|
order-dependent and order-independent
|
||||||
|
*/
|
||||||
|
template <class EOT>
|
||||||
|
class eoVlAddMutation : public eoGenericMonOp<EOT>
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
|
||||||
|
typedef typename EOT::AtomType AtomType;
|
||||||
|
|
||||||
|
/** default ctor
|
||||||
|
|
||||||
|
* @param nMax max number of atoms
|
||||||
|
* @param _atomInit an Atom initializer
|
||||||
|
*/
|
||||||
|
eoVlAddMutation(unsigned _nMax, eoInit<AtomType> & _atomInit) :
|
||||||
|
nMax(_nMax), atomInit(_atomInit) {}
|
||||||
|
|
||||||
|
bool operator()(EOT & _eo)
|
||||||
|
{
|
||||||
|
if (_eo.size() >= nMax)
|
||||||
|
return false; // unmodifed
|
||||||
|
AtomType atom;
|
||||||
|
atomInit(atom);
|
||||||
|
unsigned pos = rng.random(_eo.size()+1);
|
||||||
|
_eo.insert(_eo.begin()+pos, atom);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
unsigned nMax;
|
||||||
|
eoInit<AtomType> & atomInit;
|
||||||
|
};
|
||||||
|
|
||||||
|
//* A helper class for choosing which site to delete
|
||||||
|
template <class EOT>
|
||||||
|
class eoGeneDelChooser : public eoUF<EOT &, unsigned int>
|
||||||
|
{};
|
||||||
|
|
||||||
|
//* Unifirm choice of gene to delete
|
||||||
|
template <class EOT>
|
||||||
|
class eoUniformGeneChooser: public eoGeneDelChooser<EOT>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
eoUniformGeneChooser(){}
|
||||||
|
unsigned operator()(EOT & _eo)
|
||||||
|
{
|
||||||
|
return eo::rng.random(_eo.size());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Deletion of a gene
|
||||||
|
By default at a random position, but a "chooser" can be specified
|
||||||
|
can of course be applied to both order-dependent and order-independent
|
||||||
|
*/
|
||||||
|
template <class EOT>
|
||||||
|
class eoVlDelMutation : public eoGenericMonOp<EOT>
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
|
||||||
|
typedef typename EOT::AtomType AtomType;
|
||||||
|
|
||||||
|
/** ctor with an external gene chooser
|
||||||
|
|
||||||
|
* @param nMin min number of atoms t oleave in the individual
|
||||||
|
* @param _geneChooser an eoGeneCHooser to choose which one to delete
|
||||||
|
*/
|
||||||
|
eoVlDelMutation(unsigned _nMin, eoGeneDelChooser<EOT> & _chooser) :
|
||||||
|
nMin(_nMin), uChooser(), chooser(_chooser) {}
|
||||||
|
|
||||||
|
/** ctor with unifirm gebe chooser
|
||||||
|
|
||||||
|
* @param nMin min number of atoms t oleave in the individual
|
||||||
|
*/
|
||||||
|
eoVlDelMutation(unsigned _nMin) :
|
||||||
|
nMin(_nMin), uChooser(), chooser(uChooser) {}
|
||||||
|
|
||||||
|
bool operator()(EOT & _eo)
|
||||||
|
{
|
||||||
|
if (_eo.size() <= nMin)
|
||||||
|
return false; // unmodifed
|
||||||
|
unsigned pos = chooser(_eo);
|
||||||
|
_eo.erase(_eo.begin()+pos);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
unsigned nMin;
|
||||||
|
eoUniformGeneChooser<EOT> uChooser;
|
||||||
|
eoGeneDelChooser<EOT> & chooser;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in a new issue