*** 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)
|
||||
*
|
||||
* The random number generator is modified into a class
|
||||
* by Maarten Keijzer (mak@dhi.dk). Also added the Box-Muller
|
||||
* transformation to generate normal deviates.
|
||||
*
|
||||
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
|
||||
*/
|
||||
|
||||
/* ************ DOCUMENTATION IN ORIGINAL FILE *********************/
|
||||
|
||||
// This is the ``Mersenne Twister'' random number generator MT19937, which
|
||||
// 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
|
||||
// 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
|
||||
// July-August 1997).
|
||||
//
|
||||
// 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
|
||||
// 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
|
||||
// number generations per second on this machine.
|
||||
//
|
||||
// According to the URL <http://www.math.keio.ac.jp/~matumoto/emt.html>
|
||||
// (and paraphrasing a bit in places), the Mersenne Twister is ``designed
|
||||
// with consideration of the flaws of various existing generators,'' has
|
||||
// a period of 2^19937 - 1, gives a sequence that is 623-dimensionally
|
||||
// equidistributed, and ``has passed many stringent tests, including the
|
||||
// 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
|
||||
// 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
|
||||
// at a time, so the caching and pipelining of modern systems is exploited.
|
||||
// It is also divide- and mod-free.
|
||||
//
|
||||
// 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
|
||||
// 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 Library General Public License for more details. You should have
|
||||
// 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
|
||||
// Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// The code as Shawn received it included the following notice:
|
||||
//
|
||||
// Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. When
|
||||
// you use this, send an e-mail to <matumoto@math.keio.ac.jp> with
|
||||
// an appropriate reference to your work.
|
||||
//
|
||||
// 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
|
||||
// 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
|
||||
//
|
||||
|
||||
/* ************ END DOCUMENTATION IN ORIGINAL FILE *********************/
|
||||
|
||||
|
||||
#ifndef EO_RANDOM_NUMBER_GENERATOR
|
||||
#define EO_RANDOM_NUMBER_GENERATOR
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#include <eoPersistent.h>
|
||||
#include <eoObject.h>
|
||||
|
||||
// TODO: check for various compilers if this is exactly 32 bits
|
||||
// Unfortunately MSVC's preprocessor does not comprehends sizeof()
|
||||
// so neat preprocessing tricks will not work
|
||||
|
||||
typedef unsigned long uint32; // Compiler and platform dependent!
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// eoRng
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
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 evolutionary algorithms. Included are: rand(), random(), flip() and normal().
|
||||
|
||||
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
|
||||
shorter. If it is longer, file compatibility between EO on different platforms
|
||||
may be broken.
|
||||
*/
|
||||
class eoRng : public eoObject, public eoPersistent
|
||||
{
|
||||
public :
|
||||
/**
|
||||
ctor takes a random seed; if you want another seed, use reseed
|
||||
@see reseed
|
||||
*/
|
||||
|
||||
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];
|
||||
initialize(s);
|
||||
}
|
||||
|
||||
~eoRng(void)
|
||||
{
|
||||
delete [] state;
|
||||
}
|
||||
|
||||
/**
|
||||
Re-initializes the Random Number Generator.
|
||||
*/
|
||||
void reseed(uint32 s)
|
||||
{
|
||||
initialize(s);
|
||||
}
|
||||
|
||||
/**
|
||||
uniform(m = 1.0) returns a random double in the range [0, m)
|
||||
*/
|
||||
double uniform(double m = 1.0)
|
||||
{ // random number between [0, m]
|
||||
return m * double(rand()) / double(rand_max());
|
||||
}
|
||||
|
||||
/**
|
||||
random() returns a random integer in the range [0, m)
|
||||
*/
|
||||
uint32 random(uint32 m)
|
||||
{
|
||||
return uint32(uniform() * double(m));
|
||||
}
|
||||
|
||||
/**
|
||||
flip() tosses a biased coin such that flip(x/100.0) will
|
||||
returns true x% of the time
|
||||
*/
|
||||
bool flip(float bias)
|
||||
{
|
||||
return uniform() < bias;
|
||||
}
|
||||
|
||||
/**
|
||||
normal() zero mean gaussian deviate with standard deviation of 1
|
||||
*/
|
||||
double normal(void); // gaussian mutation, stdev 1
|
||||
|
||||
/**
|
||||
normal(stdev) zero mean gaussian deviate with user defined standard deviation
|
||||
*/
|
||||
double normal(double stdev)
|
||||
{
|
||||
return stdev * normal();
|
||||
}
|
||||
|
||||
/**
|
||||
normal(mean, stdev) user defined mean gaussian deviate with user defined standard deviation
|
||||
*/
|
||||
double normal(double mean, double stdev)
|
||||
{
|
||||
return mean + normal(stdev);
|
||||
}
|
||||
|
||||
/**
|
||||
rand() returns a random number in the range [0, rand_max)
|
||||
*/
|
||||
uint32 rand();
|
||||
|
||||
/**
|
||||
rand_max() the maximum returned by rand()
|
||||
*/
|
||||
uint32 rand_max(void) const { return (uint32) 0xffffffff; }
|
||||
|
||||
/**
|
||||
roulette_wheel(vec, total = 0) does a roulette wheel selection
|
||||
on the input vector vec. If the total is not supplied, it is
|
||||
calculated. It returns an integer denoting the selected argument.
|
||||
*/
|
||||
template <class T>
|
||||
int roulette_wheel(const std::vector<T>& vec, T total = 0)
|
||||
{
|
||||
if (total == 0)
|
||||
{ // count
|
||||
for (unsigned i = 0; i < vec.size(); ++i)
|
||||
total += vec[i];
|
||||
}
|
||||
|
||||
float change = uniform() * total;
|
||||
|
||||
int i = 0;
|
||||
|
||||
while (change > 0)
|
||||
{
|
||||
change -= vec[i++];
|
||||
}
|
||||
|
||||
return --i;
|
||||
}
|
||||
|
||||
///
|
||||
void printOn(ostream& _os) const
|
||||
{
|
||||
for (int i = 0; i < N; ++i)
|
||||
{
|
||||
_os << state[i] << ' ';
|
||||
}
|
||||
_os << int(next - state) << ' ';
|
||||
_os << left << ' ' << cached << ' ' << cacheValue;
|
||||
}
|
||||
|
||||
///
|
||||
void readFrom(istream& _is)
|
||||
{
|
||||
for (int i = 0; i < N; ++i)
|
||||
{
|
||||
_is >> state[i];
|
||||
}
|
||||
|
||||
int n;
|
||||
_is >> n;
|
||||
next = state + n;
|
||||
|
||||
_is >> left;
|
||||
_is >> cached;
|
||||
_is >> cacheValue;
|
||||
}
|
||||
|
||||
|
||||
private :
|
||||
uint32 restart(void);
|
||||
void initialize(uint32 seed);
|
||||
|
||||
uint32* state; // the array for the state
|
||||
uint32* next;
|
||||
int left;
|
||||
|
||||
bool cached;
|
||||
float cacheValue;
|
||||
|
||||
const int N;
|
||||
const int M;
|
||||
const uint32 K; // a magic constant
|
||||
|
||||
/**
|
||||
Private copy ctor and assignment operator to make sure that
|
||||
nobody accidentally copies the random number generator.
|
||||
If you want similar RNG's, make two RNG's and initialize
|
||||
them with the same seed.
|
||||
*/
|
||||
eoRng (const eoRng&); // no implementation
|
||||
eoRng& operator=(const eoRng&); // dito
|
||||
};
|
||||
|
||||
/**
|
||||
The one and only global eoRng object
|
||||
*/
|
||||
static eoRng rng;
|
||||
|
||||
/**
|
||||
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;
|
||||
};
|
||||
|
||||
// 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 loBit(u) ((u) & 0x00000001U) // mask all but lowest 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
|
||||
|
||||
inline void eoRng::initialize(uint32 seed)
|
||||
{
|
||||
//
|
||||
// We initialize state[0..(N-1)] via the generator
|
||||
//
|
||||
// x_new = (69069 * x_old) mod 2^32
|
||||
//
|
||||
// from Line 15 of Table 1, p. 106, Sec. 3.3.4 of Knuth's
|
||||
// _The Art of Computer Programming_, Volume 2, 3rd ed.
|
||||
//
|
||||
// Notes (SJC): I do not know what the initial state requirements
|
||||
// of the Mersenne Twister are, but it seems this seeding generator
|
||||
// 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
|
||||
// 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^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
|
||||
//
|
||||
// the lowest bit of x is always 1,
|
||||
// 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 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 ... ,
|
||||
// ...
|
||||
//
|
||||
// and if x_initial is 3 mod 4 then
|
||||
//
|
||||
// the 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 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 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
|
||||
// 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).
|
||||
//
|
||||
// Note that the random number user does not see the values generated
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
left = -1;
|
||||
|
||||
register uint32 x = (seed | 1U) & 0xFFFFFFFFU, *s = state;
|
||||
register int j;
|
||||
|
||||
for(left=0, *s++=x, j=N; --j;
|
||||
*s++ = (x*=69069U) & 0xFFFFFFFFU);
|
||||
}
|
||||
|
||||
|
||||
inline uint32 eoRng::restart(void)
|
||||
{
|
||||
register uint32 *p0=state, *p2=state+2, *pM=state+M, s0, s1;
|
||||
register int j;
|
||||
|
||||
left=N-1, next=state+1;
|
||||
|
||||
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);
|
||||
|
||||
for(pM=state, j=M; --j; s0=s1, s1=*p2++)
|
||||
*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 << 7) & 0x9D2C5680U;
|
||||
s1 ^= (s1 << 15) & 0xEFC60000U;
|
||||
return(s1 ^ (s1 >> 18));
|
||||
}
|
||||
|
||||
|
||||
inline uint32 eoRng::rand(void)
|
||||
{
|
||||
uint32 y;
|
||||
|
||||
if(--left < 0)
|
||||
return(restart());
|
||||
|
||||
y = *next++;
|
||||
y ^= (y >> 11);
|
||||
y ^= (y << 7) & 0x9D2C5680U;
|
||||
y ^= (y << 15) & 0xEFC60000U;
|
||||
return(y ^ (y >> 18));
|
||||
}
|
||||
|
||||
inline double eoRng::normal(void)
|
||||
{
|
||||
if (cached)
|
||||
{
|
||||
cached = false;
|
||||
return cacheValue;
|
||||
}
|
||||
|
||||
float rSquare, factor, var1, var2;
|
||||
|
||||
do
|
||||
{
|
||||
var1 = 2.0 * uniform() - 1.0;
|
||||
var2 = 2.0 * uniform() - 1.0;
|
||||
|
||||
rSquare = var1 * var1 + var2 * var2;
|
||||
}
|
||||
while (rSquare >= 1.0 || rSquare == 0.0);
|
||||
|
||||
factor = sqrt(-2.0 * log(rSquare) / rSquare);
|
||||
|
||||
cacheValue = var1 * factor;
|
||||
cached = true;
|
||||
|
||||
return (var2 * factor);
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
* Random number generator adapted from (see comments below)
|
||||
*
|
||||
* The random number generator is modified into a class
|
||||
* by Maarten Keijzer (mak@dhi.dk). Also added the Box-Muller
|
||||
* transformation to generate normal deviates.
|
||||
*
|
||||
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
|
||||
*/
|
||||
|
||||
/* ************ DOCUMENTATION IN ORIGINAL FILE *********************/
|
||||
|
||||
// This is the ``Mersenne Twister'' random number generator MT19937, which
|
||||
// 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
|
||||
// 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
|
||||
// July-August 1997).
|
||||
//
|
||||
// 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
|
||||
// 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
|
||||
// number generations per second on this machine.
|
||||
//
|
||||
// According to the URL <http://www.math.keio.ac.jp/~matumoto/emt.html>
|
||||
// (and paraphrasing a bit in places), the Mersenne Twister is ``designed
|
||||
// with consideration of the flaws of various existing generators,'' has
|
||||
// a period of 2^19937 - 1, gives a sequence that is 623-dimensionally
|
||||
// equidistributed, and ``has passed many stringent tests, including the
|
||||
// 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
|
||||
// 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
|
||||
// at a time, so the caching and pipelining of modern systems is exploited.
|
||||
// It is also divide- and mod-free.
|
||||
//
|
||||
// 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
|
||||
// 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 Library General Public License for more details. You should have
|
||||
// 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
|
||||
// Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// The code as Shawn received it included the following notice:
|
||||
//
|
||||
// Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. When
|
||||
// you use this, send an e-mail to <matumoto@math.keio.ac.jp> with
|
||||
// an appropriate reference to your work.
|
||||
//
|
||||
// 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
|
||||
// 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
|
||||
//
|
||||
|
||||
/* ************ END DOCUMENTATION IN ORIGINAL FILE *********************/
|
||||
|
||||
|
||||
#ifndef EO_RANDOM_NUMBER_GENERATOR
|
||||
#define EO_RANDOM_NUMBER_GENERATOR
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#include <eoPersistent.h>
|
||||
#include <eoObject.h>
|
||||
|
||||
// TODO: check for various compilers if this is exactly 32 bits
|
||||
// Unfortunately MSVC's preprocessor does not comprehends sizeof()
|
||||
// so neat preprocessing tricks will not work
|
||||
|
||||
typedef unsigned long uint32; // Compiler and platform dependent!
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// eoRng
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
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 evolutionary algorithms. Included are: rand(), random(), flip() and normal().
|
||||
|
||||
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
|
||||
shorter. If it is longer, file compatibility between EO on different platforms
|
||||
may be broken.
|
||||
*/
|
||||
class eoRng : public eoObject, public eoPersistent
|
||||
{
|
||||
public :
|
||||
/**
|
||||
ctor takes a random seed; if you want another seed, use reseed
|
||||
@see reseed
|
||||
*/
|
||||
|
||||
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];
|
||||
initialize(s);
|
||||
}
|
||||
|
||||
~eoRng(void)
|
||||
{
|
||||
delete [] state;
|
||||
}
|
||||
|
||||
/**
|
||||
Re-initializes the Random Number Generator.
|
||||
*/
|
||||
void reseed(uint32 s)
|
||||
{
|
||||
initialize(s);
|
||||
}
|
||||
|
||||
/**
|
||||
uniform(m = 1.0) returns a random double in the range [0, m)
|
||||
*/
|
||||
double uniform(double m = 1.0)
|
||||
{ // random number between [0, m]
|
||||
return m * double(rand()) / double(rand_max());
|
||||
}
|
||||
|
||||
/**
|
||||
random() returns a random integer in the range [0, m)
|
||||
*/
|
||||
uint32 random(uint32 m)
|
||||
{
|
||||
return uint32(uniform() * double(m));
|
||||
}
|
||||
|
||||
/**
|
||||
flip() tosses a biased coin such that flip(x/100.0) will
|
||||
returns true x% of the time
|
||||
*/
|
||||
bool flip(float bias)
|
||||
{
|
||||
return uniform() < bias;
|
||||
}
|
||||
|
||||
/**
|
||||
normal() zero mean gaussian deviate with standard deviation of 1
|
||||
*/
|
||||
double normal(void); // gaussian mutation, stdev 1
|
||||
|
||||
/**
|
||||
normal(stdev) zero mean gaussian deviate with user defined standard deviation
|
||||
*/
|
||||
double normal(double stdev)
|
||||
{
|
||||
return stdev * normal();
|
||||
}
|
||||
|
||||
/**
|
||||
normal(mean, stdev) user defined mean gaussian deviate with user defined standard deviation
|
||||
*/
|
||||
double normal(double mean, double stdev)
|
||||
{
|
||||
return mean + normal(stdev);
|
||||
}
|
||||
|
||||
/**
|
||||
rand() returns a random number in the range [0, rand_max)
|
||||
*/
|
||||
uint32 rand();
|
||||
|
||||
/**
|
||||
rand_max() the maximum returned by rand()
|
||||
*/
|
||||
uint32 rand_max(void) const { return (uint32) 0xffffffff; }
|
||||
|
||||
/**
|
||||
roulette_wheel(vec, total = 0) does a roulette wheel selection
|
||||
on the input vector vec. If the total is not supplied, it is
|
||||
calculated. It returns an integer denoting the selected argument.
|
||||
*/
|
||||
template <class T>
|
||||
int roulette_wheel(const std::vector<T>& vec, T total = 0)
|
||||
{
|
||||
if (total == 0)
|
||||
{ // count
|
||||
for (int i = 0; i < vec.size(); ++i)
|
||||
total += vec[i];
|
||||
}
|
||||
|
||||
float change = uniform() * total;
|
||||
|
||||
int i = 0;
|
||||
|
||||
while (change > 0)
|
||||
{
|
||||
change -= vec[i++];
|
||||
}
|
||||
|
||||
return --i;
|
||||
}
|
||||
|
||||
///
|
||||
void printOn(ostream& _os) const
|
||||
{
|
||||
for (int i = 0; i < N; ++i)
|
||||
{
|
||||
_os << state[i] << ' ';
|
||||
}
|
||||
_os << int(next - state) << ' ';
|
||||
_os << left << ' ' << cached << ' ' << cacheValue;
|
||||
}
|
||||
|
||||
///
|
||||
void readFrom(istream& _is)
|
||||
{
|
||||
for (int i = 0; i < N; ++i)
|
||||
{
|
||||
_is >> state[i];
|
||||
}
|
||||
|
||||
int n;
|
||||
_is >> n;
|
||||
next = state + n;
|
||||
|
||||
_is >> left;
|
||||
_is >> cached;
|
||||
_is >> cacheValue;
|
||||
}
|
||||
|
||||
|
||||
private :
|
||||
uint32 restart(void);
|
||||
void initialize(uint32 seed);
|
||||
|
||||
uint32* state; // the array for the state
|
||||
uint32* next;
|
||||
int left;
|
||||
|
||||
bool cached;
|
||||
float cacheValue;
|
||||
|
||||
const int N;
|
||||
const int M;
|
||||
const uint32 K; // a magic constant
|
||||
|
||||
/**
|
||||
Private copy ctor and assignment operator to make sure that
|
||||
nobody accidentally copies the random number generator.
|
||||
If you want similar RNG's, make two RNG's and initialize
|
||||
them with the same seed.
|
||||
*/
|
||||
eoRng (const eoRng&); // no implementation
|
||||
eoRng& operator=(const eoRng&); // dito
|
||||
};
|
||||
|
||||
/**
|
||||
The one and only global eoRng object
|
||||
*/
|
||||
static eoRng rng;
|
||||
|
||||
/**
|
||||
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;
|
||||
};
|
||||
|
||||
// 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 loBit(u) ((u) & 0x00000001U) // mask all but lowest 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
|
||||
|
||||
inline void eoRng::initialize(uint32 seed)
|
||||
{
|
||||
//
|
||||
// We initialize state[0..(N-1)] via the generator
|
||||
//
|
||||
// x_new = (69069 * x_old) mod 2^32
|
||||
//
|
||||
// from Line 15 of Table 1, p. 106, Sec. 3.3.4 of Knuth's
|
||||
// _The Art of Computer Programming_, Volume 2, 3rd ed.
|
||||
//
|
||||
// Notes (SJC): I do not know what the initial state requirements
|
||||
// of the Mersenne Twister are, but it seems this seeding generator
|
||||
// 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
|
||||
// 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^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
|
||||
//
|
||||
// the lowest bit of x is always 1,
|
||||
// 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 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 ... ,
|
||||
// ...
|
||||
//
|
||||
// and if x_initial is 3 mod 4 then
|
||||
//
|
||||
// the 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 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 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
|
||||
// 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).
|
||||
//
|
||||
// Note that the random number user does not see the values generated
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
left = -1;
|
||||
|
||||
register uint32 x = (seed | 1U) & 0xFFFFFFFFU, *s = state;
|
||||
register int j;
|
||||
|
||||
for(left=0, *s++=x, j=N; --j;
|
||||
*s++ = (x*=69069U) & 0xFFFFFFFFU);
|
||||
}
|
||||
|
||||
|
||||
inline uint32 eoRng::restart(void)
|
||||
{
|
||||
register uint32 *p0=state, *p2=state+2, *pM=state+M, s0, s1;
|
||||
register int j;
|
||||
|
||||
left=N-1, next=state+1;
|
||||
|
||||
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);
|
||||
|
||||
for(pM=state, j=M; --j; s0=s1, s1=*p2++)
|
||||
*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 << 7) & 0x9D2C5680U;
|
||||
s1 ^= (s1 << 15) & 0xEFC60000U;
|
||||
return(s1 ^ (s1 >> 18));
|
||||
}
|
||||
|
||||
|
||||
inline uint32 eoRng::rand(void)
|
||||
{
|
||||
uint32 y;
|
||||
|
||||
if(--left < 0)
|
||||
return(restart());
|
||||
|
||||
y = *next++;
|
||||
y ^= (y >> 11);
|
||||
y ^= (y << 7) & 0x9D2C5680U;
|
||||
y ^= (y << 15) & 0xEFC60000U;
|
||||
return(y ^ (y >> 18));
|
||||
}
|
||||
|
||||
inline double eoRng::normal(void)
|
||||
{
|
||||
if (cached)
|
||||
{
|
||||
cached = false;
|
||||
return cacheValue;
|
||||
}
|
||||
|
||||
float rSquare, factor, var1, var2;
|
||||
|
||||
do
|
||||
{
|
||||
var1 = 2.0 * uniform() - 1.0;
|
||||
var2 = 2.0 * uniform() - 1.0;
|
||||
|
||||
rSquare = var1 * var1 + var2 * var2;
|
||||
}
|
||||
while (rSquare >= 1.0 || rSquare == 0.0);
|
||||
|
||||
factor = sqrt(-2.0 * log(rSquare) / rSquare);
|
||||
|
||||
cacheValue = var1 * factor;
|
||||
cached = true;
|
||||
|
||||
return (var2 * factor);
|
||||
}
|
||||
|
||||
#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
|
||||
Loading…
Add table
Add a link
Reference in a new issue