Added the bounds to all eoRealOp operators (and to the eoNormalMutation).

The eoESObjectiveBounds should soon dissapear!!
This commit is contained in:
evomarc 2001-01-26 18:26:30 +00:00
commit c917207b5d
3 changed files with 426 additions and 113 deletions

View file

@ -30,11 +30,6 @@
/**
\defgroup EvolutionStrategies
Various classes for the initialization and mutation of real valued vectors.
Supports simple mutations and various more adaptable mutations, including
correlated mutations.
*/
@ -42,33 +37,113 @@
\class eoRealBounds eoRealBounds.h es/eoRealBounds.h
\ingroup EvolutionStrategies
Defines the minima and maxima for real variables
Defines bound classes for real numbers.
Scalar type:
------------
Basic class is eoRealBounds, a pure virtual.
The following pure virtual methods are to be used in mutations:
- void foldsInBounds(double &) that folds any value that falls out of
the bounds back into the bounds, by bouncing on the limit (if any)
- bool isInBounds(double &) that simply says whether or not the argument
is in the bounds
So mutation can choose whetehr they want to iterate trying until
they fall in bounds, or only try once and "repair" by using
the foldsInBounds method
There is also a uniform() method that generates a uniform value
(if possible, i.e. if bounded) in the interval.
Derived class are
eoRealInterval, that holds a minimum and maximum value
eoRealNoBounds, that implements the "unbounded bounds"
TODO: the eoRealMinBound and eoRealMaxBound that implement
the half-bounded intervals.
Vector type:
------------
Class eoRealVectorBounds implements the vectorized version:
it is basically a vector of eoRealBounds * and forwards all request
to the elements of the vector.
*/
class eoBaseRealBounds : public eoUF<double, bool>
{ };
class eoRealBounds
{
public:
virtual bool isBounded(void) = 0;
virtual bool isMinBounded(void) = 0;
virtual bool isMaxBounded(void) = 0;
virtual void foldsInBounds(double &) = 0;
virtual bool isInBounds(double) = 0;
class eoRealBounds : public eoBaseRealBounds
// accessors
virtual double minimum() = 0;
virtual double maximum() = 0;
virtual double range() = 0;
// random generators
virtual double uniform(eoRng & _rng = eo::rng) = 0;
};
class eoRealNoBounds : public eoRealBounds
{
public:
virtual ~eoRealNoBounds(){}
virtual bool isBounded(void) {return false;}
virtual bool isMinBounded(void) {return false;}
virtual bool isMaxBounded(void) {return false;}
virtual void foldsInBounds(double &) {return;}
virtual bool isInBounds(double) {return true;}
// accessors
virtual double minimum()
{
throw logic_error("Trying to get minimum of unbounded eoRealBounds");
}
virtual double maximum()
{
throw logic_error("Trying to get maximum of unbounded eoRealBounds");
}
virtual double range()
{
throw logic_error("Trying to get range of unbounded eoRealBounds");
}
// random generators
virtual double uniform(eoRng & _rng = eo::rng)
{
throw logic_error("Trying to generate uniform values in unbounded eoRealBounds");
}
};
/* fully bounded == interval */
class eoRealInterval : public eoRealBounds
{
public :
/**
Simple bounds = minimum and maximum (allowed)
*/
eoRealBounds(double _min=0, double _max=1) :
eoRealInterval(double _min=0, double _max=1) :
repMinimum(_min), repMaximum(_max), repRange(_max-_min)
{
if (repRange<=0)
throw std::logic_error("Void range in eoRealBounds");
}
double Minimum() { return repMinimum; }
double Maximum() { return repMaximum; }
double Range() { return repRange; }
// for backward compatibility
double minimum() { return repMinimum; }
double maximum() { return repMaximum; }
double range() { return repRange; }
// accessors
virtual double minimum() { return repMinimum; }
virtual double maximum() { return repMaximum; }
virtual double range() { return repRange; }
// description
virtual bool isBounded(void) {return true;}
virtual bool isMinBounded(void) {return true;}
virtual bool isMaxBounded(void) {return true;}
double uniform(eoRng & _rng = eo::rng)
{
@ -76,7 +151,7 @@ public :
}
// says if a given double is within the bounds
bool operator()(double _r)
virtual bool isInBounds(double _r)
{
if (_r < repMinimum)
return false;
@ -85,6 +160,35 @@ public :
return true;
}
// folds a value into bounds
void foldsInBounds(double & _r)
{
long iloc;
double dlargloc = 2 * range() ;
if (fabs(_r) > 1.0E9) // iloc too large!
{
_r = uniform();
return;
}
if ( (_r > maximum()) )
{
iloc = (long) ( (_r-minimum()) / dlargloc ) ;
_r -= dlargloc * iloc ;
if ( _r > maximum() )
_r = 2*maximum() - _r ;
}
if (_r < minimum())
{
iloc = (long) ( (maximum()-_r) / dlargloc ) ;
_r += dlargloc * iloc ;
if (_r < minimum())
_r = 2*minimum() - _r ;
}
}
private :
double repMinimum;
double repMaximum;
@ -94,16 +198,18 @@ private :
// now the vectorized version
class eoRealVectorBounds
{
public :
class eoRealVectorBounds : public vector<eoRealBounds *>
{
public:
// virtual desctructor (to avoid warining?)
virtual ~eoRealVectorBounds(){}
/**
Simple bounds = minimum and maximum (allowed)
*/
// Ctor: same bonds for everybody, explicit
eoRealVectorBounds(unsigned _dim, double _min=0, double _max=1) :
vecMinimum(_dim, _min), vecMaximum(_dim, _max), vecRange(_dim, _max-_min)
vector<eoRealBounds *>(_dim, new eoRealInterval(_min, _max))
{
if (_max-_min<=0)
throw std::logic_error("Void range in eoRealVectorBounds");
@ -111,114 +217,165 @@ public :
// Ctor: same bonds for everybody, given as a eoRealBounds
eoRealVectorBounds(unsigned _dim, eoRealBounds & _bounds) :
vecMinimum(_dim, _bounds.Minimum()),
vecMaximum(_dim, _bounds.Maximum()),
vecRange(_dim, _bounds.Range())
vector<eoRealBounds *>(_dim, &_bounds)
{}
// Ctor: different bonds for different variables, vectors of double
eoRealVectorBounds(vector<double> _min, vector<double> _max) :
vecMinimum(_min), vecMaximum(_max), vecRange(_min.size())
eoRealVectorBounds(vector<double> _min, vector<double> _max)
{
if (_max.size() != _min.size())
throw std::logic_error("Dimensions don't match in eoRealVectorBounds");
for (unsigned i=0; i<_min.size(); i++)
{
vecRange[i]=_max[i]-_min[i];
if (vecRange[i]<=0)
throw std::logic_error("Void range in eoRealVectorBounds");
push_back( new eoRealInterval(_min[i], _max[i]));
}
}
// Ctor, particular case of dim-2
eoRealVectorBounds(eoRealBounds & _xbounds, eoRealBounds & _ybounds) :
vecMinimum(2), vecMaximum(2), vecRange(2)
vector<eoRealBounds *>(0)
{
vecMinimum[0] = _xbounds.Minimum();
vecMaximum[0] = _xbounds.Maximum();
vecRange[0] = _xbounds.Range();
vecMinimum[1] = _ybounds.Minimum();
vecMaximum[1] = _ybounds.Maximum();
vecRange[1] = _ybounds.Range();
push_back( &_xbounds);
push_back( &_ybounds);
}
// not a ctor, but usefull to initialize, too
// is it safe to call it push_back? Maybe not, but it's meaningful!
void push_back(double _min=0, double _max=1)
virtual bool isBounded(unsigned _i)
{
return (*this)[_i]->isBounded();
}
// bounded iff all are bounded
virtual bool isBounded(void)
{
vecMinimum.push_back(_min);
vecMaximum.push_back(_max);
if (_max-_min <= 0)
throw std::logic_error("Void range in eoRealVectorBounds::add");
vecRange.push_back(_max-_min);
for (unsigned i=0; i<size(); i++)
if (! (*this)[i]->isBounded())
return false;
return true;
}
void push_back(eoRealBounds & _bounds)
// these do not make any sense as vectors!
virtual bool isMinBounded(unsigned _i)
{ return (*this)[_i]->isMinBounded();} ;
virtual bool isMaxBounded(unsigned _i)
{ return (*this)[_i]->isMaxBounded();} ;
virtual void foldsInBounds(unsigned _i, double & _r)
{
vecMinimum.push_back(_bounds.Minimum());
vecMaximum.push_back(_bounds.Maximum());
vecRange.push_back(_bounds.Range());
(*this)[_i]->foldsInBounds(_r);
}
// accessors - following rule that says that method start are capitalized
double Minimum(unsigned _i) { return vecMinimum[_i]; }
double Maximum(unsigned _i) { return vecMaximum[_i]; }
double Range(unsigned _i) { return vecRange[_i]; }
// accessors - for backward compatibility
double minimum(unsigned _i) { return vecMinimum[_i]; }
double maximum(unsigned _i) { return vecMaximum[_i]; }
double range(unsigned _i) { return vecRange[_i]; }
// handy: get the size
unsigned int size() { return vecMinimum.size();}
// returns a value uniformly chosen in bounds for a given variable
double uniform(unsigned _i, eoRng & _rng = eo::rng)
virtual void foldsInBounds(vector<double> & _v)
{
return vecMinimum[_i] + _rng.uniform(vecRange[_i]);
}
for (unsigned i=0; i<size(); i++)
{
foldsInBounds(i, _v[i]);
}
}
// returns a vector of uniformly chosen variables in bounds
vector<double> uniform(eoRng & _rng = eo::rng)
virtual bool isInBounds(unsigned _i, double _r)
{ return (*this)[_i]->isInBounds(_r); }
// isInBounds iff all are in bouds
virtual bool isInBounds(vector<double> _v)
{
vector<double> v(vecMinimum.size());
for (unsigned i=0; i<vecMinimum.size(); i++)
v[i] = vecMinimum[i] + _rng.uniform(vecRange[i]);
for (unsigned i=0; i<size(); i++)
if (! isInBounds(i, _v[i]))
return false;
return true;
}
return v;
}
// accessors
virtual double minimum(unsigned _i) {return (*this)[_i]->minimum();}
virtual double maximum(unsigned _i) {return (*this)[_i]->maximum();}
virtual double range(unsigned _i) {return (*this)[_i]->range();}
virtual double averageRange()
{
double r=0.0;
for (unsigned i=0; i<size(); i++)
r += range(i);
return r/size();
}
// random generators
virtual double uniform(unsigned _i, eoRng & _rng = eo::rng)
{
double r= (*this)[_i]->uniform();
return r;
}
// fills a vector with uniformly chosen variables in bounds
void uniform(vector<double> & _v, eoRng & _rng = eo::rng)
{
_v.resize(vecMinimum.size());
for (unsigned i=0; i<vecMinimum.size(); i++)
_v[i] = vecMinimum[i] + _rng.uniform(vecRange[i]);
_v.resize(size());
for (unsigned i=0; i<size(); i++)
{
_v[i] = uniform(i, _rng);
}
}
// says if a given double is within the bounds
bool operator()(unsigned _i, double _r)
{
if (_r < vecMinimum[_i])
return false;
if (_r > vecMaximum[_i])
return false;
return true;
}
// check the bounds for a vector: true only if ALL ar ein bounds
bool operator()(vector<double> & _v)
{
for (unsigned i=0; i<_v.size(); i++)
if (! operator()(i, _v[i]) ) // out of bound
return false;
return true;
}
private :
vector<double> vecMinimum;
vector<double> vecMaximum;
vector<double> vecRange; // to minimize operations ???
};
// the dummy unbounded eoRealVectorBounds:
class eoRealVectorNoBounds: public eoRealVectorBounds
{
public:
// virtual desctructor (to avoid warining?)
virtual ~eoRealVectorNoBounds(){}
/**
Simple bounds = minimum and maximum (allowed)
*/
// Ctor: nothing to do!
eoRealVectorNoBounds(unsigned _dim=0) : eoRealVectorBounds(_dim) {}
virtual bool isBounded(unsigned) {return false;}
virtual bool isBounded(void) {return false;}
virtual bool isMinBounded(unsigned) {return false;}
virtual bool isMaxBounded(unsigned) {return false;}
virtual void foldsInBounds(unsigned, double &) {return;}
virtual void foldsInBounds(vector<double> &) {return;}
virtual bool isInBounds(unsigned, double) {return true;}
virtual bool isInBounds(vector<double>) {return true;}
// accessors
virtual double minimum(unsigned)
{
throw logic_error("Trying to get minimum of unbounded eoRealBounds");
}
virtual double maximum(unsigned)
{
throw logic_error("Trying to get maximum of unbounded eoRealBounds");
}
virtual double range(unsigned)
{
throw logic_error("Trying to get range of unbounded eoRealBounds");
}
virtual double averageRange()
{
throw logic_error("Trying to get average range of unbounded eoRealBounds");
}
// random generators
virtual double uniform(unsigned, eoRng & _rng = eo::rng)
{
throw logic_error("No uniform distribution on unbounded eoRealBounds");
}
// fills a vector with uniformly chosen variables in bounds
void uniform(vector<double> &, eoRng & _rng = eo::rng)
{
throw logic_error("No uniform distribution on unbounded eoRealBounds");
}
};
// one object for all
eoRealNoBounds eoDummyRealNoBounds;
eoRealVectorNoBounds eoDummyVectorNoBounds;
#endif