Qualia  0.2
Chromosome.h
Go to the documentation of this file.
1 /*
2  * Chromosome.h
3  *
4  * (c) 2012 Sofian Audry -- info(@)sofianaudry(.)com
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef CHROMOSOME_H_
21 #define CHROMOSOME_H_
22 
23 class Chromosome;
24 
25 /*
26  NOTE: This section was directly copied from file GAGenome.h in GAlib
27  Copyright Massachusetts Institute of Technology and Matthew Wall.
28  TODO: - adapt the text to the Qualia GA API
29 
30 initialize
31  Use this method to set the initial state of your genomes once they have
32  been created. This initialization is for setting up the genome's state,
33  not for doing the basic mechanics of genome class management. The
34  default behaviour of this method is to change randomly the contents of the
35  genome. If you want to bias your initial population, this is where to
36  make that happen.
37  The initializer is used to initialize the genome (duh). Notice that the
38  state of the genome is unknown - memory may or may not have been allocated,
39  and the genome may or may not have been used before. So your initializer
40  should first clean up as needed, then do its thing. The initializer may be
41  called any number of times (unlike a class constructor which is called only
42  once for a given instance).
43 
44 mutate
45  Mutate the genome with probability as specified. What mutation means
46  depends upon the data type of the genome. For example, you could have
47  a bit string in which 50% mutation means each bit has a 50% chance of
48  getting flipped, or you could have a tree in which 50% mutation means each
49  node has a 50% chance of getting deleted, or you could have a bit string
50  in which 50% mutation means 50% of the bits ACTUALLY get flipped.
51  The mutations member returns the number of mutations since the genome
52  was initialized.
53  The mutator makes a change to the genome with likeliehood determined by the
54  mutation rate parameter. The exact meaning of mutation is up to you, as is
55  the specific meaning of the mutation rate. The function returns the number
56  of mutations that actually occurred.
57 
58 crossover
59  Genomes don't really have any clue about other genomes, so we don't make
60  the crossover a member function. Instead, each genome kind of knows how
61  to mate with other genomes to generate offspring, but they are not
62  capable of doing it themselves. The crossover member function is used to
63  set the default mating mode for the genomes - it does not actually perform
64  the crossover. This way the GA can use asexual crossover if it wants to
65  (but genomes only know how to do the default sexual crossover).
66  This also lets you do funky stuff like crossover between different data
67  types and group sex to generate new offspring.
68  We define two types of crossover: sexual and asexual. Most GAlib
69  algorithms use the sexual crossover, but both are available. Each genome
70  knows the preferred crossover method, but none is capable of reproducing.
71  The genetic algorithm must actually perform the mating because it involves
72  another genome (as parent and/or child).
73 
74 evaluator
75  Set the genome's objective function. This also sets marks the evaluated
76  flag to indicate that the genome must be re-evaluated.
77  Evaluation happens on-demand - the objective score is not calculated until
78  it is requested. Then it is cached so that it does not need to be re-
79  calculated each time it is requested. This means that any member function
80  that modifies the state of the genome must also set the evaluated flag to
81  indicate that the score must be recalculated.
82  The genome objective function is used by the GA to evaluate each member of
83  the population.
84 
85 comparator
86  This method is used to determine how similar two genomes are. If you want
87  to use a different comparison method without deriving a new class, then use
88  the comparator function to do so. For example, you may want to do phenotype-
89  based comparisons rather than genotype-based comparisons.
90  In many cases we have to compare two genomes to determine how similar or
91  different they are. In traditional GA literature this type of function is
92  referred to as a 'distance' function, probably because bit strings can be
93  compared using the Hamming distance as a measure of similarity. In GAlib, we
94  define a genome comparator function that does exactly this kind of
95  comparison.
96  If the genomes are identical, the similarity function should return a
97  value of 0.0, if completely different then return a value greater than 0.
98  The specific definition of what "the same" and what "different" mean is up
99  to you. Most of the default comparators use the genotype for the comparison,
100  but you can use the phenotype if you prefer. There is no upper limit to the
101  distance score as far as GAlib is concerned.
102  The no-op function returns a -1 to signify that the comparison failed.
103 
104 //evalData
105 // The evalData member is useful if you do not want to derive a new genome class
106 // but want to store data with each genome. When you clone a genome, the eval
107 // data also gets cloned so that each genome has its own eval data (unlike the
108 // user data pointer described next which is shared by all genomes).
109 //
110 //userData
111 // The userData member is used to provide all genomes access to the same user
112 // data. This can be a pointer to anything you want. Any genome cloned from
113 // another will share the same userData as the original. This means that all
114 // of the genomes in a population, for example, share the same userData.
115 //
116 //score
117 // Evaluate the 'performance' of the genome using the objective function.
118 // The score is kept in the 'score' member. The 'evaluated' member tells us
119 // whether or not we can trust the score. Be sure to set/unset the 'evaluated'
120 // member as appropriate (eg cross and mutate change the contents of the
121 // genome so they unset the 'evaluated' flag).
122 // If there is no objective function, then simply return the score. This
123 // allows us to use population-based evaluation methods (where the population
124 // method sets the score of each genome).
125 */
126 
127 typedef float (*Evaluator) (Chromosome &);
128 typedef void (*Initializer) (Chromosome &);
129 typedef void (*Mutator) (Chromosome &, float);
130 typedef int (*Comparator) (const Chromosome&, const Chromosome&);
131 typedef void (*SexualCrossover) (const Chromosome&, const Chromosome&,
133 typedef void (*AsexualCrossover) (const Chromosome&, Chromosome*);
134 
135 class Chromosome {
136 public:
138  //Chromosome(const Chromosome& c) { copyFrom(c); }
139  virtual ~Chromosome() {}
140 
141  virtual void copyFrom(const Chromosome& c) { (*this) = c; }
142 
143  virtual void init(){}
144  virtual void mutate(float p){}
145  virtual bool equals(const Chromosome& g) const = 0;
146 // virtual float evaluate() { return 0; }
147 
148 // float evaluate() const { return (*evaluator)(*this); }
151 //
152 // void init() { (*initializer)(*this); }
155 //
156 // void mutate(float p) { (*mutator)(*this,p); }
159 //
160 // float compare(const Chromosome& g) const { return (*comparator)(*this, g); }
163 
164 };
165 
166 #endif /* CHROMOSOME_H_ */