move paradiseo/eo to deprecated/ before merge with eodev

This commit is contained in:
Johann Dreo 2012-10-05 15:12:12 +02:00
commit 0c5120f675
717 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,233 @@
/*
* C++ification of Nikolaus Hansen's original C-source code for the
* CMA-ES
*
* C++-ificiation performed by Maarten Keijzer (C) 2005. Licensed under
* the LGPL. Original copyright of Nikolaus Hansen can be found below
*
*
*
*/
/* --------------------------------------------------------- */
/* --------------------------------------------------------- */
/* --- File: cmaes.c -------- Author: Nikolaus Hansen --- */
/* --------------------------------------------------------- */
/*
* CMA-ES for non-linear function minimization.
*
* Copyright (C) 1996, 2003 Nikolaus Hansen.
* e-mail: hansen@bionik.tu-berlin.de
*
* 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.1 of the License, or (at your option) any later
* version (see http://www.gnu.org/copyleft/lesser.html).
*
* 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.
*
* */
/* --- Changes : ---
* 03/03/21: argument const double *rgFunVal of
* cmaes_ReestimateDistribution() was treated incorrectly.
* 03/03/29: restart via cmaes_resume_distribution() implemented.
* 03/03/30: Always max std dev / largest axis is printed first.
* 03/08/30: Damping is adjusted for large mueff.
* 03/10/30: Damping is adjusted for large mueff always.
* 04/04/22: Cumulation time and damping for step size adjusted.
* No iniphase but conditional update of pc.
* Version 2.23.
* */
#include <es/CMAParams.h>
#include <utils/eoParser.h>
#include <string>
using namespace std;
namespace eo {
CMAParams::CMAParams(eoParser& parser, unsigned dimensionality) {
string section = "CMA parameters";
n = parser.createParam(dimensionality, "dimensionality", "Dimensionality (N) of the problem", 'N', section, dimensionality == 0).value();
maxgen = parser.createParam(
1000,
"max-gen",
"Maximum number of generations that the system will run (needed for damping)",
'M',
section).value();
if (n == 0) {
return;
}
defaults(n, maxgen);
/* handle lambda */
lambda = parser.createParam(
lambda,
"lambda",
"Number of offspring",
'l',
section).value();
if (lambda < 2) {
lambda = 4+(int)(3*log((double) n));
cerr << "Too small lambda specified, setting it to " << lambda << endl;
}
/* handle mu */
mu = parser.createParam(
mu,
"mu",
"Population size",
'm',
section).value();
if (mu >= lambda) {
mu = lambda/2;
cerr << "Mu set larger/equal to lambda, setting it to " << mu << endl;
}
/* handle selection weights */
int weight_type = parser.createParam(
0,
"weighting",
"Weighting scheme (for 'selection'): 0 = logarithmic, 1 = equal, 2 = linear",
'w',
section).value();
switch (weight_type) {
case 1:
{
for (unsigned i = 0; i < weights.size(); ++i) {
weights[i] = mu - i;
}
}
case 2:
{
weights = 1.;
}
default :
{
for (unsigned i = 0; i < weights.size(); ++i) {
weights[i] = log(mu+1.)-log(i+1.);
}
}
}
/* Normalize weights and set mu_eff */
double sumw = weights.sum();
mueff = sumw * sumw / (weights * weights).sum();
weights /= sumw;
/* most of the rest depends on mu_eff, so needs to be set again */
/* set the others using Nikolaus logic. If you want to tweak, you can parameterize over these defaults */
mucov = mueff;
ccumsig = (mueff + 2.) / (n + mueff + 3.);
ccumcov = 4. / (n + 4);
double t1 = 2. / ((n+1.4142)*(n+1.4142));
double t2 = (2.*mucov-1.) / ((n+2.)*(n+2.)+mucov);
t2 = (t2 > 1) ? 1 : t2;
t2 = (1./mucov) * t1 + (1.-1./mucov) * t2;
ccov = t2;
damp = 1 + std::max(0.3,(1.-(double)n/(double)maxgen))
* (1+2*std::max(0.,sqrt((mueff-1.)/(n+1.))-1)) /* limit sigma increase */
/ ccumsig;
vector<double> mins(1,0.0);
mins = parser.createParam(
mins,
"min-stdev",
"Array of minimum stdevs, last one will apply for all remaining axes",
0,
section).value();
if (mins.size() > n) mins.resize(n);
if (mins.size()) {
minStdevs = mins.back();
for (unsigned i = 0; i < mins.size(); ++i) {
minStdevs[i] = mins[i];
}
}
vector<double> inits(1,0.3);
inits = parser.createParam(
inits,
"init-stdev",
"Array of initial stdevs, last one will apply for all remaining axes",
0,
section).value();
if (inits.size() > n) inits.resize(n);
if (inits.size()) {
initialStdevs = inits.back();
for (unsigned i = 0; i < inits.size(); ++i) {
initialStdevs[i] = inits[i];
}
}
}
void CMAParams::defaults(unsigned n_, unsigned maxgen_) {
n = n_;
maxgen = maxgen_;
lambda = 4+(int)(3*log((double) n));
mu = lambda / 2;
weights.resize(mu);
for (unsigned i = 0; i < weights.size(); ++i) {
weights[i] = log(mu+1.)-log(i+1.);
}
/* Normalize weights and set mu_eff */
double sumw = weights.sum();
mueff = sumw * sumw / (weights * weights).sum();
weights /= sumw;
mucov = mueff;
ccumsig *= (mueff + 2.) / (n + mueff + 3.);
ccumcov = 4. / (n + 4);
double t1 = 2. / ((n+1.4142)*(n+1.4142));
double t2 = (2.*mucov-1.) / ((n+2.)*(n+2.)+mucov);
t2 = (t2 > 1) ? 1 : t2;
t2 = (1./mucov) * t1 + (1.-1./mucov) * t2;
ccov = t2;
damp = 1 + std::max(0.3,(1.-(double)n/maxgen))
* (1+2*std::max(0.,sqrt((mueff-1.)/(n+1.))-1)) /* limit sigma increase */
/ ccumsig;
minStdevs.resize(n);
minStdevs = 0.0;
initialStdevs.resize(n);
initialStdevs = 0.3;
}
}// namespace eo

View file

@ -0,0 +1,51 @@
/*
* C++ification of Nikolaus Hansen's original C-source code for the
* CMA-ES.
*
* Copyright (C) 1996, 2003, Nikolaus Hansen
* (C) 2005, Maarten Keijzer
*
* License: LGPL
*
*/
#ifndef CMAPARAMS_H__
#define CMAPARAMS_H__
#include <valarray>
class eoParser;
namespace eo {
class CMAParams {
public:
CMAParams() { /* Call this and all values need to be set by hand */ }
CMAParams(eoParser& parser, unsigned dimensionality = 0); // 0 dimensionality -> user needs to set it
void defaults(unsigned n_, unsigned maxgen_); /* apply all defaults using n and maxgen */
unsigned n;
unsigned maxgen;
unsigned lambda; /* -> mu */
unsigned mu; /* -> weights, lambda */
std::valarray<double> weights; /* <- mu, -> mueff -> mucov -> ccov */
double mueff; /* <- weights */
double mucov;
double damp; /* <- ccumsig, maxeval, lambda */
double ccumsig; /* -> damp, <- N */
double ccumcov;
double ccov; /* <- mucov, N */
std::valarray<double> minStdevs; /* Minimum standard deviations per coordinate (default = 0.0) */
std::valarray<double> initialStdevs; /* Initial standard deviations per coordinate (default = 0.3) */
};
} // namespace eo
#endif

View file

@ -0,0 +1,364 @@
/*
* C++ification of Nikolaus Hansen's original C-source code for the
* CMA-ES
*
* C++-ificiation performed by Maarten Keijzer (C) 2005. Licensed under
* the LGPL. Original copyright of Nikolaus Hansen can be found below
*
*
* Some changes have been made to the original flow and logic of the
* algorithm:
*
* - Numerical issues are now treated 'before' going into the eigenvector decomposition
* (this was done out of convenience)
* - dMaxSignifiKond (smallest x such that x == x + 1.0) replaced by
* numeric_limits<double>::epsilon() (smallest x such that 1.0 != 1.0 + x)
*
*
*/
/* --------------------------------------------------------- */
/* --------------------------------------------------------- */
/* --- File: cmaes.c -------- Author: Nikolaus Hansen --- */
/* --------------------------------------------------------- */
/*
* CMA-ES for non-linear function minimization.
*
* Copyright (C) 1996, 2003 Nikolaus Hansen.
* e-mail: hansen@bionik.tu-berlin.de
*
* 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.1 of the License, or (at your option) any later
* version (see http://www.gnu.org/copyleft/lesser.html).
*
* 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.
*
* */
/* --- Changes : ---
* 03/03/21: argument const double *rgFunVal of
* cmaes_ReestimateDistribution() was treated incorrectly.
* 03/03/29: restart via cmaes_resume_distribution() implemented.
* 03/03/30: Always max std dev / largest axis is printed first.
* 03/08/30: Damping is adjusted for large mueff.
* 03/10/30: Damping is adjusted for large mueff always.
* 04/04/22: Cumulation time and damping for step size adjusted.
* No iniphase but conditional update of pc.
* Version 2.23.
* */
#include <valarray>
#include <limits>
#include <iostream>
#include <cassert>
#include <utils/eoRNG.h>
#include <es/CMAState.h>
#include <es/CMAParams.h>
#include <es/matrices.h>
#include <es/eig.h>
using namespace std;
namespace eo {
struct CMAStateImpl {
CMAParams p;
lower_triangular_matrix C; // Covariance matrix
square_matrix B; // Eigen vectors (in columns)
valarray<double> d; // eigen values (diagonal matrix)
valarray<double> pc; // Evolution path
valarray<double> ps; // Evolution path for stepsize;
vector<double> mean; // current mean to sample around
double sigma; // global step size
unsigned gen;
vector<double> fitnessHistory;
CMAStateImpl(const CMAParams& params_, const vector<double>& m, double sigma_) :
p(params_),
C(p.n), B(p.n), d(p.n), pc(p.n), ps(p.n), mean(m), sigma(sigma_),
gen(0), fitnessHistory(3)
{
double trace = (p.initialStdevs * p.initialStdevs).sum();
/* Initialize covariance structure */
for (unsigned i = 0; i < p.n; ++i)
{
B[i][i] = 1.;
d[i] = p.initialStdevs[i] * sqrt(p.n / trace);
C[i][i] = d[i] * d[i];
pc[i] = 0.;
ps[i] = 0.;
}
}
void sample(vector<double>& v) {
unsigned n = p.n;
v.resize(n);
vector<double> tmp(n);
for (unsigned i = 0; i < n; ++i)
tmp[i] = d[i] * rng.normal();
/* add mutation (sigma * B * (D*z)) */
for (unsigned i = 0; i < n; ++i) {
double sum = 0;
for (unsigned j = 0; j < n; ++j) {
sum += B[i][j] * tmp[j];
}
v[i] = mean[i] + sigma * sum;
}
}
void reestimate(const vector<const vector<double>* >& pop, double muBest, double muWorst) {
assert(pop.size() == p.mu);
unsigned n = p.n;
fitnessHistory[gen % fitnessHistory.size()] = muBest; // needed for divergence check
vector<double> oldmean = mean;
valarray<double> BDz(n);
/* calculate xmean and rgBDz~N(0,C) */
for (unsigned i = 0; i < n; ++i) {
mean[i] = 0.;
for (unsigned j = 0; j < pop.size(); ++j) {
mean[i] += p.weights[j] * (*pop[j])[i];
}
BDz[i] = sqrt(p.mueff)*(mean[i] - oldmean[i])/sigma;
}
vector<double> tmp(n);
/* calculate z := D^(-1) * B^(-1) * rgBDz into rgdTmp */
for (unsigned i = 0; i < n; ++i) {
double sum = 0.0;
for (unsigned j = 0; j < n; ++j) {
sum += B[j][i] * BDz[j];
}
tmp[i] = sum / d[i];
}
/* cumulation for sigma (ps) using B*z */
for (unsigned i = 0; i < n; ++i) {
double sum = 0.0;
for (unsigned j = 0; j < n; ++j)
sum += B[i][j] * tmp[j];
ps[i] = (1. - p.ccumsig) * ps[i] + sqrt(p.ccumsig * (2. - p.ccumsig)) * sum;
}
/* calculate norm(ps)^2 */
double psxps = (ps * ps).sum();
double chiN = sqrt((double) p.n) * (1. - 1./(4.*p.n) + 1./(21.*p.n*p.n));
/* cumulation for covariance matrix (pc) using B*D*z~N(0,C) */
double hsig = sqrt(psxps) / sqrt(1. - pow(1.-p.ccumsig, 2.*gen)) / chiN < 1.5 + 1./(p.n-0.5);
pc = (1. - p.ccumcov) * pc + hsig * sqrt(p.ccumcov * (2. - p.ccumcov)) * BDz;
/* stop initial phase (MK, this was not reachable in the org code, deleted) */
/* remove momentum in ps, if ps is large and fitness is getting worse */
if (gen >= fitnessHistory.size()) {
// find direction from muBest and muWorst (muBest == muWorst handled seperately
double direction = muBest < muWorst? -1.0 : 1.0;
unsigned now = gen % fitnessHistory.size();
unsigned prev = (gen-1) % fitnessHistory.size();
unsigned prevprev = (gen-2) % fitnessHistory.size();
bool fitnessWorsens = (muBest == muWorst) || // <- increase norm also when population has converged (this deviates from Hansen's scheme)
( (direction * fitnessHistory[now] < direction * fitnessHistory[prev])
&&
(direction * fitnessHistory[now] < direction * fitnessHistory[prevprev]));
if(psxps/p.n > 1.5 + 10.*sqrt(2./p.n) && fitnessWorsens) {
double tfac = sqrt((1 + std::max(0., log(psxps/p.n))) * p.n / psxps);
ps *= tfac;
psxps *= tfac*tfac;
}
}
/* update of C */
/* Adapt_C(t); not used anymore */
if (p.ccov != 0.) {
//flgEigensysIsUptodate = 0;
/* update covariance matrix */
for (unsigned i = 0; i < n; ++i) {
vector<double>::iterator c_row = C[i];
for (unsigned j = 0; j <= i; ++j) {
c_row[j] =
(1 - p.ccov) * c_row[j]
+
p.ccov * (1./p.mucov) * pc[i] * pc[j]
+
(1-hsig) * p.ccumcov * (2. - p.ccumcov) * c_row[j];
/*C[i][j] = (1 - p.ccov) * C[i][j]
+ sp.ccov * (1./sp.mucov)
* (rgpc[i] * rgpc[j]
+ (1-hsig)*sp.ccumcov*(2.-sp.ccumcov) * C[i][j]); */
for (unsigned k = 0; k < p.mu; ++k) { /* additional rank mu update */
c_row[j] += p.ccov * (1-1./p.mucov) * p.weights[k]
* ( (*pop[k])[i] - oldmean[i])
* ( (*pop[k])[j] - oldmean[j])
/ sigma / sigma;
// * (rgrgx[index[k]][i] - rgxold[i])
// * (rgrgx[index[k]][j] - rgxold[j])
// / sigma / sigma;
}
}
}
}
/* update of sigma */
sigma *= exp(((sqrt(psxps)/chiN)-1.)/p.damp);
/* calculate eigensystem, must be done by caller */
//cmaes_UpdateEigensystem(0);
/* treat minimal standard deviations and numeric problems
* Note that in contrast with the original code, some numerical issues are treated *before* we
* go into the eigenvalue calculation */
treatNumericalIssues(muBest, muWorst);
gen++; // increase generation
}
void treatNumericalIssues(double best, double worst) {
/* treat stdevs */
for (unsigned i = 0; i < p.n; ++i) {
if (sigma * sqrt(C[i][i]) < p.minStdevs[i]) {
// increase stdev
sigma *= exp(0.05+1./p.damp);
break;
}
}
/* treat convergence */
if (best == worst) {
sigma *= exp(0.2 + 1./p.damp);
}
/* Jede Hauptachse i testen, ob x == x + 0.1 * sigma * rgD[i] * B[i] */
/* Test if all the means are not numerically out of whack with our coordinate system*/
for (unsigned axis = 0; axis < p.n; ++axis) {
double fac = 0.1 * sigma * d[axis];
unsigned coord;
for (coord = 0; coord < p.n; ++coord) {
if (mean[coord] != mean[coord] + fac * B[coord][axis]) {
break;
}
}
if (coord == p.n) { // means are way too big (little) for numerical accuraccy. Start rocking the craddle a bit more
sigma *= exp(0.2+1./p.damp);
}
}
/* Testen ob eine Komponente des Objektparameters festhaengt */
/* Correct issues with scale between objective values and covariances */
bool theresAnIssue = false;
for (unsigned i = 0; i < p.n; ++i) {
if (mean[i] == mean[i] + 0.2 * sigma * sqrt(C[i][i])) {
C[i][i] *= (1. + p.ccov);
theresAnIssue = true;
}
}
if (theresAnIssue) {
sigma *= exp(0.05 + 1./p.damp);
}
}
bool updateEigenSystem(unsigned max_tries, unsigned max_iters) {
if (max_iters==0) max_iters = 30 * p.n;
static double lastGoodMinimumEigenValue = 1.0;
/* Try to get a valid calculation */
for (unsigned tries = 0; tries < max_tries; ++tries) {
unsigned iters = eig( p.n, C, d, B, max_iters);
if (iters < max_iters)
{ // all is well
/* find largest/smallest eigenvalues */
double minEV = d.min();
double maxEV = d.max();
/* (MK Original comment was) :Limit Condition of C to dMaxSignifKond+1
* replaced dMaxSignifKond with 1./numeric_limits<double>::epsilon()
* */
if (maxEV * numeric_limits<double>::epsilon() > minEV) {
double tmp = maxEV * numeric_limits<double>::epsilon() - minEV;
minEV += tmp;
for (unsigned i=0;i<p.n;++i) {
C[i][i] += tmp;
d[i] += tmp;
}
} /* if */
lastGoodMinimumEigenValue = minEV;
d = sqrt(d);
//flgEigensysIsUptodate = 1;
//genOfEigensysUpdate = gen;
//clockeigensum += clock() - clockeigenbegin;
return true;
} /* if cIterEig < ... */
// numerical problems, ignore them and try again
/* Addition des letzten minEW auf die Diagonale von C */
/* Add the last known good eigen value to the diagonal of C */
double summand = lastGoodMinimumEigenValue * exp((double) tries);
for (unsigned i = 0; i < p.n; ++i)
C[i][i] += summand;
} /* for iEigenCalcVers */
return false;
}
};
CMAState::CMAState(const CMAParams& params, const std::vector<double>& initial_point, const double initial_sigma)
: pimpl(new CMAStateImpl(params, initial_point, initial_sigma)) {}
CMAState::~CMAState() { delete pimpl; }
CMAState::CMAState(const CMAState& that) : pimpl(new CMAStateImpl(*that.pimpl )) {}
CMAState& CMAState::operator=(const CMAState& that) { *pimpl = *that.pimpl; return *this; }
void CMAState::sample(vector<double>& v) const { pimpl->sample(v); }
void CMAState::reestimate(const vector<const vector<double>* >& population, double muBest, double muWorst) { pimpl->reestimate(population, muBest, muWorst); }
bool CMAState::updateEigenSystem(unsigned max_tries, unsigned max_iters) { return pimpl->updateEigenSystem(max_tries, max_iters); }
} // namespace eo

View file

