[6152] | 1 | /*
|
---|
| 2 | Copyright 2006 by Sean Luke
|
---|
| 3 | Licensed under the Academic Free License version 3.0
|
---|
| 4 | See the file "LICENSE" for more information
|
---|
| 5 | */
|
---|
| 6 |
|
---|
| 7 |
|
---|
| 8 | package ec;
|
---|
| 9 | import java.io.*;
|
---|
| 10 | import ec.util.*;
|
---|
| 11 |
|
---|
| 12 | /*
|
---|
| 13 | * Fitness.java
|
---|
| 14 | *
|
---|
| 15 | * Created: Tue Aug 10 20:10:42 1999
|
---|
| 16 | * By: Sean Luke
|
---|
| 17 | */
|
---|
| 18 |
|
---|
| 19 | /**
|
---|
| 20 | * Fitness is a prototype which describes the fitness of an individual.
|
---|
| 21 | * Every individual contains exactly one Fitness object.
|
---|
| 22 | * Fitness objects are compared to each other with the equivalentTo()
|
---|
| 23 | * and betterThan(), etc. methods.
|
---|
| 24 | *
|
---|
| 25 | <p>Rules:
|
---|
| 26 | <table>
|
---|
| 27 | <tr><td><b>comparison</b></td><td><b>method</b></td></tr>
|
---|
| 28 | <tr><td>a > b</td><td>a.betterThan(b)</td>
|
---|
| 29 | <tr><td>a >= b</td><td>a.betterThan(b) || a.equivalentTo(b)</td>
|
---|
| 30 | <tr><td>a = b</td><td>a.equivalentTo(b)</td>
|
---|
| 31 | </table>
|
---|
| 32 |
|
---|
| 33 | This applies even to multiobjective pareto-style dominance, eg:
|
---|
| 34 | <ul>
|
---|
| 35 | <li> a dominates b :: a > b
|
---|
| 36 | <li> a and b do not dominate each other :: a = b
|
---|
| 37 | <li> b dominates a :: a < b
|
---|
| 38 | </ul>
|
---|
| 39 |
|
---|
| 40 | <p><b>Parameter bases</b><br>
|
---|
| 41 | <table>
|
---|
| 42 |
|
---|
| 43 | <tr><td valign=top><tt>fit</tt></td>
|
---|
| 44 | <td>default fitness base</td></tr>
|
---|
| 45 | </table>
|
---|
| 46 |
|
---|
| 47 | * @author Sean Luke
|
---|
| 48 | * @version 1.0
|
---|
| 49 | */
|
---|
| 50 |
|
---|
| 51 |
|
---|
| 52 | public abstract class Fitness implements Prototype, Comparable
|
---|
| 53 | {
|
---|
| 54 | /** Auxiliary variable, used by coevolutionary processes, to compute the
|
---|
| 55 | number of trials used to compute this Fitness value. By default trials=1. */
|
---|
| 56 | public int trials = 1;
|
---|
| 57 |
|
---|
| 58 | /** base parameter for defaults */
|
---|
| 59 | public static final String P_FITNESS = "fitness";
|
---|
| 60 |
|
---|
| 61 | /** Basic preamble for printing Fitness values out */
|
---|
| 62 | public static final String FITNESS_PREAMBLE = "Fitness: ";
|
---|
| 63 |
|
---|
| 64 | /** Should return an absolute fitness value ranging from negative
|
---|
| 65 | infinity to infinity, NOT inclusive (thus infinity, negative
|
---|
| 66 | infinity, and NaN are NOT valid fitness values). This should
|
---|
| 67 | be interpreted as: negative infinity is worse than the WORST
|
---|
| 68 | possible fitness, and positive infinity is better than the IDEAL
|
---|
| 69 | fitness.
|
---|
| 70 |
|
---|
| 71 | <p>You are free to restrict this range any way you like: for example,
|
---|
| 72 | your fitness values might fall in the range [-5.32, 2.3]
|
---|
| 73 |
|
---|
| 74 | <p>Selection methods relying on fitness proportionate information will
|
---|
| 75 | <b>assume the fitness is non-negative</b> and should throw an error
|
---|
| 76 | if it is not. Thus if you plan on using FitProportionateSelection,
|
---|
| 77 | BestSelection, or
|
---|
| 78 | GreedyOverselection, for example, your fitnesses should assume that 0
|
---|
| 79 | is the worst fitness and positive fitness are better. If you're using
|
---|
| 80 | other selection methods (Tournament selection, various ES selection
|
---|
| 81 | procedures, etc.) your fitness values can be anything.
|
---|
| 82 |
|
---|
| 83 | <p>Similarly, if you're writing a selection method and it needs positive
|
---|
| 84 | fitnesses, you should check for negative values and issue an error; and
|
---|
| 85 | if your selection method doesn't need an <i>absolute</i> fitness
|
---|
| 86 | value, it should use the equivalentTo() and betterThan() methods instead.
|
---|
| 87 |
|
---|
| 88 | <p> If your fitness scheme does not use a metric quantifiable to
|
---|
| 89 | a single positive value (for example, MultiObjectiveFitness), you should
|
---|
| 90 | perform some reasonable translation.
|
---|
| 91 | */
|
---|
| 92 | public abstract float fitness();
|
---|
| 93 |
|
---|
| 94 | /** Should return true if this is a good enough fitness to end the run */
|
---|
| 95 | public abstract boolean isIdealFitness();
|
---|
| 96 |
|
---|
| 97 | /** Should return true if this fitness is in the same equivalence class
|
---|
| 98 | as _fitness, that is, neither is clearly better or worse than the
|
---|
| 99 | other. You may assume that _fitness is of the same class as yourself.
|
---|
| 100 | For any two fitnesses fit1 and fit2 of the same class,
|
---|
| 101 | it must be the case that fit1.equivalentTo(fit2) == fit2.equivalentTo(fit1),
|
---|
| 102 | and that only one of fit1.betterThan(fit2), fit1.equivalentTo(fit2),
|
---|
| 103 | and fit2.betterThan(fit1) can be true.
|
---|
| 104 | */
|
---|
| 105 | public abstract boolean equivalentTo(Fitness _fitness);
|
---|
| 106 |
|
---|
| 107 | /** Should return true if this fitness is clearly better than _fitness;
|
---|
| 108 | You may assume that _fitness is of the same class as yourself.
|
---|
| 109 | For any two fitnesses fit1 and fit2 of the same class,
|
---|
| 110 | it must be the case that fit1.equivalentTo(fit2) == fit2.equivalentTo(fit1),
|
---|
| 111 | and that only one of fit1.betterThan(fit2), fit1.equivalentTo(fit2),
|
---|
| 112 | and fit2.betterThan(fit1) can be true.
|
---|
| 113 | */
|
---|
| 114 | public abstract boolean betterThan(Fitness _fitness);
|
---|
| 115 |
|
---|
| 116 | /** Should print the fitness out fashion pleasing for humans to read,
|
---|
| 117 | with a verbosity of Output.V_NO_GENERAL.
|
---|
| 118 | */
|
---|
| 119 | public void printFitnessForHumans(EvolutionState state, int log)
|
---|
| 120 | {
|
---|
| 121 | printFitnessForHumans( state, log, Output.V_NO_GENERAL);
|
---|
| 122 | }
|
---|
| 123 |
|
---|
| 124 | /** Should print the fitness out fashion pleasing for humans to read,
|
---|
| 125 | using state.output.println(...,verbosity,log). The default version
|
---|
| 126 | of this method calls fitnessToStringForHumans() and println's the
|
---|
| 127 | resultant string.
|
---|
| 128 | @deprecated Verbosity no longer has meaning
|
---|
| 129 | */
|
---|
| 130 | public void printFitnessForHumans(EvolutionState state, int log,
|
---|
| 131 | int verbosity)
|
---|
| 132 | {
|
---|
| 133 | state.output.println( fitnessToStringForHumans(), verbosity, log);
|
---|
| 134 | }
|
---|
| 135 |
|
---|
| 136 | /** Should print the fitness out in a computer-readable fashion,
|
---|
| 137 | with a verbosity of Output.V_NO_GENERAL.
|
---|
| 138 | */
|
---|
| 139 | public void printFitness(EvolutionState state, int log)
|
---|
| 140 | {
|
---|
| 141 | printFitness( state, log, Output.V_NO_GENERAL);
|
---|
| 142 | }
|
---|
| 143 |
|
---|
| 144 | /** Should print the fitness out in a computer-readable fashion,
|
---|
| 145 | using state.output.println(...,verbosity,log). You might use
|
---|
| 146 | ec.util.Code to encode fitness values. The default version
|
---|
| 147 | of this method calls fitnessToString() and println's the
|
---|
| 148 | resultant string.
|
---|
| 149 | @deprecated Verbosity no longer has meaning
|
---|
| 150 | */
|
---|
| 151 | public void printFitness(EvolutionState state, int log,
|
---|
| 152 | int verbosity)
|
---|
| 153 | {
|
---|
| 154 | state.output.println( fitnessToString(), verbosity, log);
|
---|
| 155 | }
|
---|
| 156 |
|
---|
| 157 | /** Should print the fitness out in a computer-readable fashion,
|
---|
| 158 | using writer.println(...). You might use
|
---|
| 159 | ec.util.Code to encode fitness values. The default version
|
---|
| 160 | of this method calls fitnessToString() and println's the
|
---|
| 161 | resultant string.
|
---|
| 162 | */
|
---|
| 163 | public void printFitness(final EvolutionState state,
|
---|
| 164 | final PrintWriter writer)
|
---|
| 165 | {
|
---|
| 166 | writer.println( fitnessToString() );
|
---|
| 167 | }
|
---|
| 168 |
|
---|
| 169 | /** Reads in the fitness from a form outputted by fitnessToString() and thus
|
---|
| 170 | printFitnessForHumans(...). The default version of this method
|
---|
| 171 | exits the program with an "unimplemented" error. */
|
---|
| 172 | public void readFitness(final EvolutionState state,
|
---|
| 173 | final LineNumberReader reader)
|
---|
| 174 | throws IOException
|
---|
| 175 | {
|
---|
| 176 | state.output.fatal("readFitness(EvolutionState, DataOutput) not implemented in " + this.getClass());
|
---|
| 177 | }
|
---|
| 178 |
|
---|
| 179 | /** Print to a string the fitness in a fashion readable by humans, and not intended
|
---|
| 180 | to be parsed in again. The default form
|
---|
| 181 | simply calls toString(), but you'll probably want to override this to something else. */
|
---|
| 182 | public String fitnessToStringForHumans()
|
---|
| 183 | {
|
---|
| 184 | return toString();
|
---|
| 185 | }
|
---|
| 186 |
|
---|
| 187 | /** Print to a string the fitness in a fashion intended
|
---|
| 188 | to be parsed in again via readFitness(...).
|
---|
| 189 | The fitness and evaluated flag should not be included. The default form
|
---|
| 190 | simply calls toString(), which is almost certainly wrong,
|
---|
| 191 | and you'll probably want to override this to something else. */
|
---|
| 192 | public String fitnessToString()
|
---|
| 193 | {
|
---|
| 194 | return toString();
|
---|
| 195 | }
|
---|
| 196 |
|
---|
| 197 | /** Writes the binary form of an individual out to a DataOutput. This is not for serialization:
|
---|
| 198 | the object should only write out the data relevant to the object sufficient to rebuild it from a DataInput.
|
---|
| 199 | The default version exits the program with an "unimplemented" error; you should override this.
|
---|
| 200 | */
|
---|
| 201 | public void writeFitness(final EvolutionState state,
|
---|
| 202 | final DataOutput dataOutput) throws IOException
|
---|
| 203 | {
|
---|
| 204 | state.output.fatal("writeFitness(EvolutionState, DataOutput) not implemented in " + this.getClass());
|
---|
| 205 | }
|
---|
| 206 |
|
---|
| 207 |
|
---|
| 208 | /** Reads the binary form of an individual from a DataInput. This is not for serialization:
|
---|
| 209 | the object should only read in the data written out via printIndividual(state,dataInput).
|
---|
| 210 | The default version exits the program with an "unimplemented" error; you should override this.
|
---|
| 211 | */
|
---|
| 212 | public void readFitness(final EvolutionState state,
|
---|
| 213 | final DataInput dataInput) throws IOException
|
---|
| 214 | {
|
---|
| 215 | state.output.fatal("readFitness(EvolutionState, DataOutput) not implemented in " + this.getClass());
|
---|
| 216 | }
|
---|
| 217 |
|
---|
| 218 | public Object clone()
|
---|
| 219 | {
|
---|
| 220 | try { return super.clone(); }
|
---|
| 221 | catch (CloneNotSupportedException e)
|
---|
| 222 | { throw new InternalError(); } // never happens
|
---|
| 223 | }
|
---|
| 224 |
|
---|
| 225 | public void setup(EvolutionState state, Parameter base)
|
---|
| 226 | {
|
---|
| 227 | // by default does nothing
|
---|
| 228 | }
|
---|
| 229 |
|
---|
| 230 | /**
|
---|
| 231 | Returns -1 if I am FITTER than the other Fitness, 1 if I am LESS FIT than the other Fitness,
|
---|
| 232 | and 0 if we are equivalent.
|
---|
| 233 | */
|
---|
| 234 | public int compareTo(Object o)
|
---|
| 235 | {
|
---|
| 236 | Fitness other = (Fitness) o;
|
---|
| 237 | if (this.betterThan(other)) return -1;
|
---|
| 238 | if (other.betterThan(this)) return 1;
|
---|
| 239 | return 0;
|
---|
| 240 | }
|
---|
| 241 |
|
---|
| 242 | /** Sets the fitness to be the same value as the mean of the provided fitnesses. The default
|
---|
| 243 | version of this method exits with an "unimplemented" error; you should override this. */
|
---|
| 244 | public void setToMeanOf(EvolutionState state, Fitness[] fitnesses)
|
---|
| 245 | {
|
---|
| 246 | state.output.fatal("setToMeanOf(EvolutionState, Fitness[]) not implemented in " + this.getClass());
|
---|
| 247 | }
|
---|
| 248 | }
|
---|
| 249 |
|
---|