genome.cpp
1 /********************************************************************************
2  * FARSA Genetic Algorithm Library *
3  * Copyright (C) 2007-2008 Gianluca Massera <emmegian@yahoo.it> *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the Free Software *
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
18  ********************************************************************************/
19 
20 #include "core/genome.h"
21 #include "factory.h"
22 #include <QtAlgorithms>
23 
24 namespace farsa {
25 
27  prototype = NULL;
28 }
29 
30 Genome::Genome( unsigned int numGenotype, unsigned int numBits ) {
31  prototype = new Genotype( numBits );
32  data.resize( numGenotype );
33  for( unsigned int i=0; i<numGenotype; i++ ) {
34  data[i] = new Genotype( numBits );
35  data[i]->randomize();
36  }
37 }
38 
39 Genome::Genome( unsigned int numGenotype, const Genotype* prototype ) : ParameterSettableWithConfigureFunction() {
40  this->prototype = prototype->clone();
41  data.resize( numGenotype );
42  for( unsigned int i=0; i<numGenotype; i++ ) {
43  data[i] = prototype->clone();
44  data[i]->randomize();
45  }
46 }
47 
49  this->prototype = genome.prototype->clone();
50  data.resize( genome.data.size() );
51  for( int i=0; i<data.size(); i++ ) {
52  data[i] = genome.data[i]->clone();
53  }
54 }
55 
57  if ( prototype ) {
58  delete prototype;
59  }
60  // The destruction of genotypes was added by Tomassino. It is not certain that
61  // this won't create any problem...
62  for( int i=0; i<data.size(); i++ ) {
63  delete (data[i]);
64  }
65 }
66 
67 Genome& Genome::operator=( const Genome& right ) {
68  this->prototype = right.prototype->clone();
69  //--- destroy all memory allocated
70  for( int i=0; i<data.size(); i++ ) {
71  delete (data[i]);
72  }
73  data.resize( right.data.size() );
74  for( unsigned int i=0; i<right.size(); i++ ) {
75  data[i] = right.data[i]->clone();
76  }
77  return (*this);
78 }
79 
80 void Genome::configure( ConfigurationParameters& params, QString prefix ) {
81  for( int i=0; i<data.size(); i++ ) {
82  delete (data[i]);
83  }
84  data.clear();
85  this->prototype = params.getObjectFromGroup<Genotype>( prefix + QString( "GENOTYPE:prototype" ) );
86  foreach( QString group, params.getGroupsWithPrefixList(prefix, QString( "GENOTYPES" )) ) {
87  data.append( params.getObjectFromGroup<Genotype>( prefix + "/" + group ) );
88  }
89  int nindividuals = params.getValue( prefix + QString( "nindividuals" ) ).toInt();
90  if ( data.size() != 0 && nindividuals != data.size() ) {
91  qWarning() << "Genome configuration: nindividuals parameter should match the number of GENOTYPES specified.";
92  }
93  int loadedgens = data.size();
94  data.resize( nindividuals );
95  for( int i=loadedgens; i<nindividuals; i++ ) {
96  data[i] = prototype->clone();
97  }
98 }
99 
100 void Genome::save( ConfigurationParameters& params, QString prefix ) {
101  params.createParameter( prefix, QString("type"), "Genome" );
102  params.createParameter( prefix, QString("nindividuals"), QString("%1").arg(data.size()) );
103 
104  this->prototype->save( params, params.createSubGroup( prefix, "GENOTYPE:prototype" ) );
105 
106  for( int i=0; i<data.size(); i++ ) {
107  data[i]->save( params, params.createSubGroup( prefix, QString("GENOTYPES:%1").arg(i) ) );
108  }
109 }
110 
111 void Genome::describe( QString type ) {
112  Descriptor d = addTypeDescription( type, "A population of Genotypes" );
113  d.describeInt( "nindividuals" ).limits( 1, INT_MAX ).def( 100 ).props( IsMandatory ).help( "The number of Genotypes contained by the Genome" );
114  d.describeSubgroup( "GENOTYPE:prototype" ).type( "Genotype" ).props( IsMandatory ).help( "The prototype of Genotypes contained by the Genome" );
115  d.describeSubgroup( "GENOTYPE" ).type( "Genotype" ).props( AllowMultiple ).help( "The vector of all Genotypes contained by the Genome" );
116 }
117 
118 unsigned int Genome::size() const {
119  return data.size();
120 }
121 
123  data.clear();
124 }
125 
126 void Genome::append( const Genotype* genotype ) {
127  data.append( genotype->clone() );
128  return;
129 }
130 
131 Genotype* Genome::at( unsigned int i ) {
132  return data[i];
133 }
134 
135 const Genotype* Genome::at( unsigned int i ) const {
136  return data[i];
137 }
138 
140  return data.last();
141 }
142 
143 const Genotype* Genome::last() const {
144  return data.last();
145 }
146 
147 unsigned int Genome::find( const Genotype* g ) {
148  for( int i=0; i<data.size(); i++ ) {
149  if ( g == data[i] ) return i;
150  }
151  return -1;
152 }
153 
154 void Genome::set( unsigned int i, Genotype* g ) {
155  data[i] = g->clone();
156 }
157 
158 const Genotype* Genome::operator[]( unsigned int i ) const {
159  return data[i];
160 }
161 
162 Genotype* Genome::operator[]( unsigned int i ) {
163  return data[i];
164 }
165 
167  //--- can be parallelizable
168  for( int i=0; i<data.size(); i++ ) {
169  data[i]->randomize();
170  }
171 }
172 
173 } // end namespace farsa