@ -0,0 +1,78 @@
/*
* C++ification of Nikolaus Hansen's original C-source code for the
* CMA-ES.
*
* Copyright (C) 1996, 2003, Nikolaus Hansen
* (C) 2005, Maarten Keijzer
*
* License: LGPL (see source file)
*
*/
#ifndef CMASTATE_H_
#define CMASTATE_H_
#include <vector>
#include <valarray>
namespace eo {
class CMAStateImpl;
class CMAParams;
class CMAState {
CMAStateImpl* pimpl; /* pointer to implementation, hidden in source file */
public:
CMAState(const CMAParams&, const std::vector<double>& initial_point, const double initial_sigma = 1.0);
~CMAState();
CMAState(const CMAState&);
CMAState& operator=(const CMAState&);
/**
* sample a vector from the distribution
*
* If the sample is not to your liking (i.e., not within bounds)
* you can do one of two things:
*
* a) Call sample again
* b) multiply the entire vector with a number between -1 and 1
*
* Do not modify the sample in any other way as this will invalidate the
* internal consistency of the system.
*
* A final approach is to copy the sample and modify the copy externally (in the evaluation function)
* and possibly add a penalty depending on the size of the modification.
*
*/
void sample(std::vector<double>& v) const;
/**
* Reestimate covariance matrix and other internal parameters
* Does NOT update the eigen system (call that seperately)
*
* Needs a population of mu individuals, sorted on fitness, plus
*
* muBest: the best fitness in the population
* muWorst: the worst fitness in the population
*/
void reestimate(const std::vector<const std::vector<double>* >& sorted_population, double muBest, double muWorst);
/**
* call this function after reestimate in order to update the eigen system
* It is a seperate call to allow the user to periodically skip this expensive step
*
* max_iters = 0 implies 30 * N iterations
*
* If after max_tries still no numerically sound eigen system is constructed,
* the function returns false
*/
bool updateEigenSystem(unsigned max_tries = 1, unsigned max_iters = 0);
};
} // namespace eo
#endif

View file

@ -0,0 +1,56 @@
######################################################################################
### 1) Include the sources
######################################################################################
INCLUDE_DIRECTORIES(${EO_SOURCE_DIR}/src)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
######################################################################################
### 2) Define the es and cma targets
######################################################################################
SET(ES_LIB_OUTPUT_PATH ${EO_BINARY_DIR}/lib)
SET(CMA_LIB_OUTPUT_PATH ${EO_BINARY_DIR}/lib)
SET(LIBRARY_OUTPUT_PATH ${ES_LIB_OUTPUT_PATH}) # the same output for the two libs
SET(ES_SOURCES
make_algo_scalar_es.cpp
make_algo_scalar_real.cpp
make_checkpoint_es.cpp
make_checkpoint_real.cpp
make_continue_es.cpp
make_continue_real.cpp
make_genotype_es.cpp
make_genotype_real.cpp
make_op_es.cpp
make_op_real.cpp
make_pop_es.cpp
make_pop_real.cpp
make_run_es.cpp
make_run_real.cpp
)
SET(CMA_SOURCES
eig.cpp
CMAState.cpp
CMAParams.cpp
)
ADD_LIBRARY(es STATIC ${ES_SOURCES})
INSTALL(TARGETS es ARCHIVE DESTINATION local/${LIB} COMPONENT libraries)
ADD_LIBRARY(cma STATIC ${CMA_SOURCES})
INSTALL(TARGETS cma ARCHIVE DESTINATION local/${LIB} COMPONENT libraries)
######################################################################################
### 3) Optionnal
######################################################################################
SET(ES_VERSION ${GLOBAL_VERSION})
SET_TARGET_PROPERTIES(es PROPERTIES VERSION "${ES_VERSION}")
SET(CMA_VERSION ${GLOBAL_VERSION})
SET_TARGET_PROPERTIES(cma PROPERTIES VERSION "${CMA_VERSION}")
######################################################################################

View file

@ -0,0 +1,18 @@
2006-12-01 Jochen Küpper <jochen@fhi-berlin.mpg.de>
* Makefile.am: Add missing CMA header for distribution.
2006-11-16 Jochen Küpper <jochen@fhi-berlin.mpg.de>
* make_genotype_real.h (eoEsChromInit): Rewrite vecSigmaInit-handling:
If sigmaInit is relative (%), do not read vecSigmaInit. Otherwise
always use vecSigmaInit with default all values of sigmaInit.
* eoEsChromInit.h (class eoEsChromInit): Take const-reference to sigma-vector.
include <cassert>
* Local Variables:
* coding: iso-8859-1
* mode: flyspell
* fill-column: 80
* End:

View file

@ -0,0 +1,258 @@
/*
* C++ification of Nikolaus Hansen's original C-source code for the
* CMA-ES. These are the eigenvector calculations
*
* C++-ificiation performed by Maarten Keijzer (C) 2005. Licensed under
* the LGPL. Original copyright of Nikolaus Hansen can be found below
*
* This algorithm is held almost completely intact. Some other datatypes are used,
* but hardly any code has changed
*
*/
/* --------------------------------------------------------- */
/* --------------------------------------------------------- */
/* --- File: cmaes.c -------- Author: Nikolaus Hansen --- */
/* --------------------------------------------------------- */
/*
* CMA-ES for non-linear function minimization.
*
* Copyright (C) 1996, 2003 Nikolaus Hansen.
* e-mail: hansen@bionik.tu-berlin.de
*
* 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.1 of the License, or (at your option) any later
* version (see http://www.gnu.org/copyleft/lesser.html).
*
* 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.
*
* */
/* --- Changes : ---
* 03/03/21: argument const double *rgFunVal of
* cmaes_ReestimateDistribution() was treated incorrectly.
* 03/03/29: restart via cmaes_resume_distribution() implemented.
* 03/03/30: Always max std dev / largest axis is printed first.
* 03/08/30: Damping is adjusted for large mueff.
* 03/10/30: Damping is adjusted for large mueff always.
* 04/04/22: Cumulation time and damping for step size adjusted.
* No iniphase but conditional update of pc.
* Version 2.23.
* */
#include "eig.h"
using namespace std;
/* ========================================================= */
/*
Householder Transformation einer symmetrischen Matrix
auf tridiagonale Form.
-> n : Dimension
-> ma : symmetrische nxn-Matrix
<- ma : Transformationsmatrix (ist orthogonal):
Tridiag.-Matrix == <-ma * ->ma * (<-ma)^t
<- diag : Diagonale der resultierenden Tridiagonalmatrix
<- neben[0..n-1] : Nebendiagonale (==1..n-1) der res. Tridiagonalmatrix
*/
static void
Householder( int N, square_matrix& ma, valarray<double>& diag, double* neben)
{
double epsilon;
int i, j, k;
double h, sum, tmp, tmp2;
for (i = N-1; i > 0; --i)
{
h = 0.0;
if (i == 1)
neben[i] = ma[i][i-1];
else
{
for (k = i-1, epsilon = 0.0; k >= 0; --k)
epsilon += fabs(ma[i][k]);
if (epsilon == 0.0)
neben[i] = ma[i][i-1];
else
{
for(k = i-1, sum = 0.0; k >= 0; --k)
{ /* i-te Zeile von i-1 bis links normieren */
ma[i][k] /= epsilon;
sum += ma[i][k]*ma[i][k];
}
tmp = (ma[i][i-1] > 0) ? -sqrt(sum) : sqrt(sum);
neben[i] = epsilon*tmp;
h = sum - ma[i][i-1]*tmp;
ma[i][i-1] -= tmp;
for (j = 0, sum = 0.0; j < i; ++j)
{
ma[j][i] = ma[i][j]/h;
tmp = 0.0;
for (k = j; k >= 0; --k)
tmp += ma[j][k]*ma[i][k];
for (k = j+1; k < i; ++k)
tmp += ma[k][j]*ma[i][k];
neben[j] = tmp/h;
sum += neben[j] * ma[i][j];
} /* for j */
sum /= 2.*h;
for (j = 0; j < i; ++j)
{
neben[j] -= ma[i][j]*sum;
tmp = ma[i][j];
tmp2 = neben[j];
for (k = j; k >= 0; --k)
ma[j][k] -= (tmp*neben[k] + tmp2*ma[i][k]);
} /* for j */
} /* else epsilon */
} /* else i == 1 */
diag[i] = h;
} /* for i */
diag[0] = 0.0;
neben[0] = 0.0;
for (i = 0; i < N; ++i)
{
if(diag[i] != 0.0)
for (j = 0; j < i; ++j)
{
for (k = i-1, tmp = 0.0; k >= 0; --k)
tmp += ma[i][k] * ma[k][j];
for (k = i-1; k >= 0; --k)
ma[k][j] -= tmp*ma[k][i];
} /* for j */
diag[i] = ma[i][i];
ma[i][i] = 1.0;
for (k = i-1; k >= 0; --k)
ma[k][i] = ma[i][k] = 0.0;
} /* for i */
}
/*
QL-Algorithmus mit implizitem Shift, zur Berechnung von Eigenwerten
und -vektoren einer symmetrischen Tridiagonalmatrix.
-> n : Dimension.
-> diag : Diagonale der Tridiagonalmatrix.
-> neben[0..n-1] : Nebendiagonale (==0..n-2), n-1. Eintrag beliebig
-> mq : Matrix output von Householder()
-> maxIt : maximale Zahl der Iterationen
<- diag : Eigenwerte
<- neben : Garbage
<- mq : k-te Spalte ist normalisierter Eigenvektor zu diag[k]
*/
static int
QLalgo( int N, valarray<double>& diag, square_matrix& mq,
int maxIter, double* neben)
{
int i, j, k, kp1, l;
double tmp, diff, cneben, c1, c2, p;
int iter;
neben[N-1] = 0.0;
for (i = 0, iter = 0; i < N && iter < maxIter; ++i)
do /* while j != i */
{
for (j = i; j < N-1; ++j)
{
tmp = fabs(diag[j]) + fabs(diag[j+1]);
if (fabs(neben[j]) + tmp == tmp)
break;
}
if (j != i)
{
if (++iter > maxIter) return maxIter-1;
diff = (diag[i+1]-diag[i])/neben[i]/2.0;
if (diff >= 0)
diff = diag[j] - diag[i] +
neben[i] / (diff + sqrt(diff * diff + 1.0));
else
diff = diag[j] - diag[i] +
neben[i] / (diff - sqrt(diff * diff + 1.0));
c2 = c1 = 1.0;
p = 0.0;
for (k = j-1; k >= i; --k)
{
kp1 = k + 1;
tmp = c2 * neben[k];
cneben = c1 * neben[k];
if (fabs(tmp) >= fabs(diff))
{
c1 = diff / tmp;
c2 = 1. / sqrt(c1*c1 + 1.0);
neben[kp1] = tmp / c2;
c1 *= c2;
}
else
{
c2 = tmp / diff;
c1 = 1. / sqrt(c2*c2 + 1.0);
neben[kp1] = diff / c1;
c2 *= c1;
} /* else */
tmp = (diag[k] - diag[kp1] + p) * c2 + 2.0 * c1 * cneben;
diag[kp1] += tmp * c2 - p;
p = tmp * c2;
diff = tmp * c1 - cneben;
for (l = N-1; l >= 0; --l) /* TF-Matrix Q */
{
tmp = mq[l][kp1];
mq[l][kp1] = c2 * mq[l][k] + c1 * tmp;
mq[l][k] = c1 * mq[l][k] - c2 * tmp;
} /* for l */
} /* for k */
diag[i] -= p;
neben[i] = diff;
neben[j] = 0.0;
} /* if */
} while (j != i);
return iter;
} /* QLalgo() */
/* ========================================================= */
/*
Calculating eigenvalues and vectors.
Input:
N: dimension.
C: lower_triangular NxN-matrix.
niter: number of maximal iterations for QL-Algorithm.
rgtmp: N+1-dimensional vector for temporal use.
Output:
diag: N eigenvalues.
Q: Columns are normalized eigenvectors.
return: number of iterations in QL-Algorithm.
*/
namespace eo {
int
eig( int N, const lower_triangular_matrix& C, valarray<double>& diag, square_matrix& Q,
int niter)
{
int ret;
int i, j;
if (niter == 0) niter = 30*N;
for (i=0; i < N; ++i)
{
vector<double>::const_iterator row = C[i];
for (j = 0; j <= i; ++j)
Q[i][j] = Q[j][i] = row[j];
}
double* rgtmp = new double[N+1];
Householder( N, Q, diag, rgtmp);
ret = QLalgo( N, diag, Q, niter, rgtmp+1);
delete [] rgtmp;
return ret;
}
} // namespace eo

View file

@ -0,0 +1,25 @@
#ifndef EIG_H__
#define EIG_H__
#include <matrices.h>
#include <valarray>
namespace eo {
/* ========================================================= */
/*
Calculating eigenvalues and vectors.
Input:
N: dimension.
C: lower_triangular NxN-matrix.
niter: number of maximal iterations for QL-Algorithm.
Output:
diag: N eigenvalues.
Q: Columns are normalized eigenvectors.
return: number of iterations in QL-Algorithm.
*/
extern int eig( int N, const lower_triangular_matrix& C, std::valarray<double>& diag, square_matrix& Q,
int niter = 0);
} // namespace eo
#endif

View file

@ -0,0 +1,78 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; fill-column: 80; -*-
//-----------------------------------------------------------------------------
// eoCMABreed
// (c) Maarten Keijzer 2005
/*
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
*/
//-----------------------------------------------------------------------------
#ifndef _EOCMABREED_H
#define _EOCMABREED_H
#include <eoBreed.h>
#include <eoVector.h>
#include <es/CMAState.h>
#include <algorithm>
/// @todo handle bounds
template <class FitT>
class eoCMABreed : public eoBreed< eoVector<FitT, double> > {
eo::CMAState& state;
unsigned lambda;
typedef eoVector<FitT, double> EOT;
public:
eoCMABreed(eo::CMAState& state_, unsigned lambda_) : state(state_), lambda(lambda_) {}
void operator()(const eoPop<EOT>& parents, eoPop<EOT>& offspring) {
// two temporary arrays of pointers to store the sorted population
std::vector<const EOT*> sorted(parents.size());
// mu stores population as vector (instead of eoPop)
std::vector<const std::vector<double>* > mu(parents.size());
parents.sort(sorted);
for (unsigned i = 0; i < sorted.size(); ++i) {
mu[i] = static_cast< const std::vector<double>* >( sorted[i] );
}
// learn
state.reestimate(mu, sorted[0]->fitness(), sorted.back()->fitness());
if (!state.updateEigenSystem(10)) {
std::cerr << "No good eigensystem found" << std::endl;
}
// generate
offspring.resize(lambda);
for (unsigned i = 0; i < lambda; ++i) {
state.sample( static_cast< std::vector<double>& >( offspring[i] ));
offspring[i].invalidate();
}
}
};
#endif

View file

@ -0,0 +1,54 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; fill-column: 80; -*-
//-----------------------------------------------------------------------------
// eoCMAInit
// (c) Maarten Keijzer 2005
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
marc.schoenauer@polytechnique.fr
http://eeaax.cmap.polytchnique.fr/
*/
//-----------------------------------------------------------------------------
#ifndef _EOCMAINIT_H
#define _EOCMAINIT_H
#include <eoInit.h>
#include <eoVector.h>
#include <es/CMAState.h>
/// @todo handle bounds
template <class FitT>
class eoCMAInit : public eoInit< eoVector<FitT, double> > {
const eo::CMAState& state;
typedef eoVector<FitT, double> EOT;
public:
eoCMAInit(const eo::CMAState& state_) : state(state_) {}
void operator()(EOT& v) {
state.sample(static_cast<std::vector<double>& >(v));
v.invalidate();
}
};
#endif

View file

@ -0,0 +1,208 @@
//
/* (c) Maarten Keijzer 2000, GeNeura Team, 1998 - EEAAX 1999
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: http://eodev.sourceforge.net
todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mak@dhi.dk
*/
#ifndef _eoEsChromInit_H
#define _eoEsChromInit_H
#include <algorithm>
#include <cassert>
#include <cmath>
#include <vector>
#include <es/eoRealInitBounded.h>
#include <es/eoEsSimple.h>
#include <es/eoEsStdev.h>
#include <es/eoEsFull.h>
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795
#endif
/** Random Es-chromosome initializer (therefore derived from eoInit)
@ingroup Real
@ingroup Initializators
This class can initialize four types of real-valued genotypes thanks
to tempate specialization of private method create:
- eoReal just an eoVector<double>
- eoEsSimple + one self-adapting single sigma for all variables
- eoEsStdev a whole std::vector of self-adapting sigmas
- eoEsFull a full self-adapting correlation matrix
@see eoReal eoEsSimple eoEsStdev eoEsFull eoInit
*/
template <class EOT>
class eoEsChromInit : public eoRealInitBounded<EOT>
{
public:
using eoRealInitBounded<EOT>::size;
using eoRealInitBounded<EOT>::theBounds;
typedef typename EOT::Fitness FitT;
/** Constructor
@param _bounds bounds for uniform initialization
@param _sigma initial value for the stddev
@param _to_scale wether sigma should be multiplied by the range of each variable
added December 2004 - MS (together with the whole comment :-)
*/
eoEsChromInit(eoRealVectorBounds& _bounds, double _sigma = 0.3, bool _to_scale=false)
: eoRealInitBounded<EOT>(_bounds)
{
// a bit of pre-computations, to save time later (even if some are useless)
//
// first, in the case of one unique sigma
// sigma is scaled by the average range (if that means anything!)
if (_to_scale)
{
double scaleUnique = 0;
for (unsigned i=0; i<size(); i++)
scaleUnique += theBounds().range(i);
scaleUnique /= size();
uniqueSigma = _sigma * scaleUnique;
}
else
uniqueSigma = _sigma;
// now the case of a vector of sigmas first allocate space according
// to the size of the bounds (see eoRealInitBounded)
vecSigma.resize(size());
// each sigma is scaled by the range of the corresponding variable
for(unsigned i=0; i<size(); i++)
if(_to_scale)
vecSigma[i] = _sigma * theBounds().range(i);
else
vecSigma[i] = _sigma;
}
/** Constructor
@overload
Specify individual initial sigmas for each variable.
@param _bounds bounds for uniform initialization
@param _vecSigma initial value for the stddev
*/
eoEsChromInit(eoRealVectorBounds& _bounds, const std::vector<double>& _vecSigma)
: eoRealInitBounded<EOT>(_bounds), uniqueSigma(_vecSigma[0]), vecSigma(_vecSigma)
{
assert(_bounds.size() == size());
assert(_vecSigma.size() == size());
}
void operator()(EOT& _eo)
{
eoRealInitBounded<EOT>::operator()(_eo);
create_self_adapt(_eo);
_eo.invalidate();
}
private:
/** Create intializer
No adaptive mutation at all
*/
void create_self_adapt(eoReal<FitT>&)
{}
/** Create intializer
@overload
Adaptive mutation through a unique sigma
*/
void create_self_adapt(eoEsSimple<FitT>& result)
{
// pre-computed in the Ctor
result.stdev = uniqueSigma;
}
/** Create intializer
@overload
Adaptive mutation through a std::vector of sigmas
@todo Should we scale sigmas to the corresponding object variable range?
*/
void create_self_adapt(eoEsStdev<FitT>& result)
{
// pre-computed in the constructor
result.stdevs = vecSigma;
}
/** Create intializer
@overload
Adaptive mutation through a whole correlation matrix
*/
void create_self_adapt(eoEsFull<FitT>& result)
{
// first the stdevs (pre-computed in the Ctor)
result.stdevs = vecSigma;
unsigned int theSize = size();
// nb of rotation angles: N*(N-1)/2 (in general!)
result.correlations.resize(theSize*(theSize - 1) / 2);
for (unsigned i=0; i<result.correlations.size(); ++i)
{
// uniform in [-PI, PI)
result.correlations[i] = rng.uniform(2 * M_PI) - M_PI;
}
}
/** Initial value in case of a unique sigma */
double uniqueSigma;
/** Initial values in case of a vector of sigmas */
std::vector<double> vecSigma;
};
#endif
// Local Variables:
// coding: iso-8859-1
// mode:C++
// c-file-style: "Stroustrup"
// comment-column: 35
// fill-column: 80
// End:

View file

@ -0,0 +1,85 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// eoEsFull.h
// (c) GeNeura Team, 2000 - EEAAX 1999 - Maarten Keijzer 2000
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mak@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifndef _eoEsFull_h
#define _eoEsFull_h
#include <eoVector.h>
/**
\ingroup Real
The most complex evolutionary strategy representation. Co-evolving mutation
rates and correlated mutations.
*/
template <class Fit>
class eoEsFull : public eoVector<Fit, double>
{
public:
using eoVector<Fit, double>::size;
typedef double Type;
eoEsFull(void) : eoVector<Fit, double>() {}
virtual std::string className(void) const { return "eoEsFull"; }
void printOn(std::ostream& os) const
{
eoVector<Fit,double>::printOn(os);
os << ' ';
std::copy(stdevs.begin(), stdevs.end(), std::ostream_iterator<double>(os, " "));
os << ' ';
std::copy(correlations.begin(), correlations.end(), std::ostream_iterator<double>(os, " "));
os << ' ';
}
void readFrom(std::istream& is)
{
eoVector<Fit,double>::readFrom(is);
stdevs.resize(size());
unsigned i;
for (i = 0; i < size(); ++i)
is >> stdevs[i];
correlations.resize(size()*(size() - 1) / 2);
for (i = 0; i < correlations.size(); ++i)
is >> correlations[i];
}
std::vector<double> stdevs;
std::vector<double> correlations;
};
#endif

