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)
|
||||
{}
|
||||
|
||||
/// 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
|
||||
{
|
||||
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
|
||||
operator() with two operands, both can be modified.
|
||||
*/
|
||||
#define eoQuadraticOp eoQuadOp
|
||||
|
||||
template<class EOType>
|
||||
class eoQuadraticOp: public eoOp<EOType>, public eoBF<EOType&, EOType&, void> {
|
||||
|
|
@ -115,6 +116,29 @@ public:
|
|||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 _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
|
||||
for ( unsigned i = 0; i < _popSize; i++ )
|
||||
unsigned oldSize = size();
|
||||
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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,21 +27,34 @@
|
|||
#ifndef _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),
|
||||
and implements the virtual functions printOn() and readFrom()
|
||||
*/
|
||||
|
||||
template <class FitT, class GeneType>
|
||||
class eoVariableLength : public EO<FitT>, public std::list<GeneType>
|
||||
class eoVariableLength : public EO<FitT>, public std::vector<GeneType>
|
||||
{
|
||||
public :
|
||||
|
||||
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...
|
||||
void printOn(ostream& os) const
|
||||
|
|
@ -51,7 +64,7 @@ class eoVariableLength : public EO<FitT>, public std::list<GeneType>
|
|||
|
||||
os << size() << ' ';
|
||||
|
||||
std::copy(begin(), end(), ostream_iterator<double>(os));
|
||||
std::copy(begin(), end(), ostream_iterator<AtomType>(os, " "));
|
||||
}
|
||||
|
||||
/// reading...
|
||||
|
|
@ -62,14 +75,14 @@ class eoVariableLength : public EO<FitT>, public std::list<GeneType>
|
|||
unsigned sz;
|
||||
is >> sz;
|
||||
|
||||
resize(0);
|
||||
resize(sz);
|
||||
unsigned i;
|
||||
unsigned gene;
|
||||
|
||||
for (i = 0; i < sz; ++i)
|
||||
{
|
||||
is >> gene;
|
||||
push_back(gene);
|
||||
AtomType atom;
|
||||
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>
|
||||
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