Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OKBJavaConnector/ECJClient/src/ec/vector/GeneVectorIndividual.java @ 9598

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

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

File size: 13.1 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.vector;
9
10import ec.*;
11import ec.util.*;
12import java.io.*;
13
14/*
15 * GeneVectorIndividual.java
16 * Created: Thu Mar 22 13:13:20 EST 2001
17 */
18
19/**
20 * GeneVectorIndividual is a VectorIndividual whose genome is an array of VectorGenes.
21 * The default mutation method calls the mutate() method on each gene independently
22 * with <tt>species.mutationProbability</tt>.  Initialization calls reset(), which
23 * should call reset() on each gene.  Do not expect that the genes will actually
24 * exist during initialization -- see the default implementation of reset() as an example
25 * for how to handle this.
26 *
27
28 * <P><b>From ec.Individual:</b> 
29 *
30 * <p>In addition to serialization for checkpointing, Individuals may read and write themselves to streams in three ways.
31 *
32 * <ul>
33 * <li><b>writeIndividual(...,DataOutput)/readIndividual(...,DataInput)</b>&nbsp;&nbsp;&nbsp;This method
34 * transmits or receives an individual in binary.  It is the most efficient approach to sending
35 * individuals over networks, etc.  These methods write the evaluated flag and the fitness, then
36 * call <b>readGenotype/writeGenotype</b>, which you must implement to write those parts of your
37 * Individual special to your functions-- the default versions of readGenotype/writeGenotype throw errors.
38 * You don't need to implement them if you don't plan on using read/writeIndividual.
39 *
40 * <li><b>printIndividual(...,PrintWriter)/readIndividual(...,LineNumberReader)</b>&nbsp;&nbsp;&nbsp;This
41 * approach transmits or receives an indivdual in text encoded such that the individual is largely readable
42 * by humans but can be read back in 100% by ECJ as well.  To do this, these methods will encode numbers
43 * using the <tt>ec.util.Code</tt> class.  These methods are mostly used to write out populations to
44 * files for inspection, slight modification, then reading back in later on.  <b>readIndividual</b> reads
45 * in the fitness and the evaluation flag, then calls <b>parseGenotype</b> to read in the remaining individual.
46 * You are responsible for implementing parseGenotype: the Code class is there to help you.
47 * <b>printIndividual</b> writes out the fitness and evaluation flag, then calls <b>genotypeToString</b>
48 * and printlns the resultant string. You are responsible for implementing the genotypeToString method in such
49 * a way that parseGenotype can read back in the individual println'd with genotypeToString.  The default form
50 * of genotypeToString simply calls <b>toString</b>, which you may override instead if you like.  The default
51 * form of <b>parseGenotype</b> throws an error.  You are not required to implement these methods, but without
52 * them you will not be able to write individuals to files in a simultaneously computer- and human-readable fashion.
53 *
54 * <li><b>printIndividualForHumans(...,PrintWriter)</b>&nbsp;&nbsp;&nbsp;This
55 * approach prints an individual in a fashion intended for human consumption only.
56 * <b>printIndividualForHumans</b> writes out the fitness and evaluation flag, then calls <b>genotypeToStringForHumans</b>
57 * and printlns the resultant string. You are responsible for implementing the genotypeToStringForHumans method.
58 * The default form of genotypeToStringForHumans simply calls <b>toString</b>, which you may override instead if you like
59 * (though note that genotypeToString's default also calls toString).  You should handle one of these methods properly
60 * to ensure individuals can be printed by ECJ.
61 * </ul>
62
63 * <p>In general, the various readers and writers do three things: they tell the Fitness to read/write itself,
64 * they read/write the evaluated flag, and they read/write the gene array.  If you add instance variables to
65 * a VectorIndividual or subclass, you'll need to read/write those variables as well.
66 <p><b>Default Base</b><br>
67 vector.gene-vect-ind
68
69 * @author Sean Luke
70 * @version 1.0
71 */
72
73public class GeneVectorIndividual extends VectorIndividual
74    {
75    public static final String P_GENEVECTORINDIVIDUAL = "gene-vect-ind";
76    public VectorGene[] genome;
77   
78    public Parameter defaultBase()
79        {
80        return VectorDefaults.base().push(P_GENEVECTORINDIVIDUAL);
81        }
82
83    public Object clone()
84        {
85        GeneVectorIndividual myobj = (GeneVectorIndividual) (super.clone());
86
87        // must clone the genome
88        myobj.genome = (VectorGene[])(genome.clone());
89        for(int x=0;x<genome.length;x++)
90            myobj.genome[x] = (VectorGene)(genome[x].clone());
91       
92        return myobj;
93        }
94
95    public void setup(final EvolutionState state, final Parameter base)
96        {
97        super.setup(state,base);  // actually unnecessary (Individual.setup() is empty)
98
99        // since VectorSpecies set its constraint values BEFORE it called
100        // super.setup(...) [which in turn called our setup(...)], we know that
101        // stuff like genomeSize has already been set...
102       
103        Parameter def = defaultBase();
104       
105        if (!(species instanceof GeneVectorSpecies))
106            state.output.fatal("GeneVectorIndividual requires a GeneVectorSpecies", base, def);
107        GeneVectorSpecies s = (GeneVectorSpecies) species;
108       
109        // note that genome isn't initialized with any genes yet -- they're all null.
110        // reset() needs
111        genome = new VectorGene[s.genomeSize];
112        reset(state,0);
113        }
114       
115    public void defaultCrossover(EvolutionState state, int thread, VectorIndividual ind)
116        {
117        GeneVectorSpecies s = (GeneVectorSpecies) species;
118        GeneVectorIndividual i = (GeneVectorIndividual) ind;
119        VectorGene tmp;
120        int point;
121
122        if (genome.length != i.genome.length)
123            state.output.fatal("Genome lengths are not the same for fixed-length vector crossover");
124        switch(s.crossoverType)
125            {
126            case VectorSpecies.C_ONE_POINT:
127                point = state.random[thread].nextInt((genome.length / s.chunksize)+1);
128                for(int x=0;x<point*s.chunksize;x++)
129                    {
130                    tmp = i.genome[x];
131                    i.genome[x] = genome[x];
132                    genome[x] = tmp;
133                    }
134                break;
135            case VectorSpecies.C_TWO_POINT:
136                int point0 = state.random[thread].nextInt((genome.length / s.chunksize)+1);
137                point = state.random[thread].nextInt((genome.length / s.chunksize)+1);
138                if (point0 > point) { int p = point0; point0 = point; point = p; }
139                for(int x=point0*s.chunksize;x<point*s.chunksize;x++)
140                    {
141                    tmp = i.genome[x];
142                    i.genome[x] = genome[x];
143                    genome[x] = tmp;
144                    }
145                break;
146            case VectorSpecies.C_ANY_POINT:
147                for(int x=0;x<genome.length/s.chunksize;x++)
148                    if (state.random[thread].nextBoolean(s.crossoverProbability))
149                        for(int y=x*s.chunksize;y<(x+1)*s.chunksize;y++)
150                            {
151                            tmp = i.genome[y];
152                            i.genome[y] = genome[y];
153                            genome[y] = tmp;
154                            }
155                break;
156            }
157        }
158
159    /** Splits the genome into n pieces, according to points, which *must* be sorted.
160        pieces.length must be 1 + points.length */
161    public void split(int[] points, Object[] pieces)
162        {
163        int point0, point1;
164        point0 = 0; point1 = points[0];
165        for(int x=0;x<pieces.length;x++)
166            {
167            pieces[x] = new VectorGene[point1-point0];
168            System.arraycopy(genome,point0,pieces[x],0,point1-point0);
169            point0 = point1;
170            if (x >=pieces.length-2)
171                point1 = genome.length;
172            else point1 = points[x+1];
173            }
174        }
175   
176    /** Joins the n pieces and sets the genome to their concatenation.*/
177    public void join(Object[] pieces)
178        {
179        int sum=0;
180        for(int x=0;x<pieces.length;x++)
181            sum += ((VectorGene[])(pieces[x])).length;
182       
183        int runningsum = 0;
184        VectorGene[] newgenome = new VectorGene[sum];
185        for(int x=0;x<pieces.length;x++)
186            {
187            System.arraycopy(pieces[x], 0, newgenome, runningsum, ((VectorGene[])(pieces[x])).length);
188            runningsum += ((VectorGene[])(pieces[x])).length;
189            }
190        // set genome
191        genome = newgenome;
192        }
193
194    /** Destructively mutates the individual in some default manner.  The default form
195        simply randomizes genes to a uniform distribution from the min and max of the gene values. */
196    public void defaultMutate(EvolutionState state, int thread)
197        {
198        GeneVectorSpecies s = (GeneVectorSpecies) species;
199        if (s.mutationProbability>0.0)
200            for(int x=0;x<genome.length;x++)
201                if (state.random[thread].nextBoolean(s.mutationProbability))
202                    genome[x].mutate(state,thread);
203        }
204
205    /** Initializes the individual by calling reset(...) on each gene. */
206    public void reset(EvolutionState state, int thread)
207        {
208        GeneVectorSpecies s = (GeneVectorSpecies) species;
209
210        for(int x=0;x<genome.length;x++)
211            {
212            // first create the gene if it doesn't exist
213            if (genome[x]==null) genome[x] = (VectorGene)(s.genePrototype.clone());
214            // now reset it
215            genome[x].reset(state,thread);
216            }
217
218        }
219
220    public int hashCode()
221        {
222        // stolen from GPIndividual.  It's a decent algorithm.
223        int hash = this.getClass().hashCode();
224
225        for(int x=0;x<genome.length;x++)
226            hash = ( hash << 1 | hash >>> 31 ) ^ genome[x].hashCode();
227
228        return hash;
229        }
230
231    public String genotypeToStringForHumans()
232        {
233        StringBuffer s = new StringBuffer();
234        for( int i = 0 ; i < genome.length ; i++ )
235            { s.append(" "); s.append(genome[i].printGeneToStringForHumans()); }
236        return s.toString();
237        }
238       
239    public String genotypeToString()
240        {
241        StringBuffer s = new StringBuffer();
242        for( int i = 0 ; i < genome.length ; i++ )
243            { s.append(" "); s.append(genome[i].printGeneToString()); }
244        return s.toString();
245        }
246
247    protected void parseGenotype(final EvolutionState state,
248        final LineNumberReader reader) throws IOException
249        {
250        // read in the next line.  The first item is the number of genes
251        String s = reader.readLine();
252        DecodeReturn d = new DecodeReturn(s);
253        Code.decode( d );
254        int lll = (int)(d.l);
255
256        genome = new VectorGene[ lll ];
257
258        GeneVectorSpecies _species = (GeneVectorSpecies) species;
259        for( int i = 0 ; i < genome.length ; i++ )
260            {
261            genome[i] = (VectorGene)(_species.genePrototype.clone());
262            genome[i].readGene(state,reader);
263            }
264        }
265
266    public boolean equals(Object ind)
267        {
268        if (!(this.getClass().equals(ind.getClass()))) return false;
269        GeneVectorIndividual i = (GeneVectorIndividual)ind;
270        if( genome.length != i.genome.length )
271            return false;
272        for( int j = 0 ; j < genome.length ; j++ )
273            if( !(genome[j].equals(i.genome[j])))
274                return false;
275        return true;
276        }
277
278    public Object getGenome()
279        { return genome; }
280    public void setGenome(Object gen)
281        { genome = (VectorGene[]) gen; }
282    public int genomeLength()
283        { return genome.length; }
284
285    // clone all the genes
286    public void cloneGenes(Object piece)
287        {
288        VectorGene[] genes = (VectorGene[]) piece;
289        for(int i = 0 ; i < genes.length; i++)
290            {
291            if (genes[i] != null) genes[i] = (VectorGene)(genes[i].clone());
292            }
293        }
294   
295    public void writeGenotype(final EvolutionState state,
296        final DataOutput dataOutput) throws IOException
297        {
298        dataOutput.writeInt(genome.length);
299        for(int x=0;x<genome.length;x++)
300            genome[x].writeGene(state,dataOutput);
301        }
302
303    public void setGenomeLength(int len)
304        {
305        GeneVectorSpecies s = (GeneVectorSpecies) species;
306        VectorGene[] newGenome = new VectorGene[len];
307        System.arraycopy(genome, 0, newGenome, 0,
308            genome.length < newGenome.length ? genome.length : newGenome.length);
309        for(int x=genome.length; x< newGenome.length; x++)
310            if (genome[x]==null) genome[x] = (VectorGene)(s.genePrototype.clone());  // not reset
311        genome = newGenome;
312        }
313
314    public void readGenotype(final EvolutionState state,
315        final DataInput dataInput) throws IOException
316        {
317        int len = dataInput.readInt();
318        if (genome==null || genome.length != len)
319            genome = new VectorGene[len];
320        GeneVectorSpecies _species = (GeneVectorSpecies) species;
321
322        for(int x=0;x<genome.length;x++)
323            {
324            genome[x] = (VectorGene)(_species.genePrototype.clone());
325            genome[x].readGene(state,dataInput);
326            }
327        }
328
329    }
Note: See TracBrowser for help on using the repository browser.