View file

@ -0,0 +1,152 @@
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// eoEsGlobalXover.h : ES global crossover
// (c) Marc Schoenauer 2001
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: marc.schoenauer@polytechnique.fr http://eeaax.cmap.polytchnique.fr/
*/
//-----------------------------------------------------------------------------
#ifndef _eoEsGlobalXover_H
#define _eoEsGlobalXover_H
#include <utils/eoRNG.h>
#include <es/eoEsSimple.h>
#include <es/eoEsStdev.h>
#include <es/eoEsFull.h>
#include <eoGenOp.h>
// needs a selector - here random
#include <eoRandomSelect.h>
/** Global crossover operator for ES genotypes.
* Uses some Atom crossovers to handle both the object variables
* and the mutation strategy parameters
*
* @ingroup Real
* @ingroup Variators
*/
template<class EOT>
class eoEsGlobalXover: public eoGenOp<EOT>
{
public:
typedef typename EOT::Fitness FitT;
/**
* (Default) Constructor.
*/
eoEsGlobalXover(eoBinOp<double> & _crossObj, eoBinOp<double> & _crossMut) :
crossObj(_crossObj), crossMut(_crossMut) {}
/// The class name. Used to display statistics
virtual std::string className() const { return "eoEsGlobalXover"; }
/// The TOTAL number of offspring (here = nb of parents modified in place)
unsigned max_production(void) { return 1; }
/**
* modifies one parents in the populator
* using 2 new parents for each component!
*
* @param _plop a POPULATOR (not a simple population)
*/
void apply(eoPopulator<EOT>& _plop)
{
// First, select as many parents as you will have offspring
EOT& parent = *_plop; // select the first parent
// first, the object variables
for (unsigned i=0; i<parent.size(); i++)
{
// get extra parents - use private selector
// _plop.source() is the eoPop<EOT> used by _plop to get parents
const EOT& realParent1 = sel(_plop.source());
const EOT& realParent2 = sel(_plop.source());
parent[i] = realParent1[i];
crossObj(parent[i], realParent2[i]); // apply eoBinOp
}
// then the self-adaptation parameters
cross_self_adapt(parent, _plop.source());
// dont' forget to invalidate
parent.invalidate();
}
private:
/** Method for cross self-adaptation parameters
Specialization for eoEsSimple.
*/
void cross_self_adapt(eoEsSimple<FitT> & _parent, const eoPop<eoEsSimple<FitT> >& _pop)
{
const EOT& realParent1 = sel(_pop);
const EOT& realParent2 = sel(_pop);
_parent.stdev = realParent1.stdev;
crossMut(_parent.stdev, realParent2.stdev); // apply eoBinOp
}
/** Method for cross self-adaptation parameters
Specialization for eoEsStdev.
*/
void cross_self_adapt(eoEsStdev<FitT> & _parent, const eoPop<eoEsStdev<FitT> >& _pop)
{
for (unsigned i=0; i<_parent.size(); i++)
{
const EOT& realParent1 = sel(_pop);
const EOT& realParent2 = sel(_pop);
_parent.stdevs[i] = realParent1.stdevs[i];
crossMut(_parent.stdevs[i], realParent2.stdevs[i]); // apply eoBinOp
}
}
/** Method for cross self-adaptation parameters
Specialization for eoEsFull.
*/
void cross_self_adapt(eoEsFull<FitT> & _parent, const eoPop<eoEsFull<FitT> >& _pop)
{
unsigned i;
// the StDev
for (i=0; i<_parent.size(); i++)
{
const EOT& realParent1 = sel(_pop);
const EOT& realParent2 = sel(_pop);
_parent.stdevs[i] = realParent1.stdevs[i];
crossMut(_parent.stdevs[i], realParent2.stdevs[i]); // apply eoBinOp
}
// the roataion angles
for (i=0; i<_parent.correlations.size(); i++)
{
const EOT& realParent1 = sel(_pop);
const EOT& realParent2 = sel(_pop);
_parent.correlations[i] = realParent1.correlations[i];
crossMut(_parent.correlations[i], realParent2.correlations[i]); // apply eoBinOp
}
}
// the data
eoRandomSelect<EOT> sel;
eoBinOp<double> & crossObj;
eoBinOp<double> & crossMut;
};
#endif

View file

@ -0,0 +1,287 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; fill-column: 80; -*-
//-----------------------------------------------------------------------------
// eoESMute.h : ES mutation
// (c) Maarten Keijzer 2000 & GeNeura Team, 1998 for the EO part
// Th. Baeck 1994 and EEAAX 1999 for the ES part
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
marc.schoenauer@polytechnique.fr
http://eeaax.cmap.polytchnique.fr/
*/
//-----------------------------------------------------------------------------
#ifndef _EOESMUTATE_H
#define _EOESMUTATE_H
#include <cmath>
#include <eoInit.h>
#include <eoOp.h>
#include <es/eoEsMutationInit.h>
#include <es/eoEsSimple.h>
#include <es/eoEsStdev.h>
#include <es/eoEsFull.h>
#include <utils/eoRealBounds.h>
#include <utils/eoRNG.h>
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795
#endif
/** ES-style mutation in the large
@ingroup Real
@ingroup Variators
Obviously, valid only for eoES*. It is currently valid for three types
of ES chromosomes:
- eoEsSimple: Exactly one stdandard-deviation
- eoEsStdev: As many standard deviations as object variables
- eoEsFull: The whole guacemole: correlations, stdevs and object variables
Each of these three variant has it's own operator() in eoEsMutate and
intialization is also split into three cases (that share some commonalities)
*/
template <class EOT>
class eoEsMutate : public eoMonOp< EOT >
{
public:
/** Fitness-type */
typedef typename EOT::Fitness FitT;
/** Initialization.
@param _init Proxy class for initializating the three parameters
eoEsMutate needs
@param _bounds Bounds for the objective variables
*/
eoEsMutate(eoEsMutationInit& _init, eoRealVectorBounds& _bounds) : bounds(_bounds)
{
init(EOT(), _init); // initialize on actual type used
}
/** @brief Virtual Destructor */
virtual ~eoEsMutate() {};
/** Classname.
Inherited from eoObject @see eoObject
@return Name of class.
*/
virtual std::string className() const {return "eoESMutate";};
/** Mutate eoEsSimple
@param _eo Individual to mutate.
*/
virtual bool operator()( eoEsSimple<FitT>& _eo)
{
_eo.stdev *= exp(TauLcl * rng.normal());
if (_eo.stdev < stdev_eps)
_eo.stdev = stdev_eps;
// now apply to all
for (unsigned i = 0; i < _eo.size(); ++i)
{
_eo[i] += _eo.stdev * rng.normal();
}
bounds.foldsInBounds(_eo);
return true;
}
/** Standard mutation in ES
@overload
Standard mutation of object variables and standard deviations in ESs.
If there are fewer different standard deviations available than the
dimension of the objective function requires, the last standard deviation is
responsible for ALL remaining object variables.
@param _eo Individual to mutate.
@see
Schwefel 1977: Numerische Optimierung von Computer-Modellen mittels der
Evolutionsstrategie, pp. 165 ff.
*/
virtual bool operator()( eoEsStdev<FitT>& _eo )
{
double global = TauGlb * rng.normal();
for (unsigned i = 0; i < _eo.size(); i++)
{
double stdev = _eo.stdevs[i];
stdev *= exp( global + TauLcl * rng.normal() );
if (stdev < stdev_eps)
stdev = stdev_eps;
_eo.stdevs[i] = stdev;
_eo[i] += stdev * rng.normal();
}
bounds.foldsInBounds(_eo);
return true;
}
/** Correlated mutations in ES
@overload
Mutation of object variables, standard deviations, and their correlations in
ESs.
@param _eo Individual to mutate.
@see
- H.-P. Schwefel: Internal Report of KFA Juelich, KFA-STE-IB-3/80, p. 43, 1980.
- G. Rudolph: Globale Optimierung mit parallelen Evolutionsstrategien,
Diploma Thesis, University of Dortmund, 1990.
*/
virtual bool operator()( eoEsFull<FitT> & _eo )
// Code originally from Thomas Bäck
{
// First: mutate standard deviations (as for eoEsStdev<FitT>).
double global = TauGlb * rng.normal();
unsigned i;
for (i = 0; i < _eo.size(); i++)
{
double stdev = _eo.stdevs[i];
stdev *= exp( global + TauLcl*rng.normal() );
if (stdev < stdev_eps)
stdev = stdev_eps;
_eo.stdevs[i] = stdev;
}
// Mutate rotation angles.
for (i = 0; i < _eo.correlations.size(); i++)
{
_eo.correlations[i] += TauBeta * rng.normal();
if ( fabs(_eo.correlations[i]) > M_PI )
{
_eo.correlations[i] -= M_PI * (int) (_eo.correlations[i]/M_PI) ;
}
}
// Perform correlated mutations.
unsigned k, n1, n2;
double d1,d2, S, C;
std::vector<double> VarStp(_eo.size());
for (i = 0; i < _eo.size(); i++)
VarStp[i] = _eo.stdevs[i] * rng.normal();
unsigned nq = _eo.correlations.size() - 1;
for (k = 0; k < _eo.size()-1; k++)
{
n1 = _eo.size() - k - 1;
n2 = _eo.size() - 1;
for (i = 0; i < k; i++)
{
d1 = VarStp[n1];
d2 = VarStp[n2];
S = sin( _eo.correlations[nq] );
C = cos( _eo.correlations[nq] );
VarStp[n2] = d1 * S + d2 * C;
VarStp[n1] = d1 * C - d2 * S;
n2--;
nq--;
}
}
for (i = 0; i < _eo.size(); i++)
_eo[i] += VarStp[i];
bounds.foldsInBounds(_eo);
return true;
}
private :
/** Initialization of simple ES */
void init(eoEsSimple<FitT>, eoEsMutationInit& _init)
{
unsigned size = bounds.size();
TauLcl = _init.TauLcl();
TauLcl /= sqrt(2*(double) size);
std::cout << "Init<eoEsSimple>: tau local " << TauLcl << std::endl;
}
/** Initialization of standard ES
@overload
*/
void init(eoEsStdev<FitT>, eoEsMutationInit& _init)
{
unsigned size = bounds.size();
TauLcl = _init.TauLcl();
TauGlb = _init.TauGlb();
// renormalization
TauLcl /= sqrt( 2.0 * sqrt(double(size)) );
TauGlb /= sqrt( 2.0 * double(size) );
std::cout << "Init<eoStDev>: tau local " << TauLcl << " et global " << TauGlb << std::endl;
}
/** Initialization of full ES
@overload
*/
void init(eoEsFull<FitT>, eoEsMutationInit& _init)
{
init(eoEsStdev<FitT>(), _init);
TauBeta = _init.TauBeta();
std::cout << "Init<eoEsFull>: tau local " << TauLcl << " et global " << TauGlb << std::endl;
}
/** Local factor for mutation of std deviations */
double TauLcl;
/** Global factor for mutation of std deviations */
double TauGlb;
/** Factor for mutation of correlation parameters */
double TauBeta;
/** Bounds of parameters */
eoRealVectorBounds& bounds;
/** Minimum stdev.
If you let the step-size go to 0, self-adaptation stops, therefore we give a
lower bound. The actual value used is somewhat arbitrary and the is no
theoretical reasoning known for it (Sep 2005).
The code that we have in EO is a port from a C code that Thomas Bäck kindly
donated to the community some years ago. It has been modified by Marc
Schoenauer for inclusion in EvolC, than by Maarten Keijzer into EO. The
exact value was adjusted based on practice.
Removing this doesn't work well, but it was never tried to figure out what
the best value would be.
*/
static const double stdev_eps;
};
// Minimum value of stdevs, see declaration for details.
template <class EOT>
const double eoEsMutate<EOT>::stdev_eps = 1.0e-40;
#endif

View file

@ -0,0 +1,122 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; fill-column: 80 -*-
//-----------------------------------------------------------------------------
// eoEsMutationInit.h
// (c) GeNeura Team, 1998 - EEAAX 1999 - Maarten Keijzer 2000
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mak@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifndef _eoEsMutationInit_h
#define _eoEsMutationInit_h
#include <utils/eoParser.h>
/** Initialize Mutation operator
@ingroup Real
@ingroup Variators
Proxy class that is used for initializing the mutation operator. It provides an
interface between eoEsMutate and the abstract parameterLoader. It also provides
the names for the parameters in this class as virtual protected member
functions.
If you have more than a single ES in a project that need different names in the
configuration files, you might consider overriding this class to change the
names.
@see eoEsMutate
*/
class eoEsMutationInit
{
public :
/** Constructor
@param _parser Parser to read parameters from.
@param _section Parser section for \f$\tau\f$-parameters.
*/
eoEsMutationInit(eoParser& _parser,
std::string _section="ES mutation parameters" ) :
parser(_parser), repSection(_section),
TauLclParam(0), TauGlbParam(0), TauBetaParam(0) {}
/** Virtual destructor */
virtual ~eoEsMutationInit() {}
/** local tau */
double TauLcl(void)
{
if (TauLclParam == 0)
{
TauLclParam = &parser.getORcreateParam(1.0, TauLclName(),
"Local Tau (before normalization)",
TauLclShort(), section());
}
return TauLclParam->value();
}
/** global tau */
double TauGlb(void)
{
if (TauGlbParam == 0)
{
TauGlbParam = &parser.getORcreateParam(1.0, TauGlbName(),
"Global Tau (before normalization)",
TauGlbShort(), section());
}
return TauGlbParam->value();
}
/** correlation's tau */
double TauBeta(void)
{
if (TauBetaParam == 0)
{
TauBetaParam = &parser.getORcreateParam(0.0873, TauBetaName(),
"Beta", TauBetaShort(), section());
}
return TauBetaParam->value();
}
protected :
virtual std::string section(void) { return repSection; }
virtual std::string TauLclName(void) const { return "TauLoc"; }
virtual char TauLclShort(void) const { return 'l'; }
virtual std::string TauGlbName(void) const { return "TauGlob"; }
virtual char TauGlbShort(void) const { return 'g'; }
virtual std::string TauBetaName(void) const { return "Beta"; }
virtual char TauBetaShort(void) const { return 'b'; }
private:
eoParser& parser;
std::string repSection;
eoValueParam<double>* TauLclParam;
eoValueParam<double>* TauGlbParam;
eoValueParam<double>* TauBetaParam;
};
#endif

View file

@ -0,0 +1,77 @@
/* (c) GeNeura Team, 2000 - EEAAX 1999, Maarten Keijzer 2000
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option) any
later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: http://eodev.sourceforge.net
todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mak@dhi.dk
*/
#ifndef _eoEsSimple_h
#define _eoEsSimple_h
#include <EO.h>
#include <vector>
#include <eoVector.h>
/** Simple Evolution Strategy
@ingroup Real
One of the more simple evolution strategies, sporting just a single stdeviation
for the entire chromosome. For more advanced versions see also eoEsStdev
eoEsFull
@see eoEsStdev eoEsFull
*/
template <class Fit>
class eoEsSimple : public eoVector<Fit, double>
{
public :
typedef double Type;
eoEsSimple() : eoVector<Fit, double>() {}
virtual std::string className() const { return "eoEsSimple"; }
void printOn(std::ostream& os) const
{
eoVector<Fit,double>::printOn(os);
os << ' ' << stdev << ' ';
}
void readFrom(std::istream& is)
{
eoVector<Fit,double>::readFrom(is);
is >> stdev;
}
double stdev;
};
#endif
// Local Variables:
// coding: iso-8859-1
// mode:C++
// c-file-style: "Stroustrup"
// comment-column: 35
// fill-column: 80
// End:

View file

@ -0,0 +1,123 @@
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// eoEsLocalXover.h : ES global crossover
// (c) Marc Schoenauer 2001
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: marc.schoenauer@polytechnique.fr http://eeaax.cmap.polytchnique.fr/
*/
//-----------------------------------------------------------------------------
#ifndef _eoEsLocalXover_H
#define _eoEsLocalXover_H
#include <utils/eoRNG.h>
#include <es/eoEsSimple.h>
#include <es/eoEsStdev.h>
#include <es/eoEsFull.h>
#include <eoGenOp.h>
// needs a selector - here random
#include <eoRandomSelect.h>
/** Standard (i.e. eoBinOp) crossover operator for ES genotypes.
* Uses some Atom crossovers to handle both the object variables
* and the mutation strategy parameters
* It is an eoBinOp and has to be wrapped into an eoGenOp before being used
* like the global version
*
* @ingroup Real
* @ingroup Variators
*/
template<class EOT>
class eoEsStandardXover: public eoBinOp<EOT>
{
public:
typedef typename EOT::Fitness FitT;
/**
* (Default) Constructor.
*/
eoEsStandardXover(eoBinOp<double> & _crossObj, eoBinOp<double> & _crossMut) :
crossObj(_crossObj), crossMut(_crossMut) {}
/// The class name. Used to display statistics
virtual std::string className() const { return "eoEsStandardXover"; }
/**
* modifies one parents in the populator
* using a second parent
*/
bool operator()(EOT& _eo1, const EOT& _eo2)
{
bool bLoc=false;
// first, the object variables
for (unsigned i=0; i<_eo1.size(); i++)
{
bLoc |= crossObj(_eo1[i], _eo2[i]); // apply eoBinOp
}
// then the self-adaptation parameters
bLoc |= cross_self_adapt(_eo1, _eo2);
return bLoc;
}
private:
// the method to cross slef-adaptation parameters: need to specialize
bool cross_self_adapt(eoEsSimple<FitT> & _parent1, const eoEsSimple<FitT> & _parent2)
{
return crossMut(_parent1.stdev, _parent2.stdev); // apply eoBinOp
}
bool cross_self_adapt(eoEsStdev<FitT> & _parent1, const eoEsStdev<FitT> & _parent2)
{
bool bLoc=false;
for (unsigned i=0; i<_parent1.size(); i++)
{
bLoc |= crossMut(_parent1.stdevs[i], _parent2.stdevs[i]); // apply eoBinOp
}
return bLoc;
}
bool cross_self_adapt(eoEsFull<FitT> & _parent1, const eoEsFull<FitT> & _parent2)
{
bool bLoc=false;
unsigned i;
// the StDev
for (i=0; i<_parent1.size(); i++)
{
bLoc |= crossMut(_parent1.stdevs[i], _parent2.stdevs[i]); // apply eoBinOp
}
// the roataion angles
for (i=0; i<_parent1.correlations.size(); i++)
{
bLoc |= crossMut(_parent1.correlations[i], _parent2.correlations[i]); // apply eoBinOp
}
return bLoc;
}
// the data
eoRandomSelect<EOT> sel;
eoBinOp<double> & crossObj;
eoBinOp<double> & crossMut;
};
#endif

View file

@ -0,0 +1,80 @@
/* (c) GeNeura Team, 2000 - EEAAX 1999 - Maarten Keijzer 2000
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option) any
later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: http://eodev.sourceforge.net
todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mak@dhi.dk
*/
#ifndef _eoEsStdev_h
#define _eoEsStdev_h
#include <eoVector.h>
/** Evolutionary Strategy with a standard deviation per parameter
Evolutionary strategie style representation, supporting co-evolving
standard deviations.
@ingroup Real
*/
template <class Fit>
class eoEsStdev : public eoVector<Fit, double>
{
public:
using eoVector<Fit, double>::size;
typedef double Type;
eoEsStdev(void) : eoVector<Fit, double>() {}
virtual std::string className(void) const { return "eoEsStdev"; }
void printOn(std::ostream& os) const
{
eoVector<Fit,double>::printOn(os);
os << ' ';
std::copy(stdevs.begin(), stdevs.end(), std::ostream_iterator<double>(os, " "));
os << ' ';
}
void readFrom(std::istream& is)
{
eoVector<Fit,double>::readFrom(is);
stdevs.resize(size());
unsigned i;
for (i = 0; i < size(); ++i)
is >> stdevs[i];
}
std::vector<double> stdevs;
};
#endif
// Local Variables:
// coding: iso-8859-1
// mode:C++
// c-file-style: "Stroustrup"
// comment-column: 35
// fill-column: 80
// End:

