diff --git a/eo/NEWS b/eo/NEWS
index 8fce0ae33..2c10c8c81 100644
--- a/eo/NEWS
+++ b/eo/NEWS
@@ -1,7 +1,8 @@
-* release 0.9.4
+* release 0.9.4 (not yet released)
- Update introductory pages of documentation and webpage.
- Remove support for pre-standard C++ compiler (i.e. gcc-2.x), which allows to
clean up the code considerably. Assume availability of sstream and limits.
+ - Implement CMA-ES.
* release 0.9.3z.1 (1. Oct. 2005)
diff --git a/eo/doc/mainpage.html b/eo/doc/mainpage.html
index f295f68a9..9567b294f 100644
--- a/eo/doc/mainpage.html
+++ b/eo/doc/mainpage.html
@@ -102,7 +102,7 @@
- Tutorial
+ Documentation
|
@@ -120,9 +120,8 @@
The tutorial is also included in
the released
- sources.
+ sources.
-
The latest
introduction
to ParadisEO, the parallel version of EO.
+
+ The complete code is also well documented and you can look at the
+ generated interface
+ documentation.
+
|
diff --git a/eo/src/utils/eoRNG.cpp b/eo/src/utils/eoRNG.cpp
index ad347c6cc..17159bfca 100644
--- a/eo/src/utils/eoRNG.cpp
+++ b/eo/src/utils/eoRNG.cpp
@@ -1,14 +1,14 @@
#ifdef _MSC_VER
// to avoid long name warnings
#pragma warning(disable:4786)
-#endif
+#endif
#include
#include "eoRNG.h"
namespace eo
{
-/// The Global random number generator.
-eoRng rng(time(0));
+ /// The Global random number generator.
+ eoRng rng(time(0));
}
diff --git a/eo/src/utils/eoRNG.h b/eo/src/utils/eoRNG.h
index 9c7d89a04..ae5797c16 100644
--- a/eo/src/utils/eoRNG.h
+++ b/eo/src/utils/eoRNG.h
@@ -1,24 +1,24 @@
/** 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.
+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 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.
+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
+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
+Contact: todos@geneura.ugr.es, http://geneura.ugr.es
*/
#ifndef EO_RANDOM_NUMBER_GENERATOR
@@ -51,6 +51,15 @@ number generator MT19937 for generating random numbers. The various
member functions implement useful functions for evolutionary
algorithms. Included are: rand(), random(), flip() and normal().
+EO provides a global random number generator rng that is seeded by the
+current UNIX time at program start. Moreover some global convenience functions
+are provided that use the global random number generator: random,
+normal.
+
+@warning If you want to repeatedly generated the same sequence of pseudo-random
+numbers, you should always reseed the generator at the beginning of your code.
+
+
Documentation in original file
@@ -77,19 +86,19 @@ 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.
-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 with an appropriate reference to
- your work.
-- It would be nice to CC: when you write.
+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
+ with an appropriate reference to your work. It
+would be nice to Cc: and
+ when you write.
Portability
Note for people porting EO to other platforms: please make sure that the type
-uint32_t 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.
+uint32_t in the file eoRng.h is exactly 32 bits long. It may in principle 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
{
@@ -130,85 +139,87 @@ public :
/** Re-initializes the Random Number Generator
- This is the traditional seeding procedure.
+ This is the traditional seeding procedure. This version is deprecated and
+ only provided for compatibility with old code. In new projects you should
+ use reseed.
@see reseed for details on usage of the seeding value.
- @version old version
+ @version old version (deprecated)
*/
void oldReseed(uint32_t 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(1.0 + rand_max());
- }
-
- /**
- random() returns a random integer in the range [0, m)
- */
- uint32_t random(uint32_t m)
- {
- return uint32_t(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=0.5)
- {
- 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);
- }
-
- /**
- Generates random numbers using a negative exponential distribution
- */
- double negexp(double mean)
- {
- return ( -mean*log((double)rand() / rand_max()));
- }
-
- /**
- rand() returns a random number in the range [0, rand_max)
- */
- uint32_t rand();
+ */
+ double uniform(double m = 1.0)
+ { // random number between [0, m]
+ return m * double(rand()) / double(1.0 + rand_max());
+ }
/**
- rand_max() the maximum returned by rand()
+ random() returns a random integer in the range [0, m)
+ */
+ uint32_t random(uint32_t m)
+ {
+ return uint32_t(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=0.5)
+ {
+ 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);
+ }
+
+ /**
+ Generates random numbers using a negative exponential distribution
+ */
+ double negexp(double mean)
+ {
+ return ( -mean*log((double)rand() / rand_max()));
+ }
+
+ /**
+ rand() returns a random number in the range [0, rand_max)
+ */
+ uint32_t rand();
+
+ /**
+ rand_max() the maximum returned by rand()
*/
uint32_t rand_max(void) const { return uint32_t(0xffffffff); }
/**
- roulette_wheel(vec, total = 0) does a roulette wheel selection
- on the input std::vector vec. If the total is not supplied, it is
- calculated. It returns an integer denoting the selected argument.
+ roulette_wheel(vec, total = 0) does a roulette wheel selection
+ on the input std::vector vec. If the total is not supplied, it is
+ calculated. It returns an integer denoting the selected argument.
*/
template
int roulette_wheel(const std::vector& vec, TYPE total = 0)
@@ -241,79 +252,149 @@ public :
@overload
+ Provide a version returning a non-const element reference.
+
@return Uniformly chosen element from the vector.
+
+ @warning Changing the return value does alter the vector.
*/
template
TYPE& choice(std::vector& vec)
{ return vec[random(vec.size())]; }
- ///
- void printOn(std::ostream& _os) const
- {
- for (int i = 0; i < N; ++i)
- {
- _os << state[i] << ' ';
- }
- _os << int(next - state) << ' ';
- _os << left << ' ' << cached << ' ' << cacheValue;
- }
+ ///
+ void printOn(std::ostream& _os) const
+ {
+ for (int i = 0; i < N; ++i)
+ {
+ _os << state[i] << ' ';
+ }
+ _os << int(next - state) << ' ';
+ _os << left << ' ' << cached << ' ' << cacheValue;
+ }
- ///
- void readFrom(std::istream& _is)
- {
- for (int i = 0; i < N; ++i)
- {
- _is >> state[i];
- }
+ ///
+ void readFrom(std::istream& _is)
+ {
+ for (int i = 0; i < N; ++i)
+ {
+ _is >> state[i];
+ }
- int n;
- _is >> n;
- next = state + n;
+ int n;
+ _is >> n;
+ next = state + n;
- _is >> left;
- _is >> cached;
- _is >> cacheValue;
- }
+ _is >> left;
+ _is >> cached;
+ _is >> cacheValue;
+ }
- std::string className(void) const { return "Mersenne-Twister"; }
+ std::string className(void) const { return "Mersenne-Twister"; }
-private :
- uint32_t restart(void);
- void initialize(uint32_t seed);
+private:
- uint32_t* state; // the array for the state
- uint32_t* next;
- int left;
-
- // for normal distribution
- bool cached;
- float cacheValue;
-
- const int N;
- const int M;
- const uint32_t K; // a magic constant
+ uint32_t restart(void);
- /**
- 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
+ /* @brief Initialize state
+
+ 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.
+ */
+ void initialize(uint32_t seed);
+
+ /** @brief Array for the state */
+ uint32_t* state;
+
+ uint32_t* next;
+
+ int left;
+
+ // for normal distribution
+ bool cached;
+
+ float cacheValue;
+
+ const int N;
+
+ const int M;
+
+ /** @brief Magic constant */
+ const uint32_t K;
+
+
+ /** @brief Copy constructor
+
+ 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.
+
+ As it cannot be called, we do not provide an implementation.
+ */
+ eoRng(const eoRng&);
+
+ /** @brief Assignmant operator
+
+ @see Copy constructor eoRng(const eoRng&).
+ */
+ eoRng& operator=(const eoRng&);
};
-/**
- The one and only global eoRng object
-*/
+
+
namespace eo
{
-extern eoRng rng;
+ /** The one and only global eoRng object */
+ extern eoRng rng;
}
-
using eo::rng;
+
+
+
+
// Implementation of some eoRng members.... Don't mind the mess, it does work.
@@ -323,139 +404,118 @@ using eo::rng;
#define mixBits(u, v) (hiBit(u)|loBits(v)) // move hi bit of u to hi bit of v
inline void eoRng::initialize(uint32_t 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;
- left = -1;
+ register uint32_t x = (seed | 1U) & 0xFFFFFFFFU, *s = state;
+ register int j;
- register uint32_t x = (seed | 1U) & 0xFFFFFFFFU, *s = state;
- register int j;
+ for(left=0, *s++=x, j=N; --j;
+ *s++ = (x*=69069U) & 0xFFFFFFFFU);
+}
- for(left=0, *s++=x, j=N; --j;
- *s++ = (x*=69069U) & 0xFFFFFFFFU);
- }
inline uint32_t eoRng::restart(void)
{
- register uint32_t *p0=state, *p2=state+2, *pM=state+M, s0, s1;
- register int j;
+ register uint32_t *p0=state, *p2=state+2, *pM=state+M, s0, s1;
+ 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++)
- *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
+ 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);
+ 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));
+ 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_t eoRng::rand(void)
- {
+{
- uint32_t y;
+ uint32_t y;
+
+ if(--left < 0)
+ return(restart());
+
+ y = *next++;
+ y ^= (y >> 11);
+ y ^= (y << 7) & 0x9D2C5680U;
+ y ^= (y << 15) & 0xEFC60000U;
+ return(y ^ (y >> 18));
+}
- 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)
+ if (cached)
{
- cached = false;
- return cacheValue;
+ cached = false;
+ return cacheValue;
}
- float rSquare, factor, var1, var2;
+ float rSquare, factor, var1, var2;
- do
- {
- var1 = 2.0 * uniform() - 1.0;
- var2 = 2.0 * uniform() - 1.0;
+ 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);
+ rSquare = var1 * var1 + var2 * var2;
+ }
+ while (rSquare >= 1.0 || rSquare == 0.0);
- factor = sqrt(-2.0 * log(rSquare) / rSquare);
+ factor = sqrt(-2.0 * log(rSquare) / rSquare);
- cacheValue = var1 * factor;
- cached = true;
+ cacheValue = var1 * factor;
+ cached = true;
- return (var2 * factor);
+ return (var2 * factor);
}
-namespace eo {
-// a few convenience functions for generating numbers
- /**
- * Templatized random function, works with most basic types such as:
- * char
- * int
- * unsigned
- * float
- * double
- */
+
+namespace eo {
+ // a few convenience functions for generating numbers
+
+ /** @brief Random function
+
+ Templatized random function, returns a random double in the range [0, max).
+
+ @param max Maximum for distribution
+
+ It works with most basic types such as:
+ - char
+ - int
+ - unsigned
+ - float
+ - double
+ */
template
- inline
- T random(const T& mx) { return static_cast(rng.uniform() * mx); }
+ inline T random(const T& max) {
+ return static_cast(rng.uniform() * max); }
+
+ /** @brief Random function
+
+ Templatized random function, returns a random double in the range [min, max).
+
+ @param min Minimum for distribution
+ @param max Maximum for distribution
+
+ @see random(const T& max)
+ */
+ template
+ inline T random(const T& min, const T& max) {
+ return static_cast(rng.uniform() * (max-min)) + min; }
/** Normal distribution */
inline double normal() { return rng.normal(); }