ga/src/genotypes/realgenotype.cpp

00001 /********************************************************************************
00002  *  FARSA Genetic Algorithm Library                                             *
00003  *  Copyright (C) 2007-2009 Gianluca Massera <emmegian@yahoo.it>                *
00004  *                                                                              *
00005  *  This program is free software; you can redistribute it and/or modify        *
00006  *  it under the terms of the GNU General Public License as published by        *
00007  *  the Free Software Foundation; either version 2 of the License, or           *
00008  *  (at your option) any later version.                                         *
00009  *                                                                              *
00010  *  This program is distributed in the hope that it will be useful,             *
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of              *
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               *
00013  *  GNU General Public License for more details.                                *
00014  *                                                                              *
00015  *  You should have received a copy of the GNU General Public License           *
00016  *  along with this program; if not, write to the Free Software                 *
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA  *
00018  ********************************************************************************/
00019 
00020 #include "genotypes/realgenotype.h"
00021 #include "randomgenerator.h"
00022 #include <cmath>
00023 #include "configurationparameters.h"
00024 
00025 namespace farsa {
00026 
00027 RealGenotype::RealGenotype( unsigned int numGenes, float min, float max )
00028     : DoubleGenotype( numGenes, min, max, 32 ) {
00029     genes = (float*)( data );
00030 }
00031 
00032 RealGenotype::~RealGenotype() {
00033     //--- nothing to do
00034 }
00035 
00036 RealGenotype::RealGenotype( const RealGenotype& genotype )
00037     : DoubleGenotype( genotype ) {
00038     genes = (float*)( data );
00039 }
00040 
00041 RealGenotype& RealGenotype::operator=( const Genotype& genotype ) {
00042     RealGenotype* genoreal = (RealGenotype*)(&genotype);
00043     copyDataFrom( genoreal );
00044     this->numgenes = genoreal->numgenes;
00045     this->minv = genoreal->minv;
00046     this->maxv = genoreal->maxv;
00047     genes = (float*)( data );
00048     return *this;
00049 }
00050 
00051 void RealGenotype::configure( ConfigurationParameters& params, QString prefix ) {
00052     numgenes = params.getValue( prefix + QString( "ngenes" ) ).toInt();
00053     Q_ASSERT_X( numgenes > 0,
00054                 "RealGenotype::configure",
00055                 "The ngenes must be present in the config file and its value must be greater than zero" );
00056     minv = params.getValue( prefix + QString( "minValue" ) ).toDouble();
00057     maxv = params.getValue( prefix + QString( "maxValue" ) ).toDouble();
00058     Q_ASSERT_X( minv < maxv,
00059                 "RealGenotype::configure",
00060                 "The minValue and maxValue must be different!! Check you config file" );
00061     resize( numgenes*32 );
00062     QString zipdata = params.getValue( prefix + QString( "data" ) );
00063     if ( !zipdata.isNull() ) {
00064         fromCompressedString( zipdata );
00065     }
00066     genes = (float*)( data );
00067     QStringList valuesList = params.getValue( prefix + QString( "fitness" ) )
00068                                     .split( QRegExp("\\s+"), QString::SkipEmptyParts );
00069     fitnessv.resize(0);
00070     foreach( QString avalue, valuesList ) {
00071         fitnessv << avalue.toDouble();
00072     }
00073     rankv = params.getValue( prefix + QString( "rank" ) ).toDouble();
00074     notesv = params.getValue( prefix + QString( "notes" ) );
00075 }
00076 
00077 void RealGenotype::save( ConfigurationParameters& params, QString prefix ) {
00078     params.createParameter( prefix, QString("type"), "RealGenotype" );
00079     params.createParameter( prefix, QString("ngenes"), QString("%1").arg( numgenes ) );
00080     params.createParameter( prefix, QString("minValue"), QString("%1").arg( minv ) );
00081     params.createParameter( prefix, QString("maxValue"), QString("%1").arg( maxv ) );
00082     QString fitstring;
00083     foreach( double avalue, fitnessv ) {
00084         fitstring.append( QString("%1 ").arg(avalue) );
00085     }
00086     params.createParameter( prefix, QString("fitness"), fitstring );
00087     params.createParameter( prefix, QString("data"), toCompressedString() );
00088     params.createParameter( prefix, QString("rank"), QString("%1").arg(rankv) );
00089     params.createParameter( prefix, QString("notes"), notesv );
00090 }
00091 
00092 void RealGenotype::describe( QString type ) {
00093     Descriptor d = addTypeDescription( type, "RealGenotype encode a vector of real double values, each double correspond to a gene" );
00094     d.describeInt( "ngenes" ).limits( 1, INT_MAX ).def( 8 ).props( IsMandatory ).help( "The number of real values represented by the Genotype" );
00095     d.describeReal( "minValue" ).def( -5.0 ).help( "The minimum value representable" );
00096     d.describeReal( "maxValue" ).def( +5.0 ).help( "The maximum value representable" );
00097     d.describeReal( "fitness" ).props( IsList ).help( "The fitness of the Genotype", "The fitness of a Genotype support multi objective fitness; if you specify a vector of values they are considered different objectives of the fitness" );
00098     d.describeString( "data" ).help( "The bits composing the Genotype stored in a compressed string" );
00099     d.describeReal( "rank" ).def( 0 ).help( "The rank indicate who is more fitted that others and how much; the values are dependent on the kind of GeneticAlgo used" );
00100 }
00101 
00102 double RealGenotype::at( unsigned int i ) {
00103     Q_ASSERT_X( (i+1)*32 <= size(),
00104                 "RealGenotype::at",
00105                 "The value requested is beyond the dimension of this Genotype" );
00106     return (double) ( genes[i] );
00107 }
00108 
00109 void RealGenotype::set( unsigned int i, double value ) {
00110     Q_ASSERT_X( (i+1)*32 <= size(),
00111                 "RealGenotype::set",
00112                 "The value to be set is beyond the dimension of this Genotype" );
00113     genes[i] = (float) ( value );
00114     return;
00115 }
00116 
00117 void RealGenotype::randomize() {
00118     for( unsigned int i=0; i<numgenes; i++ ) {
00119         genes[i] = (float)( globalRNG->getDouble( minv, maxv ) );
00120     }
00121 }
00122 
00123 RealGenotype* RealGenotype::clone() const {
00124     return ( new RealGenotype( *this ) );
00125 }
00126 
00127 } // end namespace farsa