View file

@ -0,0 +1,281 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// eoNormalMutation.h
// (c) EEAAX 2001 - Maarten Keijzer 2000
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: Marc.Schoenauer@polytechnique.fr
mak@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifndef eoNormalMutation_h
#define eoNormalMutation_h
//-----------------------------------------------------------------------------
#include <algorithm> // swap_ranges
#include <utils/eoRNG.h>
#include <utils/eoUpdatable.h>
#include <eoEvalFunc.h>
#include <es/eoReal.h>
#include <utils/eoRealBounds.h>
//-----------------------------------------------------------------------------
/** Simple normal mutation of a std::vector of real values.
* The stDev is fixed - but it is passed ans stored as a reference,
* to enable dynamic mutations (see eoOenFithMutation below).
*
* As for the bounds, the values are here folded back into the bounds.
* The other possiblity would be to iterate until we fall inside the bounds -
* but this sometimes takes a long time!!!
*
* @ingroup Real
* @ingroup Variators
*/
template<class EOT> class eoNormalVecMutation: public eoMonOp<EOT>
{
public:
/**
* (Default) Constructor.
* The bounds are initialized with the global object that says: no bounds.
*
* @param _sigma the range for uniform nutation
* @param _p_change the probability to change a given coordinate
*/
eoNormalVecMutation(double _sigma, const double& _p_change = 1.0):
sigma(_sigma), bounds(eoDummyVectorNoBounds), p_change(_p_change) {}
/**
* Constructor with bounds
* @param _bounds an eoRealVectorBounds that contains the bounds
* @param _sigma the range for uniform nutation
* @param _p_change the probability to change a given coordinate
*
* for each component, the sigma is scaled to the range of the bound, if bounded
*/
eoNormalVecMutation(eoRealVectorBounds & _bounds,
double _sigma, const double& _p_change = 1.0):
sigma(_bounds.size(), _sigma), bounds(_bounds), p_change(_p_change)
{
// scale to the range - if any
for (unsigned i=0; i<bounds.size(); i++)
if (bounds.isBounded(i))
sigma[i] *= _sigma*bounds.range(i);
}
/** The class name */
virtual std::string className() const { return "eoNormalVecMutation"; }
/**
* Do it!
* @param _eo The cromosome undergoing the mutation
*/
bool operator()(EOT& _eo)
{
bool hasChanged=false;
for (unsigned lieu=0; lieu<_eo.size(); lieu++)
{
if (rng.flip(p_change))
{
_eo[lieu] += sigma[lieu]*rng.normal();
bounds.foldsInBounds(lieu, _eo[lieu]);
hasChanged = true;
}
}
return hasChanged;
}
private:
std::vector<double> sigma;
eoRealVectorBounds & bounds;
double p_change;
};
/** Simple normal mutation of a std::vector of real values.
* The stDev is fixed - but it is passed ans stored as a reference,
* to enable dynamic mutations (see eoOenFithMutation below).
*
* As for the bounds, the values are here folded back into the bounds.
* The other possiblity would be to iterate until we fall inside the bounds -
* but this sometimes takes a long time!!!
*
* @ingroup Real
* @ingroup Variators
*/
template<class EOT> class eoNormalMutation
: public eoMonOp<EOT>
{
public:
/**
* (Default) Constructor.
* The bounds are initialized with the global object that says: no bounds.
*
* @param _sigma the range for uniform nutation
* @param _p_change the probability to change a given coordinate
*/
eoNormalMutation(double & _sigma, const double& _p_change = 1.0):
sigma(_sigma), bounds(eoDummyVectorNoBounds), p_change(_p_change) {}
/**
* Constructor with bounds
* @param _bounds an eoRealVectorBounds that contains the bounds
* @param _sigma the range for uniform nutation
* @param _p_change the probability to change a given coordinate
*/
eoNormalMutation(eoRealVectorBounds & _bounds,
double _sigma, const double& _p_change = 1.0):
sigma(_sigma), bounds(_bounds), p_change(_p_change) {}
/** The class name */
virtual std::string className() const { return "eoNormalMutation"; }
/**
* Do it!
* @param _eo The cromosome undergoing the mutation
*/
bool operator()(EOT& _eo)
{
bool hasChanged=false;
for (unsigned lieu=0; lieu<_eo.size(); lieu++)
{
if (rng.flip(p_change))
{
_eo[lieu] += sigma*rng.normal();
bounds.foldsInBounds(lieu, _eo[lieu]);
hasChanged = true;
}
}
return hasChanged;
}
/** Accessor to ref to sigma - for update and monitor */
double & Sigma() {return sigma;}
private:
double & sigma;
eoRealVectorBounds & bounds;
double p_change;
};
/** the dynamic version: just say it is updatable -
* and write the update() method!
* here the 1 fifth rule: count the proportion of successful mutations, and
* increase sigma if more than threshold (1/5 !)
*
* @ingroup Real
* @ingroup Variators
*/
template<class EOT> class eoOneFifthMutation :
public eoNormalMutation<EOT>, public eoUpdatable
{
public:
using eoNormalMutation< EOT >::Sigma;
typedef typename EOT::Fitness Fitness;
/**
* (Default) Constructor.
*
* @param _eval the evaluation function, needed to recompute the fitmess
* @param _sigmaInit the initial value for uniform mutation
* @param _windowSize the size of the window for statistics
* @param _updateFactor multiplicative update factor for sigma
* @param _threshold the threshold (the 1/5 - 0.2)
*/
eoOneFifthMutation(eoEvalFunc<EOT> & _eval, double & _sigmaInit,
unsigned _windowSize = 10, double _updateFactor=0.83,
double _threshold=0.2):
eoNormalMutation<EOT>(_sigmaInit), eval(_eval),
threshold(_threshold), updateFactor(_updateFactor),
nbMut(_windowSize, 0), nbSuccess(_windowSize, 0), genIndex(0)
{
// minimal check
if (updateFactor>=1)
throw std::runtime_error("Update factor must be < 1 in eoOneFifthMutation");
}
/** The class name */
virtual std::string className() const { return "eoOneFifthMutation"; }
/**
* Do it!
* calls the standard mutation, then checks for success and updates stats
*
* @param _eo The chromosome undergoing the mutation
*/
bool operator()(EOT & _eo)
{
if (_eo.invalid()) // due to some crossover???
eval(_eo);
Fitness oldFitness = _eo.fitness(); // save old fitness
// call standard operator - then count the successes
if (eoNormalMutation<EOT>::operator()(_eo)) // _eo has been modified
{
_eo.invalidate(); // don't forget!!!
nbMut[genIndex]++;
eval(_eo); // compute fitness of offspring
if (_eo.fitness() > oldFitness)
nbSuccess[genIndex]++; // update counter
}
return false; // because eval has reset the validity flag
}
/** the method that will be called every generation
* if the object is added to the checkpoint
*/
void update()
{
unsigned totalMut = 0;
unsigned totalSuccess = 0;
// compute the average stats over the time window
for ( unsigned i=0; i<nbMut.size(); i++)
{
totalMut += nbMut[i];
totalSuccess += nbSuccess[i];
}
// update sigma accordingly
double prop = double(totalSuccess) / totalMut;
if (prop > threshold) {
Sigma() /= updateFactor; // increase sigma
}
else
{
Sigma() *= updateFactor; // decrease sigma
}
genIndex = (genIndex+1) % nbMut.size() ;
nbMut[genIndex] = nbSuccess[genIndex] = 0;
}
private:
eoEvalFunc<EOT> & eval;
double threshold; // 1/5 !
double updateFactor ; // the multiplicative factor
std::vector<unsigned> nbMut; // total number of mutations per gen
std::vector<unsigned> nbSuccess; // number of successful mutations per gen
unsigned genIndex ; // current index in std::vectors (circular)
};
//-----------------------------------------------------------------------------
//@}
#endif

View file

@ -0,0 +1,63 @@
/*
eoReal.h
// (c) Marc Schoenauer, Maarten Keijzer and 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: Marc.Schoenauer@polytechnique.fr
todos@geneura.ugr.es, http://geneura.ugr.es
mkeijzer@dhi.dk
*/
#ifndef eoReal_h
#define eoReal_h
//-----------------------------------------------------------------------------
#include <iostream> // std::ostream, std::istream
#include <string> // std::string
#include <eoVector.h>
/** eoReal: implementation of simple real-valued chromosome.
* based on eoVector class
*
* @ingroup Real
*/
template <class FitT> class eoReal: public eoVector<FitT, double>
{
public:
/**
* (Default) Constructor.
* @param size Size of the std::vector
* @param value fill the vector with this value
*/
eoReal(unsigned size = 0, double value = 0.0):
eoVector<FitT, double>(size, value) {}
/// My class name.
virtual std::string className() const
{
return "eoReal";
}
};
/** @example t-eoReal.cpp
*/
//-----------------------------------------------------------------------------
#endif

View file

@ -0,0 +1,100 @@
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// eoRealAtomXover.h : helper classes for std::vector<real> crossover
// (c) Marc Schoenauer 2001
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: marc.schoenauer@polytechnique.fr http://eeaax.cmap.polytchnique.fr/
*/
//-----------------------------------------------------------------------------
/** Some basic atomic crossovers for doubles
*
* Are used in all ES specifici crossovers
* and will be in more general stuff, using the generic crossovers
*/
#ifndef _eoRealAtomXover_H
#define _eoRealAtomXover_H
#include <utils/eoRNG.h>
#include <eoOp.h>
/**
Discrete crossover == exchange of values
*
* @ingroup Real
* @ingroup Variators
*/
class eoDoubleExchange: public eoBinOp<double>
{
public:
/**
* (Default) Constructor.
*/
eoDoubleExchange() {}
/// The class name. Used to display statistics
virtual std::string className() const { return "eoDoubleExchange"; }
/**
Exchanges or not the values
*/
bool operator()(double& r1, const double& r2)
{
if (eo::rng.flip())
if (r1 != r2) // if r1 == r2 you must return false
{
r1 = r2;
return true;
}
return false;
}
};
/**
Intermediate crossover == linear combination
*
* @ingroup Real
* @ingroup Variators
*/
class eoDoubleIntermediate: public eoBinOp<double>
{
public:
/**
* (Default) Constructor.
*/
eoDoubleIntermediate() {}
/// The class name. Used to display statistics
virtual std::string className() const { return "eoDoubleIntermediate"; }
/**
Linear combination of both parents
*/
bool operator()(double& r1, const double& r2)
{
double alpha = eo::rng.uniform();
r1 = alpha * r2 + (1-alpha) * r1;
return true;
}
};
#endif

View file

@ -0,0 +1,70 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// eoRealInitBounded.h
// (c) EEAAX 2000 - Maarten Keijzer 2000
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: Marc.Schoenauer@polytechnique.fr
mak@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifndef eoRealInitBounded_h
#define eoRealInitBounded_h
//-----------------------------------------------------------------------------
#include <utils/eoRNG.h>
#include <eoInit.h>
#include <es/eoReal.h>
#include <utils/eoRealVectorBounds.h>
/** Simple initialization for any EOT that derives from std::vector<double>
* uniformly in some bounds
*
* @ingroup Real
* @ingroup Variators
*/
template <class EOT>
class eoRealInitBounded : public eoInit<EOT>
{
public:
/** Ctor - from eoRealVectorBounds */
eoRealInitBounded(eoRealVectorBounds & _bounds):bounds(_bounds)
{
if (!bounds.isBounded())
throw std::runtime_error("Needs bounded bounds to initialize a std::vector<double>");
}
/** simply passes the argument to the uniform method of the bounds */
virtual void operator()(EOT & _eo)
{
bounds.uniform(_eo); // resizes, and fills uniformly in bounds
_eo.invalidate(); // was MISSING!!!!
}
/** accessor to the bounds */
virtual eoRealVectorBounds & theBounds() {return bounds;}
virtual unsigned size(){return bounds.size();}
private:
eoRealVectorBounds & bounds;
};
//-----------------------------------------------------------------------------
//@}
#endif

View file

@ -0,0 +1,513 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// eoRealOp.h
// (c) Maarten Keijzer 2000 - Marc Schoenauer 2001
/*
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: Marc.Schoenauer@polytechnique.fr
mak@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifndef eoRealOp_h
#define eoRealOp_h
//-----------------------------------------------------------------------------
#include <algorithm> // swap_ranges
#include <utils/eoRNG.h>
#include <es/eoReal.h>
#include <utils/eoRealVectorBounds.h>
//-----------------------------------------------------------------------------
/** eoUniformMutation --> changes all values of the std::vector
by uniform choice with range epsilon
with probability p_change per variable
\class eoUniformMutation eoRealOp.h Tutorial/eoRealOp.h
*
* @ingroup Real
* @ingroup Variators
*/
template<class EOT> class eoUniformMutation: public eoMonOp<EOT>
{
public:
/**
* Constructor without bounds == unbounded variables :-)
* not very clean, but who's doing unbounded optimization anyway?
* and it's there mostly for backward compatibility
*
* @param _epsilon the range for uniform nutation
* @param _p_change the probability to change a given coordinate
*/
eoUniformMutation(const double& _epsilon, const double& _p_change = 1.0):
homogeneous(true), bounds(eoDummyVectorNoBounds), epsilon(1, _epsilon),
p_change(1, _p_change) {}
/**
* Constructor with bounds
* @param _bounds an eoRealVectorBounds that contains the bounds
* @param _epsilon the range for uniform mutation - a double to be scaled
* @param _p_change the one probability to change all coordinates
*/
eoUniformMutation(eoRealVectorBounds & _bounds,
const double& _epsilon, const double& _p_change = 1.0):
homogeneous(false), bounds(_bounds), epsilon(_bounds.size(), _epsilon),
p_change(_bounds.size(), _p_change)
{
// scale to the range - if any
for (unsigned i=0; i<bounds.size(); i++)
if (bounds.isBounded(i))
epsilon[i] *= _epsilon*bounds.range(i);
}
/**
* Constructor with bounds
* @param _bounds an eoRealVectorBounds that contains the bounds
* @param _epsilon the VECTOR of ranges for uniform mutation
* @param _p_change the VECTOR of probabilities for each coordinates
*/
eoUniformMutation(eoRealVectorBounds & _bounds,
const std::vector<double>& _epsilon,
const std::vector<double>& _p_change):
homogeneous(false), bounds(_bounds), epsilon(_epsilon),
p_change(_p_change) {}
/// The class name.
virtual std::string className() const { return "eoUniformMutation"; }
/**
* Do it!
* @param _eo The indi undergoing the mutation
*/
bool operator()(EOT& _eo)
{
bool hasChanged=false;
if (homogeneous) // implies no bounds object
for (unsigned lieu=0; lieu<_eo.size(); lieu++)
{
if (rng.flip(p_change[0]))
{
_eo[lieu] += 2*epsilon[0]*rng.uniform()-epsilon[0];
hasChanged = true;
}
}
else
{
// sanity check ?
if (_eo.size() != bounds.size())
throw std::runtime_error("Invalid size of indi in eoUniformMutation");
for (unsigned lieu=0; lieu<_eo.size(); lieu++)
if (rng.flip(p_change[lieu]))
{
// check the bounds
double emin = _eo[lieu]-epsilon[lieu];
double emax = _eo[lieu]+epsilon[lieu];
if (bounds.isMinBounded(lieu))
emin = std::max(bounds.minimum(lieu), emin);
if (bounds.isMaxBounded(lieu))
emax = std::min(bounds.maximum(lieu), emax);
_eo[lieu] = emin + (emax-emin)*rng.uniform();
hasChanged = true;
}
}
return hasChanged;
}
private:
bool homogeneous; // == no bounds passed in the ctor
eoRealVectorBounds & bounds;
std::vector<double> epsilon; // the ranges for mutation
std::vector<double> p_change; // the proba that each variable is modified
};
/** eoDetUniformMutation --> changes exactly k values of the std::vector
by uniform choice with range epsilon
\class eoDetUniformMutation eoRealOp.h Tutorial/eoRealOp.h
*
* @ingroup Real
* @ingroup Variators
*/
template<class EOT> class eoDetUniformMutation: public eoMonOp<EOT>
{
public:
/**
* (Default) Constructor for homogeneous genotype
* it's there mostly for backward compatibility
*
* @param _epsilon the range for uniform nutation
* @param _no number of coordinate to modify
*/
eoDetUniformMutation(const double& _epsilon, const unsigned& _no = 1):
homogeneous(true), bounds(eoDummyVectorNoBounds),
epsilon(1, _epsilon), no(_no) {}
/**
* Constructor with bounds
* @param _bounds an eoRealVectorBounds that contains the bounds
* @param _epsilon the range for uniform nutation (to be scaled if necessary)
* @param _no number of coordinate to modify
*/
eoDetUniformMutation(eoRealVectorBounds & _bounds,
const double& _epsilon, const unsigned& _no = 1):
homogeneous(false), bounds(_bounds),
epsilon(_bounds.size(), _epsilon), no(_no)
{
// scale to the range - if any
for (unsigned i=0; i<bounds.size(); i++)
if (bounds.isBounded(i))
epsilon[i] *= _epsilon*bounds.range(i);
}
/**
* Constructor with bounds and full std::vector of epsilon
* @param _bounds an eoRealVectorBounds that contains the bounds
* @param _epsilon the VECTOR of ranges for uniform mutation
* @param _no number of coordinates to modify
*/
eoDetUniformMutation(eoRealVectorBounds & _bounds,
const std::vector<double>& _epsilon,
const unsigned& _no = 1):
homogeneous(false), bounds(_bounds), epsilon(_epsilon), no(_no)
{
// scale to the range - if any
for (unsigned i=0; i<bounds.size(); i++)
if (bounds.isBounded(i))
epsilon[i] *= _epsilon[i]*bounds.range(i);
}
/// The class name.
virtual std::string className() const { return "eoDetUniformMutation"; }
/**
* Do it!
* @param _eo The indi undergoing the mutation
*/
bool operator()(EOT& _eo)
{
if (homogeneous)
for (unsigned i=0; i<no; i++)
{
unsigned lieu = rng.random(_eo.size());
// actually, we should test that we don't re-modify same variable!
_eo[lieu] = 2*epsilon[0]*rng.uniform()-epsilon[0];
}
else
{
// sanity check ?
if (_eo.size() != bounds.size())
throw std::runtime_error("Invalid size of indi in eoDetUniformMutation");
for (unsigned i=0; i<no; i++)
{
unsigned lieu = rng.random(_eo.size());
// actually, we should test that we don't re-modify same variable!
// check the bounds
double emin = _eo[lieu]-epsilon[lieu];
double emax = _eo[lieu]+epsilon[lieu];
if (bounds.isMinBounded(lieu))
emin = std::max(bounds.minimum(lieu), emin);
if (bounds.isMaxBounded(lieu))
emax = std::min(bounds.maximum(lieu), emax);
_eo[lieu] = emin + (emax-emin)*rng.uniform();
}
}
return true;
}
private:
bool homogeneous; // == no bounds passed in the ctor
eoRealVectorBounds & bounds;
std::vector<double> epsilon; // the ranges of mutation
unsigned no;
};
// two arithmetical crossovers
/** eoSegmentCrossover --> uniform choice in segment
== arithmetical with same value along all coordinates
\class eoSegmentCrossover eoRealOp.h Tutorial/eoRealOp.h
*
* @ingroup Real
* @ingroup Variators
*/
template<class EOT> class eoSegmentCrossover: public eoQuadOp<EOT>
{
public:
/**
* (Default) Constructor.
* The bounds are initialized with the global object that says: no bounds.
*
* @param _alpha the amount of exploration OUTSIDE the parents
* as in BLX-alpha notation (Eshelman and Schaffer)
* 0 == contractive application
* Must be positive
*/
eoSegmentCrossover(const double& _alpha = 0.0) :
bounds(eoDummyVectorNoBounds), alpha(_alpha), range(1+2*_alpha) {}
/**
* Constructor with bounds
* @param _bounds an eoRealVectorBounds that contains the bounds
* @param _alpha the amount of exploration OUTSIDE the parents
* as in BLX-alpha notation (Eshelman and Schaffer)
* 0 == contractive application
* Must be positive
*/
eoSegmentCrossover(eoRealVectorBounds & _bounds,
const double& _alpha = 0.0) :
bounds(_bounds), alpha(_alpha), range(1+2*_alpha) {}
/// The class name.
virtual std::string className() const { return "eoSegmentCrossover"; }
/**
* segment crossover - modifies both parents
* @param _eo1 The first parent
* @param _eo2 The first parent
*/
bool operator()(EOT& _eo1, EOT& _eo2)
{
unsigned i;
double r1, r2, fact;
double alphaMin = -alpha;
double alphaMax = 1+alpha;
if (alpha == 0.0) // no check to perform
fact = -alpha + rng.uniform(range); // in [-alpha,1+alpha)
else // look for the bounds for fact
{
for (i=0; i<_eo1.size(); i++)
{
r1=_eo1[i];
r2=_eo2[i];
if (r1 != r2) { // otherwise you'll get NAN's
double rmin = std::min(r1, r2);
double rmax = std::max(r1, r2);
double length = rmax - rmin;
if (bounds.isMinBounded(i))
{
alphaMin = std::max(alphaMin, (bounds.minimum(i)-rmin)/length);
alphaMax = std::min(alphaMax, (rmax-bounds.minimum(i))/length);
}
if (bounds.isMaxBounded(i))
{
alphaMax = std::min(alphaMax, (bounds.maximum(i)-rmin)/length);
alphaMin = std::max(alphaMin, (rmax-bounds.maximum(i))/length);
}
}
}
fact = alphaMin + (alphaMax-alphaMin)*rng.uniform();
}
for (i=0; i<_eo1.size(); i++)
{
r1=_eo1[i];
r2=_eo2[i];
_eo1[i] = fact * r1 + (1-fact) * r2;
_eo2[i] = (1-fact) * r1 + fact * r2;
}
return true; // shoudl test if fact was 0 or 1 :-)))
}
protected:
eoRealVectorBounds & bounds;
double alpha;
double range; // == 1+2*alpha
};
/** eoHypercubeCrossover --> uniform choice in hypercube
== arithmetical with different values for each coordinate
\class eoArithmeticCrossover eoRealOp.h Tutorial/eoRealOp.h
*
* @ingroup Real
* @ingroup Variators
*/
template<class EOT> class eoHypercubeCrossover: public eoQuadOp<EOT>
{
public:
/**
* (Default) Constructor.
* The bounds are initialized with the global object that says: no bounds.
*
* @param _alpha the amount of exploration OUTSIDE the parents
* as in BLX-alpha notation (Eshelman and Schaffer)
* 0 == contractive application
* Must be positive
*/
eoHypercubeCrossover(const double& _alpha = 0.0):
bounds(eoDummyVectorNoBounds), alpha(_alpha), range(1+2*_alpha)
{
if (_alpha < 0)
throw std::runtime_error("BLX coefficient should be positive");
}
/**
* Constructor with bounds
* @param _bounds an eoRealVectorBounds that contains the bounds
* @param _alpha the amount of exploration OUTSIDE the parents
* as in BLX-alpha notation (Eshelman and Schaffer)
* 0 == contractive application
* Must be positive
*/
eoHypercubeCrossover(eoRealVectorBounds & _bounds,
const double& _alpha = 0.0):
bounds(_bounds), alpha(_alpha), range(1+2*_alpha)
{
if (_alpha < 0)
throw std::runtime_error("BLX coefficient should be positive");
}
/// The class name.
virtual std::string className() const { return "eoHypercubeCrossover"; }
/**
* hypercube crossover - modifies both parents
* @param _eo1 The first parent
* @param _eo2 The first parent
*/
bool operator()(EOT& _eo1, EOT& _eo2)
{
bool hasChanged = false;
unsigned i;
double r1, r2, fact;
if (alpha == 0.0) // no check to perform
for (i=0; i<_eo1.size(); i++)
{
r1=_eo1[i];
r2=_eo2[i];
if (r1 != r2) { // otherwise do nothing
fact = rng.uniform(range); // in [0,1)
_eo1[i] = fact * r1 + (1-fact) * r2;
_eo2[i] = (1-fact) * r1 + fact * r2;
hasChanged = true; // forget (im)possible alpha=0
}
}
else // check the bounds
// do not try to get a bound on the linear factor, but rather
// on the object variables themselves
for (i=0; i<_eo1.size(); i++)
{
r1=_eo1[i];
r2=_eo2[i];
if (r1 != r2) { // otherwise do nothing
double rmin = std::min(r1, r2);
double rmax = std::max(r1, r2);
// compute min and max for object variables
double objMin = -alpha * rmax + (1+alpha) * rmin;
double objMax = -alpha * rmin + (1+alpha) * rmax;
// first find the limits on the alpha's
if (bounds.isMinBounded(i))
{
objMin = std::max(objMin, bounds.minimum(i));
}
if (bounds.isMaxBounded(i))
{
objMax = std::min(objMax, bounds.maximum(i));
}
// then draw variables
double median = (objMin+objMax)/2.0; // uniform within bounds
// double median = (rmin+rmax)/2.0; // Bounce on bounds
double valMin = objMin + (median-objMin)*rng.uniform();
double valMax = median + (objMax-median)*rng.uniform();
// don't always put large value in _eo1 - or what?
if (rng.flip(0.5))
{
_eo1[i] = valMin;
_eo2[i] = valMax;
}
else
{
_eo1[i] = valMax;
_eo2[i] = valMin;
}
// seomthing has changed
hasChanged = true; // forget (im)possible alpha=0
}
}
return hasChanged;
}
protected:
eoRealVectorBounds & bounds;
double alpha;
double range; // == 1+2*alphaMin
};
/** eoRealUxOver --> Uniform crossover, also termed intermediate crossover
\class eoRealUxOver eoRealOp.h Tutorial/eoRealOp.h
*
* @ingroup Real
* @ingroup Variators
*/
template<class EOT> class eoRealUXover: public eoQuadOp<EOT>
{
public:
/**
* (Default) Constructor.
* @param _preference bias in the choice (usually, no bias == 0.5)
*/
eoRealUXover(const float& _preference = 0.5): preference(_preference)
{
if ( (_preference <= 0.0) || (_preference >= 1.0) )
std::runtime_error("UxOver --> invalid preference");
}
/// The class name.
virtual std::string className() const { return "eoRealUXover"; }
/**
* Uniform crossover for real std::vectors
* @param _eo1 The first parent
* @param _eo2 The second parent
* @exception std::runtime_error if sizes don't match
*/
bool operator()(EOT& _eo1, EOT& _eo2)
{
if ( _eo1.size() != _eo2.size())
std::runtime_error("UxOver --> chromosomes sizes don't match" );
bool changed = false;
for (unsigned int i=0; i<_eo1.size(); i++)
{
if (rng.flip(preference))
if (_eo1[i] != _eo2[i])
{
double tmp = _eo1[i];
_eo1[i]=_eo2[i];
_eo2[i] = tmp;
changed = true;
}
}
return changed;
}
private:
float preference;
};
//-----------------------------------------------------------------------------
//@}
#endif

