Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OKBJavaConnector/ECJClient/src/ec/EvolutionState.java @ 6703

Last change on this file since 6703 was 6152, checked in by bfarka, 14 years ago

added ecj and custom statistics to communicate with the okb services #1441

File size: 14.9 KB
Line 
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
8package ec;
9import ec.util.ParameterDatabase;
10import ec.util.Parameter;
11import ec.util.MersenneTwisterFast;
12import ec.util.Output;
13import java.io.IOException;
14import java.util.Vector;
15
16/*
17 * EvolutionState.java
18 *
19 * Created: Tue Aug 10 22:14:46 1999
20 * By: Sean Luke
21 */
22
23/**
24 * An EvolutionState object is a singleton object which holds the entire
25 * state of an evolutionary run.  By serializing EvolutionState, the entire
26 * run can be checkpointed out to a file.
27 *
28 * <p>The EvolutionState instance is passed around in a <i>lot</i> of methods,
29 * so objects can read from the parameter database, pick random numbers,
30 * and write to the output facility.
31 *
32 * <p>EvolutionState is a unique object in that it calls its own setup(...)
33 * method, from run(...).
34 *
35 * <p>An EvolutionState object contains quite a few objects, including:
36 <ul>
37 <li><i>Objects you may safely manipulate during the multithreaded sections of a run:</i>
38 <ul>
39 <li> MersenneTwisterFast random number generators (one for each evaluation or breeding thread -- use the thread number you were provided to determine which random number generator to use)
40 <li> The ParameterDatabase
41 <li> The Output facility for writing messages and logging
42 </ul>
43
44 <li><i>Singleton objects:</i>
45 <ul>
46 <li> The Initializer.
47 <li> The Finisher.
48 <li> The Breeder.
49 <li> The Evaluator.
50 <li> The Statistics facility.
51 <li> The Exchanger.
52 </ul>
53
54 <li><i>The current evolution state:</i>
55 <ul>
56 <li> The generation number.
57 <li> The population.
58 <li> The maximal number of generations.
59 </ul>
60
61 <li><i>Auxillary read-only information:</i>
62 <ul>
63 <li> The prefix to begin checkpoint file names with.
64 <li> Whether to quit upon finding a perfect individual.
65 <li> The number of breeding threads to spawn.
66 <li> The number of evaluation threads to spawn.
67 </ul>
68 
69 <li><i>A place to stash pointers to static variables so they'll get serialized: </i>
70 <ul>
71 <li> Statics
72 </ul>
73 </ul>
74
75 <p><b>Parameters</b><br>
76 <table>
77 <tr><td valign=top><tt>generations</tt><br>
78 <font size=-1>int &gt;= 1</font></td>
79 <td valign=top>(maximal number of generations to run.)</td></tr>
80
81 <tr><td valign=top><tt>checkpoint-modulo</tt><br>
82 <font size=-1>int &gt;= 1</font></td>
83 <td valign=top>(how many generations should pass before we do a checkpoint? 
84 The definition of "generations" depends on the particular EvolutionState
85 implementation you're using)</td></tr>
86
87 <tr><td valign=top><tt>checkpoint</tt><br>
88 <font size=-1>bool = <tt>true</tt> or <tt>false</tt> (default)</td>
89 <td valign=top>(should we checkpoint?)</td></tr>
90 
91 <tr><td valign=top><tt>prefix</tt><br>
92 <font size=-1>String</font></td>
93 <td valign=top>(the prefix to prepend to checkpoint files -- see ec.util.Checkpoint)</td></tr>
94
95 <tr><td valign=top><tt>quit-on-run-complete</tt><br>
96 <font size=-1>bool = <tt>true</tt> or <tt>false</tt> (default)</td>
97 <td valign=top>(do we prematurely quit the run when we find a perfect individual?)</td></tr>
98
99 <tr><td valign=top><tt>init</tt><br>
100 <font size=-1>classname, inherits and != ec.Initializer</font></td>
101 <td valign=top>(the class for initializer)</td></tr>
102
103 <tr><td valign=top><tt>finish</tt><br>
104 <font size=-1>classname, inherits and != ec.Finisher</font></td>
105 <td valign=top>(the class for finisher)</td></tr>
106
107 <tr><td valign=top><tt>breed</tt><br>
108 <font size=-1>classname, inherits and != ec.Breeder</font></td>
109 <td valign=top>(the class for breeder)</td></tr>
110
111 <tr><td valign=top><tt>eval</tt><br>
112 <font size=-1>classname, inherits and != ec.Evaluator</font></td>
113 <td valign=top>(the class for evaluator)</td></tr>
114
115 <tr><td valign=top><tt>stat</tt><br>
116 <font size=-1>classname, inherits or = ec.Statistics</font></td>
117 <td valign=top>(the class for statistics)</td></tr>
118
119 <tr><td valign=top><tt>exch</tt><br>
120 <font size=-1>classname, inherits and != ec.Exchanger</font></td>
121 <td valign=top>(the class for exchanger)</td></tr>
122
123 </table>
124
125
126 <p><b>Parameter bases</b><br>
127 <table>
128
129 <tr><td valign=top><tt>init</tt></td>
130 <td>initializer</td></tr>
131
132 <tr><td valign=top><tt>finish</tt></td>
133 <td>finisher</td></tr>
134
135 <tr><td valign=top><tt>breed</tt></td>
136 <td>breeder</td></tr>
137
138 <tr><td valign=top><tt>eval</tt></td>
139 <td>evaluator</td></tr>
140
141 <tr><td valign=top><tt>stat</tt></td>
142 <td>statistics</td></tr>
143
144 <tr><td valign=top><tt>exch</tt></td>
145 <td>exchanger</td></tr>
146 </table>
147
148 *
149 * @author Sean Luke
150 * @version 1.0
151 */
152
153public class EvolutionState implements Singleton
154    {
155    /** The parameter database (threadsafe).  Parameter objects are also threadsafe.
156        Nonetheless, you should generally try to treat this database as read-only. */
157    public ParameterDatabase parameters;
158
159    /** An array of random number generators, indexed by the thread number you were given (or, if you're not in a multithreaded area, use 0).  These generators are not threadsafe in and of themselves, but if you only use the random number generator assigned to your thread, as was intended, then you get random numbers in a threadsafe way.  These generators must each have a different seed, of course.v*/
160    public MersenneTwisterFast[] random;
161
162    /** The output and logging facility (threadsafe).  Keep in mind that output in Java is expensive. */
163    public Output output;
164
165    /** The requested number of threads to be used in breeding, excepting perhaps a "parent" thread which gathers the other threads.  If breedthreads = 1, then the system should not be multithreaded during breeding.  Don't modify this during a run. */
166    public int breedthreads;  // how many threads to use in breeding
167
168    /** The requested number of threads to be used in evaluation, excepting perhaps a "parent" thread which gathers the other threads.  If evalthreads = 1, then the system should not be multithreaded during evaluation. Don't modify this during a run.*/
169    public int evalthreads;  // how many threads to use in evaluation
170
171    /** Should we checkpoint at all? */
172    public boolean checkpoint;
173
174    /** The requested prefix start checkpoint filenames, not including a following period.  You probably shouldn't modify this during a run.*/
175    public String checkpointPrefix;  // term to prefix checkpoint filenames
176
177    /** The requested number of generations that should pass before we write out a checkpoint file. */
178    public int checkpointModulo;
179
180    /** An amount to add to each random number generator seed to "offset" it -- often this is simply the job number. 
181        If you are using more random number generators
182        internally than the ones initially created for you in the EvolutionState, you might want to create them with the seed
183        value of <tt>seedParameter+randomSeedOffset</tt>.  At present the only such class creating additional generators
184        is ec.eval.MasterProblem. */
185    public int randomSeedOffset;
186
187    /** Whether or not the system should prematurely quit when Evaluator returns true for runComplete(...) (that is, when the system found an ideal individual. */
188    public boolean quitOnRunComplete;
189
190    /** Current job iteration variables, set by Evolve.  The default version simply sets this to a single Object[1] containing
191        the current job iteration number as an Integer (for a single job, it's 0).  You probably should not modify this inside
192        an evolutionary run.  */
193    public Object[] job;
194
195    /** The original runtime arguments passed to the Java process. You probably should not modify this inside
196        an evolutionary run.  */
197    public String[] runtimeArguments;
198       
199    // set during running
200   
201    /** The current generation of the population in the run.  For non-generational approaches, this probably should represent some kind of incrementing value, perhaps the number of individuals evaluated so far.  You probably shouldn't modify this. */
202    public int generation;
203    /** The number of generations the evolutionary computation system will run until it ends.  If after the population has been evaluated the Evaluator returns true for runComplete(...), and quitOnRunComplete is true, then the system will quit.  You probably shouldn't modify this.  */
204    public int numGenerations;
205
206    /** The current population.  This is <i>not</i> a singleton object, and may be replaced after every generation in a generational approach. You should only access this in a read-only fashion.  */
207    public Population population;
208
209    /** The population initializer, a singleton object.  You should only access this in a read-only fashion. */
210    public Initializer initializer;
211
212    /** The population finisher, a singleton object.  You should only access this in a read-only fashion. */
213    public Finisher finisher;
214
215    /** The population breeder, a singleton object.  You should only access this in a read-only fashion. */
216    public Breeder breeder;
217
218    /** The population evaluator, a singleton object.  You should only access this in a read-only fashion. */
219    public Evaluator evaluator;
220
221    /** The population statistics, a singleton object.  You should generally only access this in a read-only fashion. */
222    public Statistics statistics;
223
224    /** The population exchanger, a singleton object.  You should only access this in a read-only fashion. */
225    public Exchanger exchanger;
226
227    /** "The population has started fresh (not from a checkpoint)." */
228    public final static int C_STARTED_FRESH = 0;
229
230    /** "The population started from a checkpoint." */
231    public final static int C_STARTED_FROM_CHECKPOINT = 1;
232
233    /** "The evolution run has quit, finding a perfect individual." */
234    public final static int R_SUCCESS = 0;
235
236    /** "The evolution run has quit, failing to find a perfect individual." */
237    public final static int R_FAILURE = 1;
238   
239    /** "The evolution run has not quit */
240    public final static int R_NOTDONE = 2;
241
242    public final static String P_INITIALIZER = "init";
243    public final static String P_FINISHER = "finish";
244    public final static String P_BREEDER = "breed";
245    public final static String P_EVALUATOR = "eval";
246    public final static String P_STATISTICS = "stat";
247    public final static String P_EXCHANGER = "exch";
248    public final static String P_GENERATIONS = "generations";
249    public final static String P_QUITONRUNCOMPLETE = "quit-on-run-complete";
250    public final static String P_CHECKPOINTPREFIX = "prefix";
251    public final static String P_CHECKPOINTMODULO = "checkpoint-modulo";
252    public final static String P_CHECKPOINT = "checkpoint";
253
254    /** This will be called to create your evolution state; immediately
255        after the constructor is called,
256        the parameters, random, and output fields will be set
257        for you.  The constructor probably won't be called ever if
258        restoring (deserializing) from a checkpoint.
259    */
260    public EvolutionState() { }
261   
262    /** Unlike for other setup() methods, ignore the base; it will always be null.
263        @see Prototype#setup(EvolutionState,Parameter)
264    */
265    public void setup(final EvolutionState state, final Parameter base)
266        {
267
268        Parameter p;
269
270        // we ignore the base, it's worthless anyway for EvolutionState
271
272        p = new Parameter(P_CHECKPOINT);
273        checkpoint = parameters.getBoolean(p,null,false);
274
275        p = new Parameter(P_CHECKPOINTPREFIX);
276        checkpointPrefix = parameters.getString(p,null);
277        if (checkpointPrefix==null)
278            output.fatal("No checkpoint prefix specified.",p);
279
280        p = new Parameter(P_CHECKPOINTMODULO);
281        checkpointModulo = parameters.getInt(p,null,1);
282        if (checkpointModulo==0)
283            output.fatal("The checkpoint modulo must be an integer >0.",p);
284       
285        p = new Parameter(P_GENERATIONS);
286        numGenerations = parameters.getInt(p,null,1);
287        if (numGenerations==0)
288            output.fatal("The number of generations must be an integer >0.",p);
289       
290        p=new Parameter(P_QUITONRUNCOMPLETE);
291        quitOnRunComplete = parameters.getBoolean(p,null,false);
292
293
294        /* Set up the singletons */
295        p=new Parameter(P_INITIALIZER);
296        initializer = (Initializer)
297            (parameters.getInstanceForParameter(p,null,Initializer.class));
298        initializer.setup(this,p);
299
300        p=new Parameter(P_FINISHER);
301        finisher = (Finisher)
302            (parameters.getInstanceForParameter(p,null,Finisher.class));
303        finisher.setup(this,p);
304
305        p=new Parameter(P_BREEDER);
306        breeder = (Breeder)
307            (parameters.getInstanceForParameter(p,null,Breeder.class));
308        breeder.setup(this,p);
309
310        p=new Parameter(P_EVALUATOR);
311        evaluator = (Evaluator)
312            (parameters.getInstanceForParameter(p,null,Evaluator.class));
313        evaluator.setup(this,p);
314
315        p=new Parameter(P_STATISTICS);
316        statistics = (Statistics)
317            (parameters.getInstanceForParameterEq(p,null,Statistics.class));
318        statistics.setup(this,p);
319       
320        p=new Parameter(P_EXCHANGER);
321        exchanger = (Exchanger)
322            (parameters.getInstanceForParameter(p,null,Exchanger.class));
323        exchanger.setup(this,p);
324               
325        generation = 0;
326        }
327
328
329    /** This method is called after a checkpoint
330        is restored from but before the run starts up again.  You might use this
331        to set up file pointers that were lost, etc. */
332 
333    public void resetFromCheckpoint() throws IOException
334        {
335        output.restart();   // may throw an exception if there's a bad file
336        exchanger.reinitializeContacts(this);
337        evaluator.reinitializeContacts(this);
338        }
339
340    public void finish(int result) {}
341
342    public void startFromCheckpoint() {}
343
344    public void startFresh() {}
345
346    public int evolve()
347        throws InternalError { return R_NOTDONE; }
348
349    /** Starts the run. <i>condition</i> indicates whether or not the
350        run was restarted from a checkpoint (C_STARTED_FRESH vs
351        C_STARTED_FROM_CHECKPOINT).  At the point that run(...) has been
352        called, the parameter database has already been set up, as have
353        the random number generators, the number of threads, and the
354        Output facility.  This method should call this.setup(...) to
355        set up the EvolutionState object if condition equals C_STARTED_FRESH. */
356    public void run(int condition)
357        {
358        if (condition == C_STARTED_FRESH)
359            {
360            startFresh();
361            }
362        else // condition == C_STARTED_FROM_CHECKPOINT
363            {
364            startFromCheckpoint();
365            }
366       
367        /* the big loop */
368        int result = R_NOTDONE;
369        while ( result == R_NOTDONE )
370            {
371            result = evolve();
372            }
373       
374        finish(result);
375        }
376    }
Note: See TracBrowser for help on using the repository browser.