001: /*
002: * This file is part of JGAP.
003: *
004: * JGAP offers a dual license model containing the LGPL as well as the MPL.
005: *
006: * For licensing information please see the file license.txt included with JGAP
007: * or have a look at the top of class org.jgap.Chromosome which representatively
008: * includes the JGAP license policy applicable for any file delivered with JGAP.
009: */
010: package org.jgap;
011:
012: import java.io.*;
013: import org.jgap.util.*;
014:
015: /**
016: * Fitness functions are used to determine how optimal a particular solution
017: * is relative to other solutions. This abstract class should be extended and
018: * the evaluate() method implemented. The fitness function is given a Chromosome
019: * to evaluate and should return a positive double that reflects its fitness
020: * value. The higher the value, the more fit the Chromosome. The actual range
021: * of fitness values isn't important (other than the fact that they must be
022: * positive doubles): it's the relative difference as a percentage that
023: * tends to determine the success or failure of a Chromosome. So in other words,
024: * two Chromosomes with respective fitness values of 1 and 100 have the same
025: * relative fitness to each other as two Chromosomes with respective fitness
026: * values of 10 and 1000 (in each case, the first is 1% as fit as the second).
027: * <p>
028: * Note: Two Chromosomes with equivalent sets of genes should always be
029: * assigned the same fitness value by any implementation of this interface.
030: *
031: * @author Neil Rotstan
032: * @author Klaus Meffert
033: * @since 1.0
034: */
035: public abstract class FitnessFunction implements Serializable,
036: ICloneable {
037: /** String containing the CVS revision. Read out via reflection!*/
038: private final static String CVS_REVISION = "$Revision: 1.22 $";
039:
040: public final static double NO_FITNESS_VALUE = -1.0000000d;
041:
042: public final static double DELTA = 0.0000001d;
043:
044: /**
045: * The fitness value computed during the previous run
046: */
047: private double m_lastComputedFitnessValue = NO_FITNESS_VALUE;
048:
049: /**
050: * Retrieves the fitness value of the given Chromosome. The fitness
051: * value will be a positive double.
052: *
053: * @param a_subject the Chromosome for which to compute and return the
054: * fitness value
055: * @return the fitness value of the given Chromosome
056: *
057: * @author Neil Rotstan
058: * @author Klaus Meffert
059: * @since 2.0 (until 1.1: return type int)
060: */
061: public double getFitnessValue(final IChromosome a_subject) {
062: // Delegate to the evaluate() method to actually compute the
063: // fitness value. If the returned value is less than one,
064: // then we throw a runtime exception.
065: // ---------------------------------------------------------
066: double fitnessValue = evaluate(a_subject);
067: if (fitnessValue < 0.00000000d) {
068: throw new RuntimeException(
069: "Fitness values must be positive! Received value: "
070: + fitnessValue);
071: }
072: m_lastComputedFitnessValue = fitnessValue;
073: return fitnessValue;
074: }
075:
076: /**
077: * @return the last fitness value computed via method getFitnessValue(
078: * Chromosome), or NO_FITNES_VALUE if the former method has not been called
079: * yet
080: *
081: * @author Klaus Meffert
082: * @since 2.4
083: */
084: public double getLastComputedFitnessValue() {
085: return m_lastComputedFitnessValue;
086: }
087:
088: /**
089: * Determine the fitness of the given Chromosome instance. The higher the
090: * return value, the more fit the instance. This method should always
091: * return the same fitness value for two equivalent Chromosome instances.
092: *
093: * @param a_subject the Chromosome instance to evaluate
094: *
095: * @return positive double reflecting the fitness rating of the given
096: * Chromosome. Note that if a non-positive double is returned, a
097: * RuntimeException should be generated
098: *
099: * @author Neil Rotstan
100: * @author Klaus Meffert
101: * @since 2.0 (until 1.1: return type int)
102: */
103: protected abstract double evaluate(IChromosome a_subject);
104:
105: /**
106: * Please override in your implementations!
107: *
108: * @return deep clone of the current instance
109: *
110: * @author Klaus Meffert
111: * @since 3.2
112: */
113: public Object clone() {
114: try {
115: return super .clone();
116: } catch (CloneNotSupportedException cex) {
117: throw new CloneException(cex);
118: }
119: }
120: }
|