    001    /*
    002     * Licensed to the Apache Software Foundation (ASF) under one or more
    003     * contributor license agreements.  See the NOTICE file distributed with
    004     * this work for additional information regarding copyright ownership.
    005     * The ASF licenses this file to You under the Apache License, Version 2.0
    006     * (the "License"); you may not use this file except in compliance with
    007     * the License.  You may obtain a copy of the License at
    008     *
    009     *      http://www.apache.org/licenses/LICENSE-2.0
    010     *
    011     * Unless required by applicable law or agreed to in writing, software
    012     * distributed under the License is distributed on an "AS IS" BASIS,
    013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014     * See the License for the specific language governing permissions and
    015     * limitations under the License.
    016     */
    017    package org.apache.commons.math.genetics;
    018
    019    /**
    020     * Individual in a population. Chromosomes are compared based on their fitness.
    021     *
    022     * The chromosomes are IMMUTABLE, and so their fitness is also immutable and
    023     * therefore it can be cached.
    024     *
    025     * @since 2.0
    026     * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
    027     */
    028    public abstract class Chromosome implements Comparable<Chromosome>,Fitness {
    029
    030        /**
    031         * Cached value of the fitness of this chromosome.
    032         */
    033        private double fitness = Double.MIN_VALUE;
    034
    035        /**
    036         * Access the fitness of this chromosome. The bigger the fitness, the better
    037         * the chromosome.
    038         *
    039         * Computation of fitness is usually very time-consuming task, therefore the
    040         * fitness is cached.
    041         *
    042         * @return the fitness.
    043         */
    044        public double getFitness() {
    045            if (this.fitness == Double.MIN_VALUE) {
    046                // no cache - compute the fitness
    047                this.fitness = fitness();
    048            }
    049            return this.fitness;
    050        }
    051
    052        /**
    053         * Compares two chromosomes based on their fitness. The bigger the fitness,
    054         * the better the chromosome.
    055         *
    056         * @param another another chromosome to compare
    057         * @return
    058         * <ul>
    059         *     <li>-1 if <code>another</code> is better than <code>this</code></li>
    060         *     <li>1 if <code>another</code> is worse than <code>this</code></li>
    061         *     <li>0 if the two chromosomes have the same fitness</li>
    062         * </ul>
    063         */
    064        public int compareTo(Chromosome another) {
    065            return ((Double)this.getFitness()).compareTo(another.getFitness());
    066        }
    067
    068        /**
    069         * Returns <code>true<code> iff <code>another</code> has the same
    070         * representation and therefore the same fitness. By default, it returns
    071         * false -- override it in your implementation if you need it.
    072         * @param another chromosome to compare
    073         * @return true if <code>another</code> is equivalent to this chromosome
    074         */
    075        protected boolean isSame(Chromosome another) {
    076            return false;
    077        }
    078
    079        /**
    080         * Searches the <code>population</code> for another chromosome with the same
    081         * representation. If such chromosome is found, it is returned, if no such
    082         * chromosome exists, returns <code>null</code>.
    083         *
    084         * @param population
    085         *            Population to search
    086         * @return Chromosome with the same representation, or <code>null</code> if
    087         *         no such chromosome exists.
    088         */
    089        protected Chromosome findSameChromosome(Population population) {
    090            for (Chromosome anotherChr : population) {
    091                if (this.isSame(anotherChr))
    092                    return anotherChr;
    093            }
    094            return null;
    095        }
    096
    097        /**
    098         * Searches the population for a chromosome representing the same solution,
    099         * 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    }