Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OKBJavaConnector/ECJClient/src/ec/rule/RuleIndividual.java @ 10501

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

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

File size: 10.7 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.rule;
9import ec.*;
10import ec.util.*;
11import java.io.*;
12
13/*
14 * RuleIndividual.java
15 *
16 * Created: Tue May 29 18:20:20 EDT 2001
17 * By: Sean Luke
18 */
19
20/**
21 * RuleIndividual is an Individual with an array of RuleSets, each of which
22 * is a set of Rules.  RuleIndividuals belong to some subclass of RuleSpecies
23 * (or just RuleSpecies itself).
24 *
25 * <p>RuleIndividuals really have basically one parameter: the number
26 * of RuleSets to use.  This is determined by the <tt>num-rulesets</tt>
27 * parameter.
28
29 * <P><b>From ec.Individual:</b> 
30 *
31 * <p>In addition to serialization for checkpointing, Individuals may read and write themselves to streams in three ways.
32 *
33 * <ul>
34 * <li><b>writeIndividual(...,DataOutput)/readIndividual(...,DataInput)</b>&nbsp;&nbsp;&nbsp;This method
35 * transmits or receives an individual in binary.  It is the most efficient approach to sending
36 * individuals over networks, etc.  These methods write the evaluated flag and the fitness, then
37 * call <b>readGenotype/writeGenotype</b>, which you must implement to write those parts of your
38 * Individual special to your functions-- the default versions of readGenotype/writeGenotype throw errors.
39 * You don't need to implement them if you don't plan on using read/writeIndividual.
40 *
41 * <li><b>printIndividual(...,PrintWriter)/readIndividual(...,LineNumberReader)</b>&nbsp;&nbsp;&nbsp;This
42 * approach transmits or receives an indivdual in text encoded such that the individual is largely readable
43 * by humans but can be read back in 100% by ECJ as well.  To do this, these methods will encode numbers
44 * using the <tt>ec.util.Code</tt> class.  These methods are mostly used to write out populations to
45 * files for inspection, slight modification, then reading back in later on.  <b>readIndividual</b>reads
46 * in the fitness and the evaluation flag, then calls <b>parseGenotype</b> to read in the remaining individual.
47 * You are responsible for implementing parseGenotype: the Code class is there to help you.
48 * <b>printIndividual</b> writes out the fitness and evaluation flag, then calls <b>genotypeToString<b>
49 * and printlns the resultant string. You are responsible for implementing the genotypeToString method in such
50 * a way that parseGenotype can read back in the individual println'd with genotypeToString.  The default form
51 * of genotypeToString simply calls <b>toString</b>, which you may override instead if you like.  The default
52 * form of <b>parseGenotype</b> throws an error.  You are not required to implement these methods, but without
53 * them you will not be able to write individuals to files in a simultaneously computer- and human-readable fashion.
54 *
55 * <li><b>printIndividualForHumans(...,PrintWriter)</b>&nbsp;&nbsp;&nbsp;This
56 * approach prints an individual in a fashion intended for human consumption only.
57 * <b>printIndividualForHumans</b> writes out the fitness and evaluation flag, then calls <b>genotypeToStringForHumans<b>
58 * and printlns the resultant string. You are responsible for implementing the genotypeToStringForHumans method.
59 * The default form of genotypeToStringForHumans simply calls <b>toString</b>, which you may override instead if you like
60 * (though note that genotypeToString's default also calls toString).  You should handle one of these methods properly
61 * to ensure individuals can be printed by ECJ.
62 * </ul>
63
64 * <p>In general, the various readers and writers do three things: they tell the Fitness to read/write itself,
65 * they read/write the evaluated flag, and they read/write the Rulesets.  If you add instance variables to
66 * a RuleIndividual or subclass, you'll need to read/write those variables as well.
67
68 <p><b>Parameters</b><br>
69 <table>
70 <tr><td valign=top><i>base</i>.<tt>num-rulesets</tt><br>
71 <font size=-1>int >= 1</font></td>
72 <td valign=top>(number of rulesets used)</td></tr>
73 <tr><td valign=top><i>base</i>.<tt>ruleset</tt>.<i>n</i><br>
74 <font size=-1>Classname, subclass of or = ec.rule.RuleSet</font></td>
75 <td valign=top>(class of ruleset <i>n</i>)</td></tr>
76 </table>
77 
78 <p><b>Parameter bases</b><br>
79 <table>
80 <tr><td valign=top><i>base</i>.<tt>ruleset</tt>.<i>n</i><br>
81 <td>RuleSet <i>n</i></td></tr>
82 </table>
83
84 <p><b>Default Base</b><br>
85 rule.individual
86
87 * @author Sean Luke
88 * @version 1.0
89 */
90public class RuleIndividual extends Individual
91    {
92    public static final String P_RULESET = "ruleset";
93    public static final String P_NUMRULESETS = "num-rulesets";
94   
95    /** The individual's rulesets. */
96    public RuleSet[] rulesets;
97   
98    public Parameter defaultBase()
99        {
100        return RuleDefaults.base().push(P_INDIVIDUAL);
101        }
102
103    public Object clone()
104        {
105        RuleIndividual myobj = (RuleIndividual) (super.clone());   
106        myobj.rulesets = new RuleSet[rulesets.length];
107        for(int x=0;x<rulesets.length;x++)
108            myobj.rulesets[x] = (RuleSet)(rulesets[x].clone());
109        return myobj;
110        }
111
112    /** Called by pipelines before they've modified the individual and
113        it might need to be "fixed"  -- basically a hook for you to override.
114        By default, calls validateRules on each ruleset. */
115    public void preprocessIndividual(final EvolutionState state, final int thread)
116        {
117        for (int x=0;x<rulesets.length;x++)
118            rulesets[x].preprocessRules(state,thread);
119        }
120
121    /** Called by pipelines after they've modified the individual and
122        it might need to be "fixed"  -- basically a hook for you to override.
123        By default, calls validateRules on each ruleset. */
124    public void postprocessIndividual(final EvolutionState state, final int thread)
125        {
126        for (int x=0;x<rulesets.length;x++)
127            rulesets[x].postprocessRules(state,thread);
128        }
129       
130    public boolean equals(Object ind)
131        {
132        // My loose definition: ind must be a
133        if (!getClass().equals(ind.getClass()))  // not the same class, I'm conservative that way
134            return false;
135
136        RuleIndividual other = (RuleIndividual)ind;
137        if (rulesets.length != other.rulesets.length) return false;
138        for(int x=0;x<rulesets.length;x++)
139            if (!rulesets[x].equals(other.rulesets[x])) return false;
140        return true;
141        }
142
143    public int hashCode()
144        {
145        int hash = this.getClass().hashCode();
146        for(int x=0;x<rulesets.length;x++)
147            // rotate hash and XOR
148            hash =
149                (hash << 1 | hash >>> 31 ) ^ rulesets[x].hashCode();
150        return hash;
151        }
152
153    public void setup(final EvolutionState state, final Parameter base)
154        {
155        super.setup(state,base);  // actually unnecessary (Individual.setup() is empty)
156
157        // I'm the top-level setup, I guess
158        int numrulesets = state.parameters.getInt(
159            base.push(P_NUMRULESETS), defaultBase().push(P_NUMRULESETS),
160            1);  // need at least 1 ruleset!
161        if (numrulesets == 0)
162            state.output.fatal("RuleIndividual needs at least one RuleSet!",
163                base.push(P_NUMRULESETS), defaultBase().push(P_NUMRULESETS));
164
165        rulesets  = new RuleSet[numrulesets];
166
167        for(int x=0;x<numrulesets;x++)
168            {
169            rulesets[x] = (RuleSet)(state.parameters.getInstanceForParameterEq(
170                    base.push(P_RULESET).push(""+x),defaultBase().push(P_RULESET),
171                    RuleSet.class));
172            rulesets[x].setup(state,base.push(P_RULESET).push(""+x));
173            }
174        }
175
176    public void printIndividualForHumans(final EvolutionState state,
177        final int log)
178        {
179        state.output.println(EVALUATED_PREAMBLE + (evaluated ? "true" : "false"), log);
180        fitness.printFitnessForHumans(state,log);
181        for(int x=0;x<rulesets.length;x++)
182            {
183            state.output.println("Ruleset " + x + ":", log);
184            rulesets[x].printRuleSetForHumans(state, log);
185            }
186        }
187
188    public void printIndividual(final EvolutionState state,
189        final int log)
190        {
191        state.output.println(EVALUATED_PREAMBLE + Code.encode(evaluated), log);
192        fitness.printFitness(state, log);
193        for(int x=0;x<rulesets.length;x++)
194            {
195            state.output.println("Ruleset " + x + ":", log);
196            rulesets[x].printRuleSet(state,log);
197            }
198        }
199
200    /** Overridden for the RuleIndividual genotype, writing each ruleset in turn. */
201    public void printIndividual(final EvolutionState state,
202        final PrintWriter writer)
203        {
204        writer.println(EVALUATED_PREAMBLE + Code.encode(evaluated));
205        fitness.printFitness(state,writer);
206        for(int x=0;x<rulesets.length;x++)
207            {
208            writer.println("Ruleset " + x + ":");
209            rulesets[x].printRuleSet(state,writer);
210            }
211        }
212   
213    /** Overridden for the RuleIndividual genotype, writing each ruleset in turn. */
214    public void writeGenotype(final EvolutionState state,
215        final DataOutput dataOutput) throws IOException
216        {
217        dataOutput.writeInt(rulesets.length);
218        for(int x=0;x<rulesets.length;x++)
219            rulesets[x].writeRuleSet(state,dataOutput);
220        }
221
222    /** Overridden for the RuleIndividual genotype. */
223    public void readGenotype(final EvolutionState state,
224        final DataInput dataInput) throws IOException
225        {
226        int len = dataInput.readInt();
227        if (rulesets==null || rulesets.length != len)
228            state.output.fatal("Number of RuleSets differ in RuleIndividual when reading from readGenotype(EvolutionState, DataInput).");
229        for(int x=0;x<rulesets.length;x++)
230            rulesets[x].readRuleSet(state,dataInput);
231        }
232
233
234    /** Overridden for the RuleIndividual genotype. */
235    public void parseGenotype(final EvolutionState state,
236        final LineNumberReader reader)
237        throws IOException
238        {
239        // read my ruleset
240        for(int x=0;x<rulesets.length;x++)
241            {
242            reader.readLine();  // throw it away -- it's the ruleset# indicator
243            rulesets[x].readRuleSet(state,reader);
244            }
245        }
246
247    public long size()
248        {
249        long size=0;
250        for(int x=0;x<rulesets.length;x++)
251            size+= rulesets[x].numRules();
252        return size;
253        }
254   
255    public void reset(EvolutionState state, int thread)
256        {
257        for(int x=0;x<rulesets.length;x++)
258            rulesets[x].reset(state,thread);
259        }
260
261    /** Mutates the Individual.  The default implementation simply calls mutate(...) on each of
262        the RuleSets. */
263    public void mutate(EvolutionState state, int thread)
264        {
265        for(int x=0;x<rulesets.length;x++)
266            rulesets[x].mutate(state,thread);
267        }
268    }
269
Note: See TracBrowser for help on using the repository browser.