View file

@ -0,0 +1,135 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// eoSBXcross.h
// (c) Maarten Keijzer 2000 - Marc Schoenauer 2001
/*
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: Marc.Schoenauer@polytechnique.fr
mak@dhi.dk
*/
//-----------------------------------------------------------------------------
#include <algorithm> // swap_ranges
#include <utils/eoParser.h>
#include <utils/eoRNG.h>
#include <es/eoReal.h>
#include <utils/eoRealBounds.h>
#include <utils/eoRealVectorBounds.h>
/**
* @ingroup Real
* @ingroup Variators
*/
template<class EOT> class eoSBXCrossover: public eoQuadOp<EOT>
{
public:
/****
* (Default) Constructor.
* The bounds are initialized with the global object that says: no bounds.
*
*
*/
eoSBXCrossover(const double& _eta = 1.0) :
bounds(eoDummyVectorNoBounds), eta(_eta), range(1) {}
//////////////////////////////////////////////
/**
* Constructor with bounds
* @param _bounds an eoRealVectorBounds that contains the bounds
* @param _eta the amount of exploration OUTSIDE the parents
* as in BLX-alpha notation (Eshelman and Schaffer)
* 0 == contractive application
* Must be positive
*/
eoSBXCrossover(eoRealVectorBounds & _bounds,
const double& _eta = 1.0) :
bounds(_bounds), eta(_eta), range(1) {}
///////////////////////////////////////////////
//////////////////////////////////////////////
/**
* Constructor from a parser. Will read from the argument parser
* eoRealVectorBounds that contains the bounds
* eta, the SBX parameter
*/
eoSBXCrossover(eoParser & _parser) :
// First, decide whether the objective variables are bounded
// Warning, must be the same keywords than other possible objectBounds elsewhere
bounds (_parser.getORcreateParam(eoDummyVectorNoBounds, "objectBounds", "Bounds for variables", 'B', "Variation Operators").value()) ,
// then get eta value
eta (_parser.getORcreateParam(1.0, "eta", "SBX eta parameter", '\0', "Variation Operators").value()) ,
range(1) {}
/// The class name.
virtual std::string className() const { return "eoSBXCrossover"; }
/*****************************************
* SBX crossover - modifies both parents *
* @param _eo1 The first parent *
* @param _eo2 The first parent *
*****************************************/
bool operator()(EOT& _eo1, EOT& _eo2)
{
unsigned i;
double r1, r2, beta;
for (i=0; i<_eo1.size(); i++)
{
double u = rng.uniform(range) ;
if ( u <= 0.5 )
beta = exp( (1/(eta+1))*log(2*u));
else
beta = exp((1/(eta+1))*log(1/(2*(1-u))));
r1=_eo1[i];
r2=_eo2[i];
_eo1[i] =0.5*((1+beta)*r1+(1-beta)*r2);
_eo2[i] =0.5*((1-beta)*r1+(1+beta)*r2);
if(!(bounds.isInBounds(i,_eo1[i])))
bounds.foldsInBounds(i,_eo1[i]);
if(!(bounds.isInBounds(i,_eo2[i])))
bounds.foldsInBounds(i,_eo2[i]);
}
return true;
}
protected:
eoRealVectorBounds & bounds;
double eta;
double range; // == 1
};

View file

@ -0,0 +1,84 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// make_algo_scalar_es.cpp
// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifdef _MSC_VER
// to avoid long name warnings
#pragma warning(disable:4786)
#endif
/** This file contains ***INSTANCIATED DEFINITIONS*** of select/replace fns
* of the library for evolution of ***eoEs genotypes*** inside EO.
* It should be included in the file that calls any of the corresponding fns
* Compiling this file allows one to generate part of the library (i.e. object
* files that you just need to link with your own main and fitness code).
*
* The corresponding ***INSTANCIATED DECLARATIONS*** are contained
* in src/es/es.h
* while the TEMPLATIZED code is define in make_algo_scalar.h in the src/do dir
*/
// The templatized code
#include <do/make_algo_scalar.h>
// the instanciating EOType(s)
#include <es/eoEsSimple.h> // one Sigma per individual
#include <es/eoEsStdev.h> // one sigmal per object variable
#include <es/eoEsFull.h> // full correlation matrix per indi
/// The following function merely call the templatized do_* functions above
// Algo
///////
eoAlgo<eoEsSimple<double> >& make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc<eoEsSimple<double> >& _eval, eoContinue<eoEsSimple<double> >& _continue, eoGenOp<eoEsSimple<double> >& _op, eoDistance<eoEsSimple<double> >* _dist)
{
return do_make_algo_scalar(_parser, _state, _eval, _continue, _op);
}
eoAlgo<eoEsSimple<eoMinimizingFitness> >& make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc<eoEsSimple<eoMinimizingFitness> >& _eval, eoContinue<eoEsSimple<eoMinimizingFitness> >& _continue, eoGenOp<eoEsSimple<eoMinimizingFitness> >& _op, eoDistance<eoEsSimple<eoMinimizingFitness> >* _dist)
{
return do_make_algo_scalar(_parser, _state, _eval, _continue, _op);
}
//////////////
eoAlgo<eoEsStdev<double> >& make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc<eoEsStdev<double> >& _eval, eoContinue<eoEsStdev<double> >& _continue, eoGenOp<eoEsStdev<double> >& _op, eoDistance<eoEsStdev<double> >* _dist)
{
return do_make_algo_scalar(_parser, _state, _eval, _continue, _op);
}
eoAlgo<eoEsStdev<eoMinimizingFitness> >& make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc<eoEsStdev<eoMinimizingFitness> >& _eval, eoContinue<eoEsStdev<eoMinimizingFitness> >& _continue, eoGenOp<eoEsStdev<eoMinimizingFitness> >& _op, eoDistance<eoEsStdev<eoMinimizingFitness> >* _dist)
{
return do_make_algo_scalar(_parser, _state, _eval, _continue, _op);
}
///////////////
eoAlgo<eoEsFull<double> >& make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc<eoEsFull<double> >& _eval, eoContinue<eoEsFull<double> >& _continue, eoGenOp<eoEsFull<double> >& _op, eoDistance<eoEsFull<double> >* _dist)
{
return do_make_algo_scalar(_parser, _state, _eval, _continue, _op);
}
eoAlgo<eoEsFull<eoMinimizingFitness> >& make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc<eoEsFull<eoMinimizingFitness> >& _eval, eoContinue<eoEsFull<eoMinimizingFitness> >& _continue, eoGenOp<eoEsFull<eoMinimizingFitness> >& _op, eoDistance<eoEsFull<eoMinimizingFitness> >* _dist)
{
return do_make_algo_scalar(_parser, _state, _eval, _continue, _op);
}

View file

@ -0,0 +1,60 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// make_algo_scalar_real.cpp
// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifdef _MSC_VER
// to avoid long name warnings
#pragma warning(disable:4786)
#endif
/** This file contains ***INSTANCIATED DEFINITIONS*** of select/replace fns
* of the library for evolution of ***eoReal*** inside EO.
* It should be included in the file that calls any of the corresponding fns
* Compiling this file allows one to generate part of the library (i.e. object
* files that you just need to link with your own main and fitness code).
*
* The corresponding ***INSTANCIATED DECLARATIONS*** are contained
* in src/es/real.h
* while the TEMPLATIZED code is define in make_algo_scalar.h in the src/do dir
*/
// The templatized code
#include <do/make_algo_scalar.h>
// the instanciating EOType
#include <es/eoReal.h>
/// The following function merely call the templatized do_* functions above
// Algo
///////
eoAlgo<eoReal<double> >& make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc<eoReal<double> >& _eval, eoContinue<eoReal<double> >& _continue, eoGenOp<eoReal<double> >& _op, eoDistance<eoReal<double> >* _dist)
{
return do_make_algo_scalar(_parser, _state, _eval, _continue, _op, _dist);
}
eoAlgo<eoReal<eoMinimizingFitness> >& make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc<eoReal<eoMinimizingFitness> >& _eval, eoContinue<eoReal<eoMinimizingFitness> >& _continue, eoGenOp<eoReal<eoMinimizingFitness> >& _op, eoDistance<eoReal<eoMinimizingFitness> >* _dist)
{
return do_make_algo_scalar(_parser, _state, _eval, _continue, _op, _dist);
}

View file

@ -0,0 +1,81 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// make_checkpoint_es.cpp
// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifdef _MSC_VER
// to avoid long name warnings
#pragma warning(disable:4786)
#endif
/** This file contains ***INSTANCIATED DEFINITIONS*** of checkpoint fns
* of the library for evolution of ***ES genotypes*** inside EO.
* It should be included in the file that calls any of the corresponding fns
* Compiling this file allows one to generate part of the library (i.e. object
* files that you just need to link with your own main and fitness code).
*
* The corresponding ***INSTANCIATED DECLARATIONS*** are contained
* in src/es/es.h
* while the TEMPLATIZED code is define in make_checkpoint.h in the src/do dir
*/
// The templatized code
#include <do/make_checkpoint.h>
// the instanciating EOType(s)
#include <es/eoEsSimple.h> // one Sigma per individual
#include <es/eoEsStdev.h> // one sigmal per object variable
#include <es/eoEsFull.h> // full correlation matrix per indi
/// The following function merely call the templatized do_* functions
// checkpoint
/////////////
eoCheckPoint<eoEsSimple<double> >& make_checkpoint(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsSimple<double> >& _eval, eoContinue<eoEsSimple<double> >& _continue)
{
return do_make_checkpoint(_parser, _state, _eval, _continue);
}
eoCheckPoint<eoEsSimple<eoMinimizingFitness> >& make_checkpoint(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsSimple<eoMinimizingFitness> >& _eval, eoContinue<eoEsSimple<eoMinimizingFitness> >& _continue)
{
return do_make_checkpoint(_parser, _state, _eval, _continue);
}
/////////////
eoCheckPoint<eoEsStdev<double> >& make_checkpoint(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsStdev<double> >& _eval, eoContinue<eoEsStdev<double> >& _continue)
{
return do_make_checkpoint(_parser, _state, _eval, _continue);
}
eoCheckPoint<eoEsStdev<eoMinimizingFitness> >& make_checkpoint(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsStdev<eoMinimizingFitness> >& _eval, eoContinue<eoEsStdev<eoMinimizingFitness> >& _continue)
{
return do_make_checkpoint(_parser, _state, _eval, _continue);
}
/////////////
eoCheckPoint<eoEsFull<double> >& make_checkpoint(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsFull<double> >& _eval, eoContinue<eoEsFull<double> >& _continue)
{
return do_make_checkpoint(_parser, _state, _eval, _continue);
}
eoCheckPoint<eoEsFull<eoMinimizingFitness> >& make_checkpoint(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsFull<eoMinimizingFitness> >& _eval, eoContinue<eoEsFull<eoMinimizingFitness> >& _continue)
{
return do_make_checkpoint(_parser, _state, _eval, _continue);
}

View file

@ -0,0 +1,59 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// make_checkpoint_real.cpp
// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifdef _MSC_VER
// to avoid long name warnings
#pragma warning(disable:4786)
#endif
/** This file contains ***INSTANCIATED DEFINITIONS*** of checkpoint fns
* of the library for evolution of ***eoReal*** inside EO.
* It should be included in the file that calls any of the corresponding fns
* Compiling this file allows one to generate part of the library (i.e. object
* files that you just need to link with your own main and fitness code).
*
* The corresponding ***INSTANCIATED DECLARATIONS*** are contained
* in src/es/real.h
* while the TEMPLATIZED code is define in make_checkpoint.h in the src/do dir
*/
// The templatized code
#include <do/make_checkpoint.h>
// the instanciating EOType
#include <es/eoReal.h>
/// The following function merely call the templatized do_* functions
// checkpoint
/////////////
eoCheckPoint<eoReal<double> >& make_checkpoint(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoReal<double> >& _eval, eoContinue<eoReal<double> >& _continue)
{
return do_make_checkpoint(_parser, _state, _eval, _continue);
}
eoCheckPoint<eoReal<eoMinimizingFitness> >& make_checkpoint(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoReal<eoMinimizingFitness> >& _eval, eoContinue<eoReal<eoMinimizingFitness> >& _continue)
{
return do_make_checkpoint(_parser, _state, _eval, _continue);
}

View file

@ -0,0 +1,81 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// make_continue_es.cpp
// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifdef _MSC_VER
// to avoid long name warnings
#pragma warning(disable:4786)
#endif
/** This file contains ***INSTANCIATED DEFINITIONS*** of continuator fns
* of the library for evolution of ***ES genotypes*** inside EO.
* It should be included in the file that calls any of the corresponding fns
* Compiling this file allows one to generate part of the library (i.e. object
* files that you just need to link with your own main and fitness code).
*
* The corresponding ***INSTANCIATED DECLARATIONS*** are contained
* in src/es/es.h
* while the TEMPLATIZED code is define in make_continue.h in the src/do dir
*/
// The templatized code
#include <do/make_continue.h>
// the instanciating EOType(s)
#include <es/eoEsSimple.h> // one Sigma per individual
#include <es/eoEsStdev.h> // one sigmal per object variable
#include <es/eoEsFull.h> // full correlation matrix per indi
/// The following function merely call the templatized do_* functions
// continue
///////////
eoContinue<eoEsSimple<double> >& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsSimple<double> > & _eval)
{
return do_make_continue(_parser, _state, _eval);
}
eoContinue<eoEsSimple<eoMinimizingFitness> >& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsSimple<eoMinimizingFitness> > & _eval)
{
return do_make_continue(_parser, _state, _eval);
}
///////////
eoContinue<eoEsStdev<double> >& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsStdev<double> > & _eval)
{
return do_make_continue(_parser, _state, _eval);
}
eoContinue<eoEsStdev<eoMinimizingFitness> >& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsStdev<eoMinimizingFitness> > & _eval)
{
return do_make_continue(_parser, _state, _eval);
}
///////////
eoContinue<eoEsFull<double> >& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsFull<double> > & _eval)
{
return do_make_continue(_parser, _state, _eval);
}
eoContinue<eoEsFull<eoMinimizingFitness> >& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsFull<eoMinimizingFitness> > & _eval)
{
return do_make_continue(_parser, _state, _eval);
}

