1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
// ConfigFile.cpp
#include "ConfigFile.h"
using std::string;
26 ConfigFile::ConfigFile( string filename, string delimiter,
27 string comment, string sentry )
: myDelimiter( delimiter ), myComment( comment ), mySentry( sentry )
{
// Construct a ConfigFile, getting keys and values from given file
printf( "Voy a usar ifstream" );
std::ifstream in( filename.c_str( ) );
printf( "usado ifstream" );
if( !in ) {
printf( "Fichero no encontrado\n" );
throw file_not_found( filename );
}
printf( "Sigo leyendo fichero\n" );
in >> ( *this );
printf( "Fichero leido\n" );
}
46 ConfigFile::ConfigFile( )
: myDelimiter( string( 1, '=' ) ), myComment( string( 1, '#' ) )
{
// Construct a ConfigFile without a file; empty
}
53 void ConfigFile::remove( const string& key )
{
// Remove key and its value
myContents.erase( myContents.find( key ) );
return;
}
61 bool ConfigFile::keyExists( const string& key ) const
{
// Indicate whether key is found
mapci p = myContents.find( key );
return ( p != myContents.end( ) );
}
/* static */
70 void ConfigFile::trim( string& s )
{
// Remove leading and trailing whitespace
static const char whitespace[] = " \n\t\v\r\f";
s.erase( 0, s.find_first_not_of( whitespace ) );
s.erase( s.find_last_not_of( whitespace ) + 1U );
}
79 std::ostream& operator<<( std::ostream& os, const ConfigFile& cf )
{
// Save a ConfigFile to os
for( ConfigFile::mapci p = cf.myContents.begin( );
p != cf.myContents.end( );
++p )
{
os << p->first << " " << cf.myDelimiter << " ";
os << p->second << std::endl;
}
return os;
}
93 std::istream& operator>>( std::istream& is, ConfigFile& cf )
{
// Load a ConfigFile from is
// Read in keys and values, keeping internal whitespace
typedef string::size_type pos;
const string& delim = cf.myDelimiter; // separator
const string& comm = cf.myComment; // comment
const string& sentry = cf.mySentry; // end of file sentry
const pos skip = delim.length( ); // length of separator
string nextline = ""; // might need to read ahead to see where value ends
while( is || nextline.length( ) > 0 )
{
// Read an entire line at a time
string line;
if( nextline.length( ) > 0 )
{
line = nextline; // we read ahead; use it now
nextline = "";
}
else
{
std::getline( is, line );
}
// Ignore comments
line = line.substr( 0, line.find( comm ) );
// Check for end of file sentry
if( sentry != "" && line.find( sentry ) != string::npos ) return is;
// Parse the line if it contains a delimiter
pos delimPos = line.find( delim );
if( delimPos < string::npos )
{
// Extract the key
string key = line.substr( 0, delimPos );
line.replace( 0, delimPos+skip, "" );
// See if value continues on the next line
// Stop at blank line, next line with a key, end of stream,
// or end of file sentry
bool terminate = false;
while( !terminate && is )
{
std::getline( is, nextline );
terminate = true;
string nlcopy = nextline;
ConfigFile::trim( nlcopy );
if( nlcopy == "" ) continue;
nextline = nextline.substr( 0, nextline.find( comm ) );
if( nextline.find( delim ) != string::npos )
continue;
if( sentry != "" && nextline.find( sentry ) != string::npos )
continue;
nlcopy = nextline;
ConfigFile::trim( nlcopy );
if( nlcopy != "" ) line += "\n";
line += nextline;
terminate = false;
}
// Store key and value
ConfigFile::trim( key );
ConfigFile::trim( line );
cf.myContents[key] = line; // overwrites if key is repeated
}
}
return is;
}
/**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
// ConfigFile.h
// Class for reading named values from configuration files
// Richard J. Wagner v2.1 24 May 2004 wagnerr@umich.edu
// Copyright ( c ) 2004 Richard J. Wagner
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files ( the "Software" ), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
// Typical usage
// -------------
//
// Given a configuration file "settings.inp":
// atoms = 25
// length = 8.0 # nanometers
// name = Reece Surcher
//
// Named values are read in various ways, with or without default values:
// ConfigFile config( "settings.inp" );
// int atoms = config.read<int>( "atoms" );
// double length = config.read( "length", 10.0 );
// string author, title;
// config.readInto( author, "name" );
// config.readInto( title, "title", string( "Untitled" ) );
//
// See file example.cpp for more examples.
//
// Modified file_not_found and key_not_found, now they are
// compatibles with std::exception
//
// Cambiado trim para que sea público
#ifndef CONFIGFILE_H
#define CONFIGFILE_H
#include <string>
#include <map>
#include <iostream>
#include <fstream>
#include <sstream>
#include <exception>
using std::string;
79 class ConfigFile {
// Data
protected:
82 string myDelimiter; // separator between key and value
83 string myComment; // separator between value and comments
84 string mySentry; // optional string to signal end of file
85 std::map<string, string> myContents; // extracted keys and values
typedef std::map<string, string>::iterator mapi;
typedef std::map<string, string>::const_iterator mapci;
// Methods
public:
92 ConfigFile( string filename,
93 string delimiter = "=",
94 string comment = "#",
95 string sentry = "EndConfigFile" );
96 ConfigFile( );
// Search for key and read value or optional default value
template<class T> T read( const string& key ) const; // call as read<T>
template<class T> T read( const string& key, const T& value ) const;
template<class T> bool readInto( T& var, const string& key ) const;
template<class T>
bool readInto( T& var, const string& key, const T& value ) const;
// Modify keys and values
template<class T> void add( string key, const T& value );
void remove( const string& key );
// Check whether key exists in configuration
bool keyExists( const string& key ) const;
// Check or change configuration syntax
string getDelimiter( ) const { return myDelimiter; }
114 string getComment( ) const { return myComment; }
115 string getSentry( ) const { return mySentry; }
116 string setDelimiter( const string& s )
{ string old = myDelimiter; myDelimiter = s; return old; }
118 string setComment( const string& s )
{ string old = myComment; myComment = s; return old; }
// Write or read configuration
friend std::ostream& operator<<( std::ostream& os, const ConfigFile& cf );
friend std::istream& operator>>( std::istream& is, ConfigFile& cf );
protected:
template<class T> static string T_as_string( const T& t );
template<class T> static T string_as_T( const string& s );
public:
static void trim( string& s );
// Exception types
public:
/**
* @class file_not_found
*
* Esta clase permite indicar que el fichero indicado no existe
*/
struct file_not_found : public std::exception{
string filename;
file_not_found( const string& filename_ = string( ) )
: filename( filename_ ) {}
virtual const char* what( ) const throw( ) {
string output = "Error: file '" +filename +"' not found";
return output.c_str( );
}
virtual ~file_not_found( ) throw( ) {}
};
struct key_not_found : public std::exception{ // thrown only by T read( key ) variant of read( )
string key;
key_not_found( const string& key_ = string( ) )
: key( key_ ) {}
virtual const char* what( ) const throw ( ) {
string output = "The key '" +key +"' not found";
return output.c_str( );
}
virtual ~key_not_found( ) throw( ){}
};
};
/* static */
template<class T>
string ConfigFile::T_as_string( const T& t )
{
// Convert from a T to a string
// Type T must support << operator
std::ostringstream ost;
ost << t;
return ost.str( );
}
/* static */
template<class T>
T ConfigFile::string_as_T( const string& s )
{
// Convert from a string to a T
// Type T must support >> operator
T t;
std::istringstream ist( s );
ist >> t;
return t;
}
/* static */
template<>
inline string ConfigFile::string_as_T<string>( const string& s )
{
// Convert from a string to a string
// In other words, do nothing
return s;
}
/* static */
template<>
inline bool ConfigFile::string_as_T<bool>( const string& s )
{
// Convert from a string to a bool
// Interpret "false", "F", "no", "n", "0" as false
// Interpret "true", "T", "yes", "y", "1", "-1", or anything else as true
bool b = true;
string sup = s;
for( string::iterator p = sup.begin( ); p != sup.end( ); ++p )
*p = toupper( *p ); // make string all caps
if( sup==string( "FALSE" ) || sup==string( "F" ) ||
sup==string( "NO" ) || sup==string( "N" ) ||
sup==string( "0" ) || sup==string( "NONE" ) )
b = false;
return b;
}
template<class T>
T ConfigFile::read( const string& key ) const
{
// Read the value corresponding to key
mapci p = myContents.find( key );
if( p == myContents.end( ) ) throw key_not_found( key );
return string_as_T<T>( p->second );
}
template<class T>
T ConfigFile::read( const string& key, const T& value ) const
{
// Return the value corresponding to key or given default value
// if key is not found
mapci p = myContents.find( key );
if( p == myContents.end( ) ) return value;
return string_as_T<T>( p->second );
}
template<class T>
bool ConfigFile::readInto( T& var, const string& key ) const
{
// Get the value corresponding to key and store in var
// Return true if key is found
// Otherwise leave var untouched
mapci p = myContents.find( key );
bool found = ( p != myContents.end( ) );
if( found ) var = string_as_T<T>( p->second );
return found;
}
template<class T>
bool ConfigFile::readInto( T& var, const string& key, const T& value ) const
{
// Get the value corresponding to key and store in var
// Return true if key is found
// Otherwise set var to given default
mapci p = myContents.find( key );
bool found = ( p != myContents.end( ) );
if( found )
var = string_as_T<T>( p->second );
else
var = value;
return found;
}
template<class T>
void ConfigFile::add( string key, const T& value )
{
// Add a key with given value
string v = T_as_string( value );
trim( key );
trim( v );
myContents[key] = v;
return;
}
#endif // CONFIGFILE_H
// Release notes:
// v1.0 21 May 1999
// + First release
// + Template read( ) access only through non-member readConfigFile( )
// + ConfigurationFileBool is only built-in helper class
//
// v2.0 3 May 2002
// + Shortened name from ConfigurationFile to ConfigFile
// + Implemented template member functions
// + Changed default comment separator from % to #
// + Enabled reading of multiple-line values
//
// v2.1 24 May 2004
// + Made template specializations inline to avoid compiler-dependent linkage
// + Allowed comments within multiple-line values
// + Enabled blank line termination for multiple-line values
// + Added optional sentry to detect end of configuration file
// + Rewrote messy trimWhitespace( ) function as elegant trim( )
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <exception>
23 extern Config *getConfig( void );
25 string Config::extractType( void ) {
string defaultvalue;
if ( !fileconfig.readInto( defaultvalue, m_strategy+".default" ) )
defaultvalue = "";
return defaultvalue;
}
34 string Config::extractName( void ) {
string begin = m_strategy +"." +m_type;
string name;
cerr <<"extractName" <<endl;
if ( m_type == "" ) {
return "";
}
cerr <<"extractname con '" <<begin <<"' y name '" <<name <<"'" <<endl;
// Comprueba que exista "<typestrategy>.<type>.id = <name>
if ( !fileconfig.readInto( name, begin +".id" ) )
name = m_type;
cerr <<"name vale '" <<name <<"'" <<endl;
cerr <<"finalizado extractName" <<endl;
return name;
}
/**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CONFIG
#define _CONFIG 1
#include "ConfigFile.h"
#include <string>
#include <iostream>
using namespace std;
/**
*
* @class Config
*
* Esta clase permite leer un fichero de configucación de la aplicación.
*
* El modelo que admite es el siguiente:
*
* En un fichero de configuración se especifique los distintos
* parámetros para cada uno de las estrategias del AG.
*
* Se considera estrategia a cada uno de los métodos de cruce,
* de selección o de reemplazo a aplicar.
*
* Se considera <type> de una estrategia no sólo a un tipo de estrategia
* ( como oeprador de cruce BLX o alpha ) sino también al conjunto de parámetros.
*
* La idea es poder asociar el mismo identificador de estrategia con distintos
* conjuntos de parámetros, cada uno identificado con un nombre distintivo.
*
* De esa forma, simplemente indicando el tipo de la estrategia a aplicar
* se seleccionaría el total de parámetros.
*
* formato:
* <typeestrategia>.<type>.id = <name>
*
* Para asociar a este <type> los distintos parámetros la sintaxis es la
* siguiente ( se supone que el objeto factory asociado identificará
* la distinta ).
*
* <typeestrategia>.<type>.<param1> = <value1>
* <typeestrategia>.<type>.<param2> = <value2>
*
* o bien mediante un fichero externo
* <typeestrategia>.<type>.params = <filename>
*
* <filename> en este caso contendría la sintaxis
* <param1> = <value1>
* <param2> = <value2>
* .
* .
* .
*
* Se puede especificar parámetros comunes a los distintos tipos asociados
* a una estrategia con la sintaxis.
* <typeestrategia>.<name>.<param1> = <value1>
*
* Dado que la idea de esta sintaxis es especificar parámetros comunes
* tendrá preferencia la sintaxis <typeestrategia>.<type>.<paran> sobre
* ésta.
*
* La elección de la estrategia ( el identificador <type> )
* a aplicar se puede especificar mediante paso de parámetros
* o bien mediante un valor default:
*
* <typeestrategia>.<default> = <type>
*
*/
89 class Config {
private:
typedef ConfigFile::key_not_found key_not_found;
92 ConfigFile fileconfig;
93 string m_strategy;
94 string m_type;
95 string m_name;
private:
/**
* Permite obtener el valor por defecto si existe
*
* @return el tipo asociado
*/
103 string extractType( void );
/**
* Permite obtener el nombre de la estrategia elegida.
* Si no existe lanza una excepción ( type_not_valide )
*
* @return El nombre de la estrategia elegia ( '' si todavía
* no existe ninguna elegida ).
*/
112 string extractName( void );
public:
/**
* @class config_error
*
* Esta clase es lanzada cuando se produce un error en la lectura del fichero
* de configuración
*/
struct config_error : public std::exception{
string m_msg;
string m_strategy;
config_error( const string& strategy, const string& msg )
: m_msg( msg ), m_strategy( strategy ) {}
virtual const char* what( ) const throw( ) {
string output = "Config Error: " +m_msg;
return output.c_str( );
}
virtual ~config_error( ) throw( ) {}
};
public:
/**
* Constructor.
* @param strategy
* @param name Nombre del fichero
*/
Config( string strategy, string name ) : fileconfig( name ) {
m_strategy = strategy;
m_type = extractType( );
m_name = extractName( );
}
/**
* Constructor
* @param config Fichero de configuración
*/
Config( string strategy, ConfigFile &config ) : fileconfig( config ) {
printf( "Creando fileconfig" );
m_strategy = strategy;
m_type = extractType( );
m_name = extractName( );
}
Config( string strategy, Config *config ) : fileconfig( config->fileconfig ) {
m_strategy = strategy;
m_type = extractType( );
m_name = extractName( );
}
/**
* Devuelve el nombre de la estrategia elegida
*/
string getName( ) {
if ( m_name != "" ) {
return m_name;
}
else {
return m_type;
}
}
/**
* Devuelve el nombre del grupo elegido de la estrategia
*/
string getType( ) {
return m_type;
}
/**
* Especifico el tipo
*/
void setType( string name ) {
cerr <<"setType : '" <<name <<"'" <<endl;
if ( name != "" ) {
m_type = name;
m_name = extractName( );
cerr <<"Hecho asignacion de extractName" <<endl;
}
cerr <<"Realizado setType : '" <<name <<"'" <<endl;
}
/**
* Especifico el identificador
*/
void setName( string name ) {
if ( name != "" ) {
m_name = name;
}
}
/**
* Obtengo el parámetro asociado
*
* @param param el nombre del parámetro
* @return Valor en forma de cadena
*/
template <class T>
void getParam( const char *param, T &value ) {
string begin = m_strategy +".";
string last = ".";
last += param;
string key = begin +m_type +last;
string key_name_default = begin +m_name +last;
string key_type_default = begin + param;
if ( fileconfig.readInto( value, key ) ) {
}
else if ( fileconfig.readInto( value, key_name_default ) ) {
}
else if ( fileconfig.readInto( value, key_type_default ) ) {
}
else {
throw ConfigFile::key_not_found( key_type_default );
}
}
template <class T>
void getParam( const string ¶m, T &value ) {
getParam( param.c_str( ), value );
}
};
typedef Config* ConfigPtr;
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include "cross.h"
#include "problem.h"
#include "random.h"
#include <cassert>
#include <cmath>
using namespace realea;
using namespace realea::internal;
29 void CrossBinary::operator( )( tIndividualReal *mom, tIndividualReal *dad, tChromosomeReal &child ) {
mom->incremCount( "cross" );
dad->incremCount( "cross" );
operator( )( mom->sol( ), mom->perf( ), dad->sol( ), dad->perf( ), child );
}
35 void CrossBinary::operator( )( const tChromosomeReal &mom, tFitness fit_mom, const tChromosomeReal &dad, tFitness fit_dad, tChromosomeReal &children ) {
( *m_cross )( mom, fit_mom, dad, fit_dad, children );
}
39 CrossBinary::CrossBinary( ICrossBinaryPtr cross ) : m_cross( cross ) {
}
42 CrossBinary::~CrossBinary( void ) {
delete m_cross;
}
47 CrossBLX::CrossBLX( double alpha ) : m_alpha( alpha ) {
assert( alpha > 0 );
}
51 CrossBLX::~CrossBLX( void ) {
}
56 void CrossBLX::operator( )( const tChromosomeReal &mom, tFitness fit_mom, const tChromosomeReal &dad, tFitness fit_dad, tChromosomeReal &children ) {
double puntox, puntoy, I, A1, B1;
double rate;
unsigned i, size = dad.size( );
tGen min, max;
assert( dad.size( ) == mom.size( ) );
// First copy all gen from mother
copy( mom.begin( ), mom.end( ), children.begin( ) );
if ( fit_mom == fit_dad ) {
rate = 0.5;
}
else {
rate = fit_dad/( fit_mom+fit_dad );
}
rate = 0.5;
/* REALIZAR EL CRUCE PARA Pm*Tp */
for ( i=0; i< size; i++ )
{
if ( !m_domain->canBeChanged( i ) ) {
if ( m_random->rand( ) <= rate ) {
children[i] = mom[i];
}
else {
children[i] = dad[i];
}
}
m_domain->getValues( i, &min, &max );
puntox=mom[i]; puntoy=dad[i];
if ( puntox > puntoy ) {
swap( puntox, puntoy );
}
I=( puntoy-puntox )*m_alpha;
assert( I >= 0 );
A1 = puntox-I;
if ( A1 < min )
A1 = min;
B1 = puntoy+I;
if ( B1 > max ) {
B1 = max;
}
children[i]=A1 + m_random->rand( )*( B1-A1 );
}
}
113 CrossPBLX::CrossPBLX( double alpha ) : m_alpha( alpha ) {
}
116 CrossPBLX::~CrossPBLX( void ) {
}
/**
* Get the gene numbers to cross.
*
* It grows lineally when current is increased, it starts from 0 when current == 0 to dim when current==maxtotal
*
* @param current current ratio of evaluations.
* @param mintotal min ratio when it crosses all genes
* @param dim gene dimension
*
* @return gene numbers to cross
*/
130 unsigned getNGen( double ratiocurrent, double mintotal, unsigned dim ) {
if ( ratiocurrent >= mintotal ) {
return dim;
}
else {
return ( int )ceil( dim*( ratiocurrent/mintotal ) );
}
}
140 void CrossPBLX::operator( )( const tChromosomeReal &mom, tFitness fit_mom, const tChromosomeReal &dad, tFitness fit_dad, tChromosomeReal &children ) {
double puntox, puntoy, I, A1, B1;
unsigned i, dim = dad.size( );
tGen min, max;
assert( dad.size( ) == mom.size( ) );
// Obtain the gene numbers to cross
unsigned dim_ini = ( unsigned ) ceil( m_dim_ini*dim );
unsigned dim_fin = ( unsigned ) ceil( m_dim_fin*dim );
assert( dim_ini < dim_fin );
// First copy all gen from mother
copy( mom.begin( ), mom.end( ), children.begin( ) );
// Change the gene
for ( i=dim_ini; i< dim_fin; i++ )
{
if ( !m_domain->canBeChanged( i ) ) {
continue;
}
m_domain->getValues( i, &min, &max );
puntox=mom[i]; puntoy=dad[i];
I=fabs( puntoy-puntox )*m_alpha;
A1 = mom[i]-I;
if ( A1 < min )
A1 = min;
B1 = mom[i]+I;
if ( B1 > max ) {
B1 = max;
}
children[i]=A1 + m_random->rand( )*( B1-A1 );
}
}
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CROSS_H
#define _CROSS_H 1
#include "domain.h"
#include "individual.h"
#include "random.h"
#include "signal.h"
#include "icross.h"
namespace realea {
/**
* @class CrossBLX
*
* This class implements the Crossover operator BLX-\alpha
*
*/
38 class CrossBLX : public ICrossBinary {
public:
/**
* Constructor.
*
* @param alpha alpha value, its value sets the diversity. 0 => No diversity, 0.3 => Maintain diversity, 0.5-1 => Grow the diversity
*/
45 CrossBLX( double alpha );
/**
* Destructor
*/
50 virtual ~CrossBLX( void );
52 void reset( void ) {}
/**
* Create the operator
*/
56 virtual void operator( )( const tChromosomeReal &mom, tFitness fit_mom, const tChromosomeReal &dad, tFitness fit_dad, tChromosomeReal &child );
private:
double m_alpha;
};
/**
* @class CrossPLX
*
* This class implements the Crossover operator PBLX-\alpha. It is like
* BLX but using the first parent ( mother ) as the center
* of the search.
* Also, it can be indicated the range of variable to be considered
*/
71 class CrossPBLX : public ICrossBinary {
public:
/**
* Constructor.
*
* @param alpha alpha value, its value sets the diversity. 0 => No diversity, 0.3 => Maintain diversity, 0.5-1 => Grow the diversity
*
*/
79 CrossPBLX( double alpha );
/**
* Destructor
*/
84 virtual ~CrossPBLX( void );
86 void reset( void ) {}
/**
* Create the operator
*/
90 virtual void operator( )( const tChromosomeReal &mom, tFitness fit_mom, const tChromosomeReal &dad, tFitness fit_dad, tChromosomeReal &child );
private:
double m_alpha;
double m_dim_ini;
double m_dim_fin;
};
namespace internal {
/**
* @class CrossBinary
*
* This class contain the real class that make the crossover, using a ICrossBinary that defines the operation
*/
105 class CrossBinary : public IReset {
public:
107 CrossBinary( ICrossBinaryPtr cross );
108 void operator( )( tIndividualReal *mom, tIndividualReal *dad, tChromosomeReal &child );
109 virtual void operator( )( const tChromosomeReal &mom, tFitness fit_mom, const tChromosomeReal &dad, tFitness fit_dad, tChromosomeReal &child );
110 virtual ~CrossBinary( void );
private:
112 ICrossBinaryPtr m_cross;
};
typedef CrossBinary* CrossBinaryPtr;
}
}
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _DEFINE_H
#define _DEFINE_H 1
/// @defgroup realea_common Real Evolutionary Algorithms Common ( Core classes )
#include <iostream>
#include "real.h"
namespace realea {
32 class IEval {
public:
34 virtual tFitness eval( const tChromosomeReal &sol )=0;
35 virtual ~IEval( void ) {}
};
38 class IFinish {
public:
40 virtual bool isFinish( void )=0;
41 virtual ~IFinish( void ) {}
};
}
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include "distance.h"
#include <cmath>
#include <cassert>
using namespace realea;
//double distance( tGen *x, tGen *y, unsigned size ) {
// double dist = 0;
//
// for ( i = 0; i < size; i++ ) {
// dist += ( x[i]*y[i] )*( x[i]*y[i] );
// }
//
// return sqrt( dist );
//}
36 double distreal( const tChromosomeReal &x, const tChromosomeReal &y, bool *checkGen ) {
double dist = 0;
unsigned size = x.size( );
assert( x.size( ) == y.size( ) );
for ( unsigned i = 0; i < size; i++ ) {
if ( checkGen == NULL || checkGen[i] ) {
dist += ( x[i]-y[i] )*( x[i]-y[i] );
}
}
return sqrt( dist )/size;
}
50 double distanceMin( const tChromosomeReal &x, PopulationReal *pop, unsigned *posmin ) {
tIndividualRealPtr ind;
double dist, lowest;
unsigned i;
if ( pop->size( ) == 0 ) {
throw new string( "dist:Error, popsize is zero" );
}
*posmin = 0;
lowest = 0;
for ( i = 0; i < pop->size( ); i++ ) {
ind = pop->getInd( i );
dist = distreal( x, ind->sol( ) );
if ( dist > 0 && ( lowest == 0 || dist < lowest ) ) {
*posmin = i;
lowest = dist;
}
}
return lowest;
}
75 double distanceMax( const tChromosomeReal &x, PopulationReal *pop, unsigned *posmin ) {
tIndividualRealPtr ind;
double dist, greatest;
unsigned i;
if ( pop->size( ) == 0 ) {
throw new string( "dist:Error, popsize is zero" );
}
ind = pop->getInd( 0 );
greatest = distreal( x, ind->sol( ) );
for ( i = 0; i < pop->size( ); i++ ) {
ind = pop->getInd( i );
dist = distreal( x, ind->sol( ) );
if ( dist > greatest ) {
*posmin = i;
greatest = dist;
}
}
return greatest;
}
101 void vector_distance( const tChromosomeReal &x, const tChromosomeReal &y, vector<tGen> &mindist ) {
unsigned size = x.size( );
assert( x.size( ) == y.size( ) );
for ( unsigned i = 0; i < size; i++ ) {
mindist[i] = fabs( x[i]-y[i] );
}
}
111 void min_vector_distance( const tChromosomeReal &x, const tChromosomeReal &y, vector<tGen> &mindist ) {
double dist = 0;
unsigned size = x.size( );
assert( x.size( ) == y.size( ) );
for ( unsigned i = 0; i < size; i++ ) {
dist = fabs( x[i]-y[i] );
if ( dist < mindist[i] && dist > 0 ) {
mindist[i] = dist;
}
}
}
127 unsigned getNeigh( const tChromosomeReal &x, PopulationReal *pop, double min ) {
double dist, distMin;
unsigned posmin, i, size;
distMin = -1;
size = pop->size( );
for ( int i = 0; i < size; i++ ) {
dist = distreal( x, pop->getInd( i )->sol( ) );
if ( dist > min && ( distMin < 0 || dist < distMin ) ) {
posmin = i;
distMin = dist;
}
}
assert( distMin > 0 );
return posmin;
}
147 void min_vector_distance( const tChromosomeReal &x, PopulationReal *pop, vector<tGen> &mindist ) {
tIndividualRealPtr ind;
vector<double> distMin( x.size( ) );
unsigned i, initial;
if ( pop->size( ) == 0 ) {
throw new string( "dist:Error, popsize is zero" );
}
initial = 0;
ind = pop->getInd( initial );
if ( ind->sol( ) != x ) {
initial += 1;
ind = pop->getInd( initial );
}
vector_distance( x, ind->sol( ), mindist );
for ( i = initial+1; i < pop->size( ); i++ ) {
ind = pop->getInd( i );
min_vector_distance( x, ind->sol( ), mindist );
}
}
173 void min_dim_distance( const tChromosomeReal &sol, PopulationReal *pop, vector<unsigned> &minind ) {
tChromosomeReal sol_ind;
unsigned i, dim;
unsigned ndim=sol.size( );
double dist;
vector<double> mindist( ndim );
assert( minind.size( )==ndim );
fill( mindist.begin( ), mindist.end( ), 0 );
if ( pop->size( ) == 0 ) {
throw new string( "dist:Error, popsize is zero" );
}
for ( i = 0; i < pop->size( ); i++ ) {
sol_ind = pop->getInd( i )->sol( );
for ( dim = 0; dim < ndim; ++dim ) {
dist = fabs( sol_ind[dim]-sol[dim] );
if ( mindist[dim] == 0 || ( dist > 0 && ( dist < mindist[dim] ) ) ) {
mindist[dim] = dist;
minind[dim] = i;
}
}
}
}
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _UTIL_H
#define _UTIL_H 1
#include "define.h"
#include "populationreal.h"
using realea::tChromosomeReal;
using realea::PopulationReal;
//double distance( tGen *x, tGen *y, unsigned size );
32 double distreal( const realea::tChromosomeReal &x, const realea::tChromosomeReal &y, bool *checkGen=NULL );
35 double distanceMin( const realea::tChromosomeReal &x, realea::PopulationReal *pop, unsigned *posmin );
36 double distanceMax( const realea::tChromosomeReal &x, realea::PopulationReal *pop, unsigned *posmin );
38 unsigned getNeigh( const tChromosomeReal &x, PopulationReal *pop, double min );
/**
* Obtain the vector distance from an individual to the rest
*
* @param x individual
* @param pop population
* @param mindist output with the mean difference distance
*/
47 void min_vector_distance( const tChromosomeReal &x, PopulationReal *pop, vector<tReal> &mindist );
/**
* This method return the individual closer in each solution ( ignoring the
* equal dimension values
*
* @param x initial solution
* @param pop population
* @param mindist position distance for each dimension
*/
57 void min_dim_distance( const tChromosomeReal &sol, PopulationReal *pop, vector<unsigned> &minind );
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include "domain.h"
#include <string>
#include <cassert>
#include <cstdio>
using namespace std;
using namespace realea;
28 DomainReal::DomainReal( unsigned int dim ) : m_mins( dim ), m_maxs( dim ), m_dim( dim ), m_isbound( true ), m_search_ini( 0 ), m_search_fin( dim-1 ) {
m_check_dim = new bool[dim];
fill( m_check_dim, m_check_dim+dim, true );
}
34 void DomainReal::checkGen( unsigned int gen ) {
if ( gen >= m_dim ) {
char msg[100];
sprintf( msg, "position %d is not valide for a gen", gen );
throw new string( msg );
}
}
43 void DomainReal::getValues( unsigned int gen, tReal *pmin, tReal *pmax, bool check ) {
if ( check )
checkGen( gen );
*pmin = m_mins[gen];
*pmax = m_maxs[gen];
}
51 void DomainReal::setValues( unsigned int gen, tReal min, tReal max, bool check ) {
if ( check )
checkGen( gen );
assert( min <= max );
m_mins[gen] = min;
m_maxs[gen] = max;
}
61 tReal DomainReal::clip( unsigned int gen, tReal value, bool check ) {
tReal min, max;
if ( check )
checkGen( gen );
if ( !m_isbound ) {
return value;
}
min = m_mins[gen];
max = m_maxs[gen];
if ( value < min )
return min;
else if ( value > max )
return max;
else
return value;
}
82 bool DomainReal::canBeChanged( unsigned dim ) {
assert( dim < m_dim );
return m_check_dim[dim];
if ( dim >= m_search_ini && dim <= m_search_fin )
return true;
else
return false;
}
93 void DomainReal::clip( tChromosomeReal &crom ) {
assert( crom.size( ) == m_dim );
if ( !m_isbound ) {
return;
}
for ( unsigned i = 0; i < m_dim; ++i ) {
crom[i] = clip( i, crom[i], false );
}
}
107 bool DomainReal::check( const tChromosomeReal &crom ) {
bool follow = true;
assert( crom.size( ) != m_dim );
for ( unsigned i = 0; i < m_dim && follow; ++i ) {
if ( crom[i] < m_mins[i] )
follow = false;
else if ( crom[i] > m_maxs[i] )
follow = true;
}
return follow;
}
121 void DomainReal::setDomainCenter( tChromosomeReal center, double scale ) {
unsigned i;
tReal min, max, range, value;
for ( i = 0; i < m_dim; i++ ) {
getValues( i, &min, &max );
value = center[i];
range = ( max-min )*scale/2;
if ( value - range > min ) {
min = value - range;
}
if ( value + range < max ) {
max = value + range;
}
setValues( i, min, max );
}
}
#include "random.h"
145 void DomainReal::getInitRandom( Random *random, tChromosomeReal &crom ) {
for ( unsigned i = 0; i < m_dim; ++i ) {
crom.push_back( random->randreal( m_mins[i], m_maxs[i] ) );
}
}
151 void DomainReal::getInit( Random *random, tChromosomeReal &crom ) {
getInitRandom( random, crom );
}
155 DomainReal::~DomainReal( void ) {
if ( m_check_dim != NULL ) {
delete []m_check_dim;
}
}
161 void DomainReal::setSearchDomain( bool *searchDim, int dim ) {
assert( dim == m_dim );
copy( searchDim, searchDim+dim, m_check_dim );
}
166 void DomainReal::getSearchDomain( bool *searchDim, int dim ) {
assert( dim == m_dim );
copy( m_check_dim, m_check_dim+dim, searchDim );
}
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _DOMAIN_H
#define _DOMAIN_H 1
#include "real.h"
#include "random.h"
namespace realea {
/**
* @class DomainReal
* @ingroup realea_common
*
* Represents the search domain.
*
* It stores the maximum and minimum values for each dimension.
*/
36 class DomainReal {
public:
/**
* Constructor without specify the max and min values.
* If this constructor is applied, setValues must be specify for each value
*
* @param dim dimension of chromosomes
* @see setValues
*/
45 DomainReal( unsigned int dim );
46 ~DomainReal( void );
/**
* Specifies the min and max value for a gen
*
* @param gen gen to configurate ( from 0 to ndim( ) -1 )
* @param min minimum value for this gen
* @param max maximum value for this gen
* @param check if it must be checked the position gen
* @see getValues
*/
57 void setValues( unsigned int gen, tReal min, tReal max, bool check=true );
/**
* Set the dimensions to search
*
* @param searchDim vector of boolean indicating the gens to be searched
*
* @param dim dimension of the vector
*/
66 void setSearchDomain( bool *searchDim, int dim );
/**
* Get the dimension to search
*
*/
72 void getSearchDomain( bool *searchDim, int dim );
/**
* Recovers the min and max value for a gen
*
* @param gen gen to consult ( from 0 to ndim( ) -1 )
* @param pmin minimun value of this gen, output
* @param pmax maximun value of this gen, output
* @param check if it must be checked the position gen
*/
82 void getValues( unsigned int gen, tReal *pmin, tReal *pmax, bool check=true );
/**
* Return if the dimension index can be changed during the search
*
* @param dim dimension index ( 0..ndim )
*
* @return true if the current dimension dim must be used into the search ( false in othercase )
*/
91 bool canBeChanged( unsigned dim );
/**
* clip the real ( checking that it is between the [min, max] values for this gen )
*
* @param gen gen to check
* @param value value to check
*
* @return the min if ( value < min ), value if ( value <= max ); max if ( value > max ), original
* value othercase
*
*/
103 tReal clip( unsigned int gen, tReal value, bool check=true );
/**
* Set the scale of the domain search around a solution
*
* @param center center of the new domain.
* @param scale scale of the domain search. 1->not changed, 0.1->10% of previous scale.
*
* Never it allow to over the original bounds
*
*/
114 void setDomainCenter( tChromosomeReal center, double scale );
/**
* Clip each one of the gens of the indicated chromosome
*
* @param crom chromosome to check, it can be modified
*/
121 void clip( tChromosomeReal &crom );
/**
* check if the chromosome folow the domain restrictions
*
* @param crom chrosomome to check, it can't be changed
* @return true if the chromosome has valid values
*/
129 bool check( const tChromosomeReal &crom );
/**
* Can obtain a new chromosome
*
* @var random generator of random values
* @var crom chromosome to generate
*/
137 void getInit( Random *random, tChromosomeReal &crom );
/**
* @return the dimensionality
*/
142 unsigned getDimension( void ) {
return m_dim;
}
/**
* Set the bound. It is set the clip check the solutions
*
*/
150 void setBounds( void ) {
m_isbound = true;
}
154 void setNotBounds( void ) {
m_isbound = false;
}
158 bool isBound( ) {
return m_isbound;
}
private:
/**
* Can obtain a chromosome randomly
*
* @var random generator of random values
* @var crom chromosome to be generated
*/
169 void getInitRandom( Random *random, tChromosomeReal &crom );
/**
* check if the gen is value, using asserts
*/
174 void checkGen( unsigned int gen );
175 tChromosomeReal m_mins; /// min values vector
176 tChromosomeReal m_maxs; /// max values vector
unsigned int m_dim; /// dimensionality
178 bool m_isbound; /// if true must be checked the bounds
179 unsigned m_search_ini; // The initial dimension search
180 unsigned m_search_fin; // The final dimension search
182 bool *m_check_dim; // The dimension search
};
typedef DomainReal* DomainRealPtr;
}
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ea.h"
#include <cassert>
using namespace realea;
using namespace realea::internal;
29 EAlgorithm::EAlgorithm( IEAlgorithm *alg, ProblemParamPtr problem ) : m_alg( alg ), default_popsize( alg->getDefaultPopsize( ) ), m_cross( NULL ), m_stat( NULL ) {
setProblem( problem );
}
33 void EAlgorithm::setShow( Statistics *stat ) {
if ( m_problem )
stat->setProblem( m_problem );
m_alg->setStat( stat );
m_stat = stat;
}
41 void EAlgorithm::setEval( IEval *eval ) {
m_eval = eval;
}
45 void EAlgorithm::setProblem( ProblemParamPtr problem ) {
m_problem = problem.get( );
m_alg->setProblem( m_problem );
m_running = new Running( m_problem->getFinishCriterion( ) );
m_running->setMaxEval( m_problem->getMaxEval( ) );
m_alg->setRunning( m_running );
m_alg->setMaxEval( m_running->maxEval( ) );
m_alg->setInitEval( m_problem );
m_alg->setNewEval( m_problem );
// Set the criterion to the individual class
if ( problem->minimize( ) )
tIndividualReal::setMinimize( );
else
tIndividualReal::setMinimize( );
appendSignal( m_alg );
if ( m_stat )
m_stat->setProblem( m_problem );
}
67 EAlgorithm::~EAlgorithm( void ) {
if ( m_alg )
delete m_alg;
if ( m_stat )
delete m_stat;
if ( m_running )
delete m_running;
}
79 void EAlgorithm::setMaxEval( unsigned int maxeval ) {
m_alg->setMaxEval( maxeval );
}
83 void EAlgorithm::setPopsize( unsigned int popsize ) {
m_alg->setPopsize( popsize );
}
87 RunningPtr EAlgorithm::getRunning( void ) {
return m_running;
}
91 void EAlgorithm::setDefaultPopsize( void ) {
unsigned maxeval = m_alg->getMaxEval( );
unsigned max;
if ( maxeval < default_popsize ) {
max = maxeval;
}
else {
max = default_popsize;
}
// Asigna la población con el tamaño indicado
m_alg->setPopsize( max );
}
/**
* Este método es el llamado para resolver el algoritmo evolutivo, si no se especificó una llamada de popsize
* le asigna el menor valor
*
*/
111 unsigned EAlgorithm::apply( tChromosomeReal &sol, tFitness *pfitness ) {
// Si no se ha definido la población lo define
if ( m_alg->getPop( ) == NULL )
setDefaultPopsize( );
if ( m_problem == NULL ) {
throw new ConfigException( "problem" );
}
if ( m_stat )
m_stat->newExperiment( );
unsigned res = m_alg->init( );
res += m_alg->realApply( sol, *pfitness );
if ( m_stat )
m_stat->endExperiment( );
return res;
}
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _EA_H
#define _EA_H 1
#include "iea.h"
#include "statistics.h"
#include "cross.h"
using namespace std;
namespace realea {
/**
* @class EAlgorithm
* @ingroup realea_common
*
* @brief It represents an Evolutionary Algorithm
*
*/
40 class EAlgorithm : public Resetable {
public:
/**
* Constructor.
*
* @param alg algorithm
*/
47 EAlgorithm( IEAlgorithm *alg, ProblemParamPtr problem );
/**
* Destructor. Remove the Populations.
*/
52 virtual ~EAlgorithm( void );
/**
* Set the maximum number of evaluations
*
* @param maxeval
*/
59 void setMaxEval( unsigned int maxeval );
/**
* Allow to set the popsize
*
* @param popsize size of population
*/
66 virtual void setPopsize( unsigned int popsize );
/**
* @return the running criterion.
*/
71 RunningPtr getRunning( void );
/**
* Apply the algorithm
*
* @param sol best found solution, output
* @param pfitness fitness of the best solution, output
*
* @return the evaluation numbers required for achieve the solution
*/
81 unsigned apply( tChromosomeReal &sol, tFitness *pfitness );
/**
* Set the class that obtain the statistical information
*
* @param stat Statistical class
*/
89 void setShow( Statistics *stat );
private:
/**
* Set the problem to be solved
*
* @param problem the problem a consider
*/
96 void setProblem( ProblemParamPtr problem );
/**
* Set the evaluation function ( it is problem by default )
*
* @param eval evaluation class
*/
103 void setEval( IEval *eval );
/**
* Set the default size of population, used if setPopsize is not used
*/
109 void setDefaultPopsize( void );
protected:
/**
* Eval the solution
*
* @param newind individual, it is updated with the fitness
*/
// virtual void eval( tIndividualReal *newind ) {
// m_alg->eval( newind );
// }
protected:
123 IEAlgorithm *m_alg; /**< IEAlgorithm */
124 Problem *m_problem;
125 IEval *m_eval;
126 const unsigned default_popsize; /**< Default Popsize ( obtained by setDefaultSize ) */
127 internal::CrossBinaryPtr m_cross; /**< Crossover operator */
128 Statistics *m_stat; /**< Statistical class */
129 RunningPtr m_running;
};
typedef EAlgorithm EA;
}
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _ICROSS_H
#define _ICROSS_H 1
#include "domain.h"
#include "individual.h"
#include "random.h"
#include "running.h"
#include "signal.h"
namespace realea {
/**
* @class ICross
* @ingroup realea_common
*
* This class allow to create new individuals from two individuals
*
* To create new crossover operator this class must be inherited and defined
* the method operator.
*
*/
41 class ICrossBinary : public IReset {
public:
/**
* Allow to select the domain related to the problem
*
* @param domain domain of the different values
*/
48 void setDomain( DomainRealPtr domain ) {
m_domain = domain;
}
/**
* Allow to set the random generator
*
* @param random
*/
57 void setRandom( RandomPtr random ) {
m_random = random;
}
/**
* Allow to set the running generator
*
* @param running
*/
66 void setRunning( RunningPtr running ) {
m_running = running;
}
/**
* Generate the new chromosome child from two existing chromosomes.
* ( when this method is called, variables m_random and m_domain have been properly initialised ).
*
* @param mom chromosome 'mother'
* @param dad chromosome 'father'
*
* @param child the new chromosome, output
*
*/
80 virtual void operator( )( const tChromosomeReal &mom, tFitness fit_mom, const tChromosomeReal &dad, tFitness fit_dad, tChromosomeReal &child )=0;
protected:
84 DomainRealPtr m_domain; /**< Domain of variables */
85 RandomPtr m_random; /**< Random generator */
86 RunningPtr m_running; /**< Running evaluator, to allow it adapt their values */
};
typedef ICrossBinary* ICrossBinaryPtr;
}
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include "iea.h"
#include <cassert>
using namespace realea;
using namespace realea::internal;
26 ClassEAlgorithm::ClassEAlgorithm( Random *random ) : m_problem( NULL ), m_init_eval( NULL ), m_new_eval( NULL ), m_running( NULL ), m_pop( NULL ), m_stat( NULL ) {
setRandom( random );
m_maxeval = 0;
}
31 void ClassEAlgorithm::setNewEval( IEval *eval ) {
assert( m_running != NULL );
assert( m_new_eval == NULL );
m_new_eval = new EvalRunning( eval, m_running );
}
37 void ClassEAlgorithm::setInitEval( IEval *eval ) {
assert( m_running != NULL );
assert( m_init_eval == NULL );
m_init_eval = new EvalRunning( eval, m_running );
}
43 void ClassEAlgorithm::setMaxEval( unsigned int maxeval ) {
m_maxeval = maxeval;
if ( m_running ) {
m_running->setMaxEval( m_maxeval );
}
}
51 unsigned int ClassEAlgorithm::getMaxEval( void ) {
return m_maxeval;
}
56 ClassEAlgorithm::~ClassEAlgorithm( void ) {
if ( m_pop )
delete m_pop;
if ( m_init_eval )
delete m_init_eval;
if ( m_new_eval )
delete m_new_eval;
m_new_eval = m_init_eval = NULL;
}
69 void ClassEAlgorithm::setPopsize( unsigned int popsize ) {
if ( m_pop ) {
delete m_pop;
}
m_pop = new PopulationReal( m_random, popsize, popsize );
}
77 void ClassEAlgorithm::reset( void ) {
if ( m_running )
m_running->reset( );
}
82 void ClassEAlgorithm::setRunning( Running *running ) {
if ( m_running != NULL ) {
delete m_running;
}
m_running = running;
if ( m_maxeval > 0 && m_running != NULL ) {
m_running->setMaxEval( m_maxeval );
}
}
95 RunningPtr ClassEAlgorithm::getRunning( void ) {
assert( m_running != NULL );
return m_running;
}
100 void ClassEAlgorithm::storeIndividual( tIndividualRealPtr ind, tGen **paind, unsigned *pmax,
101 tGen **paoptional, unsigned *psize_optional ) {
vector<tGen> sol = ind->sol( );
unsigned size = sol.size( )+1;
tGen *aind = new tGen[size];
copy( sol.begin( ), sol.end( ), aind );
aind[size-1] = ind->perf( );
*pmax = size;
*paind = aind;
*paoptional = NULL;
*psize_optional= 0;
}
115 void ClassEAlgorithm::recoverIndividual( unsigned pos, tGen *aind, unsigned size, tGen *aoptional, unsigned optional_size ) {
assert( size > 1 && ( size == m_pop->ndim( )+1 ) );
vector<tGen> sol( size-1 );
copy( aind, aind+size-2, sol.begin( ) );
tFitness fitness = aind[size-1];
tIndividualRealPtr ind = m_pop->getInstance( sol, fitness );
m_pop->replace( pos, ind );
}
126 ICrossEAlgorithm::ICrossEAlgorithm( Random *random ) : ClassEAlgorithm( random ), m_cross( NULL ), m_icross( NULL ) {
}
129 ICrossEAlgorithm::~ICrossEAlgorithm( void ) {
if ( m_cross )
delete m_cross;
}
134 void ICrossEAlgorithm::setCross( ICrossBinaryPtr cross ) {
m_icross = cross;
}
138 void ICrossEAlgorithm::setProblem( Problem *problem ) {
ClassEAlgorithm::setProblem( problem );
}
143 void ICrossEAlgorithm::reset( void ) {
if ( m_cross ) {
m_cross->reset( );
}
else if ( m_icross ) {
m_icross->setRandom( m_random );
m_icross->setDomain( m_problem->getDomain( ) );
m_icross->setRunning( m_running );
m_cross = new CrossBinary( m_icross );
appendSignal( m_cross );
}
ClassEAlgorithm::reset( );
}
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _IEA_H
#define _IEA_H 1
#include "problem.h"
#include "random.h"
#include "populationreal.h"
#include "statistics.h"
#include "cross.h"
using namespace std;
namespace realea {
namespace internal {
35 class EvalRunning : public IEvalInd {
public:
37 EvalRunning( IEval *eval, Running *m_running ): m_eval( eval ), m_running( m_running ) {
}
40 tFitness eval( const tChromosomeReal &sol ) {
tFitness fit = m_eval->eval( sol );
m_running->notifyEval( fit );
return fit;
}
46 unsigned eval( tIndividualReal *newind ) {
newind->eval( this );
return 1;
}
50 ~EvalRunning( void ) {}
private:
53 IEval *m_eval;
54 Running *m_running;
};
}
59 class IEAlgorithm : public Resetable {
public:
/**
* @return the default popsize
*/
64 virtual unsigned getDefaultPopsize( void )=0;
/**
* Init the algorithm before to call realApply
*/
69 virtual unsigned init( void )=0;
/**
* Real implementation that applies the algorithm
*
* @param sol best found solution, output
* @param pfitness fitness of the best solution, output
*/
77 virtual unsigned realApply( tChromosomeReal &sol, tFitness &fitness )=0;
/**
* Allow to set the popsize
*
* @param popsize size of population
*/
84 virtual void setPopsize( unsigned int popsize )=0;
86 virtual void setRandom( Random *random )=0;
88 virtual Random *getRandom( void )=0;
90 virtual void setProblem( Problem *problem )=0;
92 virtual void setRunning( Running *running )=0;
93 virtual RunningPtr getRunning( void )=0;
94 virtual void setStat( Statistics *stat )=0;
/**
* Set the maximum eval
*
* @param maxeval maximum evaluations number
*/
101 virtual void setMaxEval( unsigned int maxeval )=0;
102 virtual unsigned getMaxEval( void )=0;
/**
* Eval the solution
*
* @param newind individual, it is updated with the fitness
*/
109 virtual void reset( void )=0;
111 virtual PopulationReal *getPop( void )=0;
113 virtual void setNewEval( IEval*eval )=0;
115 virtual void setInitEval( IEval*eval )=0;
/**
* Stores an individual in a vector ( to store in a file or to send to other computers )
*
* @param ind Individual to be stored
* @param paind reference to array to be stored ( it is created ), it is fixed
* @param pmax reference to size of the array
* @param paditional reference to array of aditional information ( it can be NULL )
* @param pmaxad reference to size of the aditional array ( 0 if there is none )
*
* @see recoverIndividual
*/
129 virtual void storeIndividual( tIndividualRealPtr ind, tGen **paind, unsigned *pmax, tGen **paditional, unsigned *pmaxad )=0;
/**
* Load an individual from a sequence representation in the position indicated
*
* @param posind position to be replaced
* @param aind reference to array when it is stored
* @param reference to size size of the array
*
* @return individual recover
*
* @see storeIndividual
*/
142 virtual void recoverIndividual( unsigned posind, tGen *aind, unsigned size, tGen *aoptional, unsigned size_optional ) = 0;
};
typedef IEAlgorithm IEA;
148 class ClassEAlgorithm : public IEAlgorithm {
public:
/**
* @return the default popsize
*/
155 virtual unsigned getDefaultPopsize( void )=0;
/**
* Real implementation that applies the algorithm
*
* If it is applied several times it must continue from last time
*
* @param sol best found solution, output
* @param pfitness fitness of the best solution, output
*
*/
166 virtual unsigned realApply( tChromosomeReal &sol, tFitness &fitness )=0;
/**
* Allow to set the popsize
*
* @param popsize size of population
*/
173 virtual void setPopsize( unsigned int popsize );
175 ClassEAlgorithm( Random *random );
177 void setRandom( Random *random ) {
m_random = random;
}
181 Random *getRandom( void ) {
return m_random;
}
186 void setProblem( Problem *problem ) {
m_problem = problem;
}
190 void setRunning( Running *running );
191 RunningPtr getRunning( void );
/**
* Set the class that obtain the statistical information
*
* @param stat Statistical class
*/
198 void setStat( Statistics *stat ) {
m_stat = stat;
}
/**
* Set the maximum eval
*
* @param maxeval maximum evaluations number
*/
207 void setMaxEval( unsigned int maxeval );
210 unsigned getMaxEval( void );
213 virtual ~ClassEAlgorithm( void );
215 virtual void setNewEval( IEval*eval );
217 virtual void setInitEval( IEval*eval );
219 virtual void reset( void );
221 virtual PopulationReal *getPop( void ) {
return m_pop;
}
/**
* Stores an individual in a vector ( to store in a file or to send to other computers )
*
* @param ind Individual to be stored
* @param paind reference to array to be stored ( it is created ), it is fixed
* @param pmax reference to size of the array
* @param paditional reference to array of aditional information ( it can be NULL )
* @param pmaxad reference to size of the aditional array ( 0 if there is none )
*
* @see recoverIndividual
*/
236 virtual void storeIndividual( tIndividualRealPtr ind, tGen **paind, unsigned *pmax, tGen **paoptional, unsigned *psize_optional );
238 virtual void recoverIndividual( unsigned pos, tGen *aind, unsigned size, tGen *aoptional, unsigned size_optional );
protected:
241 Problem *m_problem; /**< Problem to abord */
242 IEvalInd *m_init_eval; /** Eval function */
243 IEvalInd *m_new_eval; /** Eval function */
245 RunningPtr m_running; /**< Running criterion */
246 PopulationReal *m_pop; /**< Main Population */
247 Random *m_random; /**< Random generator */
248 Statistics *m_stat; /**< Statistical class */
249 unsigned m_maxeval;
};
253 class ICrossEAlgorithm : public ClassEAlgorithm {
public:
255 ICrossEAlgorithm( Random *random );
/**
* Set the crossover to be applied
*
* @param cross the binary crossover
*/
262 virtual void setCross( ICrossBinaryPtr cross );
264 virtual ~ICrossEAlgorithm( void );
266 virtual void setProblem( Problem *problem );
267 virtual void reset( void );
protected:
270 internal::CrossBinaryPtr m_cross; /**< Crossover operator */
271 ICrossBinaryPtr m_icross;
};
}
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _ILOCALSEARCH_H
#define _ILOCALSEARCH_H 1
#include "problem.h"
#include "running.h"
#include "populationreal.h"
#include "random.h"
namespace realea {
/**
* This class store the internal state of the LS.
*
* @ingroup realea_common
*
* each ILocalSearch works with a subclass of that class to store its
* state ( allowing to continue the local search in next running )
*/
39 class ILSParameters {
public:
41 virtual ~ILSParameters( void ){}
};
/**
* @class ILocalSearch
*
* @brief This interface allow to define how to obtain the local search method
*
* To define new Local Search methods it is only required to implement this interface and
* define apply and getInitOptions methods.
*/
52 class ILocalSearch {
public:
/**
* Obtain the initial parameter to local searchObtain the initial parameter to local search.
*
* @param sol chromosome to be improved
* @see applyNewSol
*/
60 virtual ILSParameters *getInitOptions( tChromosomeReal &sol )=0;
/**
*
* Apply the LS method improvement
*
* @param params the initial parameters of the LS, initialised by getInitOptions
* @param sol chromosome to be improved, it is changed
* @param fitness fitness of chromosome 'sol', it is updated by the new sol values
* @param nstep evaluation number into the LS process
* @return evaluations number
*
* @see getInitOptions
*/
74 virtual unsigned apply( ILSParameters *params, tChromosomeReal &sol, tFitness &fitness, unsigned nstep )=0;
/**
* Allow to specify the population whose individuals will be improved
*
* @param pop population
*/
81 void setPopulation( PopulationReal *pop ) {
m_pop = pop;
}
/**
* Set the running criterion
*
* @param run stop criterion
*/
90 void setRunning( RunningPtr run ) {
m_running = run;
}
/**
* Set the problem
*
* @param problem problem to be evaluated
*/
99 void setProblem( Problem *problem ) {
m_problem = problem;
}
/**
* Set the Random number generator
*
* @param random
*/
108 void setRandom( Random *random ) {
m_random = random;
}
112 void setEval( IEval *eval ) {
m_eval = eval;
}
116 virtual ~ILocalSearch( void ) {}
protected:
120 Random *m_random; /**< The current randomgeneration numbers */
121 IEval *m_eval; /** The current evaluation function */
122 Problem *m_problem; /**< The current problem */
123 PopulationReal *m_pop; /** The current population */
124 RunningPtr m_running; /**< The stopping criterion */
};
/**
* This class allow us to recover and receive the parameters using an array ( for Niching Techniques )
*/
130 class IParallelLocalSearch : public ILocalSearch {
public:
/**
* Obtain the parameter from a serialized array.
*
* @param params array of params
* @param size size of array
*/
138 virtual ILSParameters *recoverOptions( tGen *params, unsigned size )=0;
/**
* Store in a real vector the values of a parameters.
*
* @param params parameter to store
* @param paparams reference to sequencial parameters ( can be NULL )
* @param size reference to size ( always is right, even if params == NULL )
*
* @see recoverOptions
*/
149 virtual void storeOptions( ILSParameters *params, tGen **paparams, unsigned *psize )=0;
};
}
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _IMUTATION_H
#define _IMUTATION_H 1
#include "real.h"
#include "domain.h"
#include "random.h"
namespace realea {
/**
* @class IMutation
* @ingroup realea_common
*
* This class define the mutation type
*
* To create a new mutation crossover, the class must inherit from this interface and redefine the
* apply method
*/
38 class IMutation {
public:
/**
* Make de mutation ( changing a gen of the chromosome sol ).
*
* @param sol the chromosome to update, it is modified
* @param gen the position of gen to change
*
*/
47 virtual tGen mutate( tChromosomeReal &sol, unsigned posi )=0;
/**
* Set the random variable
*
* It must be speficied if Mutation is going to use it.
*
* @param random the random generation numbers.
*/
56 void setRandom( Random *random ) {
m_random = random;
}
59 void setDomain( DomainRealPtr domain ) {
m_domain = domain;
}
63 virtual ~IMutation( void ) {}
protected:
66 Random *m_random;
67 DomainRealPtr m_domain;
};
}
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include "individual.h"
#include <algorithm>
#include <cassert>
#include <cstdio>
using namespace realea;
static bool m_criterion = false;
static bool m_minimize;
/**
* Sort the individuals ( not evaluated at the end )
*/
34 class SortIndMin {
public:
36 bool operator( )( tIndividualReal *a, tIndividualReal *b ) {
if ( a->isEval( ) && b->isEval( ) )
return ( a->perf( ) < b->perf( ) );
else if ( a->isEval( ) )
return true;
else
return false;
}
};
46 class SortIndMax {
public:
48 bool operator( )( tIndividualReal *a, tIndividualReal *b ) {
if ( a->isEval( ) && b->isEval( ) )
return ( a->perf( ) > b->perf( ) );
else if ( a->isEval( ) )
return true;
else
return false;
}
};
/**
* Constructor de un individuo
*/
63 tIndividualReal::tIndividualReal( const tChromosomeReal &com ) : m_sol( com ) , m_evaluated( false ), pcounters( ), m_notid( true ) {
}
67 tIndividualReal::tIndividualReal( const tChromosomeReal &com, tFitness fitness ) : m_sol( com ) , m_evaluated( true ), pcounters( ), m_notid( true ) {
m_perf = fitness;
}
72 tIndividualReal::~tIndividualReal( void ) {
pcounters.clear( );
}
76 void tIndividualReal::setMinimize( void ) {
m_minimize = true;
m_criterion = true;
}
82 void tIndividualReal::setMaximize( void ) {
m_minimize = false;
m_criterion = true;
}
87 bool tIndividualReal::isMinimize( void ) {
return m_minimize;
}
92 void tIndividualReal::change( const tChromosomeReal &sol, tFitness fitness ) {
m_evaluated = true;
m_sol = sol;
m_perf = fitness;
}
99 tFitness tIndividualReal::perf( void ) {
if ( !m_evaluated )
throw new IndException( "Performance measure has not been obtained" );
return m_perf;
}
struct FindKey : public unary_function<tCounter, bool> {
string m_key;
bool operator( )( const tCounter &value ) {
return ( value.first == m_key );
}
};
115 void tIndividualReal::incremCount( string ident ) {
tCounterList::iterator posi;
FindKey find_key;
find_key.m_key = ident;
unsigned value;
posi = find_if( pcounters.begin( ), pcounters.end( ), find_key );
if ( posi==pcounters.end( ) ) {
value = 1;
tCounter count;
count.first = ident;
count.second = 1;
// printf( "individuo %u debe incrementar %s\n", getId( ), ident.c_str( ) );
pcounters.push_back( count );
}
else {
posi->second ++;
}
}
139 unsigned int tIndividualReal::getCount( string ident ) {
tCounterList::iterator posi;
FindKey find_key;
find_key.m_key = ident;
posi = find_if( pcounters.begin( ), pcounters.end( ), find_key );
if ( posi == pcounters.end( ) )
return 0;
else
return posi->second;
}
152 void tIndividualReal::setPerf( tFitness perf ) {
if ( m_evaluated ) {
throw new string( "individual has been evaluated previously" );
}
m_perf = perf;
m_evaluated = true;
}
160 bool tIndividualReal::isEval( void ) {
return m_evaluated;
}
164 bool tIndividualReal::isBetter( tIndividualReal *theother ) {
if ( !m_criterion )
throw new IndException( "Criterion ( Maximize/Maximize ) has not been set" );
if ( m_minimize ) {
return ( this->perf( ) < theother->perf( ) );
}
else
return ( this->perf( ) > theother->perf( ) );
}
175 bool tIndividualReal::isWorse( tIndividualReal *theother ) {
if ( !m_criterion )
throw new IndException( "Criterion ( Maximize/Maximize ) has not been set" );
if ( m_minimize ) {
return ( this->perf( ) > theother->perf( ) );
}
else
return ( this->perf( ) < theother->perf( ) );
}
/**
* Set the minimize criterion
*/
190 void setMinimize( void );
/**
* Set the minimize criterion
*/
194 void setMaximize( void );
197 tGen tIndividualReal::gen( unsigned n ) {
if ( !( n < m_sol.size( ) ) ) {
printf( "Size: %u\tn: %u\n", m_sol.size( ), n );
}
assert( n < m_sol.size( ) );
return m_sol[n];
}
206 tFitness tIndividualReal::eval( IEval *funeval ) {
if ( m_evaluated ) {
return m_perf;
}
tFitness fitness = funeval->eval( this->sol( ) );
setPerf( fitness );
return fitness;
}
216 void tIndividualReal::setId( unsigned id ) {
m_id = id;
m_notid = false;
}
221 unsigned tIndividualReal::getId( void ) {
if ( m_notid ) {
throw string( "IndividualReal::Id" );
}
return m_id;
}
228 void tIndividualReal::sort( vector<tIndividualReal*> &individuals ) {
if ( tIndividualReal::isMinimize( ) )
std::sort( individuals.begin( ), individuals.end( ), SortIndMin( ) );
else
std::sort( individuals.begin( ), individuals.end( ), SortIndMax( ) );
}
/**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _INDIVIDUAL_H
#define _INDIVIDUAL_H 1
#include "real.h"
#include "define.h"
#include <map>
#include <deque>
#include <stdexcept>
using namespace std;
namespace realea {
34 class IndException: public runtime_error {
private:
36 string m_name;
public:
39 IndException( string name ) : runtime_error( name ) {
m_name = name;
}
public:
virtual ~IndException( void ) throw ( ) { }
virtual const char *what( void ) {
return m_name.c_str( );
}
};
typedef pair<string, unsigned> tCounter;
typedef deque< pair<string, unsigned> > tCounterList;
class tIndividualReal {
public:
tIndividualReal ( const tChromosomeReal &com );
tIndividualReal ( const tChromosomeReal &com, tFitness fitness );
/**
* Assign a change into the chromosome, indicating the fitness
*
* @param sol new solution
* @param fitness new fitness
* @param maintain true if maintain the identity ( counters )
*/
void change( const tChromosomeReal &sol, tFitness fitness );
/**
* Return the sol ( to the crossover or the LS )
* @return the chromosome
*/
const tChromosomeReal &sol( void ) {
return m_sol;
}
/**
* Return the performance
* @return perf its performance measure ( fitness )
*/
tFitness perf( void );
/**
* Increm a counter for that individual.
*
* This allow to count the number of events to the same individuals ( selected, crossed, improvement by LS, ... )
*
* @param ident identificator of the counter
* @see getCount
*/
void incremCount( string ident );
/**
* Return a counter value
* @param ident counter's identificator
* @return the count
*
* @see incremCount
*/
unsigned int getCount ( string ident );
/**
* @return true is the individual has been evaluated
*/
bool isEval( void );
/**
* Eval the individual
*
* @param IEval evaluation function
* @return fitness obtained
*/
tFitness eval( IEval *funeval );
/**
* get the individual value
*
* @param pos ( gen position, 0.. ndim-1 )
* @return the current gen value
*/
tGen gen( unsigned pos );
/**
* @return true if the current individual is better than the other
*/
bool isBetter( tIndividualReal *theother );
/**
* @return true if the current individual is worse than the other
*/
bool isWorse( tIndividualReal *theother );
/**
* Set the minimize criterion
*/
static void setMinimize( void );
/**
* Set the minimize criterion
*/
static void setMaximize( void );
/**
* Get the criterion
*
* @return true is setMinimize( ) has been set
*/
static bool isMinimize( void );
/**
* Set the id
*/
void setId( unsigned id );
unsigned getId( void );
/**
* Destructor
*/
virtual ~tIndividualReal( void );
/**
* Sort the vector of individuals
*/
static void sort( vector<tIndividualReal*> &individuals );
protected:
tChromosomeReal m_sol; /**< Solution represented by the individual */
private:
/**
* Set the additional value
*
* @param perf fitness value
* @param id identification
*/
void setPerf( tFitness perf );
double m_id; /**< Identity id */
tFitness m_perf; /**< Fitness */
bool m_evaluated; /**< Store if the individual has been evaluated */
deque< pair<string, unsigned> > pcounters; /**< Statistical counters */
bool m_notid; /** Check the identity */
};
typedef tIndividualReal *tIndividualRealPtr;
/**
* This class allows to evaluate an individual
*/
class IEvalInd : public IEval {
public:
virtual unsigned eval( tIndividualReal *newind )=0;
virtual tFitness eval( const tChromosomeReal &sol )=0;
};
}
#endif
1 #include "initind.h"
#include <cmath>
#include <cassert>
#define EPSILON 1E-18
using namespace realea;
using namespace realea::internal;
10 void SimpleInitInd::createInd( DomainRealPtr domain, tChromosomeReal &crom ) {
domain->getInit( m_random, crom );
}
14 void SimpleInitInd::reset( DomainRealPtr domain, unsigned count ) {
}
17 void SimpleInitInd::resetBest( DomainRealPtr domain, const tChromosomeReal &sol, unsigned count ) {
}
20 ElemDimInit::ElemDimInit( tGen min, tGen max, unsigned count, unsigned intervals ) : m_min( min ), m_size( intervals ), m_interval( intervals ) {
m_range = ( max-min )/m_size;
for ( unsigned i = 0; i < m_size; i++ ) {
ElemRangeInit elem;
elem.interval = i;
elem.count = count;
m_interval[i] = elem;
}
}
32 void ElemDimInit::reduce( tGen value ) {
unsigned pos_interval;
pos_interval = ( unsigned ) floor( ( value - m_min )/m_range+EPSILON );
if ( pos_interval >= m_interval.size( ) ) {
pos_interval = m_interval.size( )-1;
}
m_interval[pos_interval].count--;
assert( m_interval[pos_interval].count > 0 );
}
44 tGen ElemDimInit::random( Random *random ) {
unsigned pos_interval = random->randint( 0, m_size-1 );
unsigned interval = m_interval[pos_interval].interval;
assert( m_interval[pos_interval].count > 0 );
tGen value = m_min + interval*m_range+random->randreal( 0, m_range );
m_interval[pos_interval].count--;
if ( m_interval[pos_interval].count == 0 ) {
m_interval[pos_interval] = m_interval[m_size-1];
m_size -= 1;
}
return value;
}
63 void UniformInitInd::reset( DomainRealPtr domain, unsigned count ) {
unsigned ndim = domain->getDimension( );
tGen min, max;
m_interval_dim.clear( );
unsigned intervals = count/10;
for ( unsigned i = 0; i < ndim; ++i ) {
domain->getValues( i, &min, &max );
ElemDimInit elem( min, max, 10, intervals );
m_interval_dim.push_back( elem );
}
}
78 void UniformInitInd::resetBest( DomainRealPtr domain, const tChromosomeReal &best, unsigned count ) {
deque<ElemDimInit>::iterator elemDim;
unsigned i, ndim = best.size( );
reset( domain, count );
for ( i = 0, elemDim = m_interval_dim.begin( ); elemDim != m_interval_dim.end( ); elemDim++, i++ ) {
elemDim->reduce( best[i] );
}
}
88 void UniformInitInd::createInd( DomainRealPtr domain, tChromosomeReal &crom ) {
unsigned i, ndim = domain->getDimension( );
deque<ElemDimInit>::iterator elemDim;
for ( i = 0, elemDim = m_interval_dim.begin( ); elemDim != m_interval_dim.end( ); elemDim++, i++ ) {
crom.push_back( elemDim->random( m_random ) );
}
}
97 UniformInitInd::~UniformInitInd( void ) {
}
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _INIT_IND_H
#define _INIT_IND_H 1
#include "real.h"
#include "domain.h"
#include <deque>
using std::deque;
namespace realea {
/**
* @class
* Interfaz that allow to create new individuals
*/
34 class InitIndividual {
public:
/**
* Reset the class ( it is called after each EA run
*/
39 virtual void reset( DomainRealPtr domain, unsigned count )=0;
/**
* Reset the class ( it is called when the EA is reset maintaining the best individual )
* @param best the best individual
*/
44 virtual void resetBest( DomainRealPtr domain, const tChromosomeReal &best, unsigned count )=0;
/**
* Create a new individual
* @param domain Domain of the problem.
* @param crom new chromosome
*/
50 virtual void createInd( DomainRealPtr domain, tChromosomeReal &crom )=0;
51 virtual ~InitIndividual( void ) {}
};
namespace internal {
56 class SimpleInitInd : public InitIndividual {
public:
58 SimpleInitInd( Random *random ) {
m_random = random;
}
61 void reset( DomainRealPtr domain, unsigned count );
62 void resetBest( DomainRealPtr domain, const tChromosomeReal &best, unsigned count );
63 void createInd( DomainRealPtr domain, tChromosomeReal &crom );
64 ~SimpleInitInd( void ) {}
private:
66 Random *m_random;
};
struct ElemRangeInit {
unsigned interval;
unsigned count;
};
/**
* @class
*
* This class allow to generate the random value for one dimension assuring that for there are distributed
* equally for each interval
*
*/
81 class ElemDimInit {
private:
83 tGen m_min;
84 unsigned m_size;
85 vector<ElemRangeInit> m_interval;
double m_range;
public:
/**
* Constructor
* @param min minimum value
* @param max maximum value
* @param count maximum number of values for each interval
* @param intervals interval number
*/
95 ElemDimInit( tGen min, tGen max, unsigned count, unsigned intervals );
/**
* Reduce the count with the existing value
*/
99 void reduce( tGen value );
/**
* Generate a new random value considering the different intervals
* @parma random random generator
*/
104 tGen random( Random *random );
};
107 class UniformInitInd : public InitIndividual {
public:
109 UniformInitInd( Random *random ) : m_random( random ), m_interval_dim( ) {
m_random = random;
}
113 void reset( DomainRealPtr domain, unsigned count );
114 void resetBest( DomainRealPtr domain, const tChromosomeReal &best, unsigned count );
115 void createInd( DomainRealPtr domain, tChromosomeReal &crom );
116 ~UniformInitInd( void );
private:
118 Random *m_random;
119 deque<ElemDimInit> m_interval_dim;
};
}
}
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include "localsearch.h"
#include "random.h"
#include <cassert>
using namespace realea::internal;
26 NewIndividualLocalSearchManager::NewIndividualLocalSearchManager( ILocalSearch *ls ) : m_ls( ls ) {
}
29 NewIndividualLocalSearchManager::~NewIndividualLocalSearchManager( void ) {
if ( m_ls ) {
delete m_ls;
}
}
35 bool RatioLocalSearchManager::applyNewSol( tChromosomeReal &sol, tFitness *pfitness, ILSParameters *par ) {
ILSParameters *params;
bool initconf;
bool mustApply;
bool applied=false;
// Check if must be apply the LS
if ( !m_random ) {
throw new ConfigException( "LocalSearch::random" );
}
mustApply = ( m_random->rand( ) < m_ratio );
if ( mustApply ) {
if ( m_ls == NULL ) {
throw new ConfigException( "LocalSearch::ls" );
}
initconf = ( params != NULL );
if ( initconf ) {
params = m_ls->getInitOptions( sol );
}
else {
params = par;
}
applied = true;
m_ls->apply( params, sol, *pfitness, m_intensity );
if ( initconf ) {
delete params;
}
}
return applied;
}
73 RatioLocalSearchManager::RatioLocalSearchManager( ILocalSearch *ls, unsigned intensity, double ratio ) : NewIndividualLocalSearchManager( ls ) {
assert( intensity > 0 );
m_intensity = intensity;
assert( ratio > 0 && ratio <= 1 );
m_ratio = ratio;
}
80 unsigned RatioLocalSearchManager::getIntensity( void ) {
return m_intensity;
}
84 void NewIndividualLocalSearchManager::reset( void ) {
}
87 void RatioLocalSearchManager::setRandom( Random *random ) {
m_random = random;
}
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _LOCALSEARCH_H
#define _LOCALSEARCH_H 1
#include "ilocalsearch.h"
/**
* @ingroup realea::common::internal
*/
namespace realea {
namespace internal {
/**
* @class NewIndividualLocalSearchManager
*
* It is the responsable of applied the Local Search when it is created a new solution
*
* This is responsable of calling to LS method when it is needed.
*/
40 class NewIndividualLocalSearchManager: public IReset {
public:
/**
* Constructor
*/
45 NewIndividualLocalSearchManager( ILocalSearch *ls );
/**
* Restart the local search process
*/
50 void reset( void );
/**
* This method is called by each new individual, and applies the LS if it is needed.
*
* This method is called by each new individual generated. If must decide if apply the
* LS or not, in the last case it called the method m_localsearch->apply( ).
*
*
* @param sol new Chromosome to improve, it could ber modified
* @param pfitness fitness of the solution, it will be updated if sol is changed
*
* @param options options to LS method ( by default it is NULL ).
*
* @return bool true if the current sol has been changed
*
* @see ILocalSearch::apply
*/
68 virtual bool applyNewSol( tChromosomeReal &sol, tFitness *pfitness, ILSParameters *params=NULL ) = 0;
/**
* Destructor. Only removes the LocalSearch object.
*/
73 virtual ~NewIndividualLocalSearchManager( void );
protected:
75 ILocalSearch *m_ls;
};
/**
* @class LocalSearchClasicalManager
*
* Apply the LS method only to a ratio of new individuals with a const intensity
*/
83 class RatioLocalSearchManager : public NewIndividualLocalSearchManager {
public:
/**
* Constructor
*
* @param ls local search method
* @param intensity intensity of LS
* @param ratio ratio of new individuals to be improved
*/
92 RatioLocalSearchManager( ILocalSearch *ls, unsigned intensity, double porcen=0.0625 );
/**
* @return the current intensity
* @see setIntensity
*/
98 void setRandom( Random *random );
/**
* Applied the LS only to ratio of new individuals
*
* @param sol new Chromosome to improve, it could ber modified
* @param pfitness fitness of the solution, it will be updated if sol is changed
*
* @param options options to LS method ( by default it is NULL ).
*
* @return bool true if the current sol has been changed
*
* @see NewIndividualLocalSearchManager::applyNewSol
*/
114 bool applyNewSol( tChromosomeReal &sol, tFitness *pfitness, ILSParameters *params=NULL );
private:
/**
* @return the current intensity
* @see setIntensity
*/
123 unsigned getIntensity( void );
126 Random *m_random; /**< Random generator */
double m_ratio; /**< Ratio of new individuals to be improved */
129 unsigned m_intensity; /** Intensity of each LS */
130 bool m_configured;
};
}}
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ma2lsi.h"
#include "selectlsimp.h"
#include <cassert>
#include <cstdio>
#include <ctime>
#include <cmath>
using namespace realea;
using namespace realea::internal;
30 void MA2LSI::setEffortRatio( double ratio ) {
if ( ratio == 1 )
throw new string( "MA2LSI::effortRatio is not valide" );
m_effort = ratio;
}
37 MA2LSI::MA2LSI( IEAlgorithm *alg, ILocalSearch *ls ) : Hybrid( alg, ls ), m_memory( NULL ) {
m_effort = -1;
m_nevalalg = m_nevalls = 0;
m_restart = NULL;
m_debug = false;
m_select_improvement = NULL;
m_disruption_size = 0;
}
46 void MA2LSI::setDisruptionSize( double size ) {
assert( size >= 0 && size < 1 );
m_disruption_size = size;
}
52 void MA2LSI::setDebug( void ) {
m_debug = true;
}
56 MA2LSI::~MA2LSI( void ) {
if ( m_memory ) {
delete m_memory;
}
if ( m_restart ) {
delete m_restart;
}
if ( m_select_improvement ) {
delete m_select_improvement;
}
if ( m_initeval ) {
delete m_initeval;
}
}
/**
* Calculate the new frec to apply to obtain the indicated ratio.
*
* It is required because there are AEs that could not follow the frec indicated in the previous step
*
* @param nevalalg total number evaluation during the EA
* @param nevalls total number evaluation during the LS
* @param intensity LS intensity
*
* @return frec to use the EA to maintain the ratio
*/
85 unsigned calculateFrec( unsigned nevalalg, unsigned nevalls, unsigned intensity, double ratio ) {
assert( ratio > 0 );
double coc = ratio*( nevalalg + nevalls + intensity ) - nevalalg;
double div = ( 1-ratio );
if ( div == 0 ) {
throw string( "MA2LSI::Ratio is too low" );
}
return ( ( unsigned ) floor( coc/div ) );
}
99 unsigned MA2LSI::init( void ) {
initLs( );
m_initMaxEval = m_running->maxEval( );
unsigned neval = m_alg->init( );
if ( m_select_improvement == NULL ) {
m_select_improvement = new SelectBestToImprove( );
}
if ( m_memory == NULL ) {
m_memory = new LSParametersMemory( m_alg->getPop( )->size( ) );
m_alg->getPop( )->setObserver( m_memory );
}
m_nevalalg = neval;
m_nevalls = 0;
return neval;
}
119 void MA2LSI::setMaxEval( unsigned int maxeval ) {
assert( maxeval >= m_intensity );
unsigned frec = calculateFrec( m_nevalalg, m_nevalls, m_intensity, m_effort );
m_alg->setMaxEval( frec );
}
125 void MA2LSI::setRestart( RestartStrategy *restart, int maxfailed ) {
if ( m_restart ) {
delete m_restart;
}
m_restart = restart;
m_maxfailed = maxfailed;
}
136 RunningPtr MA2LSI::getRunning( void ) {
return m_alg->getRunning( );
}
140 void MA2LSI::setRunning( Running *running ) {
ProxyEA::setRunning( running );
unsigned frec = calculateFrec( m_nevalalg, m_nevalls, m_intensity, m_effort );
m_alg->setRunning( m_running->getSubRunning( frec ) );
}
148 void MA2LSI::recoverIndividual( unsigned oldind, tGen *aind, unsigned size, tGen *aoptional, unsigned size_optional ) {
m_alg->recoverIndividual( oldind, aind, size-1, aoptional, size_optional );
if ( aind[size] ) {
m_alg->getPop( )->getInd( oldind )->incremCount( "non_improved" );
}
if ( aoptional != NULL ) {
IParallelLocalSearch *ls = ( IParallelLocalSearch * ) m_ls;
ILSParameters *params = ls->recoverOptions( aoptional, size_optional );
assert( m_memory );
m_memory->store( oldind, params );
}
}
164 void MA2LSI::storeIndividual( tIndividualRealPtr ind, tGen **paind, unsigned *pmax, tGen **paoptional, unsigned *psize_optional ) {
tGen *asol, *aoptional_sol;
tGen *asol_ma;
unsigned size_sol, size_optional;
tGen *aparams;
unsigned size_param;
unsigned size;
m_alg->storeIndividual( ind, &asol, &size_sol, &aoptional_sol, &size_optional );
assert( size_optional == 0 && aoptional_sol == NULL );
asol_ma = new tGen[size_sol+1];
copy( asol, asol+size_sol, asol_ma );
delete[] asol;
asol_ma[size_sol] = ( ind->getCount( "non_improved" ) > 0 ) ? 1 : 0;
*paind = asol_ma;
*pmax = size_sol+1;
size_param = 0;
if ( m_memory ) {
unsigned posind = ind->getId( );
IParallelLocalSearch *ls = ( IParallelLocalSearch * ) m_ls;
ILSParameters *params = m_memory->recover( posind );
ls->storeOptions( params, &aparams, &size_param );
}
size = size_optional+size_param;
assert( size > 0 );
*psize_optional = size_param;
*paoptional = NULL;
if ( aoptional_sol != NULL || aparams != NULL ) {
*paoptional = new tGen[size];
if ( aoptional_sol != NULL ) {
copy( aoptional_sol, aoptional_sol+size_optional, *paoptional );
delete[] aoptional_sol;
}
if ( aparams != NULL ) {
copy( aparams, aparams+size_param, *paoptional+size_optional );
delete[] aparams;
}
}
}
214 void MA2LSI::setDif( bool debug, string ident, unsigned id, tFitness oldfit, tFitness newfit ) {
if ( debug ) {
if ( oldfit!= newfit ) {
printf( "%s[%2d]:\t%Le-> %Le\t\t%Le\n", ident.c_str( ), id, oldfit, newfit, fabs( newfit-oldfit ) );
}
// else {
// printf( "%s[%2d]:\t%Le\n", ident.c_str( ), id, newfit );
// }
}
}
227 bool MA2LSI::hasDiversity( PopulationReal *pop ) {
return true;
double percen[5];
pop->getPercentils( percen, 4 );
printf( "EA::Improvement: %e\t%e\t%e\t%e\t%e\n", percen[0], percen[1],
percen[2], percen[3], percen[4] );
if ( percen[2] == percen[4] ) {
return false;
}
else if ( percen[1] == percen[3] ) {
return false;
}
else if ( fabs( ( percen[0] - percen[2] )/percen[2] ) < 1e-3 ) {
return false;
}
else {
return true;
}
}
251 void MA2LSI::setInitEval( IEval*eval ) {
Hybrid::setInitEval( eval );
m_initeval = ( IEvalInd * ) new EvalRunning( eval, m_running );
}
256 void MA2LSI::disturb( tChromosomeReal &sol ) {
DomainRealPtr domain = m_problem->getDomain( );
unsigned dim = domain->getDimension( );
double min, max;
for ( unsigned i = 0; i < dim; i++ ) {
if ( domain->canBeChanged( i ) ) {
domain->getValues( i, &min, &max );
sol[i] += m_disruption_size*m_random->randreal( -1, 1 )*( max-min );
}
}
domain->clip( sol );
}
271 unsigned MA2LSI::realApply( tChromosomeReal &bestsol, tFitness &bestfitness ) {
tIndividualReal *ind, *best;
unsigned posind;
tFitness oldfitness, fitness, fitness_alg;
unsigned ndim = bestsol.size( );
tChromosomeReal sol( ndim ), sol_alg( ndim );
unsigned alg_failed;
int lastpos_better = -1;
tFitness lastpos_fitness;
clock_t m_time_ls, m_time_alg, m_time_ma;
clock_t clock_begin, m_time_ma_begin;
PopulationReal *pop_alg = m_alg->getPop( );
deque<tIndividualReal*> ind_to_improve;
tFitness improvement_alg, improvement_ls;
m_time_ls = m_time_alg = m_time_ma = 0;
sol=bestsol;
fitness = bestfitness;
improvement_alg = improvement_ls = 0;
unsigned initMax = m_running->numEval( );
fitness_alg = pop_alg->getInd( pop_alg->getBest( ) )->perf( );
alg_failed = 0;
m_time_ma_begin = clock( );
// while ( ( m_nevalalg+m_nevalls ) < m_initMaxEval && !m_running->hasFoundOptime( ) ) {
while ( !m_running->isFinish( ) ) {
tFitness old_fitness = fitness_alg;
clock_begin = clock( );
m_nevalalg += m_alg->realApply( sol_alg, fitness_alg );
m_time_alg += clock( )-clock_begin;
improvement_alg += fabs( fitness_alg-old_fitness );
assert( fitness_alg <= old_fitness );
if ( fitness_alg == old_fitness ) {
alg_failed++;
}
else {
alg_failed = 0;
}
if ( m_debug ) {
setDif( m_debug, "Alg", pop_alg->getBest( ), old_fitness, fitness_alg );
}
// Check the optime
if ( m_running->isOptime( fitness_alg ) ) {
continue;
}
// Select the new individual to increm
m_select_improvement->getIndsToImprove( pop_alg, ind_to_improve );
if ( ind_to_improve.size( )!=0 ) {
// Select the individual to improve
posind = m_select_improvement->selectIndToImprove( ind_to_improve );
}
else {
// Choose the new one randomly
posind = m_random->randint( 0, pop_alg->size( )-1 );
}
ind = pop_alg->getInd( posind );
sol = ind->sol( );
ILSParameters *params = m_memory->recover( posind );
bool recover = ( params != NULL );
if ( params == NULL ) {
// Apply the LS to the best one with the rest of intensity
params = m_ls->getInitOptions( sol );
}
fitness = ind->perf( );
oldfitness = fitness;
clock_begin= clock( );
m_nevalls +=
m_ls->apply( params, sol, fitness, m_intensity );
m_time_ls += clock( )-clock_begin;
ind->incremCount( "ls" );
improvement_ls += fabs( fitness-oldfitness );
setDif( m_debug, "LS ", ind->getId( ), oldfitness, fitness );
if ( m_problem->isBetter( fitness, fitness_alg ) ) {
fitness_alg = fitness;
}
if ( !m_problem->isBetter( fitness, oldfitness ) ) {
ind->incremCount( "non_improved" );
if ( recover ) {
m_memory->remove( posind );
}
else {
delete params;
}
if ( m_disruption_size > 0 ) {
unsigned pos_best = pop_alg->getBest( );
tIndividualRealPtr ind_dis=NULL;
if ( posind != pos_best ) {
ind_dis = ind;
}
else {
if ( lastpos_better >= 0 ) {
ind_dis = pop_alg->getInd( lastpos_better );
if ( ind_dis->perf( ) != lastpos_fitness || pos_best == lastpos_better ) {
ind_dis = NULL;
}
}
lastpos_better = pos_best;
lastpos_fitness = pop_alg->getInd( lastpos_better )->perf( );
}
if ( ind_dis != NULL ) {
tChromosomeReal sol = ind_dis->sol( );
disturb( sol );
fitness = m_eval->eval( sol );
pop_alg->change( ind_dis->getId( ), sol, fitness );
}
}
if ( m_disruption_size == 0 && ind_to_improve.empty( ) && m_restart != NULL && !m_running->isFinish( ) ) {
m_restart->apply( pop_alg, m_problem, m_initeval );
if ( m_debug ) {
printf( "Restart_NotImprovement\t: %Le\n", fitness );
printf( "RunningRatio: %.0f\n", 100*m_running->ratio( ) );
}
}
}
else {
pop_alg->change( posind, sol, fitness );
m_memory->store( posind, params );
}
if ( m_restart != NULL && m_maxfailed > 0 ) {
if ( alg_failed > m_maxfailed && !hasDiversity( pop_alg ) && !m_running->isFinish( ) ) {
m_restart->apply( pop_alg, m_problem, m_initeval );
if ( m_debug ) {
printf( "Restart_AlgFailed\t: %Le\n", fitness_alg );
}
alg_failed = 0;
}
}
fflush( stdout );
}
m_time_ma = clock( )-m_time_ma_begin;
if ( m_debug ) {
double ratio_effort = ( ( double ) m_nevalalg )/( m_nevalalg+m_nevalls );
printf( "RatioEffort Alg/LS: [%.0f/%.0f]\n", 100*ratio_effort, 100*( 1-ratio_effort ) );
double ratio_alg = improvement_alg/( improvement_alg+improvement_ls );
printf( "RatioImprovement Alg/LS: [%.0f/%.0f]\n", 100*ratio_alg, 100*( 1-ratio_alg ) );
}
double time_ms_alg, time_ms_ls, time_ms_ma;
time_ms_alg = ( m_time_alg*1000.0 )/CLOCKS_PER_SEC;
time_ms_ls = ( m_time_ls*1000.0 )/CLOCKS_PER_SEC;
time_ms_ma = ( m_time_ma*1000.0 )/CLOCKS_PER_SEC;
printf( "Time[ALG]: %.2f\n", time_ms_alg );
printf( "Time[LS]: %.2f\n", time_ms_ls );
printf( "Time[MA]: %.2f\n", time_ms_ma );
printf( "Ratio[ALG/MA]: %.2f\n", 100*time_ms_alg/time_ms_ma );
printf( "Ratio[LS/MA]: %.2f\n", 100*time_ms_ls/time_ms_ma );
printf( "Ratio[( ALG+LS )/MA]: %.2f\n", 100*( time_ms_alg+time_ms_ls )/time_ms_ma );
unsigned neval = m_running->numEval( )-initMax;
best = pop_alg->getInd( pop_alg->getBest( ) );
bestsol = best->sol( );
bestfitness = best->perf( );
m_running->reset( );
return neval;
}
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _MA2LSI_H
#define _MA2LSI_H 1
#include "hybrid.h"
#include "restart.h"
#include "selectls.h"
#include "lsparammem.h"
namespace realea {
/**
* @class MA2LSI
*
* @brief memetic algorithm following the model proposed in the Daniel Molina's thesis
*/
35 class MA2LSI : public Hybrid {
public:
/**
* Constructor
*
*
*/
42 MA2LSI( IEAlgorithm *alg, ILocalSearch *ls );
44 ~MA2LSI( void );
/**
* @param ratio. Set the global ratio invested into the Local Search
*
* @param ratio global ls/total ratio
* ( change the intensity, because only one LS improvement is made )
*/
51 void setEffortRatio( double ratio );
52 void setDebug( void );
54 void recoverIndividual( unsigned oldind, tGen *aind, unsigned size, tGen *aoptional, unsigned size_optional );
55 void storeIndividual( tIndividualRealPtr ind, tGen **paind, unsigned *pmax, tGen **padditional, unsigned *pmaxad );
57 void setMaxEval( unsigned int maxeval );
59 void setSelectImprovementStrategy( SelectImprovementLS *select_improvement ) {
m_select_improvement = select_improvement;
}
63 void setRunning( Running *running );
65 RunningPtr getRunning( );
/**
* Set the restart strategy. If it is not called never it will make a restart.
*/
70 void setRestart( RestartStrategy *restart, int maxfailed=-1 );
/**
* Alter the EA and after the LS, then the EA again, the LS, ...
*/
75 unsigned realApply( tChromosomeReal &sol, tFitness &fitness );
76 unsigned init( void );
78 void setInitEval( IEval* eval );
/**
* Set a distorsion size when the solution is a local optimum
*
* @param size size of maximum disruption
*/
85 void setDisruptionSize( double size );
protected:
/**
* Check if there is enough diversity
*/
90 bool hasDiversity( PopulationReal *pop );
/**
* Set the differences
*/
95 void setDif( bool debug, string ident, unsigned id, tFitness oldfit, tFitness newfit );
protected:
/**
* Disturb the solution ( similar to mutation
* it uses the disruption_size
*
*/
103 void disturb( tChromosomeReal &sol );
protected:
double m_disruption_size;
107 internal::LSParametersMemory *m_memory;
108 unsigned m_nevalalg;
109 unsigned m_nevalls;
110 unsigned m_maxfailed;
111 IEvalInd *m_initeval;
112 unsigned m_initMaxEval;
double m_effort;
114 RestartStrategy *m_restart;
115 SelectImprovementLS *m_select_improvement;
116 bool m_debug;
};
};
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ma2lsia.h"
#include "selectlsimp.h"
#include <cassert>
#include <cmath>
#include <cstdio>
using namespace realea;
using namespace realea::internal;
29 void MA2LSIA::setEffortRatio( double ratio ) {
if ( ratio == 1 )
throw new string( "MA2LSIA::effortRatio is not valide" );
m_effort = ratio;
}
36 MA2LSIA::MA2LSIA( IEAlgorithm *alg, ILocalSearch *ls ) : Hybrid( alg, ls ), m_memory( NULL ) {
m_effort = -1;
m_restart = NULL;
m_debug = false;
m_select_improvement = NULL;
m_frec_update = 5;
}
44 void MA2LSIA::setDebug( void ) {
m_debug = true;
}
48 MA2LSIA::~MA2LSIA( void ) {
if ( m_memory ) {
delete m_memory;
}
if ( m_restart ) {
delete m_restart;
}
if ( m_select_improvement ) {
delete m_select_improvement;
}
if ( m_initeval ) {
delete m_initeval;
}
}
66 unsigned MA2LSIA::calculateFrec( double nevalalg, double nevalls, unsigned intensity, unsigned evalprev, double ratio ) {
assert( ratio > 0 );
double coc = ratio*( nevalalg + nevalls + intensity ) - evalprev;
double div = ( 1-ratio );
if ( div == 0 ) {
throw string( "MA2LSIA::Ratio is too low" );
}
return ( ( unsigned ) floor( coc/div ) );
}
80 unsigned MA2LSIA::init( void ) {
initLs( );
m_initMaxEval = m_running->maxEval( );
unsigned neval = m_alg->init( );
if ( m_select_improvement == NULL ) {
m_select_improvement = new SelectBestToImprove( );
}
if ( m_memory == NULL ) {
m_memory = new LSParametersMemory( m_alg->getPop( )->size( ) );
m_alg->getPop( )->setObserver( m_memory );
}
m_nevalalg = neval;
m_nevalls = 0;
return neval;
}
100 void MA2LSIA::setMaxEval( unsigned int maxeval ) {
assert( maxeval >= m_intensity );
unsigned frec = calculateFrec( m_nevalalg, m_nevalls, m_intensity, m_nevalalg, m_effort );
m_alg->setMaxEval( frec );
}
106 void MA2LSIA::setRestart( RestartStrategy *restart, int maxfailed ) {
if ( m_restart ) {
delete m_restart;
}
m_restart = restart;
m_maxfailed = maxfailed;
}
117 void MA2LSIA::setRunning( Running *running ) {
ProxyEA::setRunning( running );
unsigned frec = calculateFrec( m_nevalalg, m_nevalls, m_intensity, m_nevalalg, m_effort );
m_alg->setRunning( m_running->getSubRunning( frec ) );
}
123 void MA2LSIA::updateFrec( double ratio_effort, double ratio_improvement ) {
// Improvement of LS is lesser than expected
if ( ratio_effort != ratio_improvement ) {
double C = ratio_effort/ratio_improvement;
unsigned frec = ( unsigned ) ceil( C*m_intensity/( 1-C ) );
if ( frec < 50 ) {
frec = 50;
}
else if ( frec > 3000 ) {
frec = 3000;
}
printf( "New MaxEval: %u\n", frec );
m_alg->setMaxEval( frec );
}
}
143 void MA2LSIA::recoverIndividual( unsigned oldind, tGen *aind, unsigned size, tGen *aoptional, unsigned size_optional ) {
m_alg->recoverIndividual( oldind, aind, size-1, aoptional, size_optional );
if ( aind[size] ) {
m_alg->getPop( )->getInd( oldind )->incremCount( "non_improved" );
}
if ( aoptional != NULL ) {
IParallelLocalSearch *ls = ( IParallelLocalSearch * ) m_ls;
ILSParameters *params = ls->recoverOptions( aoptional, size_optional );
assert( m_memory );
m_memory->store( oldind, params );
}
}
159 void MA2LSIA::storeIndividual( tIndividualRealPtr ind, tGen **paind, unsigned *pmax, tGen **paoptional, unsigned *psize_optional ) {
tGen *asol, *aoptional_sol;
tGen *asol_ma;
unsigned size_sol, size_optional;
tGen *aparams;
unsigned size_param;
unsigned size;
m_alg->storeIndividual( ind, &asol, &size_sol, &aoptional_sol, &size_optional );
assert( size_optional == 0 && aoptional_sol == NULL );
asol_ma = new tGen[size_sol+1];
copy( asol, asol+size_sol, asol_ma );
delete[] asol;
asol_ma[size_sol] = ( ind->getCount( "non_improved" ) > 0 ) ? 1 : 0;
*paind = asol_ma;
*pmax = size_sol+1;
size_param = 0;
if ( m_memory ) {
unsigned posind = ind->getId( );
IParallelLocalSearch *ls = ( IParallelLocalSearch * ) m_ls;
ILSParameters *params = m_memory->recover( posind );
ls->storeOptions( params, &aparams, &size_param );
}
size = size_optional+size_param;
assert( size > 0 );
*psize_optional = size_param;
*paoptional = NULL;
if ( aoptional_sol != NULL || aparams != NULL ) {
*paoptional = new tGen[size];
if ( aoptional_sol != NULL ) {
copy( aoptional_sol, aoptional_sol+size_optional, *paoptional );
delete[] aoptional_sol;
}
if ( aparams != NULL ) {
copy( aparams, aparams+size_param, *paoptional+size_optional );
delete[] aparams;
}
}
}
209 void MA2LSIA::setDif( bool debug, string ident, unsigned id, tFitness oldfit, tFitness newfit ) {
if ( debug ) {
if ( oldfit!= newfit ) {
printf( "%s[%2d]:\t%e-> %e\t\t%e\n", ident.c_str( ), id, oldfit, newfit, fabs( newfit-oldfit ) );
}
else {
printf( "%s[%2d]:\t%e\n", ident.c_str( ), id, newfit );
}
}
}
222 bool MA2LSIA::hasDiversity( PopulationReal *pop ) {
return true;
double percen[5];
pop->getPercentils( percen, 4 );
printf( "EA::Improvement: %e\t%e\t%e\t%e\t%e\n", percen[0], percen[1],
percen[2], percen[3], percen[4] );
if ( percen[2] == percen[4] ) {
return false;
}
else if ( percen[1] == percen[3] ) {
return false;
}
else if ( fabs( ( percen[0] - percen[2] )/percen[2] ) < 1e-3 ) {
return false;
}
else {
return true;
}
}
246 void MA2LSIA::setInitEval( IEval*eval ) {
Hybrid::setInitEval( eval );
m_initeval = ( IEvalInd * ) new EvalRunning( eval, m_running );
}
251 unsigned MA2LSIA::realApply( tChromosomeReal &bestsol, tFitness &bestfitness ) {
tIndividualReal *ind, *best;
unsigned posind;
tFitness oldfitness, fitness, fitness_alg;
unsigned ndim = bestsol.size( );
tChromosomeReal sol( ndim ), sol_alg( ndim );
unsigned alg_failed;
PopulationReal *pop_alg = m_alg->getPop( );
deque<tIndividualReal*> ind_to_improve;
tFitness improvement_alg, improvement_ls;
tFitness improvement_alg_step, improvement_ls_step;
double nevalalg_step, nevalls_step;
tFitness improvement_ratio, old_improvement_ratio, improvement;
unsigned inc_neval;
sol=bestsol;
fitness = bestfitness;
improvement_alg = improvement_ls = 0;
improvement_alg_step = improvement_ls_step = 0;
nevalalg_step = nevalls_step = 0;
unsigned initMax = m_running->numEval( );
fitness_alg = pop_alg->getInd( pop_alg->getBest( ) )->perf( );
improvement_ratio = m_effort;
alg_failed = 0;
unsigned n_itera = 0;
// while ( ( m_nevalalg+m_nevalls ) < m_initMaxEval && !m_running->hasFoundOptime( ) ) {
while ( !m_running->isFinish( ) ) {
tFitness old_fitness = fitness_alg;
inc_neval = m_alg->realApply( sol_alg, fitness_alg );
m_nevalalg += inc_neval; nevalalg_step += inc_neval;
improvement = fabs( fitness_alg-old_fitness );
improvement_alg += improvement; improvement_alg_step += improvement;
if ( fitness_alg == old_fitness ) {
alg_failed++;
}
else {
alg_failed = 0;
}
if ( m_debug ) {
setDif( m_debug, "Alg", pop_alg->getBest( ), old_fitness, fitness_alg );
}
// Check the optime
if ( m_running->isOptime( fitness_alg ) ) {
continue;
}
// Select the new individual to increm
m_select_improvement->getIndsToImprove( pop_alg, ind_to_improve );
if ( ind_to_improve.size( )!=0 ) {
// Select the individual to improve
posind = m_select_improvement->selectIndToImprove( ind_to_improve );
}
else {
// Choose the new one randomly
posind = m_random->randint( 0, pop_alg->size( )-1 );
}
ind = pop_alg->getInd( posind );
sol = ind->sol( );
ILSParameters *params = m_memory->recover( posind );
bool recover = ( params != NULL );
if ( params == NULL ) {
// Apply the LS to the best one with the rest of intensity
params = m_ls->getInitOptions( sol );
}
fitness = ind->perf( );
oldfitness = fitness;
inc_neval = m_ls->apply( params, sol, fitness, m_intensity );
m_nevalls += inc_neval;
nevalls_step += inc_neval;
ind->incremCount( "ls" );
improvement = fabs( fitness-oldfitness );
improvement_ls += improvement;
improvement_ls_step += improvement;
setDif( m_debug, "LS ", ind->getId( ), oldfitness, fitness );
if ( m_problem->isBetter( fitness, fitness_alg ) ) {
fitness_alg = fitness;
}
if ( !m_problem->isBetter( fitness, oldfitness ) ) {
ind->incremCount( "non_improved" );
if ( recover ) {
m_memory->remove( posind );
}
else {
delete params;
}
if ( ind_to_improve.empty( ) && m_restart != NULL && !m_running->isFinish( ) ) {
m_restart->apply( pop_alg, m_problem, m_initeval );
if ( m_debug ) {
printf( "Restart_NotImprovement\t: %e\n", fitness );
}
}
}
else {
pop_alg->change( posind, sol, fitness );
m_memory->store( posind, params );
}
if ( m_restart != NULL && m_maxfailed > 0 ) {
if ( alg_failed > m_maxfailed && !hasDiversity( pop_alg ) && !m_running->isFinish( ) ) {
m_restart->apply( pop_alg, m_problem, m_initeval );
if ( m_debug ) {
printf( "Restart_AlgFailed\t: %e\n", fitness_alg );
}
alg_failed = 0;
}
}
n_itera ++;
if ( n_itera == m_frec_update ) {
old_improvement_ratio = improvement_ratio;
improvement_ratio = improvement_alg_step/( improvement_alg_step+improvement_ls_step );
updateFrec( old_improvement_ratio, improvement_ratio );
nevalalg_step = nevalls_step = 0;
improvement_alg_step = improvement_ls_step = 0;
n_itera = 0;
}
}
if ( m_debug ) {
double ratio_effort = ( ( double )m_nevalalg )/( m_nevalalg+m_nevalls );
printf( "RatioEffort Alg/LS: [%.0f/%.0f]\n", 100*ratio_effort, 100*( 1-ratio_effort ) );
double ratio_alg = improvement_alg/( improvement_alg+improvement_ls );
printf( "RatioImprovement Alg/LS: [%.0f/%.0f]\n", 100*ratio_alg, 100*( 1-ratio_alg ) );
}
unsigned neval = m_running->numEval( )-initMax;
best = pop_alg->getInd( pop_alg->getBest( ) );
bestsol = best->sol( );
bestfitness = best->perf( );
m_running->reset( );
m_alg->setMaxEval( m_intensity );
return neval;
}
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _MA2LSIA_H
#define _MA2LSIA_H 1
#include "hybrid.h"
#include "restart.h"
#include "selectls.h"
#include "lsparammem.h"
namespace realea {
/**
* @class MA2LSI
*
* @brief memetic algorithm following the model proposed in the Daniel Molina's thesis
*/
35 class MA2LSIA : public Hybrid {
public:
/**
* Constructor
*
*
*/
42 MA2LSIA( IEAlgorithm *alg, ILocalSearch *ls );
44 ~MA2LSIA( void );
/**
* @param ratio. Set the global ratio invested into the Local Search
*
* @param ratio global ls/total ratio
* ( change the intensity, because only one LS improvement is made )
*/
51 void setEffortRatio( double ratio );
52 void setDebug( void );
54 void recoverIndividual( unsigned oldind, tGen *aind, unsigned size, tGen *aoptional, unsigned size_optional );
55 void storeIndividual( tIndividualRealPtr ind, tGen **paind, unsigned *pmax, tGen **padditional, unsigned *pmaxad );
57 void setMaxEval( unsigned int maxeval );
59 void setSelectImprovementStrategy( SelectImprovementLS *select_improvement ) {
m_select_improvement = select_improvement;
}
63 void setRunning( Running *running );
/**
* Set the restart strategy. If it is not called never it will make a restart.
*/
68 void setRestart( RestartStrategy *restart, int maxfailed=-1 );
/**
* Alter the EA and after the LS, then the EA again, the LS, ...
*/
73 unsigned realApply( tChromosomeReal &sol, tFitness &fitness );
74 unsigned init( void );
76 void setInitEval( IEval* eval );
private:
/**
* Calculate the new frec to apply to obtain the indicated ratio.
*
* It is required because there are AEs that could not follow the frec indicated in the previous step
*
* @param nevalalg total number evaluation during the EA
* @param nevalls total number evaluation during the LS
* @param intensity LS intensity
*
* @return frec to use the EA to maintain the ratio
*/
90 unsigned calculateFrec( double nevalalg, double nevalls, unsigned intensity, unsigned neval, double ratio );
91 bool hasDiversity( PopulationReal *pop );
92 void setDif( bool debug, string ident, unsigned id, tFitness oldfit, tFitness newfit );
93 void updateFrec( double effort, double effort_obtained );
private:
96 internal::LSParametersMemory *m_memory;
97 unsigned m_frec_update;
98 unsigned m_nevalalg;
99 unsigned m_nevalls;
100 unsigned m_maxfailed;
101 IEvalInd *m_initeval;
102 unsigned m_initMaxEval;
double m_effort;
104 RestartStrategy *m_restart;
105 SelectImprovementLS *m_select_improvement;
106 bool m_debug;
};
};
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <cppunit/BriefTestProgressListener.h>
#include <cppunit/CompilerOutputter.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/TestRunner.h>
int
29 main( int argc, char* argv )
{
// Create the event manager and test controller
CPPUNIT_NS::TestResult controller;
// Add a listener that colllects test result
CPPUNIT_NS::TestResultCollector result;
controller.addListener( &result );
// Add a listener that print dots as test run.
CPPUNIT_NS::BriefTestProgressListener progress;
controller.addListener( &progress );
// Add the top suite to the test runner
CPPUNIT_NS::TestRunner runner;
runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry( ).makeTest( ) );
runner.run( controller );
// Print test in a compiler compatible format.
CPPUNIT_NS::CompilerOutputter outputter( &result, CPPUNIT_NS::stdCOut( ) );
outputter.write( );
return result.wasSuccessful( ) ? 0 : 1;
return 0;
}
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include "mutation.h"
#include "problem.h"
#include "random.h"
#include <cassert>
#include <string>
using std::string;
using namespace realea;
30 Mutation::Mutation( IMutation *mut, double ratio ) {
assert( mut != NULL );
m_mutation = mut;
if ( ratio < 0 || ratio > 1.0 ) {
throw new string( "Mutation::ratio is not a valide number" );
}
m_ratio = ratio;
m_random = NULL;
}
42 bool Mutation::apply( tChromosomeReal &sol ) {
bool changed = false;
unsigned size = sol.size( );
if ( m_ratio > 0 ) {
if ( !m_random ) {
throw ConfigException( "Mutation::random" );
}
changed = ( m_random->rand( ) <= m_ratio );
}
if ( changed ) {
unsigned pos;
do {
pos = m_random->randint( 0, size-1 );
} while( !m_domain->canBeChanged( pos ) );
sol[pos] = m_mutation->mutate( sol, pos );
}
return changed;
}
67 void Mutation::setRandom( Random *random ) {
m_random = random;
m_mutation->setRandom( random );
}
72 void Mutation::setDomain( DomainRealPtr domain ) {
m_mutation->setDomain( domain );
m_domain = domain;
}
77 tGen MutationBGA::mutate( tChromosomeReal &sol, unsigned pos ) {
const unsigned num=16;
const double pai = 1.0/num;
tReal rangi, min, max;
unsigned i;
double dif;
double sum=0;
if ( !m_domain ) {
new ConfigException( "MutationBGA::domain" );
}
m_domain->getValues( pos, &min, &max );
rangi = 0.1*( max-min );
if ( !m_random ) {
new ConfigException( "MutationBGA::random" );
}
for ( i = 0, dif = 1; i < num; i++, dif/=2 ) {
if ( m_random->rand( ) < pai ) {
sum += dif;
}
}
tGen value = sol[pos];
if ( sum == 0 ) {
return value;
}
// Obtain the sign
if ( m_random->rand( ) < 0.5 ) {
value += rangi*sum;
if ( value > max ) {
value = max;
}
}
else {
value -= rangi*sum;
if ( value < min ) {
value = min;
}
}
return( value );
}
129 Mutation::~Mutation( void ) {
if ( m_mutation ) {
delete m_mutation;
}
}
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _MUTATION_H
#define _MUTATION_H 1
#include "imutation.h"
namespace realea {
/**
* @class Mutation, mutación operator ( for AGs ).
*
* @ingroup realea_common
*
* Usage:
*
* m_mutation->apply( sol );
*
*/
37 class Mutation {
public:
/**
* Constructor.
*
* @param mut IMutation to be applied if it is decided
*
* @param ratio Ratio of individuals to be applied
*/
46 Mutation( IMutation *mut, double ratio=0.125 );
/**
* Set the random variable
*
* It must be speficied if Mutation is going to use it.
*
* @param random the random generation numbers.
*/
56 void setRandom( Random *random );
57 void setDomain( DomainRealPtr domain );
59 virtual ~Mutation( void );
/**
* This method check if must be applied the chromosome, in that case it is updated.
*
* @return true if the solution has been changed.
*/
65 bool apply( tChromosomeReal &sol );
private:
double m_ratio;
68 IMutation *m_mutation;
69 DomainRealPtr m_domain;
protected:
72 Random *m_random;
};
typedef Mutation* MutationPtr;
77 class MutationBGA : public IMutation {
public:
79 virtual tGen mutate( tChromosomeReal &sol, unsigned pos );
};
}
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include "orandom.h"
#define MASK 2147483647
#define PRIME 65539
#define SCALE 0.4656612875e-9
26 void ORandom::setSeed( unsigned long seed ) {
m_seed = seed;
}
30 double ORandom::rand( void ) {
m_seed = ( m_seed * PRIME ) & MASK;
return ( m_seed * SCALE );
}
35 unsigned long ORandom::getSeed( void ) {
return m_seed;
}
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _SRANDOM_H
#define _SRANDOM_H
#include "random.h"
/**
* @class ORandom
*
* @ingroup realea_common
*
* @brief This class generates number randomly using a pseudogenerator that uses a PRIME multiplication
*/
34 class ORandom : public IRealRandom {
/**
* init the seed
*
* @param seed ( value != 0 )
*/
40 void setSeed( unsigned long seed );
/**
* @return A random double between 0 and 1
*/
45 virtual double rand( void );
/**
* @return the actual seed
*/
50 unsigned long getSeed( void );
private:
unsigned long m_seed; /*< seed */
};
#endif
1 #ifndef _POPULATION_OBSERVER_H
/**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#define _POPULATION_OBSERVER_H 1
#include "real.h"
namespace realea {
/**
* @class PopulationObserver
*
* @brief This class allows to store an information for each individual
*
*/
33 class PopulationObserver {
public:
/**
* It is called when the population is restarted completely
*/
38 virtual void reset( void )=0;
/**
* It is called when a specific individual is changed
*
* @param id identification of the individual changed
*/
44 virtual void notifyChange( unsigned id )=0;
/**
* It is called when the id are changed.
*
* @param olid old identification id
* @param newid new identification id
* @see removeWorses
*/
52 virtual void changeId( unsigned oldid, unsigned newid )=0;
53 virtual ~PopulationObserver( void ) {}
};
}
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include "populationreal.h"
#include "random.h"
#include "initind.h"
#include "define.h"
#include <algorithm>
#include <iostream>
#include <cassert>
using std::sort;
using namespace realea;
using realea::internal::SimpleInitInd;
using realea::internal::UniformInitInd;
33 void PopulationReal::setObserver( PopulationObserver *observer ) {
m_observers.push_back( observer );
}
37 PopulationReal::PopulationReal( Random *random, unsigned int max, unsigned int pob ):
m_aditionalsize( max ), m_size( pob ), m_individuals( ),
m_random( random ),
m_knownbest( false ), m_knownworst( false ), m_observers( ) {
m_individuals.reserve( m_aditionalsize );
// m_initInd = new SimpleInitInd( m_random );
m_initInd = new UniformInitInd( m_random );
}
46 PopulationReal::~PopulationReal( void ) {
vector<tIndividualRealPtr>::iterator item;
deque<PopulationObserver*>::iterator observer;
for ( item = m_individuals.begin( ); item != m_individuals.end( ); ++item ) {
delete ( *item );
}
m_observers.clear( );
if ( m_initInd ) {
delete m_initInd;
}
}
template<class T>
63 void call_reset( T *elem ) {
elem->reset( );
}
67 void PopulationReal::reset( DomainRealPtr domain, int posi ) {
unsigned size = m_individuals.size( );
tIndividualRealPtr old=NULL;
m_knownbest = m_knownworst = false;
if ( posi >= 0 ) {
old = m_individuals[posi];
m_individuals[posi] = NULL;
}
for ( int i = 0; i < size; ++i ) {
if ( m_individuals[i] ) {
delete m_individuals[i];
m_individuals[i] = NULL;
}
}
if ( !m_individuals.empty( ) ) {
m_individuals.erase( m_individuals.begin( ), m_individuals.end( ) );
}
if ( old != NULL ) {
m_initInd->resetBest( domain, old->sol( ), m_size );
}
else {
m_initInd->reset( domain, m_size );
}
for ( unsigned i = 0; i < m_size; ++i ) {
tChromosomeReal crom;
if ( i != posi ) {
m_initInd->createInd( domain, crom );
tIndividualReal *individual = getInstance( crom );
individual->setId( i );
m_individuals.push_back( individual );
}
else {
m_individuals.push_back( old );
}
}
resetObservers( );
}
112 tIndividualReal *PopulationReal::getInstance( tChromosomeReal &crom ) {
return new tIndividualReal( crom );
}
116 tIndividualReal *PopulationReal::getInstance( tChromosomeReal &crom, tFitness fitness ) {
return new tIndividualReal( crom, fitness );
}
120 bool isNull( tIndividualReal *ind ) {
return ( ind==NULL );
}
124 bool PopulationReal::thereNull( void ) {
return false;
vector<tIndividualReal*>::iterator posNull = find_if( m_individuals.begin( ), m_individuals.end( ), isNull );
return ( posNull != m_individuals.end( ) );
}
131 void PopulationReal::updateObservers( void ) {
vector<tIndividualReal*>::iterator posind;
deque<PopulationObserver*>::iterator observer;
tIndividualRealPtr individual;
unsigned newid, oldid;
for ( newid = 0, posind = m_individuals.begin( ); posind != m_individuals.end( ); ++posind ) {
for ( observer = m_observers.begin( ); observer != m_observers.end( ); ++observer ) {
individual = *posind;
oldid = individual->getId( );
newid++;
individual->setId( newid );
( *observer )->changeId( oldid, newid );
}
}
}
/**
* Update the identifications of a specific individual
*
* @param id individual id to notify
*/
154 void PopulationReal::notifyObservers( unsigned id ) {
deque<PopulationObserver*>::iterator observer;
for ( observer = m_observers.begin( ); observer != m_observers.end( ); ++observer ) {
( *observer )->notifyChange( id );
}
}
/**
* Update the identifications of individuals ( it is called after removeWorses )
*
* @see removeWorses sort
*/
167 void PopulationReal::resetObservers( void ) {
deque<PopulationObserver*>::iterator observer;
for ( observer = m_observers.begin( ); observer != m_observers.end( ); ++observer ) {
( *observer )->reset( );
}
}
176 void PopulationReal::sort( void ) {
tIndividualReal::sort( m_individuals );
m_knownbest = m_knownworst = true;
m_best = 0;
m_worst = m_individuals.size( )-1;
if ( thereNull( ) ) {
throw new string( "PopulationReal::sort, there is null" );
}
}
189 bool isNotEval( tIndividualReal *ind ) {
return ( !ind->isEval( ) );
}
193 void PopulationReal::removePending( void ) {
if ( m_individuals.empty( ) )
return;
// All not evaluated are at the end
vector<tIndividualReal*>::iterator beginNotEval = find_if( m_individuals.begin( ), m_individuals.end( ), isNotEval );
// Check there is eval and not eval
if ( ( beginNotEval != m_individuals.end( ) ) ) {
remove( beginNotEval-m_individuals.begin( ), m_individuals.size( ) );
}
}
206 void PopulationReal::remove( unsigned begin, unsigned end ) {
assert( begin <= end );
assert( end <= m_individuals.size( ) );
for ( unsigned i = begin; i < end; i++ ) {
delete m_individuals[i];
m_individuals[i]=NULL;
}
vector<tIndividualReal*>::iterator base = m_individuals.begin( );
m_individuals.erase( base+begin, base+end );
}
219 void PopulationReal::removeWorses( void ) {
sort( );
removePending( );
unsigned size = m_individuals.size( );
if ( !m_individuals.empty( ) && size > m_size ) {
remove( m_size, size );
}
updateObservers( );
m_worst = m_individuals.size( )-1;
}
232 void PopulationReal::random( void ) {
unsigned int size=m_individuals.size( );
int ssize, pos;
if ( size == 0 )
return;
m_knownbest = m_knownworst = false;
ssize = size;
int *sample = new int[size];
initSample( sample, ssize );
for ( unsigned i = 0; i < size; ++i ) {
pos = m_random->getSample( sample, &ssize );
swap( m_individuals[i], m_individuals[pos] );
}
delete[] sample;
}
253 tIndividualReal *PopulationReal::getInd( unsigned int pos ) {
assert( pos < m_size );
return m_individuals[pos];
}
258 void PopulationReal::append( tChromosomeReal &sol, tFitness fitness ) {
tIndividualRealPtr ind = getInstance( sol, fitness );
ind->setId( m_individuals.size( ) );
m_individuals.push_back( ind );
}
264 void PopulationReal::append( tIndividualReal *real ) {
if ( m_individuals.size( ) == m_aditionalsize ) {
throw new runtime_error( "maximum number of elems in population" );
}
m_individuals.push_back( real );
m_knownbest = m_knownworst = false;
}
273 void PopulationReal::change( unsigned int pos, const tChromosomeReal &sol, tFitness fitness ) {
assert( pos < m_size );
m_individuals[pos]->change( sol, fitness );
m_knownbest = m_knownworst = false;
}
279 unsigned PopulationReal::getBest( void ) {
assert( !m_individuals.empty( ) );
unsigned int ind;
tIndividualReal *current, *best;
int pos_best;
if ( m_knownbest ) {
return m_best;
}
pos_best = -1;
best = NULL;
unsigned size = m_individuals.size( );
for ( ind = 0; ind < size; ++ind ) {
current = m_individuals[ind];
if ( !current->isEval( ) ) {
continue;
}
if ( best == NULL ) {
pos_best = ind;
best = current;
}
else if ( current->isBetter( best ) ) {
best = current;
pos_best = ind;
}
}
m_best = pos_best;
m_knownbest = true;
return pos_best;
}
316 class PopulationSort {
public:
318 bool operator( )( const unsigned &posa, const unsigned &posb ) {
if ( !m_inds[posa]->isBetter( m_inds[posb] ) )
return false;
else
return true;
}
324 PopulationSort( vector<tIndividualRealPtr> &v ) : m_inds( v ) {}
private:
326 vector<tIndividualRealPtr> m_inds;
};
329 vector<unsigned> PopulationReal::getBests( unsigned num ) {
vector<unsigned> positions( m_size );
vector<unsigned> bests( num );
for ( unsigned i = 0; i < m_individuals.size( ); i++ ) {
positions[i] = i;
}
partial_sort( positions.begin( ), positions.begin( )+num, positions.end( ),
PopulationSort( m_individuals ) );
copy( positions.begin( ), positions.begin( )+num, bests.begin( ) );
return bests;
}
344 unsigned PopulationReal::getWorst( void ) {
assert( !m_individuals.empty( ) );
unsigned int ind;
tIndividualReal *current, *worst;
int pos_worst=-1;
if ( m_knownworst ) {
return m_worst;
}
worst = NULL;
unsigned size = m_individuals.size( );
for ( ind = 0; ind < size; ++ind ) {
current = m_individuals[ind];
if ( !current->isEval( ) ) {
continue;
}
if ( worst == NULL ) {
pos_worst = ind;
worst = current;
}
else if ( current->isWorse( worst ) ) {
worst = current;
pos_worst = ind;
}
}
m_worst = pos_worst;
m_knownworst = true;
return pos_worst;
}
380 void PopulationReal::eval( IEvalInd *evalInd, unsigned neweval ) {
vector<tIndividualRealPtr>::iterator item;
bool maxEval = false;
for ( item = m_individuals.begin( ); item != m_individuals.end( ) && !maxEval; ++item ) {
if ( !( *item )->isEval( ) ) {
neweval -=
evalInd->eval( *item );
if ( neweval == 0 ) {
maxEval = true;
}
}
}
}
397 unsigned PopulationReal::size( void ) {
if ( m_individuals.size( ) < m_size )
return m_individuals.size( );
else
return m_size;
}
405 unsigned PopulationReal::ndim( void ) {
assert( m_individuals.size( ) > 0 );
return m_individuals[0]->sol( ).size( );
}
410 void PopulationReal::replace( unsigned pos, tIndividualRealPtr newind ) {
tIndividualRealPtr old = m_individuals[pos];
m_individuals[pos] = newind;
m_individuals[pos]->setId( old->getId( ) );
delete old;
notifyObservers( pos );
// Update the best and worst positions
if ( m_knownbest ) {
if ( m_best == pos ) {
m_knownbest = false;
}
else if ( newind->isBetter( m_individuals[m_best] ) ) {
m_best = pos;
}
}
if ( m_knownworst ) {
if ( m_worst == pos ) {
m_knownworst = false;
}
else if ( newind->isWorse( m_individuals[m_worst] ) ) {
m_worst = pos;
}
}
}
441 tFitness PopulationReal::getMean( void ) {
tFitness sum=0;
unsigned i;
assert( !m_individuals.empty( ) );
for ( i = 0; i < m_individuals.size( ) && m_individuals[i]->isEval( ); ++i ) {
sum += m_individuals[i]->perf( );
}
assert( i == m_individuals.size( ) );
return sum/m_individuals.size( );
}
454 tFitness PopulationReal::getMedian( void ) {
vector<unsigned> positions( m_size );
unsigned num, posi;
for ( unsigned i = 0; i < m_individuals.size( ); i++ ) {
positions[i] = i;
}
num = m_individuals.size( )/2;
partial_sort( positions.begin( ), positions.begin( )+num, positions.end( ),
PopulationSort( m_individuals ) );
posi = positions[num-1];
return m_individuals[posi]->perf( );
}
470 void PopulationReal::getPercentils( double *percen, unsigned num ) {
vector<unsigned> positions( m_size );
unsigned i, posi;
for ( i = 0; i < m_individuals.size( ); i++ ) {
positions[i] = i;
}
partial_sort( positions.begin( ), positions.end( ), positions.end( ),
PopulationSort( m_individuals ) );
percen[0] = m_individuals[getBest( )]->perf( );
for ( i = 1; i <= num; ++i ) {
posi = i*m_size/num;
posi = positions[posi-1];
percen[i] = m_individuals[posi]->perf( );
}
}
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _POPULATION_H
#define _POPULATION_H 1
#include "individual.h"
#include "domain.h"
#include "initind.h"
#include "random.h"
#include "define.h"
#include "popobserver.h"
#include <deque>
using namespace std;
namespace realea {
/**
* @class PopulationReal
* @ingroup realea_common
*
* @brief Stores the individuals ( solutions )
*
* Stores a group of individuals ( its size m_minsize is fixed, but a temporal greater number m_aditionalsize is allowed )
*/
44 class PopulationReal {
public:
/**
* Constructor.
* @param random generator of the population
* @param max maximum population size.
* @param pob normal population size.
*/
52 PopulationReal( Random *random, unsigned int max, unsigned int pob );
53 virtual ~PopulationReal( void );
/**
* Reset the population size randomly.
*
* @param domain domain of individuals.
* @param init the begin position of individuals to be restarted.
* ( init = -1 does not keep anyone. init == x keep the individual )
*/
61 virtual void reset( DomainRealPtr domain, int init=-1 );
/**
* Removes the ( m_aditionalsize - m_minsize ) worse individuals.
*/
66 void removeWorses( void );
/**
* Orders randomly the individuals
*/
71 void random( void );
/**
* Sorts the individuals in function of its fitness
*/
76 void sort( void );
/**
* @param pos the position
* @return the current individual in position pos
*/
82 tIndividualReal *getInd( unsigned int pos );
/**
* Replaces the current individual in position pos with new individual real
*
* @param pos of the current individual to be removed ( > 0 <= size( ) )
* @param ind new individual to be inserted
*/
90 void replace( int pos, const tIndividualReal *ind );
/**
* Append a new individual
*
* @param ind new individual
*/
97 void append( tIndividualReal *ind );
98 void append( tChromosomeReal &sol, tFitness fitness );
/**
* change the current position with individual sol
*/
102 void change( unsigned int pos, const tChromosomeReal &sol, tFitness fitness );
/**
* Este método permite reemplazar un individuo de la población
* por un nuevo individuo
*/
108 void replace( unsigned pos, tIndividualRealPtr newind );
/**
* @return the position of best individual ( by fitness )
* @see getBests
*/
114 unsigned getBest( void );
/**
* @return the Median of the population's fitness
*/
119 tFitness getMedian( void );
/**
* @return the mean of the population's fitness
*/
123 tFitness getMean( void );
/**
* Obtain the difference percentiles ( useful to test the behaviour
* population
*/
128 void getPercentils( double *percen, unsigned num );
/**
* @return the positions of best individuals ( by fitness )
*
* @param num the number of best individuals to return.
* ( if num == 1 it is equals that call to getBest )
* @see getBest
*/
136 vector<unsigned> getBests( unsigned num );
/**
* @return the position of worst individual ( by fitness )
*/
141 unsigned getWorst( void );
/**
* @return the actual size ( ignoring individual )
*/
145 unsigned size( void );
/**
* @return dimension of individuals
*/
149 unsigned ndim( void );
/**
* The current new individuals are evaluated.
*
* @param fitness Fitness class.
* @param neweval maximum new evaluations ( -1 not limit )
*/
156 void eval( IEvalInd *fitness, unsigned newevals=-1 );
/**
* add Observer
*/
161 void setObserver( PopulationObserver *observer );
/**
* get a new instance of a chromosome
*/
166 virtual tIndividualReal* getInstance( tChromosomeReal &crom, tFitness fitness );
/**
* get a new instance of a chromosome
*/
171 virtual tIndividualReal* getInstance( tChromosomeReal &crom );
private:
/**
* Update the identifications of individuals ( it is called after removeWorses )
*
* @see removeWorses sort
*/
180 void updateObservers( void );
/**
* Update the identifications of individuals ( it is called after removeWorses )
*
* @see removeWorses sort
*/
187 void resetObservers( void );
/**
* @return true if there is an individual null
*/
192 bool thereNull( void );
/**
* Remove all individuals between begin and end ( included )
*
* @param begin initial elem ( included )
* @param end finish elem ( excluded )
*/
200 void remove( unsigned begin, unsigned end );
/**
* Remove all individuals with not been evaluated
*/
204 void removePending( void );
unsigned int m_aditionalsize, /**< Aditional size ( for storing temporally more individual */
m_size; /**< Normal size of population */
210 vector<tIndividualReal*> m_individuals; /**< vector of individuals stored into the population */
212 unsigned m_best; /*< position of best individual */
213 unsigned m_worst; /*< position of worst individual */
216 bool m_knownbest;
217 bool m_knownworst;
218 InitIndividual *m_initInd; /*< Creator of new individuals */
219 deque<PopulationObserver *>m_observers; /**< Store the class to notify */
protected:
/**
* Update the identifications of a specific individual
*
* @param id individual id to notify
*/
227 void notifyObservers( unsigned id );
230 Random *m_random; /*< random generator */
};
typedef PopulationReal* PopulationRealPtr;
}
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include "problem.h"
#include <cassert>
#include "running.h"
using namespace realea;
26 Problem::Problem( void ) : m_checkOptime( NULL ), m_domain( NULL ) {
}
29 bool Problem::isBetter( tFitness value1, tFitness value2 ) {
return m_checkOptime->isBetter( value1, value2 );
}
33 bool Problem::minimize( void ) {
if ( m_domain == NULL ) {
throw new ConfigException( "domain" );
}
return m_checkOptime->minimize( );
}
41 bool Problem::maximize( void ) {
return !minimize( );
}
45 void Problem::setMaximize( void ) {
m_checkOptime->setMaximize( );
}
49 void Problem::setMinimize( void ) {
m_checkOptime->setMinimize( );
}
54 void Problem::setDimension( unsigned int dim ) {
m_domain = new DomainReal( dim );
}
58 void Problem::setDomainValues( unsigned int gen, tGen min, tGen max, bool check ) {
if ( m_domain == NULL ) {
throw new ConfigException( "domain" );
}
m_domain->setValues( gen, min, max, check );
}
67 Problem::~Problem( void ) {
if ( m_checkOptime ) {
delete m_checkOptime;
}
if ( m_domain ) {
delete m_domain;
}
}
78 void Problem::setOptimize( tFitness optime, double threshold ) {
m_checkOptime = new OptimeCriterion( optime, threshold );
}
82 DomainRealPtr Problem::getDomain( void ) {
if ( m_domain == NULL ) {
throw new ConfigException( "domain" );
}
return m_domain;
}
89 void Problem::setThreshold( double dif ) {
if ( m_checkOptime == NULL ) {
throw new ConfigException( "optime" );
}
m_checkOptime->setThreshold( dif );
}
97 tFitness Problem::getOptime( void ) {
if ( m_checkOptime == NULL ) {
throw new ConfigException( "optime" );
}
return m_checkOptime->getOptime( );
}
104 void Problem::setEval( tEval eval ) {
m_eval = eval;
}
108 void Problem::setMaxEval( unsigned eval ) {
m_maxeval = eval;
}
112 unsigned Problem::getMaxEval( void ) {
return m_maxeval;
}
119 tFitness Problem::eval( const tChromosomeReal &sol ) {
tFitness fit = ( *m_eval )( &sol[0], sol.size( ) );
return fit;
}
124 unsigned Problem::getDimension( void ) {
return m_domain->getDimension( );
}
128 void Problem::copy( Problem *problem ) {
assert( problem->m_checkOptime == NULL &&
problem->m_domain == NULL );
problem->m_checkOptime = this->m_checkOptime;
problem->m_domain = this->m_domain;
problem->m_eval = this->m_eval;
problem->m_maxeval = this->m_maxeval;
}
/**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CONFIGPROGRAM_
#define _CONFIGPROGRAM_ 1
#include "signal.h"
#include "domain.h"
#include "define.h"
#include "running.h"
#include <string>
#include <stdexcept>
#include <memory>
#include <memory>
using namespace std;
namespace realea {
38 class ConfigException: public runtime_error {
private:
40 string m_name;
public:
43 ConfigException( string name ) : runtime_error( name ) {
m_name = name;
}
public:
virtual ~ConfigException( void ) throw ( ) { }
virtual const char *what( void ) {
string msg;
51 msg = "Parameter Config " +m_name +" is not yet defined";
52 return msg.c_str( );
}
};
typedef tFitness ( *tEval )( const tGen *x, int dim );
/**
* @class Problem
*
* @brief This class represent a problem to be resolved
*
* To apply the EA to new problems, a subclass of ProblemFactory must be defined, and it must
* return an adequated initialized problem ( instance of this class )
*
* @see ProblemFactory
*/
68 class Problem : public Resetable, public IEval {
public:
/**
* Destructor
*/
73 virtual ~Problem( void );
/**
* Constructor
*/
77 Problem( void );
/**
* Set the function evaluation. It is a function that return a tFitness from a Chromosome real
* typedef tFitness ( *tEval )( const tGen *x, int dim )
*
* @param eval Evaluation function.
*/
85 void setEval( tEval eval );
/**
* Set the minimize criterion
*/
90 void setMinimize( void );
/**
* Set the minimize criterion
*/
94 void setMaximize( void );
/**
* @return true if it is a minimization problem
*/
98 bool minimize( void );
/**
* @return true if it is a maximization problem
*/
102 bool maximize( void );
/**
* @return true value1 is better than value2 in the problem
*/
106 bool isBetter( tFitness x, tFitness y );
/**
* Set the problem's dimensionality
*
* @param dim new dimensionality
*/
113 void setDimension( unsigned int dim );
/**
* @return the dimensionality of current problem
*/
117 virtual unsigned int getDimension( void );
/**
* Set for a gen the range ( maximum and minimum values )
*
* @param gen pos of current gen to set ( from 0..getDimension( )-1 )
* @param min minimum value
* @param max maximum value
* @param check set if the gen must be checked, default true
*/
127 void setDomainValues( unsigned int gen, tGen min, tGen max, bool check=true );
/**
* Set the optimum value and the threshold
* A solution is an optimum if their difference in fitness with the optimum
* is lower than this threshould ( if it is not defined, threshold is equal to 0 )
* @param optime optimum value
* @param threshold threshold value ( must be positive )
*/
137 void setOptimize( tFitness optime, double threshold );
/**
* Set the threshold, a solution is an optimum if their difference in fitness with the optimum
* is lower than this threshould ( if it is not defined, threshold is equal to 0 )
*
* @param dif threshold value ( must be positive )
*
*/
146 void setThreshold( double dif );
/**
* Set the maximum evaluation number for the problem
*
* @param maxeval maximum eval number
*/
153 void setMaxEval( unsigned int maxeval );
/**
* @return the maximum evaluation number
*/
158 unsigned getMaxEval( void );
/**
* @return the domain of the problem
*/
164 virtual DomainRealPtr getDomain( void );
/**
* @return the optime value
*/
168 tFitness getOptime( void );
170 OptimeCriterion *getFinishCriterion( void ) {
return m_checkOptime;
}
174 unsigned getMaxEval( unsigned max );
176 tFitness eval( const tChromosomeReal &sol );
177 void copy( Problem *problem );
protected:
OptimeCriterion *m_checkOptime;
181 DomainRealPtr m_domain;
182 unsigned m_maxeval;
183 tEval m_eval;
};
typedef auto_ptr<Problem> ProblemPtr;
typedef ProblemPtr& ProblemParamPtr;
191 void setProblem( Problem* &prob );
192 Problem* getProblem( void );
}
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _PROBLEM_FACTORY_H
#define _PROBLEM_FACTORY_H 1
#include "problem.h"
namespace realea {
28 class ProblemFactory {
public:
30 virtual ProblemPtr get( unsigned int ident=1 )=0;
31 virtual ~ProblemFactory( void ) {
}
};
}
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include "problemtablefactory.h"
#include <cassert>
using namespace realea;
25 ProblemTableFactory::ProblemTableFactory( unsigned maxeval, FUNCTION *fun, unsigned max ) {
m_fun = fun;
m_max = max;
m_maxeval = maxeval;
}
31 ProblemTableFactory::~ProblemTableFactory( void ) {
m_fun = NULL;
};
35 ProblemPtr ProblemTableFactory::get( unsigned int ident ) {
ProblemPtr prob ( new Problem( ) );
assert( ident >= 1 && ident <= m_max );
// Obtengo la función
FUNCTION *fun = &( m_fun[ident-1] );
// Inicio el problema
unsigned ndim = fun->genes;
prob->setDimension( ndim );
double min = fun->range[0];
double max = fun->range[1];
for ( unsigned i = 0; i < ndim; ++i ) {
prob->setDomainValues( i, min, max, true );
}
prob->setOptimize( fun->optime, 0 );
prob->setMaxEval( m_maxeval );
prob->setMinimize( );
prob->setEval( fun->eval );
return prob;
}
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _PROBLEM_TABLE_FACTORY_H
#define _PROBLEM_TABLE_FACTORY_H 1
#include "problemfactory.h"
namespace realea {
/**
* @file La idea de la clase ProblemTableFactory es facilitar la creación de
* benchmark
*
* La clase FUNCTION permite especificar los parámetros necesarios para
* una función de evaluación.
*/
struct FUNCTION {
int ident; /**< Parámetro identificador de la función */
int genes; /**< Dimensión de las soluciones */
string name; /**< Nombre de la función ( para poder mostrarla en pantalla */
tEval eval; /**< Puntero a la función de evaluación */
tGen range[2]; /**< Guarda los valores mÃnimos y máximos para dicha función */
tGen initrange[2]; /**< Guarda los valores mÃnimos y máximos de la inicialización dicha función */
double optime; /**< Valor óptimo */
};
/**
* @class Permite crear fácilmente clases de tipo ProblemFactory para un conjunto
* de funciones.
*/
49 class ProblemTableFactory : public ProblemFactory {
public:
/**
* Asigna la tabla de funciones a la clase. Nunca se borrará, para poder
* usar una tabla estática
*
* @param maxeval maximum eval
* @param fun tabla de funciones
* @param max vector de elementos
*/
59 ProblemTableFactory( unsigned maxeval, FUNCTION *fun, unsigned max );
60 ~ProblemTableFactory( void );
61 ProblemPtr get( unsigned int ident );
private:
FUNCTION *m_fun;
64 unsigned m_max;
65 unsigned m_maxeval;
};
}
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include "random.h"
#include <iostream>
#include <math.h>
#include <cassert>
using namespace std;
27 Random::Random( IRealRandom *random ) {
assert( random != NULL );
this->random = random;
}
32 Random::~Random( void ) {
delete this->random;
}
const double PI=3.1415926;
39 double Random::normal( double desv ) {
double u1, u2;
double result;
do {
u1=Random::rand( );
} while ( u1 == 0 );
u2=Random::rand( );
result = desv * sqrt ( -2*log( u1 ) ) * sin ( 2*PI*u2 );
return result;
}
53 void initSample( int *sample, int max ) {
int i;
for ( i = 0; i < max; i++ ) {
sample[i] = i;
}
}
61 int Random::getSample( int *sample, int *pmax ) {
int max = *pmax;
int r, pos;
assert( max >= 0 );
r = randint( 0, max-1 );
pos = sample[r];
sample[r] = sample[max-1];
--max;
*pmax = max;
return pos;
}
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _IRANDOM_H
#define _IRANDOM_H
/**
* @class IRealRandom
*
* This class generates a new real value randomly
* It is used by class Random to create all individuals
*/
30 class IRealRandom {
/**
* @return A random double between 0 and 1
*/
public:
35 virtual double rand( void )=0;
36 virtual ~IRealRandom( void ) {}
};
/**
* @class Random
*
* @ingroup realea_common
* @brief This class generates number randomly.
*
*/
48 class Random {
public:
/**
* Constructor. It requires a simple number generator
*
* @param random real random generator
*/
55 Random( IRealRandom *random );
/**
* Destructor. Release the IRealRandom object
*/
59 virtual ~Random( void );
/**
* @return A random double between 0 and 1
*/
64 double rand( void ) {
return this->random->rand( );
}
/**
* Generates randomly a integer between low and high
*
* @param low lowest value
* @param high higher value
*
* @return an integer in [low, high] randomly generated
*/
77 int randint( unsigned low, unsigned high ) {
double random;
random = Random::rand( );
return ( ( int ) ( low + ( high-low+1 )*random ) );
}
/**
* Generates randomly a double between low and high
*
* @param low lowest value
* @param high higher value
*
* @return a double in [low, high] randomly generated
*/
92 double randreal( double low, double high ) {
return ( low + ( high-low )*Random::rand( ) );
}
/**
* Generate a double number following a normal distribution with
* center in 0 and std as its standard desviation
*
* @param std Standard Deviation
* @return a double in the range [0, 1]
*/
104 virtual double normal( double desv );
/**
* return a position value of a vector positions
*
* @param sample array of positions
* @param pmax maximum size of sample, it is modified
*
* @return a position randomly chosen
*/
114 int getSample( int *sample, int *pmax );
private:
116 IRealRandom *random; /** < Generator of new number */
};
typedef Random* RandomPtr;
/**
* Allows to generate a array of positions ( to easier the random election of positions
* @param sample array of positions, will be replaced with the valores of position ( 0, ..., max-1 )
* @param max maximum size
*
*/
127 void initSample( int *sample, int max );
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file This file contains the definition of real chromosomes
*/
#ifndef _REALEA_REAL_H
#define _REALEA_REAL_H 1
#include <vector>
using namespace std;
#ifndef _tGen
typedef double tReal;
typedef tReal tGen;
#define _tGen
#endif
#ifndef _TFITNESS
typedef long double tFitness;
#define _TFITNESS 1
#endif
namespace realea {
typedef vector<tReal> tChromosomeReal;
}
#endif
1 #include "restart.h"
using namespace realea;
5 void RestartBest::apply( PopulationReal *pop_alg, Problem *problem, IEvalInd *initeval ) {
pop_alg->reset( problem->getDomain( ), pop_alg->getBest( ) );
pop_alg->eval( initeval );
}
10 RestartReduce::RestartReduce( double scale ) : RestartBest( ) {
m_scale = scale;
}
14 void RestartReduce::apply( PopulationReal *pop_alg, Problem *problem, IEvalInd *initeval ) {
DomainRealPtr domain = problem->getDomain( );
tIndividualReal *best = pop_alg->getInd( pop_alg->getBest( ) );
domain->setDomainCenter( best->sol( ), m_scale );
RestartBest::apply( pop_alg, problem, initeval );
}
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _RESTART_H
#define _RESTART_H 1
#include "real.h"
#include "define.h"
#include "problem.h"
#include "populationreal.h"
namespace realea {
/**
* @class RestartStrategy Set the restart strategy over a population
*
* It
*/
35 class RestartStrategy {
public:
37 virtual void apply( PopulationReal *pop_alg, Problem *problem, IEvalInd *eval )=0;
38 virtual ~RestartStrategy( ) {}
};
/**
* @class RestartBest. Restart all the population individuals except the best one
*/
44 class RestartBest: public RestartStrategy {
public:
46 RestartBest( void ) {}
47 void apply( PopulationReal *pop_alg, Problem *problem, IEvalInd *eval );
};
/**
* @class RestartReduce. Restart all the population individuals except the best one, and set the
* domain space
*/
54 class RestartReduce: public RestartBest {
public:
56 RestartReduce( double scale );
57 void apply( PopulationReal *pop_alg, Problem *problem, IEvalInd *eval );
private:
double m_scale;
};
}
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include "running.h"
#include <math.h>
#include <cassert>
#include <cstdio>
using namespace realea;
OptimeCriterion::OptimeCriterion( double optime, double dif ) {
m_optime = optime;
m_threshold = dif;
}
void OptimeCriterion::setThreshold( double dif ) {
assert( dif > 0 );
m_threshold = dif;
}
bool OptimeCriterion::isOptime( double fitness ) {
if ( fitness < m_optime )
return true;
else
return ( fitness-m_optime <= m_threshold );
}
double OptimeCriterion::getThreshold( void ) {
return m_threshold;
}
48 void Running::increm( void ) {
if ( m_optimized ) {
printf( "Warning: Optimized value achieved\n" );
// throw new RunningException( "Optimized value achieved" );
}
if ( m_maxmsecs == 0 && m_neval == m_maxeval ) {
printf( "Warning: Max eval achieved\n" );
// throw new RunningException( "Max eval achieved" );
}
m_neval += 1;
}
62 void Running::reset( void ) {
m_neval = 0;
m_timeInit = clock( );
m_optimized = false;
}
68 Running::Running( OptimeCriterion *isOptime ) : m_checkOptime( isOptime ), m_children( ) {
m_maxeval = m_neval = 0;
m_optimized = false;
m_parent = NULL;
m_maxmsecs = 0;
m_timeInit = 0;
}
76 void Running::setMaxEval( unsigned int max ) {
m_maxeval = max;
m_neval = 0;
}
81 unsigned int Running::maxEval( void ) {
return m_maxeval;
}
85 bool Running::isOptime( double fitness ) {
if ( m_checkOptime->isOptime( fitness ) ) {
m_optimized = true;
return true;
}
else {
return false;
}
}
96 bool Running::isFinish( void ) {
if ( m_optimized || ( m_maxmsecs == 0 && ( m_neval >= m_maxeval ) ) ) {
return true;
}
else if ( m_parent != NULL ) {
return m_parent->isFinish( );
}
else if ( m_maxmsecs > 0 ) {
clock_t current = clock( );
clock_t dif = ( 10*( current-m_timeInit ) )/CLOCKS_PER_SEC;
return ( dif >= m_maxmsecs );
}
else {
return false;
}
}
113 double Running::ratio( void ) {
if ( m_neval == 0 ) {
return 0;
}
else {
return ( ( ( double )m_neval )/m_maxeval );
}
}
122 unsigned int Running::numEval( void ) {
return m_neval;
}
126 void Running::setThreshold( double dif ) {
if ( m_neval > 0 ) {
throw new RunningException( "Threshold can't be changed in running" );
}
m_checkOptime->setThreshold( dif );
}
135 double Running::getThreshold( void ) {
if ( m_checkOptime == NULL ) {
throw new RunningException( "Max eval achieved" );
}
return m_checkOptime->getThreshold( );
}
143 void Running::notifyEval( double fit ) {
assert( fit >= 0 );
increm( );
if ( isOptime( fit ) )
m_best = fit;
else if ( m_neval == 1 )
m_best = fit;
else if ( m_checkOptime->isBetter( fit, m_best ) ) {
m_best = fit;
}
if ( m_parent != NULL ) {
m_parent->notifyEval( fit );
}
}
160 RunningPtr Running::getSubRunning( unsigned submaxeval ) {
Running *run = new Running( m_checkOptime );
run->setMaxEval( submaxeval );
run->m_parent = this;
m_children.push_back( run );
return run;
}
169 Running::~Running( void ) {
list<Running*>::iterator item;
for ( item = m_children.begin( ); item != m_children.end( ); ++item ) {
delete *item;
}
}
177 void Running::setMaxTime( unsigned ms ) {
m_maxmsecs = ms;
m_timeInit = clock( );
}
/**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _RUNNABLE_H
#define _RUNNABLE_H 1
#include "signal.h"
#include "define.h"
#include <ctime>
#include <stdexcept>
using namespace std;
/**
* @class OptimeCriterion
* @ingroup realea_common
*
* @brief Let specify when a class is optimum.
*
* This class' target is easier to specify when the optimum is achieved
*
*/
#define MINIMIZE minimize
#define MAXIMIZE maximize
namespace realea {
struct OptimeCriterion {
public:
/**
* Constructor.
*
* @param optime optimum value
* @param dif threshold value
*/
OptimeCriterion( double optime, double dif );
/**
* Set the threshold required to identify two solution are equivalent
* @param dif diference value
*/
void setThreshold( double dif );
/**
* @return the threshold
*/
inline double getThreshold( void );
/**
* Check if the fitness is too close to optimum
*
* @param fitness fitness of current solution
* @return true if abs( fitness - fitness_optimum ) < threshold
*/
bool isOptime( double fitness );
/**
* Set the minimize criterion
*/
void setMinimize( void ) {
m_minimize = true;
}
/**
* Set the minimize criterion
*/
void setMaximize( void ) {
m_minimize = false;
}
bool minimize( void ) {
return m_minimize;
}
bool maximize( void ) {
return !m_minimize;
}
/**
* return if fitness value1 is better than value2
*
* @param value1
* @param value2
* @return true if value is better than value2
*/
bool isBetter( double value1, double value2 ) {
if ( m_minimize ) {
return ( value1 < value2 );
}
else {
return ( value1 > value2 );
}
}
double getOptime( void ) {
return m_optime;
}
private:
double m_optime;
double m_threshold; /**< Threshold value */
double m_minimize;
};
124 class RunningException : public runtime_error {
public:
126 RunningException( string msg ) : runtime_error( msg ), m_msg( msg ) {
}
129 const char *what( void ) {
return m_msg.c_str( );
}
~RunningException( void ) throw ( ) {}
private:
string m_msg;
};
/**
* @class Running
*
* @brief Allow to control the stopping criterion
*
* It detect if the algorithm must stop, or because the maximum evaluation number is achieved
* or because the difference between the current solution and optimum is < threshold
*/
146 class Running : public IReset, public IFinish {
public:
/**
* Increment the evaluation number
*/
151 void increm( void );
154 void notify( double fitness );
/**
* Reset the counting ( for restart the experimentation )
*/
159 void reset( void );
/**
* Constructor
* @param isOptime optimum criterion
*/
165 Running( OptimeCriterion *isOptime );
/**
* Set the maximum evaluation
*
* @param maxEval new maximum evaluation number
*/
171 void setMaxEval( unsigned int maxEval );
173 virtual ~Running( void );
/**
* Return a new subrunning ( to let algorithm that uses anothers )
*
* @param submaxeval maxeval of the new running returning
*
* @return a new running with the maxeval indicated
*/
182 Running*getSubRunning( unsigned submaxeval );
/**
* @return the maximum evaluation number
*/
187 unsigned int maxEval( void );
/**
* @return true if the algorithm must stop ( following the optimum criterion of the maximum evaluations
* number )
*/
192 bool isFinish( void );
/**
* Set the ratio of maximum evaluation done
*
* @return a real value between 0 and 1, the ratio of number evaluation currency done
*/
199 double ratio( );
/**
* Check if the fitness is too close to optimum
*
* @param fitness fitness of current solution
* @return true if abs( fitness - fitness_optimum ) < threshold
*/
207 bool isOptime( double fitness );
/**
* Set the threshold required to identify two solution are equivalent
* @param dif diference value
*/
213 void setThreshold( double dif );
215 void setMaxTime( unsigned seconds );
/**
* @return the current evaluation number
*/
220 unsigned int numEval( void );
/**
* @return the threshold used
*/
225 double getThreshold( void );
/**
* @return the maximum evaluation
*/
230 unsigned pending( void ) {
return ( m_maxeval-m_neval );
}
/**
* It is notify when a new chromosome is evaluated
*
* @param fit new fitness obtained.
*/
239 void notifyEval( double fit );
/**
* @return true if the optime has been achieved
*/
243 bool hasFoundOptime( void ) {
return m_optimized;
}
247 bool isBetter( double fit1, double fit2 ) {
return m_checkOptime->isBetter( fit1, fit2 );
}
private:
unsigned int m_neval; /**< Current evaluation number */
unsigned int m_maxeval; /**< Maximum evaluation number */
unsigned int m_maxmsecs; /**< Maximum time number */
257 clock_t m_timeInit;
OptimeCriterion *m_checkOptime; /**< Optimum criterion applied */
261 bool m_optimized; /**< Stores if the optimum has been achieved */
Running *m_parent; /**< Stores a new Running to assign */
264 list<Running*> m_children;
double m_best; /** @var Best fitness obtained */
};
typedef Running* RunningPtr;
}
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _SELECT_IMPROVEMENT_LS_H
#define _SELECT_IMPROVEMENT_LS_H 1
#include "populationreal.h"
namespace realea {
28 class SelectImprovementLS {
public:
/**
* Select the individuals of the population that could be improved by the LS method
*
* @param pop population to search
*
* @param subpop an deque of individuals with the elements to improve
*/
37 virtual void getIndsToImprove( PopulationReal *pop, deque<tIndividualReal*> &subpop )=0;
/**
* Return the individual id to improve
*
* @param individuals individuals to consider
*
* @return identification of the chosen individual
*
*/
47 virtual unsigned selectIndToImprove( deque<tIndividualReal*> &individuals )=0;
48 virtual ~SelectImprovementLS( void ) {}
};
}
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include "signal.h"
22 Resetable::~Resetable( void ) {
if ( m_observers )
delete m_observers;
}
27 void Resetable::appendSignal( IReset *obj ) {
if ( m_observers == NULL ) {
m_observers = new list<IReset*>;
}
m_observers->push_back( obj );
}
34 void Resetable::clearSignal( void ) {
if ( m_observers )
m_observers->clear( );
}
39 void Resetable::reset( void ) {
list<IReset*>::iterator item;
if ( m_observers == NULL )
return;
for ( item = m_observers->begin( ); item != m_observers->end( );
item++ ) {
( *item )->reset( );
}
realReset( );
}
53 void Resetable::clear( void ) {
list<IReset *>::iterator item;
if ( m_observers == NULL )
return;
for ( item = m_observers->begin( ); item != m_observers->end( );
item++ ) {
( *item )->clear( );
}
realClear( );
}
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _SIGNALABLE
#define _SIGNALABLE 1
#include <list>
using namespace std;
27 class NotifyObserver {
public:
29 virtual void notify( void ) {
}
32 virtual ~NotifyObserver( void ) {}
};
35 class NotifyEvalObserver {
public:
37 virtual void notify( double fitness )=0;
39 virtual ~NotifyEvalObserver( void ) {}
};
43 class IReset {
public:
45 virtual ~IReset( void ) {}
46 virtual void reset( void ){}
47 virtual void clear( void ){}
};
50 class Resetable : public IReset {
private:
52 list<IReset*> *m_observers;
public:
55 Resetable( void ): m_observers( NULL ) {}
56 virtual ~Resetable( void );
57 virtual void realReset( void ) {}
58 virtual void realClear( void ){}
/**
* Permite añadir un elemento a la lista
*/
62 void appendSignal( IReset *obj );
/**
* Permite eliminar un elemento de la lista
*/
67 void clearSignal( void );
69 void reset( void );
70 void clear( void );
};
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include "srandom.h"
#include <string>
23 void SRandom::setSeed( unsigned long seed ) {
m_seed = seed;
changed = 1;
}
#define M 714025
#define IA 1366
#define IC 150889
32 SRandom::SRandom( unsigned long seed ) {
setSeed( seed );
}
36 double SRandom::rand( void ) {
int j;
static long ir[98], iy;// idum = 13171191;
static long idum = m_seed;
static int iff=0;
if ( idum < 0 || iff == 0 || changed == 1 ) {
iff=1;
if ( ( idum=( IC-( idum ) ) % M ) < 0 ) idum = -( idum );
for ( j=1;j<=97;j++ ) {
idum=( IA*( idum )+IC ) % M;
ir[j]=( idum );
}
idum=( IA*( idum )+IC ) % M;
iy=( idum );
changed = 0;
}
j=( int )( 1 + 97.0*( iy )/M );
if ( j > 97 || j < 1 )
throw new std::string( "Failure in random number generator" );
iy=ir[j];
idum=( IA*( idum )+IC ) % M;
ir[j]=( idum );
m_seed = idum;
return ( float ) ( iy )/M;
}
66 unsigned long SRandom::getSeed( void ) {
return m_seed;
}
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _SRANDOM_H
#define _SRANDOM_H
#include "random.h"
#define MASK 2147483647
#define PRIME 65539
#define SCALE 0.4656612875e-9
/**
* @class SRandom
*
* @ingroup realea_common
*
* @brief This class generates number randomly using a seed, following the original code of R. MartÃ
*/
38 class SRandom : public IRealRandom {
public:
/**
* Constructor
*
* @param seed seed
* @see setSeed
*/
46 SRandom( unsigned long seed );
/**
* init the seed
*
* @param seed ( value != 0 )
*/
52 void setSeed( unsigned long seed );
/**
* @return A random double between 0 and 1
*/
57 virtual double rand( void );
/**
* @return the actual seed
*/
62 unsigned long getSeed( void );
private:
unsigned long m_seed; /*< seed */
int changed; /*< Store if setValue is applied */
};
#endif
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include "statistics.h"
#include <cassert>
#include <cstdio>
using namespace realea;
26 Statistics::Statistics( int num_gen ) {
reset( );
m_rate = num_gen;
}
31 void Statistics::reset( void ) {
m_experiment = m_generation = 0;
}
35 void Statistics::newExperiment( void ) {
printf( "Experiment: %d\n", m_experiment );
++m_experiment;
m_generation = 0;
}
41 void Statistics::newGeneration( void ) {
++m_generation;
}
45 void Statistics::endGeneration( tFitness best ) {
if ( m_generation > 1 ) {
if ( m_problem->isBetter( m_lastbest, best ) ) {
printf( "m_lastBest: %Le\tbest : %Le\n", m_lastbest, best );
}
assert( !m_problem->isBetter( m_lastbest, best ) );
}
if ( m_rate > 0 ) {
unsigned rate = ( unsigned ) m_rate;
if ( ( m_generation % rate )==0 ) {
printf( "Best[%d]: %Le\n", m_generation, best );
}
}
m_lastbest = best;
}
66 void Statistics::newEvent( string event ) {
map<string, bool>::iterator pos;
bool active;
pos = m_events.find( event );
if ( pos == m_events.end( ) )
active = false;
else {
active = ( *pos ).second;
}
if ( active )
printf( "%s:[%d]\n", event.c_str( ), m_generation );
}
82 void Statistics::endExperiment( void ) {
printf( "BestExperiment[%d]: %Le\n", m_experiment, m_lastbest );
}
86 void Statistics::activeEvent( string event ) {
m_events[event] = true;
}
1 /**
* Copyright 2008, Daniel Molina Cabrera <danimolina@gmail.com>
*
* This file is part of software Realea
*
* Realea is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* ( at your option ) any later version.
*
* Realea 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _EA_STATISTICS_H
#define _EA_STATISTICS_H 1
/**
* Este fichero permite mostrar información estadÃstica sobre la ejecución de un AE.
*
* Permite mostrar información por cada % de nueva generación, y tras cada evaluación
*
*/
#include "problem.h"
#include "populationreal.h"
namespace realea {
35 class Statistics {
public:
/**
* Constructor, permite especificar cada cuantos genes debe de mostrarse la información
*/
40 Statistics ( int num_gen );
42 void setProblem( Problem *problem ) {
m_problem = problem;
}
/*
* Inicia las estadÃsticas
*/
49 void reset( void );
/**
* Avisa de un evento. Por defecto sólo muestra los eventos activados con
* activeEvent
*
* @param event Nombre del evento
*/
57 void newEvent( string event );
/**
* Indica que se activa el evento deseado
*/
61 void activeEvent( string event );
/**
* Notifica que empieza un nuevo experimento
*/
65 void newExperiment( void );
/**
* Notifica que empieza una nueva generación
*/
69 void newGeneration( void );
/**
* Avisa del fin de la generación, indicando el mejor fitness encontrado hasta el momento
*/
73 void endGeneration( tFitness best );
/**
* Avisa del fin del experimento
*/
77 void endExperiment( void );
private:
79 Problem *m_problem;
80 tFitness m_lastbest;
81 unsigned m_experiment, m_generation;
82 unsigned m_rate;
83 map<string, bool> m_events;
};
}
#endif