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.math4.legacy.genetics;
18
19 /**
20 * Individual in a population. Chromosomes are compared based on their fitness.
21 * <p>
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 */
27 public abstract class Chromosome implements Comparable<Chromosome>,Fitness {
28 /** Value assigned when no fitness has been computed yet. */
29 private static final double NO_FITNESS = Double.NEGATIVE_INFINITY;
30
31 /** Cached value of the fitness of this chromosome. */
32 private double fitness = NO_FITNESS;
33
34 /**
35 * Access the fitness of this chromosome. The bigger the fitness, the better the chromosome.
36 * <p>
37 * Computation of fitness is usually very time-consuming task, therefore the fitness is cached.
38 *
39 * @return the fitness
40 */
41 public double getFitness() {
42 if (this.fitness == NO_FITNESS) {
43 // no cache - compute the fitness
44 this.fitness = fitness();
45 }
46 return this.fitness;
47 }
48
49 /**
50 * Compares two chromosomes based on their fitness. The bigger the fitness, the better the chromosome.
51 *
52 * @param another another chromosome to compare
53 * @return
54 * <ul>
55 * <li>-1 if <code>another</code> is better than <code>this</code></li>
56 * <li>1 if <code>another</code> is worse than <code>this</code></li>
57 * <li>0 if the two chromosomes have the same fitness</li>
58 * </ul>
59 */
60 @Override
61 public int compareTo(final Chromosome another) {
62 return Double.compare(getFitness(), another.getFitness());
63 }
64
65 /**
66 * Returns <code>true</code> iff <code>another</code> has the same representation and therefore the same fitness. By
67 * default, it returns false -- override it in your implementation if you need it.
68 *
69 * @param another chromosome to compare
70 * @return true if <code>another</code> is equivalent to this chromosome
71 */
72 protected boolean isSame(final Chromosome another) {
73 return false;
74 }
75
76 /**
77 * Searches the <code>population</code> for another chromosome with the same representation. If such chromosome is
78 * found, it is returned, if no such chromosome exists, returns <code>null</code>.
79 *
80 * @param population Population to search
81 * @return Chromosome with the same representation, or <code>null</code> if no such chromosome exists.
82 */
83 protected Chromosome findSameChromosome(final Population population) {
84 for (Chromosome anotherChr : population) {
85 if (this.isSame(anotherChr)) {
86 return anotherChr;
87 }
88 }
89 return null;
90 }
91
92 /**
93 * Searches the population for a chromosome representing the same solution, and if it finds one,
94 * updates the fitness to its value.
95 *
96 * @param population Population to search
97 */
98 public void searchForFitnessUpdate(final Population population) {
99 Chromosome sameChromosome = findSameChromosome(population);
100 if (sameChromosome != null) {
101 fitness = sameChromosome.getFitness();
102 }
103 }
104 }