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 |
|
---|