*** empty log message ***
This commit is contained in:
parent
9fba2bfbb9
commit
4ebd212d14
15 changed files with 1872 additions and 452 deletions
54
eo/src/eoBackInserter.h
Normal file
54
eo/src/eoBackInserter.h
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
/* -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
eoInserter.h
|
||||||
|
Abstract population insertion operator, which is used by the eoGeneralOps
|
||||||
|
to insert the results in the (intermediate) population. This file also
|
||||||
|
contains the definitions of a derived classes that implements a back inserter,
|
||||||
|
probably the only efficient inserter for populations of type vector.
|
||||||
|
|
||||||
|
(c) Maarten Keijzer (mkeijzer@mad.scientist.com) and GeNeura Team, 1999, 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef eoBackInserter_h
|
||||||
|
#define eoBackInserter_h
|
||||||
|
|
||||||
|
#include "eoInserter.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eoBackInserter: Interface class that enables an operator to insert
|
||||||
|
new individuals at the back of the new population.
|
||||||
|
*/
|
||||||
|
template <class EOT>
|
||||||
|
class eoBackInserter : public eoPopInserter<EOT>
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
|
||||||
|
eoBackInserter(void) : eoPopInserter<EOT>() {}
|
||||||
|
|
||||||
|
void insert(const EOT& _eot)
|
||||||
|
{
|
||||||
|
pop().push_back(_eot);
|
||||||
|
}
|
||||||
|
|
||||||
|
string className(void) const { return "eoBackInserter"; }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
57
eo/src/eoDetTournamentIndiSelector.h
Normal file
57
eo/src/eoDetTournamentIndiSelector.h
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
/* -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
eoDetTournamentIndiSelector.h
|
||||||
|
|
||||||
|
(c) Maarten Keijzer (mkeijzer@mad.scientist.com) and GeNeura Team, 1999, 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef eoDetTournamentIndiSelector_h
|
||||||
|
#define eoDetTournamentIndiSelector_h
|
||||||
|
|
||||||
|
#include "eoIndiSelector.h"
|
||||||
|
#include "selectors.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eoDetTournamentIndiSelector: selects children through a deterministic_tournament
|
||||||
|
*/
|
||||||
|
template <class EOT>
|
||||||
|
class eoDetTournamentIndiSelector : public eoPopIndiSelector<EOT>
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
|
||||||
|
eoDetTournamentIndiSelector(int _tournamentSize)
|
||||||
|
: eoPopIndiSelector<EOT>(),
|
||||||
|
tournamentSize(_tournamentSize)
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual ~eoDetTournamentIndiSelector(void) {}
|
||||||
|
|
||||||
|
const EOT& do_select(void)
|
||||||
|
{
|
||||||
|
return *deterministic_tournament(begin(), end(), tournamentSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
|
int tournamentSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
134
eo/src/eoIndiSelector.h
Normal file
134
eo/src/eoIndiSelector.h
Normal file
|
|
@ -0,0 +1,134 @@
|
||||||
|
/* -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
eoIndiSelector.h
|
||||||
|
Abstract selection operator, which is used by the eoGeneralOps
|
||||||
|
to obtain individuals from a source population. It also gives a
|
||||||
|
direct descended eoPopIndiSelector that can be used to
|
||||||
|
initialize objects with an eoPop<EOT>. For most uses use eoPopIndividualSelector
|
||||||
|
rather than eoIndividualSelector to derive from.
|
||||||
|
|
||||||
|
(c) Maarten Keijzer (mkeijzer@mad.scientist.com) and GeNeura Team, 1999, 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef eoIndiSelector_h
|
||||||
|
#define eoIndiSelector_h
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eoIndividualSelector: This class defines the interface
|
||||||
|
*/
|
||||||
|
template <class EOT>
|
||||||
|
class eoIndiSelector
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
|
||||||
|
eoIndiSelector() {}
|
||||||
|
|
||||||
|
virtual ~eoIndiSelector(void) {}
|
||||||
|
|
||||||
|
virtual size_t size(void) const = 0;
|
||||||
|
virtual const EOT& operator[](size_t) const = 0;
|
||||||
|
|
||||||
|
virtual const EOT& select(void) = 0;
|
||||||
|
|
||||||
|
virtual vector<const EOT*> select(size_t _how_many)
|
||||||
|
{ // default implementation just calls select a couple of times
|
||||||
|
// this can be overridden in favour of a more efficient implementation
|
||||||
|
vector<const EOT*> result(_how_many);
|
||||||
|
|
||||||
|
for (int i = 0; i < _how_many; ++i)
|
||||||
|
{
|
||||||
|
result[i] = &select();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eoPopIndiSelector: Intermediate class for dispensing populations
|
||||||
|
various useful things can be done with this class:
|
||||||
|
you can specify how many of the population can ever be dispensed to the
|
||||||
|
operators, but you can also specify a preference to the first guy being
|
||||||
|
dispensed. This is useful if you want to perform the operator on a specific
|
||||||
|
individual.
|
||||||
|
*/
|
||||||
|
template <class EOT>
|
||||||
|
class eoPopIndiSelector : public eoIndiSelector<EOT>
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
eoPopIndiSelector(void) : pop(0), firstChoice(-1), last(0), eoIndiSelector<EOT>() {}
|
||||||
|
|
||||||
|
virtual ~eoPopIndiSelector(void) {}
|
||||||
|
|
||||||
|
struct eoUnitializedException{};
|
||||||
|
|
||||||
|
/** Initialization function
|
||||||
|
*/
|
||||||
|
eoPopIndiSelector& operator()(const eoPop<EOT>& _pop, int _end = -1, int _myGuy = -1)
|
||||||
|
{
|
||||||
|
pop = &_pop;
|
||||||
|
last = _end;
|
||||||
|
|
||||||
|
if (last < 0 || last > pop->size())
|
||||||
|
{
|
||||||
|
last = pop->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
firstChoice = _myGuy;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size(void) const { valid(); return last; }
|
||||||
|
const EOT& operator[](size_t _i) const { valid(); return pop->operator[](_i); }
|
||||||
|
|
||||||
|
eoPop<EOT>::const_iterator begin(void) const { valid(); return pop->begin(); }
|
||||||
|
eoPop<EOT>::const_iterator end(void) const { valid(); return pop->end(); }
|
||||||
|
|
||||||
|
|
||||||
|
/// select does the work. Note that it is not virtual. It calls do_select that needs to be implemented by the derived classes
|
||||||
|
const EOT& select(void)
|
||||||
|
{
|
||||||
|
valid();
|
||||||
|
if (firstChoice < 0 || firstChoice >= size())
|
||||||
|
{
|
||||||
|
return do_select(); // let the child figure out what to do
|
||||||
|
}
|
||||||
|
|
||||||
|
const EOT& result = pop->operator[](firstChoice);
|
||||||
|
firstChoice = -1;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const EOT& do_select(void) = 0;
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
|
void valid(void) const
|
||||||
|
{
|
||||||
|
if (pop == 0)
|
||||||
|
throw eoUnitializedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
const eoPop<EOT>* pop; // need a pointer as this the pop argument can be re-instated
|
||||||
|
int last;
|
||||||
|
int firstChoice;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
93
eo/src/eoInserter.h
Normal file
93
eo/src/eoInserter.h
Normal file
|
|
@ -0,0 +1,93 @@
|
||||||
|
/* -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
eoInserter.h
|
||||||
|
Abstract population insertion operator, which is used by the eoGeneralOps
|
||||||
|
to insert the results in the (intermediate) population. It also contains
|
||||||
|
a direct descended eoPopInserter that defines a convenient inbetween class
|
||||||
|
for working with eoPop<EOT>. The user will most likely derive from eoPopInserter
|
||||||
|
rather than eoInserter.
|
||||||
|
|
||||||
|
(c) Maarten Keijzer (mak@dhi.dk) and GeNeura Team, 1999, 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef eoInserter_h
|
||||||
|
#define eoInserter_h
|
||||||
|
|
||||||
|
#include "eoObject.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eoInserter: Interface class that enables an operator to insert
|
||||||
|
new individuals into the (intermediate) population.
|
||||||
|
*/
|
||||||
|
template <class EOT>
|
||||||
|
class eoInserter : public eoObject
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
virtual ~eoInserter() {}
|
||||||
|
|
||||||
|
struct eoInserterException{};
|
||||||
|
|
||||||
|
virtual void insert(const EOT&) = 0; // can throw an eoInserterException
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eoPopInserter: In-between class that defines an initialization
|
||||||
|
* of the eoIndividualInserter.
|
||||||
|
*/
|
||||||
|
template <class EOT>
|
||||||
|
class eoPopInserter : public eoInserter<EOT>
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
|
||||||
|
eoPopInserter(void) : thePop(0), eoInserter<EOT>() {}
|
||||||
|
|
||||||
|
/// Binds the population to this class. This is an initialization routine used by breeders
|
||||||
|
eoInserter<EOT>& operator()(eoPop<EOT>& _pop)
|
||||||
|
{
|
||||||
|
thePop = &_pop;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected :
|
||||||
|
|
||||||
|
eoPop<EOT>& pop(void) const { valid(); return *thePop; }
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
|
void valid(void) const
|
||||||
|
{
|
||||||
|
if (thePop == 0)
|
||||||
|
throw eoInserterException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Need a pointer as the inserter should be able to bind to different populations.
|
||||||
|
// This is caused by the 'one template parameter only' convention in EO.
|
||||||
|
|
||||||
|
eoPop<EOT>* thePop;
|
||||||
|
|
||||||
|
// If eoGOpBreeder could be templatized over the inserter and the selector,
|
||||||
|
// the pop could be a ref as this class could be created every time it is applied
|
||||||
|
// and subsequently would get the population through the constructor
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
54
eo/src/eoProportionalGOpSelector.h
Normal file
54
eo/src/eoProportionalGOpSelector.h
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
eoProportionalGOpSelector.h
|
||||||
|
Proportional Generalized Operator Selector.
|
||||||
|
|
||||||
|
(c) Maarten Keijzer (mkeijzer@mad.scientist.com), GeNeura Team 1998, 1999, 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef eoProportionalGOpSelector_h
|
||||||
|
#define eoProportionalGOpSelector_h
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "eoGOpSelector.h"
|
||||||
|
|
||||||
|
/** eoProportionalGOpSel: do proportional selection, returns one of the
|
||||||
|
operators
|
||||||
|
*/
|
||||||
|
template <class EOT>
|
||||||
|
class eoProportionalGOpSel : public eoGOpSelector<EOT>
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
eoProportionalGOpSel() : eoGOpSelector<EOT>() {}
|
||||||
|
|
||||||
|
/** Returns the operator proportionally selected */
|
||||||
|
virtual eoGeneralOp<EOT>& selectOp()
|
||||||
|
{
|
||||||
|
unsigned what = rng.roulette_wheel(getRates());
|
||||||
|
return *operator[](what);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
virtual string className() const { return "eoGOpSelector"; };
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
904
eo/src/eoRNG.h
904
eo/src/eoRNG.h
|
|
@ -1,452 +1,452 @@
|
||||||
/*
|
/*
|
||||||
* Random number generator adapted from (see comments below)
|
* Random number generator adapted from (see comments below)
|
||||||
*
|
*
|
||||||
* The random number generator is modified into a class
|
* The random number generator is modified into a class
|
||||||
* by Maarten Keijzer (mak@dhi.dk). Also added the Box-Muller
|
* by Maarten Keijzer (mak@dhi.dk). Also added the Box-Muller
|
||||||
* transformation to generate normal deviates.
|
* transformation to generate normal deviates.
|
||||||
*
|
*
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Lesser General Public
|
modify it under the terms of the GNU Lesser General Public
|
||||||
License as published by the Free Software Foundation; either
|
License as published by the Free Software Foundation; either
|
||||||
version 2 of the License, or (at your option) any later version.
|
version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
This library is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
Lesser General Public License for more details.
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
You should have received a copy of the GNU Lesser General Public
|
||||||
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: todos@geneura.ugr.es, http://geneura.ugr.es
|
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ************ DOCUMENTATION IN ORIGINAL FILE *********************/
|
/* ************ DOCUMENTATION IN ORIGINAL FILE *********************/
|
||||||
|
|
||||||
// This is the ``Mersenne Twister'' random number generator MT19937, which
|
// This is the ``Mersenne Twister'' random number generator MT19937, which
|
||||||
// generates pseudorandom integers uniformly distributed in 0..(2^32 - 1)
|
// generates pseudorandom integers uniformly distributed in 0..(2^32 - 1)
|
||||||
// starting from any odd seed in 0..(2^32 - 1). This version is a recode
|
// starting from any odd seed in 0..(2^32 - 1). This version is a recode
|
||||||
// by Shawn Cokus (Cokus@math.washington.edu) on March 8, 1998 of a version by
|
// by Shawn Cokus (Cokus@math.washington.edu) on March 8, 1998 of a version by
|
||||||
// Takuji Nishimura (who had suggestions from Topher Cooper and Marc Rieffel in
|
// Takuji Nishimura (who had suggestions from Topher Cooper and Marc Rieffel in
|
||||||
// July-August 1997).
|
// July-August 1997).
|
||||||
//
|
//
|
||||||
// Effectiveness of the recoding (on Goedel2.math.washington.edu, a DEC Alpha
|
// Effectiveness of the recoding (on Goedel2.math.washington.edu, a DEC Alpha
|
||||||
// running OSF/1) using GCC -O3 as a compiler: before recoding: 51.6 sec. to
|
// running OSF/1) using GCC -O3 as a compiler: before recoding: 51.6 sec. to
|
||||||
// generate 300 million random numbers; after recoding: 24.0 sec. for the same
|
// generate 300 million random numbers; after recoding: 24.0 sec. for the same
|
||||||
// (i.e., 46.5% of original time), so speed is now about 12.5 million random
|
// (i.e., 46.5% of original time), so speed is now about 12.5 million random
|
||||||
// number generations per second on this machine.
|
// number generations per second on this machine.
|
||||||
//
|
//
|
||||||
// According to the URL <http://www.math.keio.ac.jp/~matumoto/emt.html>
|
// According to the URL <http://www.math.keio.ac.jp/~matumoto/emt.html>
|
||||||
// (and paraphrasing a bit in places), the Mersenne Twister is ``designed
|
// (and paraphrasing a bit in places), the Mersenne Twister is ``designed
|
||||||
// with consideration of the flaws of various existing generators,'' has
|
// with consideration of the flaws of various existing generators,'' has
|
||||||
// a period of 2^19937 - 1, gives a sequence that is 623-dimensionally
|
// a period of 2^19937 - 1, gives a sequence that is 623-dimensionally
|
||||||
// equidistributed, and ``has passed many stringent tests, including the
|
// equidistributed, and ``has passed many stringent tests, including the
|
||||||
// die-hard test of G. Marsaglia and the load test of P. Hellekalek and
|
// die-hard test of G. Marsaglia and the load test of P. Hellekalek and
|
||||||
// S. Wegenkittl.'' It is efficient in memory usage (typically using 2506
|
// S. Wegenkittl.'' It is efficient in memory usage (typically using 2506
|
||||||
// to 5012 bytes of static data, depending on data type sizes, and the code
|
// to 5012 bytes of static data, depending on data type sizes, and the code
|
||||||
// is quite short as well). It generates random numbers in batches of 624
|
// is quite short as well). It generates random numbers in batches of 624
|
||||||
// at a time, so the caching and pipelining of modern systems is exploited.
|
// at a time, so the caching and pipelining of modern systems is exploited.
|
||||||
// It is also divide- and mod-free.
|
// It is also divide- and mod-free.
|
||||||
//
|
//
|
||||||
// This library is free software; you can redistribute it and/or modify it
|
// This library is free software; you can redistribute it and/or modify it
|
||||||
// under the terms of the GNU Library General Public License as published by
|
// under the terms of the GNU Library General Public License as published by
|
||||||
// the Free Software Foundation (either version 2 of the License or, at your
|
// 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
|
// option, any later version). This library is distributed in the hope that
|
||||||
// it will be useful, but WITHOUT ANY WARRANTY, without even the implied
|
// it will be useful, but WITHOUT ANY WARRANTY, without even the implied
|
||||||
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||||
// the GNU Library General Public License for more details. You should have
|
// the GNU Library General Public License for more details. You should have
|
||||||
// received a copy of the GNU Library General Public License along with this
|
// received a copy of the GNU Library General Public License along with this
|
||||||
// library; if not, write to the Free Software Foundation, Inc., 59 Temple
|
// library; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
// Place, Suite 330, Boston, MA 02111-1307, USA.
|
// Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||||
//
|
//
|
||||||
// The code as Shawn received it included the following notice:
|
// The code as Shawn received it included the following notice:
|
||||||
//
|
//
|
||||||
// Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. When
|
// Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. When
|
||||||
// you use this, send an e-mail to <matumoto@math.keio.ac.jp> with
|
// you use this, send an e-mail to <matumoto@math.keio.ac.jp> with
|
||||||
// an appropriate reference to your work.
|
// an appropriate reference to your work.
|
||||||
//
|
//
|
||||||
// It would be nice to CC: <Cokus@math.washington.edu> when you write.
|
// It would be nice to CC: <Cokus@math.washington.edu> when you write.
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
// uint32 must be an unsigned integer type capable of holding at least 32
|
// uint32 must be an unsigned integer type capable of holding at least 32
|
||||||
// bits; exactly 32 should be fastest, but 64 is better on an Alpha with
|
// bits; exactly 32 should be fastest, but 64 is better on an Alpha with
|
||||||
// GCC at -O3 optimization so try your options and see what's best for you
|
// GCC at -O3 optimization so try your options and see what's best for you
|
||||||
//
|
//
|
||||||
|
|
||||||
/* ************ END DOCUMENTATION IN ORIGINAL FILE *********************/
|
/* ************ END DOCUMENTATION IN ORIGINAL FILE *********************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef EO_RANDOM_NUMBER_GENERATOR
|
#ifndef EO_RANDOM_NUMBER_GENERATOR
|
||||||
#define EO_RANDOM_NUMBER_GENERATOR
|
#define EO_RANDOM_NUMBER_GENERATOR
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
#include <eoPersistent.h>
|
#include <eoPersistent.h>
|
||||||
#include <eoObject.h>
|
#include <eoObject.h>
|
||||||
|
|
||||||
// TODO: check for various compilers if this is exactly 32 bits
|
// TODO: check for various compilers if this is exactly 32 bits
|
||||||
// Unfortunately MSVC's preprocessor does not comprehends sizeof()
|
// Unfortunately MSVC's preprocessor does not comprehends sizeof()
|
||||||
// so neat preprocessing tricks will not work
|
// so neat preprocessing tricks will not work
|
||||||
|
|
||||||
typedef unsigned long uint32; // Compiler and platform dependent!
|
typedef unsigned long uint32; // Compiler and platform dependent!
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// eoRng
|
// eoRng
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
eoRng is a persitent class that uses the ``Mersenne Twister'' random number generator MT19937
|
eoRng is a persitent class that uses the ``Mersenne Twister'' random number generator MT19937
|
||||||
for generating random numbers. The various member functions implement useful functions
|
for generating random numbers. The various member functions implement useful functions
|
||||||
for evolutionary algorithms. Included are: rand(), random(), flip() and normal().
|
for evolutionary algorithms. Included are: rand(), random(), flip() and normal().
|
||||||
|
|
||||||
Note for people porting EO to other platforms: please make sure that the typedef
|
Note for people porting EO to other platforms: please make sure that the typedef
|
||||||
uint32 in the file eoRng.h is exactly 32 bits long. It may be longer, but not
|
uint32 in the file eoRng.h is exactly 32 bits long. It may be longer, but not
|
||||||
shorter. If it is longer, file compatibility between EO on different platforms
|
shorter. If it is longer, file compatibility between EO on different platforms
|
||||||
may be broken.
|
may be broken.
|
||||||
*/
|
*/
|
||||||
class eoRng : public eoObject, public eoPersistent
|
class eoRng : public eoObject, public eoPersistent
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
/**
|
/**
|
||||||
ctor takes a random seed; if you want another seed, use reseed
|
ctor takes a random seed; if you want another seed, use reseed
|
||||||
@see reseed
|
@see reseed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
eoRng(uint32 s = (uint32) time(0) ) : state(0), next(0), left(-1), cached(false), N(624), M(397), K(0x9908B0DFU) {
|
eoRng(uint32 s = (uint32) time(0) ) : state(0), next(0), left(-1), cached(false), N(624), M(397), K(0x9908B0DFU) {
|
||||||
state = new uint32[N+1];
|
state = new uint32[N+1];
|
||||||
initialize(s);
|
initialize(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
~eoRng(void)
|
~eoRng(void)
|
||||||
{
|
{
|
||||||
delete [] state;
|
delete [] state;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Re-initializes the Random Number Generator.
|
Re-initializes the Random Number Generator.
|
||||||
*/
|
*/
|
||||||
void reseed(uint32 s)
|
void reseed(uint32 s)
|
||||||
{
|
{
|
||||||
initialize(s);
|
initialize(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
uniform(m = 1.0) returns a random double in the range [0, m)
|
uniform(m = 1.0) returns a random double in the range [0, m)
|
||||||
*/
|
*/
|
||||||
double uniform(double m = 1.0)
|
double uniform(double m = 1.0)
|
||||||
{ // random number between [0, m]
|
{ // random number between [0, m]
|
||||||
return m * double(rand()) / double(rand_max());
|
return m * double(rand()) / double(rand_max());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
random() returns a random integer in the range [0, m)
|
random() returns a random integer in the range [0, m)
|
||||||
*/
|
*/
|
||||||
uint32 random(uint32 m)
|
uint32 random(uint32 m)
|
||||||
{
|
{
|
||||||
return uint32(uniform() * double(m));
|
return uint32(uniform() * double(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
flip() tosses a biased coin such that flip(x/100.0) will
|
flip() tosses a biased coin such that flip(x/100.0) will
|
||||||
returns true x% of the time
|
returns true x% of the time
|
||||||
*/
|
*/
|
||||||
bool flip(float bias)
|
bool flip(float bias)
|
||||||
{
|
{
|
||||||
return uniform() < bias;
|
return uniform() < bias;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
normal() zero mean gaussian deviate with standard deviation of 1
|
normal() zero mean gaussian deviate with standard deviation of 1
|
||||||
*/
|
*/
|
||||||
double normal(void); // gaussian mutation, stdev 1
|
double normal(void); // gaussian mutation, stdev 1
|
||||||
|
|
||||||
/**
|
/**
|
||||||
normal(stdev) zero mean gaussian deviate with user defined standard deviation
|
normal(stdev) zero mean gaussian deviate with user defined standard deviation
|
||||||
*/
|
*/
|
||||||
double normal(double stdev)
|
double normal(double stdev)
|
||||||
{
|
{
|
||||||
return stdev * normal();
|
return stdev * normal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
normal(mean, stdev) user defined mean gaussian deviate with user defined standard deviation
|
normal(mean, stdev) user defined mean gaussian deviate with user defined standard deviation
|
||||||
*/
|
*/
|
||||||
double normal(double mean, double stdev)
|
double normal(double mean, double stdev)
|
||||||
{
|
{
|
||||||
return mean + normal(stdev);
|
return mean + normal(stdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
rand() returns a random number in the range [0, rand_max)
|
rand() returns a random number in the range [0, rand_max)
|
||||||
*/
|
*/
|
||||||
uint32 rand();
|
uint32 rand();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
rand_max() the maximum returned by rand()
|
rand_max() the maximum returned by rand()
|
||||||
*/
|
*/
|
||||||
uint32 rand_max(void) const { return (uint32) 0xffffffff; }
|
uint32 rand_max(void) const { return (uint32) 0xffffffff; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
roulette_wheel(vec, total = 0) does a roulette wheel selection
|
roulette_wheel(vec, total = 0) does a roulette wheel selection
|
||||||
on the input vector vec. If the total is not supplied, it is
|
on the input vector vec. If the total is not supplied, it is
|
||||||
calculated. It returns an integer denoting the selected argument.
|
calculated. It returns an integer denoting the selected argument.
|
||||||
*/
|
*/
|
||||||
template <class T>
|
template <class T>
|
||||||
int roulette_wheel(const std::vector<T>& vec, T total = 0)
|
int roulette_wheel(const std::vector<T>& vec, T total = 0)
|
||||||
{
|
{
|
||||||
if (total == 0)
|
if (total == 0)
|
||||||
{ // count
|
{ // count
|
||||||
for (unsigned i = 0; i < vec.size(); ++i)
|
for (int i = 0; i < vec.size(); ++i)
|
||||||
total += vec[i];
|
total += vec[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
float change = uniform() * total;
|
float change = uniform() * total;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
while (change > 0)
|
while (change > 0)
|
||||||
{
|
{
|
||||||
change -= vec[i++];
|
change -= vec[i++];
|
||||||
}
|
}
|
||||||
|
|
||||||
return --i;
|
return --i;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
void printOn(ostream& _os) const
|
void printOn(ostream& _os) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < N; ++i)
|
for (int i = 0; i < N; ++i)
|
||||||
{
|
{
|
||||||
_os << state[i] << ' ';
|
_os << state[i] << ' ';
|
||||||
}
|
}
|
||||||
_os << int(next - state) << ' ';
|
_os << int(next - state) << ' ';
|
||||||
_os << left << ' ' << cached << ' ' << cacheValue;
|
_os << left << ' ' << cached << ' ' << cacheValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
void readFrom(istream& _is)
|
void readFrom(istream& _is)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < N; ++i)
|
for (int i = 0; i < N; ++i)
|
||||||
{
|
{
|
||||||
_is >> state[i];
|
_is >> state[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
int n;
|
int n;
|
||||||
_is >> n;
|
_is >> n;
|
||||||
next = state + n;
|
next = state + n;
|
||||||
|
|
||||||
_is >> left;
|
_is >> left;
|
||||||
_is >> cached;
|
_is >> cached;
|
||||||
_is >> cacheValue;
|
_is >> cacheValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private :
|
private :
|
||||||
uint32 restart(void);
|
uint32 restart(void);
|
||||||
void initialize(uint32 seed);
|
void initialize(uint32 seed);
|
||||||
|
|
||||||
uint32* state; // the array for the state
|
uint32* state; // the array for the state
|
||||||
uint32* next;
|
uint32* next;
|
||||||
int left;
|
int left;
|
||||||
|
|
||||||
bool cached;
|
bool cached;
|
||||||
float cacheValue;
|
float cacheValue;
|
||||||
|
|
||||||
const int N;
|
const int N;
|
||||||
const int M;
|
const int M;
|
||||||
const uint32 K; // a magic constant
|
const uint32 K; // a magic constant
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Private copy ctor and assignment operator to make sure that
|
Private copy ctor and assignment operator to make sure that
|
||||||
nobody accidentally copies the random number generator.
|
nobody accidentally copies the random number generator.
|
||||||
If you want similar RNG's, make two RNG's and initialize
|
If you want similar RNG's, make two RNG's and initialize
|
||||||
them with the same seed.
|
them with the same seed.
|
||||||
*/
|
*/
|
||||||
eoRng (const eoRng&); // no implementation
|
eoRng (const eoRng&); // no implementation
|
||||||
eoRng& operator=(const eoRng&); // dito
|
eoRng& operator=(const eoRng&); // dito
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The one and only global eoRng object
|
The one and only global eoRng object
|
||||||
*/
|
*/
|
||||||
static eoRng rng;
|
static eoRng rng;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The class uniform_generator can be used in the STL generate function
|
The class uniform_generator can be used in the STL generate function
|
||||||
to easily generate random floats and doubles between [0, _max). _max
|
to easily generate random floats and doubles between [0, _max). _max
|
||||||
defaults to 1.0
|
defaults to 1.0
|
||||||
*/
|
*/
|
||||||
template <class T = double> class uniform_generator
|
template <class T = double> class uniform_generator
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
uniform_generator(T _max = T(1.0), eoRng& _rng = rng) : maxim(_max), uniform(_rng) {}
|
uniform_generator(T _max = T(1.0), eoRng& _rng = rng) : maxim(_max), uniform(_rng) {}
|
||||||
|
|
||||||
virtual T operator()(void) { return (T) uniform.uniform(maxim); }
|
virtual T operator()(void) { return (T) uniform.uniform(maxim); }
|
||||||
private :
|
private :
|
||||||
T maxim;
|
T maxim;
|
||||||
eoRng& uniform;
|
eoRng& uniform;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The class random_generator can be used in the STL generate function
|
The class random_generator can be used in the STL generate function
|
||||||
to easily generate random ints between [0, _max).
|
to easily generate random ints between [0, _max).
|
||||||
*/
|
*/
|
||||||
template <class T = uint32> class random_generator
|
template <class T = uint32> class random_generator
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
random_generator(int _max, eoRng& _rng = rng) : maxim(_max), random(_rng) {}
|
random_generator(int _max, eoRng& _rng = rng) : maxim(_max), random(_rng) {}
|
||||||
|
|
||||||
virtual T operator()(void) { return (T) random.random(max); }
|
virtual T operator()(void) { return (T) random.random(max); }
|
||||||
|
|
||||||
private :
|
private :
|
||||||
T maxim;
|
T maxim;
|
||||||
eoRng& random;
|
eoRng& random;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The class normal_generator can be used in the STL generate function
|
The class normal_generator can be used in the STL generate function
|
||||||
to easily generate gaussian distributed floats and doubles. The user
|
to easily generate gaussian distributed floats and doubles. The user
|
||||||
can supply a standard deviation which defaults to 1.
|
can supply a standard deviation which defaults to 1.
|
||||||
*/
|
*/
|
||||||
template <class T = double> class normal_generator
|
template <class T = double> class normal_generator
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
normal_generator(T _stdev = T(1.0), eoRng& _rng = rng) : stdev(_stdev), normal(_rng) {}
|
normal_generator(T _stdev = T(1.0), eoRng& _rng = rng) : stdev(_stdev), normal(_rng) {}
|
||||||
|
|
||||||
virtual T operator()(void) { return (T) normal.normal(stdev); }
|
virtual T operator()(void) { return (T) normal.normal(stdev); }
|
||||||
|
|
||||||
private :
|
private :
|
||||||
T stdev;
|
T stdev;
|
||||||
eoRng& normal;
|
eoRng& normal;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Implementation of some eoRng members.... Don't mind the mess, it does work.
|
// Implementation of some eoRng members.... Don't mind the mess, it does work.
|
||||||
|
|
||||||
|
|
||||||
#define hiBit(u) ((u) & 0x80000000U) // mask all but highest bit of u
|
#define hiBit(u) ((u) & 0x80000000U) // mask all but highest bit of u
|
||||||
#define loBit(u) ((u) & 0x00000001U) // mask all but lowest bit of u
|
#define loBit(u) ((u) & 0x00000001U) // mask all but lowest bit of u
|
||||||
#define loBits(u) ((u) & 0x7FFFFFFFU) // mask the highest bit of u
|
#define loBits(u) ((u) & 0x7FFFFFFFU) // mask the highest bit of u
|
||||||
#define mixBits(u, v) (hiBit(u)|loBits(v)) // move hi bit of u to hi bit of v
|
#define mixBits(u, v) (hiBit(u)|loBits(v)) // move hi bit of u to hi bit of v
|
||||||
|
|
||||||
inline void eoRng::initialize(uint32 seed)
|
inline void eoRng::initialize(uint32 seed)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// We initialize state[0..(N-1)] via the generator
|
// We initialize state[0..(N-1)] via the generator
|
||||||
//
|
//
|
||||||
// x_new = (69069 * x_old) mod 2^32
|
// x_new = (69069 * x_old) mod 2^32
|
||||||
//
|
//
|
||||||
// from Line 15 of Table 1, p. 106, Sec. 3.3.4 of Knuth's
|
// from Line 15 of Table 1, p. 106, Sec. 3.3.4 of Knuth's
|
||||||
// _The Art of Computer Programming_, Volume 2, 3rd ed.
|
// _The Art of Computer Programming_, Volume 2, 3rd ed.
|
||||||
//
|
//
|
||||||
// Notes (SJC): I do not know what the initial state requirements
|
// Notes (SJC): I do not know what the initial state requirements
|
||||||
// of the Mersenne Twister are, but it seems this seeding generator
|
// of the Mersenne Twister are, but it seems this seeding generator
|
||||||
// could be better. It achieves the maximum period for its modulus
|
// could be better. It achieves the maximum period for its modulus
|
||||||
// (2^30) iff x_initial is odd (p. 20-21, Sec. 3.2.1.2, Knuth); if
|
// (2^30) iff x_initial is odd (p. 20-21, Sec. 3.2.1.2, Knuth); if
|
||||||
// x_initial can be even, you have sequences like 0, 0, 0, ...;
|
// x_initial can be even, you have sequences like 0, 0, 0, ...;
|
||||||
// 2^31, 2^31, 2^31, ...; 2^30, 2^30, 2^30, ...; 2^29, 2^29 + 2^31,
|
// 2^31, 2^31, 2^31, ...; 2^30, 2^30, 2^30, ...; 2^29, 2^29 + 2^31,
|
||||||
// 2^29, 2^29 + 2^31, ..., etc. so I force seed to be odd below.
|
// 2^29, 2^29 + 2^31, ..., etc. so I force seed to be odd below.
|
||||||
//
|
//
|
||||||
// Even if x_initial is odd, if x_initial is 1 mod 4 then
|
// Even if x_initial is odd, if x_initial is 1 mod 4 then
|
||||||
//
|
//
|
||||||
// the lowest bit of x is always 1,
|
// the lowest bit of x is always 1,
|
||||||
// the next-to-lowest bit of x is always 0,
|
// the next-to-lowest bit of x is always 0,
|
||||||
// the 2nd-from-lowest bit of x alternates ... 0 1 0 1 0 1 0 1 ... ,
|
// the 2nd-from-lowest bit of x alternates ... 0 1 0 1 0 1 0 1 ... ,
|
||||||
// the 3rd-from-lowest bit of x 4-cycles ... 0 1 1 0 0 1 1 0 ... ,
|
// the 3rd-from-lowest bit of x 4-cycles ... 0 1 1 0 0 1 1 0 ... ,
|
||||||
// the 4th-from-lowest bit of x has the 8-cycle ... 0 0 0 1 1 1 1 0 ... ,
|
// the 4th-from-lowest bit of x has the 8-cycle ... 0 0 0 1 1 1 1 0 ... ,
|
||||||
// ...
|
// ...
|
||||||
//
|
//
|
||||||
// and if x_initial is 3 mod 4 then
|
// and if x_initial is 3 mod 4 then
|
||||||
//
|
//
|
||||||
// the lowest bit of x is always 1,
|
// the lowest bit of x is always 1,
|
||||||
// the next-to-lowest bit of x is always 1,
|
// the next-to-lowest bit of x is always 1,
|
||||||
// the 2nd-from-lowest bit of x alternates ... 0 1 0 1 0 1 0 1 ... ,
|
// the 2nd-from-lowest bit of x alternates ... 0 1 0 1 0 1 0 1 ... ,
|
||||||
// the 3rd-from-lowest bit of x 4-cycles ... 0 0 1 1 0 0 1 1 ... ,
|
// the 3rd-from-lowest bit of x 4-cycles ... 0 0 1 1 0 0 1 1 ... ,
|
||||||
// the 4th-from-lowest bit of x has the 8-cycle ... 0 0 1 1 1 1 0 0 ... ,
|
// the 4th-from-lowest bit of x has the 8-cycle ... 0 0 1 1 1 1 0 0 ... ,
|
||||||
// ...
|
// ...
|
||||||
//
|
//
|
||||||
// The generator's potency (min. s>=0 with (69069-1)^s = 0 mod 2^32) is
|
// The generator's potency (min. s>=0 with (69069-1)^s = 0 mod 2^32) is
|
||||||
// 16, which seems to be alright by p. 25, Sec. 3.2.1.3 of Knuth. It
|
// 16, which seems to be alright by p. 25, Sec. 3.2.1.3 of Knuth. It
|
||||||
// also does well in the dimension 2..5 spectral tests, but it could be
|
// also does well in the dimension 2..5 spectral tests, but it could be
|
||||||
// better in dimension 6 (Line 15, Table 1, p. 106, Sec. 3.3.4, Knuth).
|
// better in dimension 6 (Line 15, Table 1, p. 106, Sec. 3.3.4, Knuth).
|
||||||
//
|
//
|
||||||
// Note that the random number user does not see the values generated
|
// Note that the random number user does not see the values generated
|
||||||
// here directly since restart() will always munge them first, so maybe
|
// here directly since restart() will always munge them first, so maybe
|
||||||
// none of all of this matters. In fact, the seed values made here could
|
// none of all of this matters. In fact, the seed values made here could
|
||||||
// even be extra-special desirable if the Mersenne Twister theory says
|
// even be extra-special desirable if the Mersenne Twister theory says
|
||||||
// so-- that's why the only change I made is to restrict to odd seeds.
|
// so-- that's why the only change I made is to restrict to odd seeds.
|
||||||
//
|
//
|
||||||
|
|
||||||
left = -1;
|
left = -1;
|
||||||
|
|
||||||
register uint32 x = (seed | 1U) & 0xFFFFFFFFU, *s = state;
|
register uint32 x = (seed | 1U) & 0xFFFFFFFFU, *s = state;
|
||||||
register int j;
|
register int j;
|
||||||
|
|
||||||
for(left=0, *s++=x, j=N; --j;
|
for(left=0, *s++=x, j=N; --j;
|
||||||
*s++ = (x*=69069U) & 0xFFFFFFFFU);
|
*s++ = (x*=69069U) & 0xFFFFFFFFU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline uint32 eoRng::restart(void)
|
inline uint32 eoRng::restart(void)
|
||||||
{
|
{
|
||||||
register uint32 *p0=state, *p2=state+2, *pM=state+M, s0, s1;
|
register uint32 *p0=state, *p2=state+2, *pM=state+M, s0, s1;
|
||||||
register int j;
|
register int j;
|
||||||
|
|
||||||
left=N-1, next=state+1;
|
left=N-1, next=state+1;
|
||||||
|
|
||||||
for(s0=state[0], s1=state[1], j=N-M+1; --j; s0=s1, s1=*p2++)
|
for(s0=state[0], s1=state[1], j=N-M+1; --j; s0=s1, s1=*p2++)
|
||||||
*p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
|
*p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
|
||||||
|
|
||||||
for(pM=state, j=M; --j; s0=s1, s1=*p2++)
|
for(pM=state, j=M; --j; s0=s1, s1=*p2++)
|
||||||
*p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
|
*p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
|
||||||
|
|
||||||
s1=state[0], *p0 = *pM ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
|
s1=state[0], *p0 = *pM ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
|
||||||
s1 ^= (s1 >> 11);
|
s1 ^= (s1 >> 11);
|
||||||
s1 ^= (s1 << 7) & 0x9D2C5680U;
|
s1 ^= (s1 << 7) & 0x9D2C5680U;
|
||||||
s1 ^= (s1 << 15) & 0xEFC60000U;
|
s1 ^= (s1 << 15) & 0xEFC60000U;
|
||||||
return(s1 ^ (s1 >> 18));
|
return(s1 ^ (s1 >> 18));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline uint32 eoRng::rand(void)
|
inline uint32 eoRng::rand(void)
|
||||||
{
|
{
|
||||||
uint32 y;
|
uint32 y;
|
||||||
|
|
||||||
if(--left < 0)
|
if(--left < 0)
|
||||||
return(restart());
|
return(restart());
|
||||||
|
|
||||||
y = *next++;
|
y = *next++;
|
||||||
y ^= (y >> 11);
|
y ^= (y >> 11);
|
||||||
y ^= (y << 7) & 0x9D2C5680U;
|
y ^= (y << 7) & 0x9D2C5680U;
|
||||||
y ^= (y << 15) & 0xEFC60000U;
|
y ^= (y << 15) & 0xEFC60000U;
|
||||||
return(y ^ (y >> 18));
|
return(y ^ (y >> 18));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline double eoRng::normal(void)
|
inline double eoRng::normal(void)
|
||||||
{
|
{
|
||||||
if (cached)
|
if (cached)
|
||||||
{
|
{
|
||||||
cached = false;
|
cached = false;
|
||||||
return cacheValue;
|
return cacheValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
float rSquare, factor, var1, var2;
|
float rSquare, factor, var1, var2;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
var1 = 2.0 * uniform() - 1.0;
|
var1 = 2.0 * uniform() - 1.0;
|
||||||
var2 = 2.0 * uniform() - 1.0;
|
var2 = 2.0 * uniform() - 1.0;
|
||||||
|
|
||||||
rSquare = var1 * var1 + var2 * var2;
|
rSquare = var1 * var1 + var2 * var2;
|
||||||
}
|
}
|
||||||
while (rSquare >= 1.0 || rSquare == 0.0);
|
while (rSquare >= 1.0 || rSquare == 0.0);
|
||||||
|
|
||||||
factor = sqrt(-2.0 * log(rSquare) / rSquare);
|
factor = sqrt(-2.0 * log(rSquare) / rSquare);
|
||||||
|
|
||||||
cacheValue = var1 * factor;
|
cacheValue = var1 * factor;
|
||||||
cached = true;
|
cached = true;
|
||||||
|
|
||||||
return (var2 * factor);
|
return (var2 * factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
51
eo/src/eoRandomIndiSelector.h
Normal file
51
eo/src/eoRandomIndiSelector.h
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
/* -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
eoRandomIndiSelector.h
|
||||||
|
Selects individuals at random.
|
||||||
|
|
||||||
|
(c) Maarten Keijzer (mkeijzer@mad.scientist.com) and GeNeura Team, 1999, 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef eoRandomIndiSelector_h
|
||||||
|
#define eoRandomIndiSelector_h
|
||||||
|
|
||||||
|
#include "eoIndiSelector.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eoRandomSelector: just selects a random child
|
||||||
|
*/
|
||||||
|
template <class EOT>
|
||||||
|
class eoRandomIndiSelector : public eoPopIndiSelector<EOT>
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
|
||||||
|
eoRandomIndiSelector(void) : eoPopIndiSelector<EOT>() {}
|
||||||
|
virtual ~eoRandomIndiSelector(void) {}
|
||||||
|
|
||||||
|
/// very complex function that returns just an individual
|
||||||
|
const EOT& do_select(void)
|
||||||
|
{
|
||||||
|
return operator[](rng.random(size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
61
eo/src/eoSequentialGOpSelector.h
Normal file
61
eo/src/eoSequentialGOpSelector.h
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
eoSequentialGOpSelector.h
|
||||||
|
Sequential Generalized Operator Selector.
|
||||||
|
|
||||||
|
(c) Maarten Keijzer (mkeijzer@mad.scientist.com), GeNeura Team 1998, 1999, 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef eoSequentialGOpSelector_h
|
||||||
|
#define eoSequentialGOpSelector_h
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "eoGOpSelector.h"
|
||||||
|
/** eoSequentialGOpSel: do proportional selection, but return a sequence of
|
||||||
|
operations to be applied one after the other.
|
||||||
|
*/
|
||||||
|
template <class EOT>
|
||||||
|
class eoSequentialGOpSel : public eoGOpSelector<EOT>
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
|
||||||
|
virtual eoGeneralOp<EOT>& selectOp()
|
||||||
|
{
|
||||||
|
combined.clear();
|
||||||
|
|
||||||
|
for (int i = 0; i < size(); ++i)
|
||||||
|
{
|
||||||
|
if (operator[](i) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (rng.flip(getRates()[i]))
|
||||||
|
combined.addOp(operator[](i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return combined;
|
||||||
|
}
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
|
eoCombinedOp<EOT> combined;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
85
eo/src/eoSteadyStateEA.h
Normal file
85
eo/src/eoSteadyStateEA.h
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// eoSteadyStateEA.h
|
||||||
|
// (c) GeNeura Team, 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
|
||||||
|
*/
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef _eoSteadyStateEA_h
|
||||||
|
#define _eoSteadyStateEA_h
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "eoSteadyStateGeneration.h" // eoPop
|
||||||
|
#include <eoTerm.h>
|
||||||
|
|
||||||
|
/** EOSteadyStateEA:
|
||||||
|
An easy-to-use evolutionary algorithm, just supply
|
||||||
|
a general operator selector, a selector for choosing the ones
|
||||||
|
to reproduce and an eoSteadyStateInserter that takes care of evaluating
|
||||||
|
and inserter the guy/girl in the steady state population.
|
||||||
|
*/
|
||||||
|
template<class EOT> class eoSteadyStateEA: public eoAlgo<EOT>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Constructor.
|
||||||
|
eoSteadyStateEA(
|
||||||
|
eoGOpSelector<EOT>& _opSelector,
|
||||||
|
eoPopIndiSelector<EOT>& _selector,
|
||||||
|
eoSteadyStateInserter<EOT>& _inserter,
|
||||||
|
eoTerm<Chrom>& _terminator,
|
||||||
|
unsigned _steps = 0 )
|
||||||
|
: step(_opSelector, _selector, _inserter),
|
||||||
|
terminator( _terminator)
|
||||||
|
{};
|
||||||
|
|
||||||
|
/// Constructor from an already created generation
|
||||||
|
eoSteadyStateEA(eoSteadyStateGeneration<EOT>& _gen,
|
||||||
|
eoTerm<EOT>& _terminator):
|
||||||
|
step(_gen),
|
||||||
|
terminator( _terminator){};
|
||||||
|
|
||||||
|
/// Apply one generation of evolution to the population.
|
||||||
|
virtual void operator()(eoPop<Chrom>& pop) {
|
||||||
|
do {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
step(pop);
|
||||||
|
}
|
||||||
|
catch (exception& e)
|
||||||
|
{
|
||||||
|
string s = e.what();
|
||||||
|
s.append( " in eoSteadyStateEA ");
|
||||||
|
throw runtime_error( s );
|
||||||
|
}
|
||||||
|
} while ( terminator( pop ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Class name.
|
||||||
|
string className() const { return "eoSteadyStateEA"; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
eoSteadyStateGeneration<EOT> step;
|
||||||
|
eoTerm<EOT>& terminator;
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#endif eoEasyEA_h
|
||||||
88
eo/src/eoSteadyStateGeneration.h
Normal file
88
eo/src/eoSteadyStateGeneration.h
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// eoSteadyStateGeneration.h
|
||||||
|
// (c) GeNeura Team, 1998
|
||||||
|
/*
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef eoSteadyStateGeneration_h
|
||||||
|
#define eoSteadyStateGeneration_h
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <eoAlgo.h> // eoPop
|
||||||
|
#include <eoEvalFunc.h>
|
||||||
|
#include <eoPopOps.h> // eoSelect, eoTranform, eoMerge
|
||||||
|
|
||||||
|
#include "eoGOpSelector.h"
|
||||||
|
#include "eoIndiSelector.h"
|
||||||
|
#include "eoSteadyStateInserter.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/** eoSteadyStateGeneration
|
||||||
|
* Single step of a steady state evolutionary algorithm.
|
||||||
|
* Proceeds by updating one individual at a time, by first selecting parents,
|
||||||
|
* creating one or more children and subsequently overwrite (a) bad individual(s)
|
||||||
|
*/
|
||||||
|
template<class EOT> class eoSteadyStateGeneration: public eoAlgo<EOT>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Constructor.
|
||||||
|
eoSteadyStateGeneration(
|
||||||
|
eoGOpSelector<EOT>& _opSelector,
|
||||||
|
eoPopIndiSelector<EOT>& _selector,
|
||||||
|
eoSteadyStateInserter<EOT>& _inserter,
|
||||||
|
unsigned _steps = 0) :
|
||||||
|
opSelector(_opSelector),
|
||||||
|
selector(_selector),
|
||||||
|
inserter(_inserter) ,
|
||||||
|
steps(_steps) {};
|
||||||
|
|
||||||
|
|
||||||
|
/// Apply one generation of evolution to the population.
|
||||||
|
virtual void operator()(eoPop<EOT>& pop)
|
||||||
|
{
|
||||||
|
unsigned nSteps = steps;
|
||||||
|
if (nSteps == 0)
|
||||||
|
{
|
||||||
|
nSteps = pop.size(); // make a 'generation equivalent'
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < nSteps; ++i)
|
||||||
|
{
|
||||||
|
opSelector.selectOp()(selector(pop), inserter(pop));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Class name.
|
||||||
|
string className() const { return "eoSteadyStateGeneration"; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
eoGOpSelector<EOT>& opSelector;
|
||||||
|
eoPopIndiSelector<EOT>& selector;
|
||||||
|
eoSteadyStateInserter<EOT>& inserter;
|
||||||
|
unsigned steps;
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#endif eoGeneration_h
|
||||||
51
eo/src/eoSteadyStateInserter.h
Normal file
51
eo/src/eoSteadyStateInserter.h
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
/* -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
eoSteadyStateInserter.h
|
||||||
|
Still abstract population insertion operator that is initialized with
|
||||||
|
and eoEvalFunc object to be able to evaluate individuals before inserting
|
||||||
|
them.
|
||||||
|
|
||||||
|
(c) Maarten Keijzer (mak@dhi.dk) and GeNeura Team, 1999, 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef eoSteadyStateInserter_h
|
||||||
|
#define eoSteadyStateInserter_h
|
||||||
|
|
||||||
|
|
||||||
|
#include "eoEvalFunc.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eoSteadyStateInserter: Interface class that enables an operator to update
|
||||||
|
* a population with a new individual... it contains an eoEvalFunc object to
|
||||||
|
* make sure that every individual is evaluated before it is inserted
|
||||||
|
*/
|
||||||
|
template <class EOT>
|
||||||
|
class eoSteadyStateInserter : public eoPopInserter<EOT>
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
eoSteadyStateInserter(eoEvalFunc<EOT>& _eval) : eval(_eval) , eoPopInserter<EOT>() {}
|
||||||
|
|
||||||
|
protected :
|
||||||
|
|
||||||
|
eoEvalFunc<EOT>& eval;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
73
eo/src/eoStochTournamentInserter.h
Normal file
73
eo/src/eoStochTournamentInserter.h
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
/* -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
eoStochTournamentInserter.h
|
||||||
|
Concrete steady state inserter. It is initialized with a population and
|
||||||
|
inserts individuals in the population based on an inverse stochastic
|
||||||
|
tournament
|
||||||
|
|
||||||
|
(c) Maarten Keijzer (mkeijzer@mad.scientist.com) and GeNeura Team, 1999, 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef eoStochTournamentInserter_h
|
||||||
|
#define eoStochTournamentInserter_h
|
||||||
|
|
||||||
|
|
||||||
|
#include "eoSteadyStateInserter.h"
|
||||||
|
#include "selectors.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eoDetTournamentInserter: Uses an inverse stochastic tournament to figure
|
||||||
|
* out who gets overridden by the new individual. It resets the fitness of the
|
||||||
|
* individual.
|
||||||
|
*/
|
||||||
|
template <class EOT>
|
||||||
|
class eoStochTournamentInserter : public eoSteadyStateInserter<EOT>
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
|
||||||
|
eoStochTournamentInserter(eoEvalFunc<EOT>& _eval, double _t_rate) : t_rate(_t_rate), eoSteadyStateInserter<EOT>(_eval)
|
||||||
|
{
|
||||||
|
if (t_rate < 0.5)
|
||||||
|
{ // warning, error?
|
||||||
|
t_rate = 0.55;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t_rate >= 1.0)
|
||||||
|
{
|
||||||
|
t_rate = 0.99; // 1.0 would mean deterministic tournament
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert(const EOT& _eot)
|
||||||
|
{
|
||||||
|
EOT& eo = inverse_stochastic_tournament<EOT>(pop(), t_rate);
|
||||||
|
eo = _eot; // overwrite loser of tournament
|
||||||
|
|
||||||
|
eo.invalidate();
|
||||||
|
eval(eo); // Evaluate after insert
|
||||||
|
}
|
||||||
|
|
||||||
|
string className(void) const { return "eoStochTournamentInserter"; }
|
||||||
|
|
||||||
|
private :
|
||||||
|
double t_rate;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
221
eo/src/eoWrappedOps.h
Normal file
221
eo/src/eoWrappedOps.h
Normal file
|
|
@ -0,0 +1,221 @@
|
||||||
|
/* -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
eoWrappedOps.h
|
||||||
|
Derived from the General genetic operator, which can be used to wrap any unary or binary
|
||||||
|
operator. File also contains the eoCombinedOp, needed by the eoSequentialGOpSelector
|
||||||
|
|
||||||
|
(c) Maarten Keijzer (mak@dhi.dk) and GeNeura Team, 1999, 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef eoWrappedOps_h
|
||||||
|
#define eoWrappedOps_h
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <eoOp.h> // eoOp, eoMonOp, eoBinOp
|
||||||
|
#include "eoRNG.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
/// Wraps monary operators
|
||||||
|
template <class EOT>
|
||||||
|
class eoWrappedMonOp : public eoGeneralOp<EOT>
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
///
|
||||||
|
eoWrappedMonOp(const eoMonOp<EOT>& _op) : eoGeneralOp<EOT>(), op(_op) {};
|
||||||
|
|
||||||
|
///
|
||||||
|
virtual ~eoWrappedMonOp() {}
|
||||||
|
|
||||||
|
/// Instantiates the abstract method
|
||||||
|
void operator()( eoIndiSelector<EOT>& _in,
|
||||||
|
eoInserter<EOT>& _out) const {
|
||||||
|
EOT result = _in.select();
|
||||||
|
op( result );
|
||||||
|
_out.insert(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
virtual string className() const {return "eoWrappedMonOp";};
|
||||||
|
|
||||||
|
|
||||||
|
private :
|
||||||
|
const eoMonOp<EOT>& op;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// Wraps binary operators
|
||||||
|
template <class EOT>
|
||||||
|
class eoWrappedBinOp : public eoGeneralOp<EOT>
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
///
|
||||||
|
eoWrappedBinOp(const eoBinOp<EOT>& _op) : eoGeneralOp<EOT>(), op(_op) {}
|
||||||
|
|
||||||
|
///
|
||||||
|
virtual ~eoWrappedBinOp() {}
|
||||||
|
|
||||||
|
/// Instantiates the abstract method. EOT should have copy ctor.
|
||||||
|
void operator()(eoIndiSelector<EOT>& _in,
|
||||||
|
eoInserter<EOT>& _out) const {
|
||||||
|
EOT out1 = _in.select();
|
||||||
|
const EOT& out2 = _in.select();
|
||||||
|
op(out1, out2);
|
||||||
|
_out.insert(out1);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
virtual string className() const {return "eoWrappedBinOp";};
|
||||||
|
|
||||||
|
private :
|
||||||
|
const eoBinOp<EOT>& op;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Wraps Quadratic operators
|
||||||
|
template <class EOT>
|
||||||
|
class eoWrappedQuadraticOp : public eoGeneralOp<EOT>
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
///
|
||||||
|
eoWrappedQuadraticOp(const eoQuadraticOp<EOT>& _op) : eoGeneralOp<EOT>(), op(_op) {}
|
||||||
|
|
||||||
|
///
|
||||||
|
virtual ~eoWrappedQuadraticOp() {}
|
||||||
|
|
||||||
|
/// Instantiates the abstract method. EOT should have copy ctor.
|
||||||
|
void operator()(eoIndiSelector<EOT>& _in,
|
||||||
|
eoInserter<EOT>& _out) const {
|
||||||
|
EOT out1 = _in.select();
|
||||||
|
EOT out2 = _in.select();
|
||||||
|
op(out1, out2);
|
||||||
|
_out.insert(out1);
|
||||||
|
_out.insert(out2);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
virtual string className() const {return "eoWrappedQuadraticOp";};
|
||||||
|
|
||||||
|
private :
|
||||||
|
const eoQuadraticOp<EOT>& op;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Combines several ops
|
||||||
|
template <class EOT>
|
||||||
|
class eoCombinedOp : public eoGeneralOp<EOT>
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
|
||||||
|
///
|
||||||
|
eoCombinedOp() : eoGeneralOp<EOT>() {}
|
||||||
|
|
||||||
|
///
|
||||||
|
virtual ~eoCombinedOp() {}
|
||||||
|
|
||||||
|
/// Adds a new operator to the combined Op
|
||||||
|
void addOp(eoGeneralOp<EOT>* _op)
|
||||||
|
{
|
||||||
|
ops.push_back(_op);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Erases all operators added so far
|
||||||
|
void clear(void) {
|
||||||
|
ops.resize(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper class to make sure that stuff that is inserted will be used again with the next operator
|
||||||
|
template <class EOT>
|
||||||
|
class eoIndiSelectorInserter : public eoIndiSelector<EOT>, public eoInserter<EOT>
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
eoIndiSelectorInserter(eoIndiSelector<EOT>& _in)
|
||||||
|
: eoIndiSelector<EOT>(), eoInserter<EOT>(), in(_in)
|
||||||
|
{}
|
||||||
|
|
||||||
|
size_t size() const { return in.size(); }
|
||||||
|
const EOT& operator[](size_t _n) const { return in[_n]; }
|
||||||
|
|
||||||
|
const EOT& select(void)
|
||||||
|
{
|
||||||
|
if (results.empty())
|
||||||
|
{
|
||||||
|
return in.select();
|
||||||
|
}
|
||||||
|
// else we use the previously inserted individual,
|
||||||
|
// an iterator to it is stored in 'results', but the memory
|
||||||
|
// is kept by 'intermediate'.
|
||||||
|
|
||||||
|
list<EOT>::iterator it = *results.begin();
|
||||||
|
results.pop_front();
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert(const EOT& _eot)
|
||||||
|
{
|
||||||
|
intermediate.push_front(_eot);
|
||||||
|
results.push_front(intermediate.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill(eoInserter<EOT>& _out)
|
||||||
|
{
|
||||||
|
typedef list<list<EOT>::iterator>::iterator Iterator;
|
||||||
|
|
||||||
|
for (Iterator it = results.begin(); it != results.end(); ++it)
|
||||||
|
{
|
||||||
|
_out.insert(**it);
|
||||||
|
}
|
||||||
|
|
||||||
|
results.clear();
|
||||||
|
intermediate.clear(); // reclaim memory
|
||||||
|
}
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
|
eoIndiSelector<EOT>& in;
|
||||||
|
|
||||||
|
// using lists as we need to push and pop a lot
|
||||||
|
// 'results' are iterators to the contents of 'intermediate'
|
||||||
|
// to prevent copying to and from intermediate...
|
||||||
|
list<list<EOT>::iterator> results;
|
||||||
|
list<EOT> intermediate;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Applies all ops in the combined op
|
||||||
|
void operator()( eoIndiSelector<EOT>& _in,
|
||||||
|
eoInserter<EOT>& _out ) const {
|
||||||
|
|
||||||
|
eoIndiSelectorInserter<EOT> in_out(_in);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < ops.size(); ++i)
|
||||||
|
{
|
||||||
|
(*ops[i])(in_out, in_out);
|
||||||
|
}
|
||||||
|
|
||||||
|
in_out.fill(_out);
|
||||||
|
}
|
||||||
|
|
||||||
|
private :
|
||||||
|
vector<eoGeneralOp<EOT>* > ops;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif eoGeneral_h
|
||||||
85
eo/src/rnd_generators.h
Normal file
85
eo/src/rnd_generators.h
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
/* -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
rnd_generators.h
|
||||||
|
Some utility functors for generating random generators:
|
||||||
|
uniform_generator : generates uniform floats or doubles
|
||||||
|
random_generator : generates unsigneds, ints etc.
|
||||||
|
normal_generator : normally distributed floats or doubles
|
||||||
|
|
||||||
|
(c) Maarten Keijzer (mak@dhi.dk) and GeNeura Team, 1999, 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef eoRND_GENERATORS_H
|
||||||
|
#define eoRND_GENERATORS_H
|
||||||
|
|
||||||
|
#include "eoRNG.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
The class uniform_generator can be used in the STL generate function
|
||||||
|
to easily generate random floats and doubles between [0, _max). _max
|
||||||
|
defaults to 1.0
|
||||||
|
*/
|
||||||
|
template <class T = double> class uniform_generator
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
uniform_generator(T _max = T(1.0), eoRng& _rng = rng) : maxim(_max), uniform(_rng) {}
|
||||||
|
|
||||||
|
virtual T operator()(void) { return (T) uniform.uniform(maxim); }
|
||||||
|
private :
|
||||||
|
T maxim;
|
||||||
|
eoRng& uniform;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
The class random_generator can be used in the STL generate function
|
||||||
|
to easily generate random ints between [0, _max).
|
||||||
|
*/
|
||||||
|
template <class T = uint32> class random_generator
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
random_generator(int _max, eoRng& _rng = rng) : maxim(_max), random(_rng) {}
|
||||||
|
|
||||||
|
virtual T operator()(void) { return (T) random.random(max); }
|
||||||
|
|
||||||
|
private :
|
||||||
|
T maxim;
|
||||||
|
eoRng& random;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
The class normal_generator can be used in the STL generate function
|
||||||
|
to easily generate gaussian distributed floats and doubles. The user
|
||||||
|
can supply a standard deviation which defaults to 1.
|
||||||
|
*/
|
||||||
|
template <class T = double> class normal_generator
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
normal_generator(T _stdev = T(1.0), eoRng& _rng = rng) : stdev(_stdev), normal(_rng) {}
|
||||||
|
|
||||||
|
virtual T operator()(void) { return (T) normal.normal(stdev); }
|
||||||
|
|
||||||
|
private :
|
||||||
|
T stdev;
|
||||||
|
eoRng& normal;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
313
eo/src/selectors.h
Normal file
313
eo/src/selectors.h
Normal file
|
|
@ -0,0 +1,313 @@
|
||||||
|
/* -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
selectors.h
|
||||||
|
A bunch of useful selector functions. They generally have three forms:
|
||||||
|
|
||||||
|
template <class It>
|
||||||
|
It select(It begin, It end, params, eoRng& gen = rng);
|
||||||
|
|
||||||
|
template <class EOT>
|
||||||
|
const EOT& select(const eoPop<EOT>& pop, params, eoRng& gen = rng);
|
||||||
|
|
||||||
|
template <class EOT>
|
||||||
|
EOT& select(eoPop<EOT>& pop, params, eoRng& gen = rng);
|
||||||
|
|
||||||
|
where select is one of: roulette_wheel, deterministic_tournament
|
||||||
|
and stochastic_tournament (at the moment).
|
||||||
|
|
||||||
|
(c) Maarten Keijzer (mak@dhi.dk) and GeNeura Team, 1999, 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SELECT__H
|
||||||
|
#define SELECT__H
|
||||||
|
|
||||||
|
#include "eoRNG.h"
|
||||||
|
#include "eoException.h"
|
||||||
|
|
||||||
|
template <class EOT>
|
||||||
|
bool minimizing_fitness()
|
||||||
|
{
|
||||||
|
EOT eo1; // Assuming people don't do anything fancy in the default constructor!
|
||||||
|
EOT eo2;
|
||||||
|
|
||||||
|
/* Dear user, when the two line below do not compile you are most
|
||||||
|
likely not working with scalar fitness values. In that case we're sorry
|
||||||
|
but you cannot use lottery or roulette_wheel selection...
|
||||||
|
*/
|
||||||
|
eo1.fitness(0.0); // tried to cast it to an EOT::Fitness, but for some reason GNU barfs on this
|
||||||
|
eo2.fitness(1.0);
|
||||||
|
|
||||||
|
return eo2 < eo1; // check whether we have a minimizing fitness
|
||||||
|
};
|
||||||
|
|
||||||
|
inline double scale_fitness(const std::pair<double, double>& _minmax, double _value)
|
||||||
|
{
|
||||||
|
if (_minmax.first == _minmax.second)
|
||||||
|
{
|
||||||
|
return 0.0; // no differences in fitness, population converged!
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
|
||||||
|
return (_value - _minmax.first) / (_minmax.second - _minmax.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class It>
|
||||||
|
double sum_fitness(It begin, It end)
|
||||||
|
{
|
||||||
|
double sum = 0.0;
|
||||||
|
|
||||||
|
for (; begin != end; ++begin)
|
||||||
|
{
|
||||||
|
double v = static_cast<double>(begin->fitness());
|
||||||
|
if (v < 0.0)
|
||||||
|
throw eoNegativeFitnessException();
|
||||||
|
sum += v;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EOT>
|
||||||
|
double sum_fitness(const eoPop<EOT>& _pop)
|
||||||
|
{
|
||||||
|
return sum_fitness(_pop.begin(), _pop.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EOT>
|
||||||
|
double sum_fitness(const eoPop<EOT>& _pop, std::pair<double, double>& _minmax)
|
||||||
|
{
|
||||||
|
eoPop<EOT>::const_iterator it = _pop.begin();
|
||||||
|
|
||||||
|
_minmax.first = it->fitness();
|
||||||
|
_minmax.second = it++->fitness();
|
||||||
|
|
||||||
|
for(; it != _pop.end(); ++it)
|
||||||
|
{
|
||||||
|
double v = static_cast<double>(it->fitness());
|
||||||
|
|
||||||
|
_minmax.first = std::min(_minmax.first, v);
|
||||||
|
_minmax.second = std::max(_minmax.second, v);
|
||||||
|
|
||||||
|
rawTotal += v;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minimizing_fitness<EOT>())
|
||||||
|
{
|
||||||
|
std::swap(_minmax.first, _minmax.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
scaledTotal = 0.0;
|
||||||
|
|
||||||
|
// unfortunately a second loop is neccessary to scale the fitness
|
||||||
|
for (it = _pop.begin(); it != _pop.end(); ++it)
|
||||||
|
{
|
||||||
|
double v = scale_fitness(static_cast<double>(it->fitness()));
|
||||||
|
|
||||||
|
scaledTotal += v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class It>
|
||||||
|
It roulette_wheel(It _begin, It _end, double total, eoRng& _gen = rng)
|
||||||
|
{
|
||||||
|
float roulette = _gen.uniform(total);
|
||||||
|
|
||||||
|
It i = _begin;
|
||||||
|
|
||||||
|
while (roulette > 0.0)
|
||||||
|
{
|
||||||
|
roulette -= static_cast<double>(*(i++));
|
||||||
|
}
|
||||||
|
|
||||||
|
return --i;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EOT>
|
||||||
|
const EOT& roulette_wheel(const eoPop<EOT>& _pop, double total, eoRng& _gen = rng)
|
||||||
|
{
|
||||||
|
float roulette = _gen.uniform(total);
|
||||||
|
|
||||||
|
eoPop<EOT>::const_iterator i = _pop.begin();
|
||||||
|
|
||||||
|
while (roulette > 0.0)
|
||||||
|
{
|
||||||
|
roulette -= static_cast<double>((i++)->fitness());
|
||||||
|
}
|
||||||
|
|
||||||
|
return *--i;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EOT>
|
||||||
|
EOT& roulette_wheel(eoPop<EOT>& _pop, double total, eoRng& _gen = rng)
|
||||||
|
{
|
||||||
|
float roulette = _gen.uniform(total);
|
||||||
|
|
||||||
|
eoPop<EOT>::iterator i = _pop.begin();
|
||||||
|
|
||||||
|
while (roulette > 0.0)
|
||||||
|
{
|
||||||
|
roulette -= static_cast<double>((i++)->fitness());
|
||||||
|
}
|
||||||
|
|
||||||
|
return *--i;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class It>
|
||||||
|
It deterministic_tournament(It _begin, It _end, unsigned _t_size, eoRng& _gen = rng)
|
||||||
|
{
|
||||||
|
It best = _begin + _gen.random(_end - _begin);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < _t_size - 1; ++i)
|
||||||
|
{
|
||||||
|
It competitor = _begin + _gen.random(_end - _begin);
|
||||||
|
|
||||||
|
if (*best < *competitor)
|
||||||
|
{
|
||||||
|
best = competitor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return best;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EOT>
|
||||||
|
const EOT& deterministic_tournament(const eoPop<EOT>& _pop, unsigned _t_size, eoRng& _gen = rng)
|
||||||
|
{
|
||||||
|
return *deterministic_tournament(_pop.begin(), _pop.end(), _t_size, _gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EOT>
|
||||||
|
EOT& deterministic_tournament(eoPop<EOT>& _pop, unsigned _t_size, eoRng& _gen = rng)
|
||||||
|
{
|
||||||
|
return *deterministic_tournament(_pop.begin(), _pop.end(), _t_size, _gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class It>
|
||||||
|
It inverse_deterministic_tournament(It _begin, It _end, unsigned _t_size, eoRng& _gen = rng)
|
||||||
|
{
|
||||||
|
It worst = _begin + _gen.random(_end - _begin);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < _t_size - 1; ++i)
|
||||||
|
{
|
||||||
|
It competitor = _begin + _gen.random(_end - _begin);
|
||||||
|
|
||||||
|
if (competitor == worst)
|
||||||
|
{
|
||||||
|
--i;
|
||||||
|
continue; // try again
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*competitor < *worst)
|
||||||
|
{
|
||||||
|
worst = competitor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return worst;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EOT>
|
||||||
|
const EOT& inverse_deterministic_tournament(const eoPop<EOT>& _pop, unsigned _t_size, eoRng& _gen = rng)
|
||||||
|
{
|
||||||
|
return *inverse_deterministic_tournament<EOT>(_pop.begin(), _pop.end(), _t_size, _gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EOT>
|
||||||
|
EOT& inverse_deterministic_tournament(eoPop<EOT>& _pop, unsigned _t_size, eoRng& _gen = rng)
|
||||||
|
{
|
||||||
|
return *inverse_deterministic_tournament(_pop.begin(), _pop.end(), _t_size, _gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class It>
|
||||||
|
It stochastic_tournament(It _begin, It _end, double _t_rate, eoRng& _gen = rng)
|
||||||
|
{
|
||||||
|
It i1 = _begin + _gen.random(_end - _begin);
|
||||||
|
It i2 = _begin + _gen.random(_end - _begin);
|
||||||
|
|
||||||
|
bool return_better = _gen.flip(_t_rate);
|
||||||
|
|
||||||
|
if (*i1 < *i2)
|
||||||
|
{
|
||||||
|
if (return_better) return i2;
|
||||||
|
// else
|
||||||
|
|
||||||
|
return i1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (return_better) return i1;
|
||||||
|
// else
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
|
||||||
|
return i2;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EOT>
|
||||||
|
const EOT& stochastic_tournament(const eoPop<EOT>& _pop, double _t_rate, eoRng& _gen = rng)
|
||||||
|
{
|
||||||
|
return *stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EOT>
|
||||||
|
EOT& stochastic_tournament(eoPop<EOT>& _pop, double _t_rate, eoRng& _gen = rng)
|
||||||
|
{
|
||||||
|
return *stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class It>
|
||||||
|
It inverse_stochastic_tournament(It _begin, It _end, double _t_rate, eoRng& _gen = rng)
|
||||||
|
{
|
||||||
|
It i1 = _begin + _gen.random(_end - _begin);
|
||||||
|
It i2 = _begin + _gen.random(_end - _begin);
|
||||||
|
|
||||||
|
bool return_worse = _gen.flip(_t_rate);
|
||||||
|
|
||||||
|
if (*i1 < *i2)
|
||||||
|
{
|
||||||
|
if (return_worse) return i1;
|
||||||
|
// else
|
||||||
|
|
||||||
|
return i2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (return_worse) return i2;
|
||||||
|
// else
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
|
||||||
|
return i1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EOT>
|
||||||
|
const EOT& inverse_stochastic_tournament(const eoPop<EOT>& _pop, double _t_rate, eoRng& _gen = rng)
|
||||||
|
{
|
||||||
|
return *inverse_stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class EOT>
|
||||||
|
EOT& inverse_stochastic_tournament(eoPop<EOT>& _pop, double _t_rate, eoRng& _gen = rng)
|
||||||
|
{
|
||||||
|
return *inverse_stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in a new issue