View file

@ -0,0 +1,59 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// make_continue_real.cpp
// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifdef _MSC_VER
// to avoid long name warnings
#pragma warning(disable:4786)
#endif
/** This file contains ***INSTANCIATED DEFINITIONS*** of continuator fns
* of the library for evolution of ***REAL vectors*** inside EO.
* It should be included in the file that calls any of the corresponding fns
* Compiling this file allows one to generate part of the library (i.e. object
* files that you just need to link with your own main and fitness code).
*
* The corresponding ***INSTANCIATED DECLARATIONS*** are contained
* in src/es/real.h
* while the TEMPLATIZED code is define in make_continue.h in the src/do dir
*/
// The templatized code
#include <do/make_continue.h>
// the instanciating EOType
#include <es/eoReal.h>
/// The following function merely call the templatized do_* functions
// continue
///////////
eoContinue<eoReal<double> >& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoReal<double> > & _eval)
{
return do_make_continue(_parser, _state, _eval);
}
eoContinue<eoReal<eoMinimizingFitness> >& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoReal<eoMinimizingFitness> > & _eval)
{
return do_make_continue(_parser, _state, _eval);
}

View file

@ -0,0 +1,152 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// es.h
// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk
*/
//-----------------------------------------------------------------------------
/** This file contains all ***INSTANCIATED*** declarations of all components
* of the library for ***ES-like gnptype*** evolution inside EO.
* It should be included in the file that calls any of the corresponding fns
*
* The corresponding ***INSTANCIATED*** definitions are contained in
* the different .cpp files in the src/es dir,
* while the TEMPLATIZED code is define in the different make_XXX.h files
* either in hte src/do dir for representation independant functions,
* or in the src/es dir for representation dependent stuff.
*
* See also real.h for the similar declarations of eoReal genotypes
* i.e. ***without*** mutation parameters attached to individuals
*
* Unlike most EO .h files, it does not (and should not) contain any code,
* just declarations
*/
#ifndef es_h
#define es_h
#include <eoAlgo.h>
#include <eoScalarFitness.h>
#include <utils/eoParser.h>
#include <eoEvalFuncPtr.h>
#include <eoEvalFuncCounter.h>
#include <utils/eoCheckPoint.h>
#include <eoGenOp.h>
#include <eoPop.h>
#include <utils/eoDistance.h>
#include <es/eoEsSimple.h> // one Sigma per individual
#include <es/eoEsStdev.h> // one sigmal per object variable
#include <es/eoEsFull.h> // full correlation matrix per indi
// include all similar declaration for eoReal - i.e. real-valued genotyes
// without self-adaptation
#include <es/make_real.h>
/** @addtogroup Builders
* @{
*/
//Representation dependent - rewrite everything anew for each representation
//////////////////////////
// the genotypes
eoRealInitBounded<eoEsSimple<double> > & make_genotype(eoParser& _parser, eoState& _state, eoEsSimple<double> _eo);
eoRealInitBounded<eoEsSimple<eoMinimizingFitness> > & make_genotype(eoParser& _parser, eoState& _state, eoEsSimple<eoMinimizingFitness> _eo);
eoRealInitBounded<eoEsStdev<double> > & make_genotype(eoParser& _parser, eoState& _state, eoEsStdev<double> _eo);
eoRealInitBounded<eoEsStdev<eoMinimizingFitness> > & make_genotype(eoParser& _parser, eoState& _state, eoEsStdev<eoMinimizingFitness> _eo);
eoRealInitBounded<eoEsFull<double> > & make_genotype(eoParser& _parser, eoState& _state, eoEsFull<double> _eo);
eoRealInitBounded<eoEsFull<eoMinimizingFitness> > & make_genotype(eoParser& _parser, eoState& _state, eoEsFull<eoMinimizingFitness> _eo);
// the operators
eoGenOp<eoEsSimple<double> >& make_op(eoParser& _parser, eoState& _state, eoRealInitBounded<eoEsSimple<double> >& _init);
eoGenOp<eoEsSimple<eoMinimizingFitness> >& make_op(eoParser& _parser, eoState& _state, eoRealInitBounded<eoEsSimple<eoMinimizingFitness> >& _init);
eoGenOp<eoEsStdev<double> >& make_op(eoParser& _parser, eoState& _state, eoRealInitBounded<eoEsStdev<double> >& _init);
eoGenOp<eoEsStdev<eoMinimizingFitness> >& make_op(eoParser& _parser, eoState& _state, eoRealInitBounded<eoEsStdev<eoMinimizingFitness> >& _init);
eoGenOp<eoEsFull<double> >& make_op(eoParser& _parser, eoState& _state, eoRealInitBounded<eoEsFull<double> >& _init);
eoGenOp<eoEsFull<eoMinimizingFitness> >& make_op(eoParser& _parser, eoState& _state, eoRealInitBounded<eoEsFull<eoMinimizingFitness> >& _init);
//Representation INdependent
////////////////////////////
// you don't need to modify that part even if you use your own representation
// init pop
eoPop<eoEsSimple<double> >& make_pop(eoParser& _parser, eoState& _state, eoInit<eoEsSimple<double> >&);
eoPop<eoEsSimple<eoMinimizingFitness> >& make_pop(eoParser& _parser, eoState& _state, eoInit<eoEsSimple<eoMinimizingFitness> >&);
eoPop<eoEsStdev<double> >& make_pop(eoParser& _parser, eoState& _state, eoInit<eoEsStdev<double> >&);
eoPop<eoEsStdev<eoMinimizingFitness> >& make_pop(eoParser& _parser, eoState& _state, eoInit<eoEsStdev<eoMinimizingFitness> >&);
eoPop<eoEsFull<double> >& make_pop(eoParser& _parser, eoState& _state, eoInit<eoEsFull<double> >&);
eoPop<eoEsFull<eoMinimizingFitness> >& make_pop(eoParser& _parser, eoState& _state, eoInit<eoEsFull<eoMinimizingFitness> >&);
// the continue's
eoContinue<eoEsSimple<double> >& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsSimple<double> > & _eval);
eoContinue<eoEsSimple<eoMinimizingFitness> >& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsSimple<eoMinimizingFitness> > & _eval);
eoContinue<eoEsStdev<double> >& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsStdev<double> > & _eval);
eoContinue<eoEsStdev<eoMinimizingFitness> >& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsStdev<eoMinimizingFitness> > & _eval);
eoContinue<eoEsFull<double> >& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsFull<double> > & _eval);
eoContinue<eoEsFull<eoMinimizingFitness> >& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsFull<eoMinimizingFitness> > & _eval);
// the checkpoint
eoCheckPoint<eoEsSimple<double> >& make_checkpoint(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsSimple<double> >& _eval, eoContinue<eoEsSimple<double> >& _continue);
eoCheckPoint<eoEsSimple<eoMinimizingFitness> >& make_checkpoint(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsSimple<eoMinimizingFitness> >& _eval, eoContinue<eoEsSimple<eoMinimizingFitness> >& _continue);
eoCheckPoint<eoEsStdev<double> >& make_checkpoint(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsStdev<double> >& _eval, eoContinue<eoEsStdev<double> >& _continue);
eoCheckPoint<eoEsStdev<eoMinimizingFitness> >& make_checkpoint(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsStdev<eoMinimizingFitness> >& _eval, eoContinue<eoEsStdev<eoMinimizingFitness> >& _continue);
eoCheckPoint<eoEsFull<double> >& make_checkpoint(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsFull<double> >& _eval, eoContinue<eoEsFull<double> >& _continue);
eoCheckPoint<eoEsFull<eoMinimizingFitness> >& make_checkpoint(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoEsFull<eoMinimizingFitness> >& _eval, eoContinue<eoEsFull<eoMinimizingFitness> >& _continue);
// the algo
eoAlgo<eoEsSimple<double> >& make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc<eoEsSimple<double> >& _eval, eoContinue<eoEsSimple<double> >& _ccontinue, eoGenOp<eoEsSimple<double> >& _op, eoDistance<eoEsSimple<double> >* _dist = NULL);
eoAlgo<eoEsSimple<eoMinimizingFitness> >& make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc<eoEsSimple<eoMinimizingFitness> >& _eval, eoContinue<eoEsSimple<eoMinimizingFitness> >& _ccontinue, eoGenOp<eoEsSimple<eoMinimizingFitness> >& _op, eoDistance<eoEsSimple<eoMinimizingFitness> >* _dist = NULL);
eoAlgo<eoEsStdev<double> >& make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc<eoEsStdev<double> >& _eval, eoContinue<eoEsStdev<double> >& _ccontinue, eoGenOp<eoEsStdev<double> >& _op, eoDistance<eoEsStdev<double> >* _dist = NULL);
eoAlgo<eoEsStdev<eoMinimizingFitness> >& make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc<eoEsStdev<eoMinimizingFitness> >& _eval, eoContinue<eoEsStdev<eoMinimizingFitness> >& _ccontinue, eoGenOp<eoEsStdev<eoMinimizingFitness> >& _op, eoDistance<eoEsStdev<eoMinimizingFitness> >* _dist = NULL);
eoAlgo<eoEsFull<double> >& make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc<eoEsFull<double> >& _eval, eoContinue<eoEsFull<double> >& _ccontinue, eoGenOp<eoEsFull<double> >& _op, eoDistance<eoEsFull<double> >* _dist = NULL);
eoAlgo<eoEsFull<eoMinimizingFitness> >& make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc<eoEsFull<eoMinimizingFitness> >& _eval, eoContinue<eoEsFull<eoMinimizingFitness> >& _ccontinue, eoGenOp<eoEsFull<eoMinimizingFitness> >& _op, eoDistance<eoEsFull<eoMinimizingFitness> >* _dist = NULL);
// run
void run_ea(eoAlgo<eoEsSimple<double> >& _ga, eoPop<eoEsSimple<double> >& _pop);
void run_ea(eoAlgo<eoEsSimple<eoMinimizingFitness> >& _ga, eoPop<eoEsSimple<eoMinimizingFitness> >& _pop);
void run_ea(eoAlgo<eoEsStdev<double> >& _ga, eoPop<eoEsStdev<double> >& _pop);
void run_ea(eoAlgo<eoEsStdev<eoMinimizingFitness> >& _ga, eoPop<eoEsStdev<eoMinimizingFitness> >& _pop);
void run_ea(eoAlgo<eoEsFull<double> >& _ga, eoPop<eoEsFull<double> >& _pop);
void run_ea(eoAlgo<eoEsFull<eoMinimizingFitness> >& _ga, eoPop<eoEsFull<eoMinimizingFitness> >& _pop);
// end of parameter input (+ .status + help)
// that one is not templatized, but is here for completeness
void make_help(eoParser & _parser);
/** @} */
/** @} */
#endif

View file

@ -0,0 +1,121 @@
/* (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
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: http://eodev.sourceforge.net
todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk
*/
#ifdef _MSC_VER
// to avoid long name warnings
#pragma warning(disable:4786)
#endif
/** Init functions
This file contains ***INSTANCIATED DEFINITIONS*** of eoReal Init fns
It should be included in the file that calls any of the corresponding
fns Compiling this file allows one to generate part of the library
(i.e. object files that you just need to link with your own main and
fitness code).
The corresponding ***INSTANCIATED DECLARATIONS*** are contained in
src/es/make_real.h while the TEMPLATIZED code is define in
make_genotype_real.h
It is instanciated in src/es/make_genotype_real.cpp - and incorporated
in the ga/libga.a
It returns an eoInit<EOT> that can later be used to initialize the
population (see make_pop.h).
It uses a parser (to get user parameters) and a state (to store the
memory) the last argument is to disambiguate the call upon different
instanciations.
WARNING: that last argument will generally be the result of calling
the default ctor of EOT, resulting in most cases in an EOT that is
***not properly initialized***
*/
// the templatized code (same for real and es here)
#include <es/make_genotype_real.h>
/// The following function merely call the templatized do_* functions
eoRealInitBounded<eoEsSimple<double> >& make_genotype(eoParser& _parser,
eoState& _state,
eoEsSimple<double> _eo)
{
return do_make_genotype(_parser, _state, _eo);
}
eoRealInitBounded<eoEsSimple<eoMinimizingFitness> >& make_genotype(eoParser& _parser,
eoState& _state,
eoEsSimple<eoMinimizingFitness> _eo)
{
return do_make_genotype(_parser, _state, _eo);
}
eoRealInitBounded<eoEsStdev<double> >& make_genotype(eoParser& _parser,
eoState& _state,
eoEsStdev<double> _eo)
{
return do_make_genotype(_parser, _state, _eo);
}
eoRealInitBounded<eoEsStdev<eoMinimizingFitness> >& make_genotype(eoParser& _parser,
eoState& _state,
eoEsStdev<eoMinimizingFitness> _eo)
{
return do_make_genotype(_parser, _state, _eo);
}
eoRealInitBounded<eoEsFull<double> > & make_genotype(eoParser& _parser,
eoState& _state,
eoEsFull<double> _eo)
{
return do_make_genotype(_parser, _state, _eo);
}
eoRealInitBounded<eoEsFull<eoMinimizingFitness> >& make_genotype(eoParser& _parser,
eoState& _state,
eoEsFull<eoMinimizingFitness> _eo)
{
return do_make_genotype(_parser, _state, _eo);
}
// Local Variables:
// coding: iso-8859-1
// c-file-style: "Stroustrup"
// comment-column: 35
// fill-column: 80
// End:

View file

@ -0,0 +1,73 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// make_genotype_real.cpp
// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifdef _MSC_VER
// to avoid long name warnings
#pragma warning(disable:4786)
#endif
/** This file contains ***INSTANCIATED DEFINITIONS*** of eoReal Init fns
* It should be included in the file that calls any of the corresponding fns
* Compiling this file allows one to generate part of the library (i.e. object
* files that you just need to link with your own main and fitness code).
*
* The corresponding ***INSTANCIATED DECLARATIONS*** are contained
* in src/es/make_real.h
* while the TEMPLATIZED code is define in make_genotype_real.h
*
* It is instanciated in src/es/make_genotype_real.cpp -
* and incorporated in the ga/libga.a
*
* It returns an eoInit<EOT> that can later be used to initialize
* the population (see make_pop.h).
*
* It uses a parser (to get user parameters) and a state (to store the memory)
* the last argument is to disambiguate the call upon different instanciations.
*
* WARNING: that last argument will generally be the result of calling
* the default ctor of EOT, resulting in most cases in an EOT
* that is ***not properly initialized***
*/
// the templatized code
#include <es/make_genotype_real.h>
/// The following functions merely call the templatized do_* functions
eoRealInitBounded<eoReal<double> > & make_genotype(eoParser& _parser,
eoState& _state,
eoReal<double> _eo)
{
return do_make_genotype(_parser, _state, _eo);
}
eoRealInitBounded<eoReal<eoMinimizingFitness> > & make_genotype(eoParser& _parser,
eoState& _state,
eoReal<eoMinimizingFitness> _eo)
{
return do_make_genotype(_parser, _state, _eo);
}

View file

@ -0,0 +1,128 @@
//-----------------------------------------------------------------------------
/** (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
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: http://eodev.sourceforge.net
todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk
*/
#ifndef EO_make_genotype_h
#define EO_make_genotype_h
#include <iostream>
#include <sstream>
#include <vector>
#include "es/eoReal.h"
#include "es/eoEsChromInit.h"
#include "utils/eoParser.h"
#include "utils/eoRealVectorBounds.h"
#include "utils/eoState.h"
/** @addtogroup Builders
* @{
*/
/** Initialize genotype
This fuction does the initialization of what's needed for a particular genotype
(here, std::vector<double> == eoReal). It could be here tempatied only on the
fitness, as it can be used to evolve bitstrings with any fitness. However, for
consistency reasons, it was finally chosen, as in the rest of EO, to templatize
by the full EOT, as this eventually allows to choose the type of genotype at run
time (see in es dir)
It is instanciated in src/es/make_genotyupe_real.cpp and incorporated in the
src/es/libes.a
It returns an eoInit<EOT> tha can later be used to initialize the population
(see make_pop.h).
It uses a parser (to get user parameters) and a state (to store the memory) the
last argument is to disambiguate the call upon different instanciations.
@warning: that last argument will generally be the result of calling the default
ctor of EOT, resulting in most cases in an EOT that is ***not properly
initialized***
*/
template <class EOT>
eoEsChromInit<EOT> & do_make_genotype(eoParser& _parser, eoState& _state, EOT)
{
// the fitness type
typedef typename EOT::Fitness FitT;
eoEsChromInit<EOT> *init;
// for eoReal, only thing needed is the size - but might have been created elswhere ...
eoValueParam<unsigned>& vecSize
= _parser.getORcreateParam(unsigned(10), "vecSize",
"The number of variables ",
'n', "Genotype Initialization");
// to build an eoReal Initializer, we need bounds: [-1,1] by default
eoValueParam<eoRealVectorBounds>& boundsParam
= _parser.getORcreateParam(eoRealVectorBounds(vecSize.value(), -1, 1),
"initBounds",
"Bounds for initialization (MUST be bounded)",
'B', "Genotype Initialization");
// now some initial value for sigmas - even if useless?
// should be used in Normal mutation
eoValueParam<std::string>& sigmaParam
= _parser.getORcreateParam(std::string("0.3"), "sigmaInit",
"Initial value for Sigmas (with a '%' -> scaled by the range of each variable)",
's', "Genotype Initialization");
// check for %
bool to_scale = false;
size_t pos = sigmaParam.value().find('%');
if(pos < sigmaParam.value().size()) {
// found a % - use scaling and get rid of '%'
to_scale = true;
sigmaParam.value().resize(pos);
}
std::istringstream is(sigmaParam.value());
double sigma;
is >> sigma;
// minimum check
if(sigma < 0)
throw std::runtime_error("Negative sigma in make_genotype");
if(to_scale)
init = new eoEsChromInit<EOT>(boundsParam.value(), sigma, to_scale);
else {
// define parameter
eoValueParam<std::vector<double> >& vecSigmaParam
= _parser.getORcreateParam(std::vector<double>(vecSize.value(), sigma), "vecSigmaInit",
"Initial value for Sigmas (only used when initSigma is not scaled)",
'S', "Genotype Initialization");
init = new eoEsChromInit<EOT>(boundsParam.value(), vecSigmaParam.value());
}
// store in state
_state.storeFunctor(init);
return *init;
}
/** @} */
#endif // EO_make_genotype_h
// Local Variables:
// coding: iso-8859-1
// mode:C++
// c-file-style: "Stroustrup"
// comment-column: 35
// fill-column: 80
// End:

View file

