00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "genotypes/signedrangegenotype.h"
00021 #include <cmath>
00022 #include "configurationparameters.h"
00023
00024 namespace farsa {
00025
00026 #if defined(_WIN32) && !defined(__MINGW32__)
00027
00028 static int rint (double x) {
00029 char *buf;
00030 int i,dec,sig;
00031 buf = _fcvt(x, 0, &dec, &sig);
00032 i = atoi(buf);
00033 if( sig == 1 ) {
00034 i = i * -1;
00035 }
00036 return i;
00037 }
00038 #endif
00039
00040 SignedRangeGenotype::SignedRangeGenotype( unsigned int numGenes, double max, unsigned int bitPrec )
00041 : DoubleGenotype( numGenes, -max, +max, bitPrec ) {
00042 Q_ASSERT_X( bitPrec > 1,
00043 "SignedRangeGenotype Constructor",
00044 "bitPrecision parameters must be greater than 1" );
00045 dx = ( maxValue() ) / ( std::pow(2.0f, (int)(bitPrec-1)) - 1 );
00046 }
00047
00048 SignedRangeGenotype::~SignedRangeGenotype() {
00049
00050 }
00051
00052 SignedRangeGenotype::SignedRangeGenotype( const SignedRangeGenotype& genotype )
00053 : DoubleGenotype( genotype ) {
00054 this->dx = genotype.dx;
00055 }
00056
00057 SignedRangeGenotype& SignedRangeGenotype::operator=( const Genotype& genotype ) {
00058 SignedRangeGenotype* genodouble = (SignedRangeGenotype*)( &genotype );
00059 copyDataFrom( genodouble );
00060 this->numgenes = genodouble->numgenes;
00061 this->bitprec = genodouble->bitprec;
00062 this->maxv = genodouble->maxv;
00063 this->minv = genodouble->minv;
00064 this->dx = genodouble->dx;
00065 return *this;
00066 }
00067
00068 void SignedRangeGenotype::configure( ConfigurationParameters& params, QString prefix ) {
00069 numgenes = params.getValue( prefix + QString( "ngenes" ) ).toInt();
00070 Q_ASSERT_X( numgenes > 0,
00071 "SignedRangeGenotype::configure",
00072 "The ngenes must be present in the config file and its value must be greater than zero" );
00073 bitprec = params.getValue( prefix + QString( "nbits" ) ).toInt();
00074 Q_ASSERT_X( bitprec > 1,
00075 "SignedRangeGenotype::configure",
00076 "The nbits must be greater than 1 !! Check your config file" );
00077 maxv = params.getValue( prefix + QString( "maxValue" ) ).toDouble();
00078 minv = -maxv;
00079 Q_ASSERT_X( maxv > 0,
00080 "SignedRangeGenotype::configure",
00081 "The maxValue must be greater than zero!! Check you config file" );
00082 resize( numgenes*bitprec );
00083 dx = ( maxValue() ) / ( std::pow(2.0f, (int)(bitprec-1)) - 1 );
00084 QString zipdata = params.getValue( prefix + QString( "data" ) );
00085 if ( !zipdata.isNull() ) {
00086 fromCompressedString( zipdata );
00087 }
00088 QStringList valuesList = params.getValue( prefix + QString( "fitness" ) )
00089 .split( QRegExp("\\s+"), QString::SkipEmptyParts );
00090 fitnessv.resize(0);
00091 foreach( QString avalue, valuesList ) {
00092 fitnessv << avalue.toDouble();
00093 }
00094 rankv = params.getValue( prefix + QString( "rank" ) ).toDouble();
00095 notesv = params.getValue( prefix + QString( "notes" ) );
00096 }
00097
00098 void SignedRangeGenotype::save( ConfigurationParameters& params, QString prefix ) {
00099 params.createParameter( prefix, QString("type"), "SignedRange" );
00100 params.createParameter( prefix, QString("ngenes"), QString("%1").arg( numgenes ) );
00101 params.createParameter( prefix, QString("nbits"), QString("%1").arg( bitprec ) );
00102 params.createParameter( prefix, QString("maxValue"), QString("%1").arg( maxv ) );
00103 QString fitstring;
00104 foreach( double avalue, fitnessv ) {
00105 fitstring.append( QString("%1 ").arg(avalue) );
00106 }
00107 params.createParameter( prefix, QString("fitness"), fitstring );
00108 params.createParameter( prefix, QString("data"), toCompressedString() );
00109 params.createParameter( prefix, QString("rank"), QString("%1").arg(rankv) );
00110 params.createParameter( prefix, QString("notes"), notesv );
00111 }
00112
00113 void SignedRangeGenotype::describe( QString type ) {
00114 Descriptor d = addTypeDescription( type, "SignedRangeGenotype encode a vector of real values, each value correspond to a gene" );
00115 d.describeInt( "ngenes" ).limits( 1, INT_MAX ).def( 8 ).props( IsMandatory ).help( "The number of real values represented by the Genotype" );
00116 d.describeInt( "nbits" ).limits( 4, 32 ).def( 16 ).help( "The number of bits used to encode one real value", "The SignedRangeGenotype encode the real value in a discrete way inside a boundary; Supposing nbits is 4, then 4 bits are used to encode a real value where the first bit represent the sign, and the other three represents the number of discretization of the interval from -maxValue to +maxValue. In this way, the representation of zero is always present and has two encoding: 0000 (-0) and 1000 (+0)" );
00117 d.describeReal( "maxValue" ).def( 5.0 ).help( "The absolute maximum value representable. Look at the help of nbits for details" );
00118 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" );
00119 d.describeString( "data" ).help( "The bits composing the Genotype stored in a compressed string" );
00120 d.describeReal( "rank" ).help( "The rank indicate who is more fitted that others and how much; the values are dependent on the kind of GeneticAlgo used" );
00121 }
00122
00123 double SignedRangeGenotype::at( unsigned int i ) {
00124 Q_ASSERT_X( (i+1)*bitprec <= size(),
00125 "SignedRangeGenotype::at",
00126 "The value requested is beyond the dimension of this Genotype" );
00127 double ret = extractUInt( i*bitprec+1, (i+1)*bitprec );
00128
00129 if ( bit( i*bitprec ) ) {
00130 return -(dx*ret);
00131 } else {
00132 return +(dx*ret);
00133 }
00134 }
00135
00136 void SignedRangeGenotype::set( unsigned int i, double value ) {
00137 Q_ASSERT_X( (i+1)*bitprec <= size(),
00138 "SignedRangeGenotype::set",
00139 "The value to be set is beyond the dimension of this Genotype" );
00140 value = qMin( maxv, value );
00141 value = qMax( -maxv, value );
00142 unsigned int intP = (unsigned int)( rint( qAbs(value)/dx ) );
00143 insertUInt( (unsigned int)intP, i*bitprec+1, (i+1)*bitprec );
00144 if ( value < 0 ) {
00145 Genotype::set( i*bitprec );
00146 } else {
00147 Genotype::unset( i*bitprec );
00148 }
00149 return;
00150 }
00151
00152 SignedRangeGenotype* SignedRangeGenotype::clone() const {
00153 return ( new SignedRangeGenotype( *this ) );
00154 }
00155
00156 }