View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.math.genetics;
18  
19  /**
20   * Individual in a population. Chromosomes are compared based on their fitness.
21   * 
22   * The chromosomes are IMMUTABLE, and so their fitness is also immutable and
23   * therefore it can be cached.
24   * 
25   * @since 2.0
26   * @version $Revision: 800116 $ $Date: 2009-08-02 13:49:59 -0400 (Sun, 02 Aug 2009) $
27   */
28  public abstract class Chromosome implements Comparable<Chromosome>,Fitness {
29      
30      /**
31       * Cached value of the fitness of this chromosome.
32       */
33      private double fitness = Double.MIN_VALUE;
34      
35      /**
36       * Access the fitness of this chromosome. The bigger the fitness, the better
37       * the chromosome.
38       * 
39       * Computation of fitness is usually very time-consuming task, therefore the
40       * fitness is cached.
41       * 
42       * @return the fitness.
43       */
44      public double getFitness() {
45          if (this.fitness == Double.MIN_VALUE) {
46              // no cache - compute the fitness
47              this.fitness = fitness();
48          }
49          return this.fitness;
50      }
51          
52      /**
53       * Compares two chromosomes based on their fitness. The bigger the fitness,
54       * the better the chromosome.
55       * 
56       * @param another another chromosome to compare
57       * @return
58       * <ul>
59       *     <li>-1 if <code>another</code> is better than <code>this</code></li>
60       *     <li>1 if <code>another</code> is worse than <code>this</code></li>
61       *     <li>0 if the two chromosomes have the same fitness</li>
62       * </ul>
63       */
64      public int compareTo(Chromosome another) {
65          return ((Double)this.getFitness()).compareTo(another.getFitness());
66      }
67  
68      /**
69       * Returns <code>true<code> iff <code>another</code> has the same
70       * representation and therefore the same fitness. By default, it returns
71       * false -- override it in your implementation if you need it. 
72       * @param another chromosome to compare
73       * @return true if <code>another</code> is equivalent to this chromosome
74       */
75      protected boolean isSame(Chromosome another) {
76          return false;
77      }
78  
79      /**
80       * Searches the <code>population</code> for another chromosome with the same
81       * representation. If such chromosome is found, it is returned, if no such
82       * chromosome exists, returns <code>null</code>.
83       * 
84       * @param population
85       *            Population to search
86       * @return Chromosome with the same representation, or <code>null</code> if
87       *         no such chromosome exists.
88       */
89      protected Chromosome findSameChromosome(Population population) {
90          for (Chromosome anotherChr : population) {
91              if (this.isSame(anotherChr))
92                  return anotherChr;
93          }
94          return null;
95      }
96  
97      /**
98       * Searches the population for a chromosome representing the same solution,
99       * and if it finds one, updates the fitness to its value.
100      * 
101      * @param population
102      *            Population to search
103      */
104     public void searchForFitnessUpdate(Population population) {
105         Chromosome sameChromosome = findSameChromosome(population);
106         if (sameChromosome != null) {
107             fitness = sameChromosome.getFitness();
108         }
109     }
110     
111 }