@ -0,0 +1,299 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// make_op.h - the real-valued version
// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifndef _make_op_h
#define _make_op_h
// the operators
#include <eoOp.h>
#include <eoGenOp.h>
#include <eoCloneOps.h>
#include <eoOpContainer.h>
// combinations of simple eoOps (eoMonOp and eoQuadOp)
#include <eoProportionalCombinedOp.h>
// the specialized Real stuff
#include <es/eoReal.h>
#include <es/eoRealInitBounded.h>
#include <es/eoRealOp.h>
#include <es/eoNormalMutation.h>
// also need the parser and param includes
#include <utils/eoParser.h>
#include <utils/eoState.h>
/** @addtogroup Builders
* @{
*/
/*
* This function builds the operators that will be applied to the eoReal
*
* It uses a parser (to get user parameters) and a state (to store the memory)
* the last argument is an individual, needed for 2 reasons
* it disambiguates the call after instanciations
* some operator might need some private information about the indis
*
* This is why the template is the complete EOT even though only the fitness
* is actually templatized here: the following only applies to bitstrings
*
* Note : the last parameter is an eoInit: if some operator needs some info
* about the gneotypes, the init has it all (e.g. bounds, ...)
* Simply do
* EOT myEO;
* _init(myEO);
* and myEO is then an ACTUAL object
*/
template <class EOT>
eoGenOp<EOT> & do_make_op(eoParameterLoader& _parser, eoState& _state, eoInit<EOT>& _init)
{
// First, decide whether the objective variables are bounded
eoValueParam<eoParamParamType>& boundsParam
= _parser.getORcreateParam(eoParamParamType("(0,1)"), "objectBounds",
"Bounds for variables (unbounded if absent)",
'B', "Genetic Operators");
// get initisalizer size == std::vector size
// eoRealInitBounded<EOT> * realInit = (eoRealInitBounded<EOT>*)(&_init);
// unsigned vecSize = realInit->theBounds().size();
// get std::vector size: safer???
EOT eoTmp;
_init(eoTmp);
unsigned vecSize = eoTmp.size();
// the bounds pointer
eoRealVectorBounds * ptBounds;
if (_parser.isItThere(boundsParam)) // otherwise, no bounds
{
/////Warning: this code should probably be replaced by creating
///// some eoValueParam<eoRealVectorBounds> with specific implementation
//// in eoParser.cpp. At the moemnt, it is there (cf also make_genotype
eoParamParamType & ppBounds = boundsParam.value(); // std::pair<std::string,std::vector<std::string> >
// transform into a std::vector<double>
std::vector<double> v;
std::vector<std::string>::iterator it;
for (it=ppBounds.second.begin(); it<ppBounds.second.end(); it++)
{
istrstream is(it->c_str());
double r;
is >> r;
v.push_back(r);
}
// now create the eoRealVectorBounds object
if (v.size() == 2) // a min and a max for all variables
ptBounds = new eoRealVectorBounds(vecSize, v[0], v[1]);
else // no time now
throw std::runtime_error("Sorry, only unique bounds for all variables implemented at the moment. Come back later");
// we need to give ownership of this pointer to somebody
/////////// end of temporary code
}
else // no param for bounds was given
ptBounds = new eoRealVectorNoBounds(vecSize); // DON'T USE eoDummyVectorNoBounds
// as it does not have any dimension
// this is a temporary version(!),
// while Maarten codes the full tree-structured general operator input
// BTW we must leave that simple version available somehow, as it is the one
// that 90% people use!
eoValueParam<std::string>& operatorParam
= _parser.getORcreateParam(std::string("SGA"), "operator",
"Description of the operator (SGA only now)",
'o', "Genetic Operators");
if (operatorParam.value() != std::string("SGA"))
throw std::runtime_error("Sorry, only SGA-like operator available right now\n");
// now we read Pcross and Pmut,
// the relative weights for all crossovers -> proportional choice
// the relative weights for all mutations -> proportional choice
// and create the eoGenOp that is exactly
// crossover with pcross + mutation with pmut
eoValueParam<double>& pCrossParam
= _parser.getORcreateParam(0.6, "pCross", "Probability of Crossover",
'C', "Genetic Operators" );
// minimum check
if ( (pCrossParam.value() < 0) || (pCrossParam.value() > 1) )
throw std::runtime_error("Invalid pCross");
eoValueParam<double>& pMutParam
= _parser.getORcreateParam(0.1, "pMut", "Probability of Mutation",
'M', "Genetic Operators" );
// minimum check
if ( (pMutParam.value() < 0) || (pMutParam.value() > 1) )
throw std::runtime_error("Invalid pMut");
// the crossovers
/////////////////
// the parameters
eoValueParam<double>& segmentRateParam
= _parser.getORcreateParam(double(1.0), "segmentRate",
"Relative rate for segment crossover",
's', "Genetic Operators" );
// minimum check
if ( (segmentRateParam.value() < 0) )
throw std::runtime_error("Invalid segmentRate");
eoValueParam<double>& arithmeticRateParam
= _parser.getORcreateParam(double(2.0), "arithmeticRate",
"Relative rate for arithmetic crossover",
'A', "Genetic Operators" );
// minimum check
if ( (arithmeticRateParam.value() < 0) )
throw std::runtime_error("Invalid arithmeticRate");
// minimum check
bool bCross = true;
if (segmentRateParam.value()+arithmeticRateParam.value()==0)
{
std::cerr << "Warning: no crossover" << std::endl;
bCross = false;
}
// Create the CombinedQuadOp
eoPropCombinedQuadOp<EOT> *ptCombinedQuadOp = NULL;
eoQuadOp<EOT> *ptQuad = NULL;
if (bCross)
{
// segment crossover for bitstring - pass it the bounds
ptQuad = new eoSegmentCrossover<EOT>(*ptBounds);
_state.storeFunctor(ptQuad);
ptCombinedQuadOp = new eoPropCombinedQuadOp<EOT>(*ptQuad, segmentRateParam.value());
// arithmetic crossover
ptQuad = new eoArithmeticCrossover<EOT>(*ptBounds);
_state.storeFunctor(ptQuad);
ptCombinedQuadOp->add(*ptQuad, arithmeticRateParam.value());
// don't forget to store the CombinedQuadOp
_state.storeFunctor(ptCombinedQuadOp);
}
// the mutations
/////////////////
// the parameters
eoValueParam<double> & epsilonParam
= _parser.getORcreateParam(0.01, "epsilon", "Half-size of interval for Uniform Mutation",
'e', "Genetic Operators" );
// minimum check
if ( (epsilonParam.value() < 0) )
throw std::runtime_error("Invalid epsilon");
eoValueParam<double> & uniformMutRateParam
= _parser.getORcreateParam(1.0, "uniformMutRate",
"Relative rate for uniform mutation", 'u', "Genetic Operators" );
// minimum check
if ( (uniformMutRateParam.value() < 0) )
throw std::runtime_error("Invalid uniformMutRate");
eoValueParam<double> & detMutRateParam
= _parser.getORcreateParam(1.0, "detMutRate",
"Relative rate for deterministic uniform mutation",
'd', "Genetic Operators" );
// minimum check
if ( (detMutRateParam.value() < 0) )
throw std::runtime_error("Invalid detMutRate");
eoValueParam<double> & normalMutRateParam
= _parser.getORcreateParam(1.0, "normalMutRate",
"Relative rate for Gaussian mutation",
'd', "Genetic Operators" );
// minimum check
if ( (normalMutRateParam.value() < 0) )
throw std::runtime_error("Invalid normalMutRate");
// and the sigma
eoValueParam<double> & sigmaParam
= _parser.getORcreateParam(1.0, "sigma",
"Sigma (fixed) for Gaussian mutation",
'S', "Genetic Operators" );
// minimum check
if ( (sigmaParam.value() < 0) )
throw std::runtime_error("Invalid sigma");
// minimum check
bool bMut = true;
if (uniformMutRateParam.value()+detMutRateParam.value()+normalMutRateParam.value()==0)
{
std::cerr << "Warning: no mutation" << std::endl;
bMut = false;
}
if (!bCross && !bMut)
throw std::runtime_error("No operator called in SGA operator definition!!!");
// Create the CombinedMonOp
eoPropCombinedMonOp<EOT> *ptCombinedMonOp = NULL;
eoMonOp<EOT> *ptMon = NULL;
if (bMut)
{
// uniform mutation on all components:
// offspring(i) uniformly chosen in [parent(i)-epsilon, parent(i)+epsilon]
ptMon = new eoUniformMutation<EOT>(*ptBounds, epsilonParam.value());
_state.storeFunctor(ptMon);
// create the CombinedMonOp
ptCombinedMonOp = new eoPropCombinedMonOp<EOT>(*ptMon, uniformMutRateParam.value());
// mutate exactly 1 component (uniformly) per individual
ptMon = new eoDetUniformMutation<EOT>(*ptBounds, epsilonParam.value());
_state.storeFunctor(ptMon);
ptCombinedMonOp->add(*ptMon, detMutRateParam.value());
// mutate all component using Gaussian mutation
ptMon = new eoNormalMutation<EOT>(*ptBounds, sigmaParam.value());
_state.storeFunctor(ptMon);
ptCombinedMonOp->add(*ptMon, normalMutRateParam.value());
_state.storeFunctor(ptCombinedMonOp);
}
// now build the eoGenOp:
// to simulate SGA (crossover with proba pCross + mutation with proba pMut
// we must construct
// a sequential combination of
// with proba 1, a proportional combination of
// a QuadCopy and our crossover
// with proba pMut, our mutation
// the crossover - with probability pCross
eoProportionalOp<EOT> * cross = new eoProportionalOp<EOT> ;
_state.storeFunctor(cross);
ptQuad = new eoQuadCloneOp<EOT>;
_state.storeFunctor(ptQuad);
cross->add(*ptCombinedQuadOp, pCrossParam.value()); // user crossover
cross->add(*ptQuad, 1-pCrossParam.value()); // clone operator
// now the sequential
eoSequentialOp<EOT> *op = new eoSequentialOp<EOT>;
_state.storeFunctor(op);
op->add(*cross, 1.0); // always crossover (but clone with prob 1-pCross
op->add(*ptCombinedMonOp, pMutParam.value());
// that's it!
return *op;
}
/** @} */
#endif

View file

@ -0,0 +1,79 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// make_op_real.cpp
// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifdef _MSC_VER
// to avoid long name warnings
#pragma warning(disable:4786)
#endif
/** This file contains ***INSTANCIATED DEFINITIONS*** of operators fns
* of the library for ***eoReal*** evolution inside EO.
* It should be included in the file that calls any of the corresponding fns
* Compiling this file allows one to generate part of the library (i.e. object
* files that you just need to link with your own main and fitness code).
*
* The corresponding ***INSTANCIATED DECLARATIONS*** are contained
* in es.h in src/es dir
* while the TEMPLATIZED code is define in make_op.h in the es dir
*
*/
// Templatized code
#include <es/make_op_es.h>
/// The following function merely call the templatized do_* functions above
// operators
////////////
eoGenOp<eoEsSimple<double> >& make_op(eoParser& _parser, eoState& _state, eoRealInitBounded<eoEsSimple<double> >& _init)
{
return do_make_op(_parser, _state, _init);
}
eoGenOp<eoEsSimple<eoMinimizingFitness> >& make_op(eoParser& _parser, eoState& _state, eoRealInitBounded<eoEsSimple<eoMinimizingFitness> >& _init)
{
return do_make_op(_parser, _state, _init);
}
eoGenOp<eoEsStdev<double> >& make_op(eoParser& _parser, eoState& _state, eoRealInitBounded<eoEsStdev<double> >& _init)
{
return do_make_op(_parser, _state, _init);
}
eoGenOp<eoEsStdev<eoMinimizingFitness> >& make_op(eoParser& _parser, eoState& _state, eoRealInitBounded<eoEsStdev<eoMinimizingFitness> >& _init)
{
return do_make_op(_parser, _state, _init);
}
eoGenOp<eoEsFull<double> >& make_op(eoParser& _parser, eoState& _state, eoRealInitBounded<eoEsFull<double> >& _init)
{
return do_make_op(_parser, _state, _init);
}
eoGenOp<eoEsFull<eoMinimizingFitness> >& make_op(eoParser& _parser, eoState& _state, eoRealInitBounded<eoEsFull<eoMinimizingFitness> >& _init)
{
return do_make_op(_parser, _state, _init);
}

View file

@ -0,0 +1,202 @@
/* (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
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: http://eodev.sourceforge.net
todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk
*/
#ifndef EO_make_op_h
#define EO_make_op_h
// the operators
#include <eoOp.h>
#include <eoGenOp.h>
#include <eoCloneOps.h>
#include <eoOpContainer.h>
// combinations of simple eoOps (eoMonOp and eoQuadOp)
#include <eoProportionalCombinedOp.h>
// the specialized Real stuff
#include <es/eoReal.h>
#include <es/eoRealAtomXover.h>
#include <es/eoEsChromInit.h>
#include <es/eoEsMutationInit.h>
#include <es/eoEsMutate.h>
#include <es/eoEsGlobalXover.h>
#include <es/eoEsStandardXover.h>
// also need the parser and param includes
#include <utils/eoParser.h>
#include <utils/eoState.h>
/** @addtogroup Builders
* @{
*/
/*
* This function builds the operators that will be applied to the eoReal
*
* It uses a parser (to get user parameters) and a state (to store the memory)
* the last argument is an individual, needed for 2 reasons
* it disambiguates the call after instanciations
* some operator might need some private information about the indis
*
* This is why the template is the complete EOT even though only the fitness
* is actually templatized here: the following only applies to bitstrings
*
* Note : the last parameter is an eoInit: if some operator needs some info
* about the gneotypes, the init has it all (e.g. bounds, ...)
* Simply do
* EOT myEO;
* _init(myEO);
* and myEO is then an ACTUAL object
*/
template <class EOT>
eoGenOp<EOT> & do_make_op(eoParser& _parser, eoState& _state, eoRealInitBounded<EOT>& _init)
{
// get std::vector size
unsigned vecSize = _init.size();
// First, decide whether the objective variables are bounded
eoValueParam<eoRealVectorBounds>& boundsParam
= _parser.getORcreateParam(eoRealVectorBounds(vecSize,eoDummyRealNoBounds),
"objectBounds", "Bounds for variables",
'B', "Variation Operators");
std::cerr << boundsParam.value() << std::endl;
// now we read Pcross and Pmut,
eoValueParam<std::string>& operatorParam
= _parser.getORcreateParam(std::string("SGA"), "operator",
"Description of the operator (SGA only now)",
'o', "Variation Operators");
if (operatorParam.value() != std::string("SGA"))
throw std::runtime_error("Sorry, only SGA-like operator available right now\n");
// now we read Pcross and Pmut,
// and create the eoGenOp that is exactly
// crossover with pcross + mutation with pmut
eoValueParam<double>& pCrossParam
= _parser.getORcreateParam(1.0, "pCross", "Probability of Crossover",
'C', "Variation Operators" );
// minimum check
if ( (pCrossParam.value() < 0) || (pCrossParam.value() > 1) )
throw std::runtime_error("Invalid pCross");
eoValueParam<double>& pMutParam
= _parser.getORcreateParam(1.0, "pMut", "Probability of Mutation",
'M', "Variation Operators" );
// minimum check
if ( (pMutParam.value() < 0) || (pMutParam.value() > 1) )
throw std::runtime_error("Invalid pMut");
// crossover
/////////////
// ES crossover
eoValueParam<std::string>& crossTypeParam
= _parser.getORcreateParam(std::string("global"), "crossType",
"Type of ES recombination (global or standard)",
'C', "Variation Operators");
eoValueParam<std::string>& crossObjParam
= _parser.getORcreateParam(std::string("discrete"), "crossObj",
"Recombination of object variables (discrete, intermediate or none)",
'O', "Variation Operators");
eoValueParam<std::string>& crossStdevParam
= _parser.getORcreateParam(std::string("intermediate"), "crossStdev",
"Recombination of mutation strategy parameters "
"(intermediate, discrete or none)",
'S', "Variation Operators");
// The pointers: first the atom Xover
eoBinOp<double> *ptObjAtomCross = NULL;
eoBinOp<double> *ptStdevAtomCross = NULL;
// then the EOT-level one (need to be an eoGenOp as global Xover is
eoGenOp<EOT> *ptCross;
// check for the atom Xovers
if (crossObjParam.value() == std::string("discrete"))
ptObjAtomCross = new eoDoubleExchange;
else if (crossObjParam.value() == std::string("intermediate"))
ptObjAtomCross = new eoDoubleIntermediate;
else if (crossObjParam.value() == std::string("none"))
ptObjAtomCross = new eoBinCloneOp<double>;
else throw std::runtime_error("Invalid Object variable crossover type");
if (crossStdevParam.value() == std::string("discrete"))
ptStdevAtomCross = new eoDoubleExchange;
else if (crossStdevParam.value() == std::string("intermediate"))
ptStdevAtomCross = new eoDoubleIntermediate;
else if (crossStdevParam.value() == std::string("none"))
ptStdevAtomCross = new eoBinCloneOp<double>;
else throw std::runtime_error("Invalid mutation strategy parameter crossover type");
// and build the indi Xover
if (crossTypeParam.value() == std::string("global"))
ptCross = new eoEsGlobalXover<EOT>(*ptObjAtomCross, *ptStdevAtomCross);
else if (crossTypeParam.value() == std::string("standard"))
{ // using a standard eoBinOp, but wrap it into an eoGenOp
eoBinOp<EOT> & crossTmp = _state.storeFunctor(
new eoEsStandardXover<EOT>(*ptObjAtomCross, *ptStdevAtomCross)
);
ptCross = new eoBinGenOp<EOT>(crossTmp);
}
else throw std::runtime_error("Invalide Object variable crossover type");
// now that everything is OK, DON'T FORGET TO STORE MEMORY
_state.storeFunctor(ptObjAtomCross);
_state.storeFunctor(ptStdevAtomCross);
_state.storeFunctor(ptCross);
// mutation
/////////////
// Ok, time to set up the self-adaptive mutation
// Proxy for the mutation parameters
eoEsMutationInit mutateInit(_parser, "Variation Operators");
eoEsMutate<EOT> & mut = _state.storeFunctor(
new eoEsMutate<EOT>(mutateInit, boundsParam.value()));
// now the general op - a sequential application of crossover and mutatation
// no need to first have crossover combined with a clone as it is an
// eoBinOp and not an eoQuadOp as in SGA paradigm
eoSequentialOp<EOT> & op = _state.storeFunctor(new eoSequentialOp<EOT>);
op.add(*ptCross, pCrossParam.value());
op.add(mut, pMutParam.value());
// that's it!
return op;
}
#endif // EO_make_op_h
/** @} */
// Local Variables:
// coding: iso-8859-1
// mode:C++
// c-file-style: "Stroustrup"
// comment-column: 35
// fill-column: 80
// End:

View file

@ -0,0 +1,59 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// make_op_real.cpp
// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifdef _MSC_VER
// to avoid long name warnings
#pragma warning(disable:4786)
#endif
/** This file contains ***INSTANCIATED DEFINITIONS*** of operators fns
* of the library for ***eoReal*** evolution inside EO.
* It should be included in the file that calls any of the corresponding fns
* Compiling this file allows one to generate part of the library (i.e. object
* files that you just need to link with your own main and fitness code).
*
* The corresponding ***INSTANCIATED DECLARATIONS*** are contained
* in es.h in src/es dir
* while the TEMPLATIZED code is define in make_op.h in the es dir
*
*/
// Templatized code
#include <es/make_op_real.h>
/// The following function merely call the templatized do_* functions above
// oeprators
////////////
eoGenOp<eoReal<double> >& make_op(eoParser& _parser, eoState& _state, eoRealInitBounded<eoReal<double> >& _init)
{
return do_make_op(_parser, _state, _init);
}
eoGenOp<eoReal<eoMinimizingFitness> >& make_op(eoParser& _parser, eoState& _state, eoRealInitBounded<eoReal<eoMinimizingFitness> >& _init)
{
return do_make_op(_parser, _state, _init);
}

View file

@ -0,0 +1,289 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// make_op.h - the real-valued version
// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifndef _make_op_h
#define _make_op_h
// the operators
#include <eoOp.h>
#include <eoGenOp.h>
#include <eoCloneOps.h>
#include <eoOpContainer.h>
// combinations of simple eoOps (eoMonOp and eoQuadOp)
#include <eoProportionalCombinedOp.h>
// the specialized Real stuff
#include <es/eoReal.h>
#include <es/eoEsChromInit.h>
#include <es/eoRealOp.h>
#include <es/eoNormalMutation.h>
// also need the parser and param includes
#include <utils/eoParser.h>
#include <utils/eoState.h>
/** @addtogroup Builders
* @{
*/
/*
* This function builds the operators that will be applied to the eoReal
*
* It uses a parser (to get user parameters) and a state (to store the memory)
* the last argument is an individual, needed for 2 reasons
* it disambiguates the call after instanciations
* some operator might need some private information about the indis
*
* This is why the template is the complete EOT even though only the fitness
* is actually templatized here: the following only applies to bitstrings
*
* Note : the last parameter is an eoInit: if some operator needs some info
* about the gneotypes, the init has it all (e.g. bounds, ...)
* Simply do
* EOT myEO;
* _init(myEO);
* and myEO is then an ACTUAL object
*/
template <class EOT>
eoGenOp<EOT> & do_make_op(eoParser& _parser, eoState& _state, eoRealInitBounded<EOT>& _init)
{
// get std::vector size
unsigned vecSize = _init.size();
// First, decide whether the objective variables are bounded
eoValueParam<eoRealVectorBounds>& boundsParam
= _parser.getORcreateParam(eoRealVectorBounds(vecSize,eoDummyRealNoBounds), "objectBounds",
"Bounds for variables", 'B', "Variation Operators");
// this is a temporary version(!),
// while Maarten codes the full tree-structured general operator input
// BTW we must leave that simple version available somehow, as it is the one
// that 90% people use!
eoValueParam<std::string>& operatorParam
= _parser.getORcreateParam(std::string("SGA"), "operator",
"Description of the operator (SGA only now)",
'o', "Variation Operators");
if (operatorParam.value() != std::string("SGA"))
throw std::runtime_error("Sorry, only SGA-like operator available right now\n");
// now we read Pcross and Pmut,
// the relative weights for all crossovers -> proportional choice
// the relative weights for all mutations -> proportional choice
// and create the eoGenOp that is exactly
// crossover with pcross + mutation with pmut
eoValueParam<double>& pCrossParam
= _parser.getORcreateParam(0.6, "pCross",
"Probability of Crossover",
'C', "Variation Operators" );
// minimum check
if ( (pCrossParam.value() < 0) || (pCrossParam.value() > 1) )
throw std::runtime_error("Invalid pCross");
eoValueParam<double>& pMutParam
= _parser.getORcreateParam(0.1, "pMut",
"Probability of Mutation",
'M', "Variation Operators" );
// minimum check
if ( (pMutParam.value() < 0) || (pMutParam.value() > 1) )
throw std::runtime_error("Invalid pMut");
// the crossovers
/////////////////
// the parameters
eoValueParam<double>& alphaParam
= _parser.getORcreateParam(double(0.0), "alpha",
"Bound for factor of linear recombinations",
'a', "Variation Operators" );
// minimum check
if ( (alphaParam.value() < 0) )
throw std::runtime_error("Invalid BLX coefficient alpha");
eoValueParam<double>& segmentRateParam
= _parser.getORcreateParam(double(1.0), "segmentRate",
"Relative rate for segment crossover",
's', "Variation Operators" );
// minimum check
if ( (segmentRateParam.value() < 0) )
throw std::runtime_error("Invalid segmentRate");
eoValueParam<double>& hypercubeRateParam
= _parser.getORcreateParam(double(1.0), "hypercubeRate",
"Relative rate for hypercube crossover",
'A', "Variation Operators" );
// minimum check
if ( (hypercubeRateParam.value() < 0) )
throw std::runtime_error("Invalid hypercubeRate");
eoValueParam<double>& uxoverRateParam
= _parser.getORcreateParam(double(1.0), "uxoverRate",
"Relative rate for uniform crossover",
'A', "Variation Operators" );
// minimum check
if ( (uxoverRateParam.value() < 0) )
throw std::runtime_error("Invalid uxoverRate");
// minimum check
bool bCross = true;
if (segmentRateParam.value()+hypercubeRateParam.value()+uxoverRateParam.value()==0)
{
std::cerr << "Warning: no crossover" << std::endl;
bCross = false;
}
// Create the CombinedQuadOp
eoPropCombinedQuadOp<EOT> *ptCombinedQuadOp = NULL;
eoQuadOp<EOT> *ptQuad = NULL;
if (bCross)
{
// segment crossover for bitstring - pass it the bounds
ptQuad = new eoSegmentCrossover<EOT>(boundsParam.value(), alphaParam.value());
_state.storeFunctor(ptQuad);
ptCombinedQuadOp = new eoPropCombinedQuadOp<EOT>(*ptQuad, segmentRateParam.value());
// hypercube crossover
ptQuad = new eoHypercubeCrossover<EOT>(boundsParam.value(), alphaParam.value());
_state.storeFunctor(ptQuad);
ptCombinedQuadOp->add(*ptQuad, hypercubeRateParam.value());
// uniform crossover
ptQuad = new eoRealUXover<EOT>();
_state.storeFunctor(ptQuad);
ptCombinedQuadOp->add(*ptQuad, uxoverRateParam.value());
// don't forget to store the CombinedQuadOp
_state.storeFunctor(ptCombinedQuadOp);
}
// the mutations
/////////////////
// the parameters
eoValueParam<double> & epsilonParam
= _parser.getORcreateParam(0.01, "epsilon",
"Half-size of interval for Uniform Mutation",
'e', "Variation Operators" );
// minimum check
if ( (epsilonParam.value() < 0) )
throw std::runtime_error("Invalid epsilon");
eoValueParam<double> & uniformMutRateParam
= _parser.getORcreateParam(1.0, "uniformMutRate",
"Relative rate for uniform mutation",
'u', "Variation Operators" );
// minimum check
if ( (uniformMutRateParam.value() < 0) )
throw std::runtime_error("Invalid uniformMutRate");
eoValueParam<double> & detMutRateParam
= _parser.getORcreateParam(1.0, "detMutRate",
"Relative rate for deterministic uniform mutation",
'd', "Variation Operators" );
// minimum check
if ( (detMutRateParam.value() < 0) )
throw std::runtime_error("Invalid detMutRate");
eoValueParam<double> & normalMutRateParam
= _parser.getORcreateParam(1.0, "normalMutRate",
"Relative rate for Gaussian mutation", 'd', "Variation Operators" );
// minimum check
if ( (normalMutRateParam.value() < 0) )
throw std::runtime_error("Invalid normalMutRate");
eoValueParam<double> & sigmaParam
= _parser.getORcreateParam(0.3, "sigma",
"Sigma (fixed) for Gaussian mutation",
's', "Variation Operators" );
eoValueParam<double> & pNormalParam
= _parser.getORcreateParam(1.0, "pNormal",
"Proba. to change each variable for Gaussian mutation",
's', "Variation Operators" );
// minimum check
bool bMut = true;
if (uniformMutRateParam.value()+detMutRateParam.value()+normalMutRateParam.value()==0)
{
std::cerr << "Warning: no mutation" << std::endl;
bMut = false;
}
if (!bCross && !bMut)
throw std::runtime_error("No operator called in SGA operator definition!!!");
// Create the CombinedMonOp
eoPropCombinedMonOp<EOT> *ptCombinedMonOp = NULL;
eoMonOp<EOT> *ptMon = NULL;
if (bMut)
{
// uniform mutation on all components:
// offspring(i) uniformly chosen in [parent(i)-epsilon, parent(i)+epsilon]
ptMon = new eoUniformMutation<EOT>(boundsParam.value(), epsilonParam.value());
_state.storeFunctor(ptMon);
// create the CombinedMonOp
ptCombinedMonOp = new eoPropCombinedMonOp<EOT>(*ptMon, uniformMutRateParam.value());
// mutate exactly 1 component (uniformly) per individual
ptMon = new eoDetUniformMutation<EOT>(boundsParam.value(), epsilonParam.value());
_state.storeFunctor(ptMon);
ptCombinedMonOp->add(*ptMon, detMutRateParam.value());
// mutate all component using Gaussian mutation
ptMon = new eoNormalVecMutation<EOT>(boundsParam.value(), sigmaParam.value(), pNormalParam.value());
_state.storeFunctor(ptMon);
ptCombinedMonOp->add(*ptMon, normalMutRateParam.value());
_state.storeFunctor(ptCombinedMonOp);
}
// now build the eoGenOp:
// to simulate SGA (crossover with proba pCross + mutation with proba pMut
// we must construct
// a sequential combination of
// with proba 1, a proportional combination of
// a QuadCopy and our crossover
// with proba pMut, our mutation
// the crossover - with probability pCross
eoProportionalOp<EOT> * cross = new eoProportionalOp<EOT> ;
_state.storeFunctor(cross);
ptQuad = new eoQuadCloneOp<EOT>;
_state.storeFunctor(ptQuad);
cross->add(*ptCombinedQuadOp, pCrossParam.value()); // user crossover
cross->add(*ptQuad, 1-pCrossParam.value()); // clone operator
// now the sequential
eoSequentialOp<EOT> & op = _state.storeFunctor(new eoSequentialOp<EOT>);
op.add(*cross, 1.0); // always crossover (but clone with prob 1-pCross
op.add(*ptCombinedMonOp, pMutParam.value());
// that's it!
return op;
}
/** @} */
#endif

View file

@ -0,0 +1,84 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// make_pop_es.cpp
// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifdef _MSC_VER
// to avoid long name warnings
#pragma warning(disable:4786)
#endif
/** This file contains ***INSTANCIATED DEFINITIONS*** of pop. init. fns
* of the library for evolution of ***ES genotypes*** indis inside EO.
* It should be included in the file that calls any of the corresponding fns
* Compiling this file allows one to generate part of the library (i.e. object
* files that you just need to link with your own main and fitness code).
*
* The corresponding ***INSTANCIATED DECLARATIONS*** are contained
* in src/es/es.h
* while the TEMPLATIZED code is define in make_pop.h in the src/do dir
*/
// The templatized code
#include <do/make_pop.h>
// the instanciating EOType(s)
#include <es/eoEsSimple.h> // one Sigma per individual
#include <es/eoEsStdev.h> // one sigmal per object variable
#include <es/eoEsFull.h> // full correlation matrix per indi
/// The following function merely call the templatized do_* functions above
// Init POP
///////////
eoPop<eoEsSimple<double> >& make_pop(eoParser& _parser, eoState& _state, eoInit<eoEsSimple<double> > & _init)
{
return do_make_pop(_parser, _state, _init);
}
eoPop<eoEsSimple<eoMinimizingFitness> >& make_pop(eoParser& _parser, eoState& _state, eoInit<eoEsSimple<eoMinimizingFitness> > & _init)
{
return do_make_pop(_parser, _state, _init);
}
///////////
eoPop<eoEsStdev<double> >& make_pop(eoParser& _parser, eoState& _state, eoInit<eoEsStdev<double> > & _init)
{
return do_make_pop(_parser, _state, _init);
}
eoPop<eoEsStdev<eoMinimizingFitness> >& make_pop(eoParser& _parser, eoState& _state, eoInit<eoEsStdev<eoMinimizingFitness> > & _init)
{
return do_make_pop(_parser, _state, _init);
}
///////////
eoPop<eoEsFull<double> >& make_pop(eoParser& _parser, eoState& _state, eoInit<eoEsFull<double> > & _init)
{
return do_make_pop(_parser, _state, _init);
}
eoPop<eoEsFull<eoMinimizingFitness> >& make_pop(eoParser& _parser, eoState& _state, eoInit<eoEsFull<eoMinimizingFitness> > & _init)
{
return do_make_pop(_parser, _state, _init);
}

View file

@ -0,0 +1,60 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// make_pop_real.cpp
// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifdef _MSC_VER
// to avoid long name warnings
#pragma warning(disable:4786)
#endif
/** This file contains ***INSTANCIATED DEFINITIONS*** of pop. init. fns
* of the library for evolution of ***eoReal*** indis inside EO.
* It should be included in the file that calls any of the corresponding fns
* Compiling this file allows one to generate part of the library (i.e. object
* files that you just need to link with your own main and fitness code).
*
* The corresponding ***INSTANCIATED DECLARATIONS*** are contained
* in src/es/real.h
* while the TEMPLATIZED code is define in make_pop.h in the src/do dir
*/
// The templatized code
#include <do/make_pop.h>
// the instanciating EOType
#include <es/eoReal.h>
/// The following function merely call the templatized do_* functions above
// Init POP
///////////
eoPop<eoReal<double> >& make_pop(eoParser& _parser, eoState& _state, eoInit<eoReal<double> > & _init)
{
return do_make_pop(_parser, _state, _init);
}
eoPop<eoReal<eoMinimizingFitness> >& make_pop(eoParser& _parser, eoState& _state, eoInit<eoReal<eoMinimizingFitness> > & _init)
{
return do_make_pop(_parser, _state, _init);
}

View file

@ -0,0 +1,107 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// real.h
// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk
*/
//-----------------------------------------------------------------------------
/** This file contains all ***INSTANCIATED*** declarations of all components
* of the library for ***std::vector<RealValues>*** evolution inside EO.
* It should be included in the file that calls any of the corresponding fns
*
* The corresponding ***INSTANCIATED*** definitions are contained in
* the different .cpp files in the src/es dir,
* while the TEMPLATIZED code is define in the different make_XXX.h files
* either in hte src/do dir for representation independant functions,
* or in the src/es dir for representation dependent stuff.
*
* See also es.h for the similar declarations of ES-like genotypes
* i.e. ***with*** mutation parameters attached to individuals
*
* Unlike most EO .h files, it does not (and should not) contain any code,
* just declarations
*/
#ifndef real_h
#define real_h
#include <eoAlgo.h>
#include <eoScalarFitness.h>
#include <utils/eoParser.h>
#include <eoEvalFuncPtr.h>
#include <eoEvalFuncCounter.h>
#include <utils/eoCheckPoint.h>
#include <eoGenOp.h>
#include <eoPop.h>
#include <utils/eoDistance.h>
#include <es/eoRealInitBounded.h>
#include <es/eoReal.h>
//Representation dependent - rewrite everything anew for each representation
//////////////////////////
/** @addtogroup Builders
* @{
*/
// the genotypes
eoRealInitBounded<eoReal<double> > & make_genotype(eoParser& _parser, eoState& _state, eoReal<double> _eo);
eoRealInitBounded<eoReal<eoMinimizingFitness> > & make_genotype(eoParser& _parser, eoState& _state, eoReal<eoMinimizingFitness> _eo);
// the operators
eoGenOp<eoReal<double> >& make_op(eoParser& _parser, eoState& _state, eoRealInitBounded<eoReal<double> >& _init);
eoGenOp<eoReal<eoMinimizingFitness> >& make_op(eoParser& _parser, eoState& _state, eoRealInitBounded<eoReal<eoMinimizingFitness> >& _init);
//Representation INdependent
////////////////////////////
// you don't need to modify that part even if you use your own representation
// init pop
eoPop<eoReal<double> >& make_pop(eoParser& _parser, eoState& _state, eoInit<eoReal<double> >&);
eoPop<eoReal<eoMinimizingFitness> >& make_pop(eoParser& _parser, eoState& _state, eoInit<eoReal<eoMinimizingFitness> >&);
// the continue's
eoContinue<eoReal<double> >& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoReal<double> > & _eval);
eoContinue<eoReal<eoMinimizingFitness> >& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoReal<eoMinimizingFitness> > & _eval);
// the checkpoint
eoCheckPoint<eoReal<double> >& make_checkpoint(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoReal<double> >& _eval, eoContinue<eoReal<double> >& _continue);
eoCheckPoint<eoReal<eoMinimizingFitness> >& make_checkpoint(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoReal<eoMinimizingFitness> >& _eval, eoContinue<eoReal<eoMinimizingFitness> >& _continue);
// the algo
eoAlgo<eoReal<double> >& make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc<eoReal<double> >& _eval, eoContinue<eoReal<double> >& _ccontinue, eoGenOp<eoReal<double> >& _op, eoDistance<eoReal<double> >* _dist = NULL);
eoAlgo<eoReal<eoMinimizingFitness> >& make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc<eoReal<eoMinimizingFitness> >& _eval, eoContinue<eoReal<eoMinimizingFitness> >& _ccontinue, eoGenOp<eoReal<eoMinimizingFitness> >& _op, eoDistance<eoReal<eoMinimizingFitness> >* _dist = NULL);
// run
void run_ea(eoAlgo<eoReal<double> >& _ga, eoPop<eoReal<double> >& _pop);
void run_ea(eoAlgo<eoReal<eoMinimizingFitness> >& _ga, eoPop<eoReal<eoMinimizingFitness> >& _pop);
// end of parameter input (+ .status + help)
// that one is not templatized
// Because of that, the source is in src/utils dir
void make_help(eoParser & _parser);
/** @} */
#endif

View file

@ -0,0 +1,86 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// make_run_es.cpp
// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifdef _MSC_VER
// to avoid long name warnings
#pragma warning(disable:4786)
#endif
/** This file contains ***INSTANCIATED DEFINITIONS*** of run funs
* of the library for evolution of ***ES genotypes*** inside EO.
* It should be included in the file that calls any of the corresponding fns
* Compiling this file allows one to generate part of the library (i.e. object
* files that you just need to link with your own main and fitness code).
*
* The corresponding ***INSTANCIATED DECLARATIONS*** are contained
* in src/es/es.h
* while the TEMPLATIZED code is define in make_run.h in the src/do dir
*/
// The templatized code
#include <do/make_run.h>
// the instanciating EOType(s)
#include <es/eoEsSimple.h> // one Sigma per individual
#include <es/eoEsStdev.h> // one sigmal per object variable
#include <es/eoEsFull.h> // full correlation matrix per indi
// the instanciating fitnesses
#include <eoScalarFitness.h>
/// The following function merely call the templatized do_* functions above
// run
/////////
void run_ea(eoAlgo<eoEsSimple<double> >& _ga, eoPop<eoEsSimple<double> >& _pop)
{
do_run(_ga, _pop);
}
void run_ea(eoAlgo<eoEsSimple<eoMinimizingFitness> >& _ga, eoPop<eoEsSimple<eoMinimizingFitness> >& _pop)
{
do_run(_ga, _pop);
}
/////////
void run_ea(eoAlgo<eoEsStdev<double> >& _ga, eoPop<eoEsStdev<double> >& _pop)
{
do_run(_ga, _pop);
}
void run_ea(eoAlgo<eoEsStdev<eoMinimizingFitness> >& _ga, eoPop<eoEsStdev<eoMinimizingFitness> >& _pop)
{
do_run(_ga, _pop);
}
/////////
void run_ea(eoAlgo<eoEsFull<double> >& _ga, eoPop<eoEsFull<double> >& _pop)
{
do_run(_ga, _pop);
}
void run_ea(eoAlgo<eoEsFull<eoMinimizingFitness> >& _ga, eoPop<eoEsFull<eoMinimizingFitness> >& _pop)
{
do_run(_ga, _pop);
}

View file

@ -0,0 +1,62 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// make_run_real.cpp
// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifdef _MSC_VER
// to avoid long name warnings
#pragma warning(disable:4786)
#endif
/** This file contains ***INSTANCIATED DEFINITIONS*** of run funs
* of the library for evolution of ***eoReal*** inside EO.
* It should be included in the file that calls any of the corresponding fns
* Compiling this file allows one to generate part of the library (i.e. object
* files that you just need to link with your own main and fitness code).
*
* The corresponding ***INSTANCIATED DECLARATIONS*** are contained
* in src/es/real.h
* while the TEMPLATIZED code is define in make_run.h in the src/do dir
*/
// The templatized code
#include <do/make_run.h>
// the instanciating EOType
#include <es/eoReal.h>
// the instanciating fitnesses
#include <eoScalarFitness.h>
/// The following function merely call the templatized do_* functions above
// run
/////////
void run_ea(eoAlgo<eoReal<double> >& _ga, eoPop<eoReal<double> >& _pop)
{
do_run(_ga, _pop);
}
void run_ea(eoAlgo<eoReal<eoMinimizingFitness> >& _ga, eoPop<eoReal<eoMinimizingFitness> >& _pop)
{
do_run(_ga, _pop);
}

View file

@ -0,0 +1,45 @@
#ifndef MATRICES_H
#define MATRICES_H
#include <vector>
/** @ingroup Utilities
*/
class lower_triangular_matrix {
unsigned n;
std::vector<double> data;
public:
lower_triangular_matrix(unsigned n_ = 0) : n(n_), data(n * (n+1) / 2) {};
void resize(unsigned n_) {
n = n_;
data.resize(n*(n+1)/2);
}
std::vector<double>::iterator operator[](unsigned i) { return data.begin() + i * (i+1) / 2; }
std::vector<double>::const_iterator operator[](unsigned i) const { return data.begin() + i*(i+1)/2; }
};
/** @ingroup Utilities
*/
class square_matrix {
unsigned n;
std::vector<double> data;
public:
square_matrix(unsigned n_ = 0) : n(n_), data(n * n) {};
void resize(unsigned n_) {
n = n_;
data.resize(n*n);
}
std::vector<double>::iterator operator[](unsigned i) { return data.begin() + i * n; }
std::vector<double>::const_iterator operator[](unsigned i) const { return data.begin() + i*n; }
};
#endif