Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OKBJavaConnector/ECJClient/src/ec/vector/breed/MultipleVectorCrossoverPipeline.java @ 6152

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

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

File size: 31.0 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
7package ec.vector.breed;
8
9import ec.vector.*;
10import ec.*;
11import ec.util.Parameter;
12
13
14/*
15 * MultipleVectorCrossoverPipeline.java
16 *
17 * Created: Thu May 14 2009
18 * By: Beenish Jamil
19 */
20
21
22/**
23 *
24 MultipleVectorCrossoverPipeline is a BreedingPipeline which implements a uniform
25 (any point) crossover between multiple vectors. It is intended to be used with
26 three or more vectors. It takes n parent individuals and returns n crossed over
27 individuals. The number of parents and consequently children is specified by the
28 number of sources parameter.
29 <p>The standard vector crossover probability is used for this crossover type.
30 <br> <i> Note</i> : It is necessary to set the crossover-type parameter to 'any'
31 in order to use this pipeline.
32 
33 
34 <p><b>Typical Number of Individuals Produced Per <tt>produce(...)</tt> call</b><br>
35 number of parents
36
37 <p><b>Number of Sources</b><br>
38 variable (generally 3 or more)
39
40 
41 <p><b>Default Base</b><br>
42 vector.multixover
43*/
44
45// This class is MUCH MUCH longer than it need be.  We could just do it by using
46// ECJ's generic split and join operations, but only rely on that in the default
47// case, and instead use faster per-array operations.
48
49
50public class MultipleVectorCrossoverPipeline extends BreedingPipeline {
51
52    /** default base */
53    public static final String P_CROSSOVER = "multixover";
54   
55    /** Temporary holding place for parents */
56    VectorIndividual[] parents;
57   
58    public Parameter defaultBase() { return VectorDefaults.base().push(P_CROSSOVER); }   
59   
60    /** Returns the number of parents */
61    public int numSources() { return DYNAMIC_SOURCES;}
62   
63    public Object clone()
64        {
65        MultipleVectorCrossoverPipeline c = (MultipleVectorCrossoverPipeline)(super.clone());
66
67        // deep-cloned stuff
68        c.parents = (VectorIndividual[]) parents.clone();
69
70        return c;
71        }
72
73    public void setup(final EvolutionState state, final Parameter base)
74        {
75        super.setup(state,base);       
76        parents = new VectorIndividual[sources.length];
77        }
78       
79    /**
80     * Returns the minimum number of children that are produced per crossover
81     */
82    public int typicalIndsProduced()
83        {
84        return minChildProduction()*sources.length; // minChild is always 1     
85        }
86   
87       
88    public int produce(final int min,
89        final int max,
90        final int start,
91        final int subpopulation,
92        final Individual[] inds,
93        final EvolutionState state,
94        final int thread)
95
96        {
97       
98        // how many individuals should we make?
99        int n = typicalIndsProduced();
100        if (n < min) n = min;
101        if (n > max) n = max;
102
103       
104        // should we bother?
105        if (!state.random[thread].nextBoolean(likelihood))
106            return reproduce(n, start, subpopulation, inds, state, thread, true);  // DO produce children from source -- we've not done so already
107
108
109        if(inds[0] instanceof BitVectorIndividual)
110            n = multipleBitVectorCrossover(min, max, start, subpopulation, // redundant reassignment
111                inds, state, thread);
112       
113        else if(inds[0] instanceof ByteVectorIndividual)
114            n = multipleByteVectorCrossover(min, max, start, subpopulation,
115                inds, state, thread);
116       
117        else if(inds[0] instanceof DoubleVectorIndividual)
118            n = multipleDoubleVectorCrossover(min, max, start, subpopulation,
119                inds, state, thread);
120       
121        else if(inds[0] instanceof FloatVectorIndividual)
122            n = multipleFloatVectorCrossover(min, max, start, subpopulation,
123                inds, state, thread);
124
125        else if(inds[0] instanceof IntegerVectorIndividual)
126            n = multipleIntegerVectorCrossover(min, max, start, subpopulation,
127                inds, state, thread);
128       
129        else if(inds[0] instanceof GeneVectorIndividual)
130            n = multipleGeneVectorCrossover(min, max, start, subpopulation,
131                inds, state, thread);
132
133        else if(inds[0] instanceof LongVectorIndividual)
134            n = multipleLongVectorCrossover(min, max, start, subpopulation,
135                inds, state, thread);
136
137        else if(inds[0] instanceof ShortVectorIndividual)
138            n = multipleShortVectorCrossover(min, max, start, subpopulation,
139                inds, state, thread);
140
141        else // default crossover -- shouldn't need this unless a new vector type is added
142            {
143            // check how many sources are provided
144            if(sources.length <= 2)
145                // this method shouldn't be called for just two parents
146                state.output.error("Only two parents specified!");
147
148
149            // fill up parents:
150            for(int i = 0;i<parents.length; i++) // parents.length == sources.length
151                {               
152                // produce one parent from each source
153                sources[i].produce(1,1,i,subpopulation,parents,state,thread);
154                if (!(sources[i] instanceof BreedingPipeline))  // it's a selection method probably
155                    parents[i] = (VectorIndividual)(parents[i].clone());
156                }
157
158
159            //... some required intermediary steps ....
160
161            // assuming all of the species are the same species ...
162            VectorSpecies species = (VectorSpecies)parents[0].species;
163
164            // an array of the split points (width = 1)
165            int[] points = new int[(int)parents[0].genomeLength() - 1];
166            for(int i = 0; i < points.length; i++){
167                points[i] = i+1;    // first split point/index = 1
168                }
169
170
171            // split all the parents into object arrays
172            Object[][] pieces = new Object[parents.length][(int)parents[0].genomeLength()];
173
174            // splitting...
175            for(int i = 0; i < parents.length; i++){
176                if(parents[i].genomeLength() != parents[0].genomeLength())             
177                    state.output.fatal("All vectors must be of the same length for crossover!");
178                else
179                    parents[i].split(points, pieces[i]);
180                }
181
182
183            // crossing them over now
184            for(int i = 0; i < pieces[0].length; i++)
185                {   
186                if(state.random[thread].nextBoolean(species.crossoverProbability))
187                    {
188                    // shuffle
189                    for(int j = pieces.length-1; j > 0; j--) // no need to shuffle first index at the end
190                        {
191                        // find parent to swap piece with
192                        int parent2 = state.random[thread].nextInt(j); // not inclusive; don't want to swap with self
193                        // swap
194                        Object temp = pieces[j][i];
195                        pieces[j][i] = pieces[parent2][i];
196                        pieces[parent2][i] = temp;
197                        }
198                    }
199                }
200
201            // join them and add them to the population starting at the start location
202            for(int i = 0, q = start; i < parents.length; i++, q++)
203                {
204                parents[i].join(pieces[i]);                         
205                parents[i].evaluated = false;
206                if(q<inds.length) // just in case
207                    {               
208                    inds[q] = (VectorIndividual)parents[i];
209                    }
210                }
211            }
212        return n;
213        }
214   
215   
216    /** Crosses over the Bit Vector Individuals using a
217        uniform crossover method.     
218        *
219        * There is no need to call this method separately; produce(...) calls it
220        * whenever necessary by default.
221        */
222    public int multipleBitVectorCrossover(final int min,
223        final int max,
224        final int start,
225        final int subpopulation,
226        final Individual[] inds,
227        final EvolutionState state,
228        final int thread)
229        {
230        if(!(inds[0] instanceof BitVectorIndividual))
231            state.output.fatal("Trying to produce bit vector individuals when you can't!");
232       
233       
234        // check how many sources are provided
235        if(sources.length <= 2)
236            // this method shouldn't be called for just two parents
237            state.output.error("Only two parents specified!");
238
239       
240        // how many individuals should we make?
241        int n = typicalIndsProduced();
242        if (n < min) n = min;
243        if (n > max) n = max;
244           
245       
246       
247        // fill up parents:
248        for(int i = 0;i<parents.length; i++) // parents.length == sources.length
249            {                   
250            // produce one parent from each source
251            sources[i].produce(1,1,i,subpopulation,parents,state,thread);
252            if (!(sources[i] instanceof BreedingPipeline))  // it's a selection method probably
253                parents[i] = (BitVectorIndividual)(parents[i].clone());
254            }
255       
256       
257        VectorSpecies species = (VectorSpecies)inds[0].species; // doesn't really matter if
258        //this is dblvector or vector as long as we
259        // can get the crossover probability
260
261       
262        // crossover
263        for(int i = 0; i < parents[0].genomeLength(); i++)
264            {
265            if(state.random[thread].nextBoolean(species.crossoverProbability))
266                {               
267                for(int j = parents.length-1; j > 0; j--)
268                    {                       
269                    int swapIndex = state.random[thread].nextInt(j); // not inclusive; don't want to swap with self                     
270                    boolean temp = ((BitVectorIndividual) parents[j]).genome[i]; // modifying genomes directly. it's okay since they're clones
271                    ((BitVectorIndividual)parents[j]).genome[i] =
272                        ((BitVectorIndividual)parents[swapIndex]).genome[i];
273                    ((BitVectorIndividual)parents[swapIndex]).genome[i] = temp;                 
274                    }                       
275                }
276            }
277       
278        // add to population
279        for(int i = 0, q = start; i < parents.length; i++, q++)
280            {         
281            parents[i].evaluated = false;
282            if(q<inds.length) // just in case
283                {           
284                inds[q] = (BitVectorIndividual)parents[i];
285                }
286            }       
287        return n;       
288        }
289   
290   
291    /** Crosses over the Byte Vector Individuals using a
292        uniform crossover method.     
293        *
294        * There is no need to call this method separately; produce(...) calls it
295        * whenever necessary by default.
296        */
297    public int multipleByteVectorCrossover(final int min,
298        final int max,
299        final int start,
300        final int subpopulation,
301        final Individual[] inds,
302        final EvolutionState state,
303        final int thread)
304        {
305        if(!(inds[0] instanceof ByteVectorIndividual))
306            state.output.fatal("Trying to produce byte vector individuals when you can't!");
307       
308       
309        // check how many sources are provided
310        if(sources.length <= 2)
311            // this method shouldn't be called for just two parents
312            state.output.error("Only two parents specified!");
313
314       
315        // how many individuals should we make?
316        int n = typicalIndsProduced();
317        if (n < min) n = min;
318        if (n > max) n = max;
319           
320       
321       
322        // fill up parents:
323        for(int i = 0;i<parents.length; i++) // parents.length == sources.length
324            {                   
325            // produce one parent from each source
326            sources[i].produce(1,1,i,subpopulation,parents,state,thread);
327            if (!(sources[i] instanceof BreedingPipeline))  // it's a selection method probably
328                parents[i] = (ByteVectorIndividual)(parents[i].clone());
329            }
330       
331       
332        VectorSpecies species = (VectorSpecies)inds[0].species; // doesn't really matter if
333        //this is dblvector or vector as long as we
334        // can get the crossover probability
335
336       
337        // crossover
338        for(int i = 0; i < parents[0].genomeLength(); i++)
339            {
340            if(state.random[thread].nextBoolean(species.crossoverProbability))
341                {               
342                for(int j = parents.length-1; j > 0; j--)
343                    {                       
344                    int swapIndex = state.random[thread].nextInt(j); // not inclusive; don't want to swap with self                     
345                    byte temp = ((ByteVectorIndividual) parents[j]).genome[i]; // modifying genomes directly. it's okay since they're clones
346                    ((ByteVectorIndividual)parents[j]).genome[i] = ((ByteVectorIndividual)parents[swapIndex]).genome[i];
347                    ((ByteVectorIndividual)parents[swapIndex]).genome[i] = temp;                       
348                    }                       
349                }
350            }
351       
352        // add to population
353        for(int i = 0, q = start; i < parents.length; i++, q++)
354            {         
355            parents[i].evaluated = false;
356            if(q<inds.length) // just in case
357                {           
358                inds[q] = (ByteVectorIndividual)parents[i];
359                }
360            }       
361        return n;       
362        }
363   
364   
365    /** Crosses over the Double Vector Individuals using a
366        uniform crossover method.   
367        *
368        * There is no need to call this method separately; produce(...) calls it
369        * whenever necessary by default.   
370        */
371    public int multipleDoubleVectorCrossover(final int min,
372        final int max,
373        final int start,
374        final int subpopulation,
375        final Individual[] inds,
376        final EvolutionState state,
377        final int thread)
378        {
379       
380        if(!(inds[0] instanceof DoubleVectorIndividual))
381            state.output.fatal("Trying to produce double vector individuals when you can't!");
382       
383        // check how many sources are provided
384        if(sources.length <= 2)
385            // this method shouldn't be called for just two parents
386            state.output.error("Only two parents specified!");
387
388       
389        // how many individuals should we make?
390        int n = typicalIndsProduced();
391        if (n < min) n = min;
392        if (n > max) n = max;
393           
394       
395
396        // fill up parents:
397        for(int i = 0;i<parents.length; i++) // parents.length == sources.length
398            {                   
399            // produce one parent from each source
400            sources[i].produce(1,1,i,subpopulation,parents,state,thread);
401            if (!(sources[i] instanceof BreedingPipeline))  // it's a selection method probably
402                parents[i] = (DoubleVectorIndividual)(parents[i].clone());
403            }
404       
405       
406        VectorSpecies species = (VectorSpecies)inds[0].species; // doesn't really matter if
407        //this is dblvector or vector as long as we
408        // can get the crossover probability
409       
410       
411        // crossover
412        for(int i = 0; i < parents[0].genomeLength(); i++)
413            {
414            if(state.random[thread].nextBoolean(species.crossoverProbability))
415                {               
416                for(int j = parents.length-1; j > 0; j--)
417                    {                       
418                    int swapIndex = state.random[thread].nextInt(j); // not inclusive; don't want to swap with self                     
419                    double temp = ((DoubleVectorIndividual) parents[j]).genome[i]; // modifying genomes directly. it's okay since they're clones
420                    ((DoubleVectorIndividual)parents[j]).genome[i] = ((DoubleVectorIndividual)parents[swapIndex]).genome[i];
421                    ((DoubleVectorIndividual)parents[swapIndex]).genome[i] = temp;                     
422                    }                       
423                }
424            }
425       
426        // add to population
427        for(int i = 0, q = start; i < parents.length; i++, q++)
428            {         
429            parents[i].evaluated = false;
430            if(q<inds.length) // just in case
431                {           
432                inds[q] = (DoubleVectorIndividual)parents[i];
433                }
434            }       
435        return n;       
436        }
437
438   
439    /** Crosses over the Float Vector Individuals using a
440        uniform crossover method.     
441        *
442        * There is no need to call this method separately; produce(...) calls it
443        * whenever necessary by default.
444        */
445    public int multipleFloatVectorCrossover(final int min,
446        final int max,
447        final int start,
448        final int subpopulation,
449        final Individual[] inds,
450        final EvolutionState state,
451        final int thread)
452        {
453        if(!(inds[0] instanceof FloatVectorIndividual))
454            state.output.fatal("Trying to produce float vector individuals when you can't!");
455       
456       
457        // check how many sources are provided
458        if(sources.length <= 2)
459            // this method shouldn't be called for just two parents
460            state.output.error("Only two parents specified!");
461
462       
463        // how many individuals should we make?
464        int n = typicalIndsProduced();
465        if (n < min) n = min;
466        if (n > max) n = max;
467           
468       
469       
470        // fill up parents:
471        for(int i = 0;i<parents.length; i++) // parents.length == sources.length
472            {                   
473            // produce one parent from each source
474            sources[i].produce(1,1,i,subpopulation,parents,state,thread);
475            if (!(sources[i] instanceof BreedingPipeline))  // it's a selection method probably
476                parents[i] = (FloatVectorIndividual)(parents[i].clone());
477            }
478       
479       
480        VectorSpecies species = (VectorSpecies)inds[0].species; // doesn't really matter if
481        //this is dblvector or vector as long as we
482        // can get the crossover probability
483
484       
485        // crossover
486        for(int i = 0; i < parents[0].genomeLength(); i++)
487            {
488            if(state.random[thread].nextBoolean(species.crossoverProbability))
489                {               
490                for(int j = parents.length-1; j > 0; j--)
491                    {                       
492                    int swapIndex = state.random[thread].nextInt(j); // not inclusive; don't want to swap with self                     
493                    float temp = ((FloatVectorIndividual) parents[j]).genome[i]; // modifying genomes directly. it's okay since they're clones
494                    ((FloatVectorIndividual)parents[j]).genome[i] = ((FloatVectorIndividual)parents[swapIndex]).genome[i];
495                    ((FloatVectorIndividual)parents[swapIndex]).genome[i] = temp;                       
496                    }                       
497                }
498            }
499       
500        // add to population
501        for(int i = 0, q = start; i < parents.length; i++, q++)
502            {         
503            parents[i].evaluated = false;
504            if(q<inds.length) // just in case
505                {           
506                inds[q] = (FloatVectorIndividual)parents[i];
507                }
508            }       
509        return n;       
510        }
511   
512       
513    /** Crosses over the Gene Vector Individuals using a
514        uniform crossover method.     
515        *
516        * There is no need to call this method separately; produce(...) calls it
517        * whenever necessary by default.
518        */
519    public int multipleGeneVectorCrossover(final int min,
520        final int max,
521        final int start,
522        final int subpopulation,
523        final Individual[] inds,
524        final EvolutionState state,
525        final int thread)
526        {
527        if(!(inds[0] instanceof GeneVectorIndividual))
528            state.output.fatal("Trying to produce gene vector individuals when you can't!");
529       
530       
531        // check how many sources are provided
532        if(sources.length <= 2)
533            // this method shouldn't be called for just two parents
534            state.output.error("Only two parents specified!");
535
536       
537        // how many individuals should we make?
538        int n = typicalIndsProduced();
539        if (n < min) n = min;
540        if (n > max) n = max;
541           
542       
543       
544        // fill up parents:
545        for(int i = 0;i<parents.length; i++) // parents.length == sources.length
546            {                   
547            // produce one parent from each source
548            sources[i].produce(1,1,i,subpopulation,parents,state,thread);
549            if (!(sources[i] instanceof BreedingPipeline))  // it's a selection method probably
550                parents[i] = (GeneVectorIndividual)(parents[i].clone());
551            }
552       
553       
554        VectorSpecies species = (VectorSpecies)inds[0].species; // doesn't really matter if
555        //this is dblvector or vector as long as we
556        // can get the crossover probability
557
558       
559        // crossover
560        for(int i = 0; i < parents[0].genomeLength(); i++)
561            {
562            if(state.random[thread].nextBoolean(species.crossoverProbability))
563                {               
564                for(int j = parents.length-1; j > 0; j--)
565                    {                       
566                    int swapIndex = state.random[thread].nextInt(j); // not inclusive; don't want to swap with self                     
567                    VectorGene temp = ((GeneVectorIndividual) parents[j]).genome[i]; // modifying genomes directly. it's okay since they're clones
568                    ((GeneVectorIndividual)parents[j]).genome[i] = ((GeneVectorIndividual)parents[swapIndex]).genome[i];
569                    ((GeneVectorIndividual)parents[swapIndex]).genome[i] = temp;                       
570                    }                       
571                }
572            }
573       
574        // add to population
575        for(int i = 0, q = start; i < parents.length; i++, q++)
576            {         
577            parents[i].evaluated = false;
578            if(q<inds.length) // just in case
579                {           
580                inds[q] = (GeneVectorIndividual)parents[i];
581                }
582            }       
583        return n;       
584        }
585
586       
587    /**Crosses over the Integer Vector Individuals using a uniform crossover method.   
588     *
589     * There is no need to call this method separately; produce(...) calls it
590     * whenever necessary by default.   
591     */
592    public int multipleIntegerVectorCrossover(final int min,
593        final int max,
594        final int start,
595        final int subpopulation,
596        final Individual[] inds,
597        final EvolutionState state,
598        final int thread)
599        {
600       
601        if(!(inds[0] instanceof IntegerVectorIndividual))
602            state.output.fatal("Trying to produce integer vector individuals when you can't!");
603       
604
605       
606        // check how many sources are provided
607        if(sources.length <= 2)
608            // this method shouldn't be called for just two parents
609            state.output.error("Only two parents specified!");
610
611       
612        // how many individuals should we make?
613        int n = typicalIndsProduced();
614        if (n < min) n = min;
615        if (n > max) n = max;
616           
617           
618       
619        // fill up parents:
620        for(int i = 0;i<parents.length; i++) // parents.length == sources.length
621            {                   
622            // produce one parent from each source     
623            sources[i].produce(1,1,i,subpopulation,parents,state,thread);
624            if (!(sources[i] instanceof BreedingPipeline))  // it's a selection method probably
625                parents[i] = (IntegerVectorIndividual)(parents[i].clone());
626
627            }
628       
629       
630        VectorSpecies species = (VectorSpecies)inds[0].species; // doesn't really matter if
631        //this is dblvector or vector as long as we
632        // can get the crossover probability
633
634       
635        // crossover
636        for(int i = 0; i < parents[0].genomeLength(); i++)
637            {
638            if(state.random[thread].nextBoolean(species.crossoverProbability))
639                {               
640                for(int j = parents.length-1; j > 0; j--)
641                    {                       
642                    int swapIndex = state.random[thread].nextInt(j); // not inclusive; don't want to swap with self                     
643                    int temp = ((IntegerVectorIndividual) parents[j]).genome[i]; // modifying genomes directly. it's okay since they're clones
644                    ((IntegerVectorIndividual)parents[j]).genome[i] = ((IntegerVectorIndividual)parents[swapIndex]).genome[i];
645                    ((IntegerVectorIndividual)parents[swapIndex]).genome[i] = temp;                     
646                    }                       
647                }
648            }
649       
650        // add to population
651        for(int i = 0, q = start; i < parents.length; i++, q++)
652            {         
653            parents[i].evaluated = false;
654            if(q<inds.length) // just in case
655                {           
656                inds[q] = (IntegerVectorIndividual)parents[i];
657                }
658            }       
659        return n;       
660        }
661 
662       
663    /** Crosses over the Long Vector Individuals using a
664        uniform crossover method.     
665        *
666        * There is no need to call this method separately; produce(...) calls it
667        * whenever necessary by default.
668        */
669    public int multipleLongVectorCrossover(final int min,
670        final int max,
671        final int start,
672        final int subpopulation,
673        final Individual[] inds,
674        final EvolutionState state,
675        final int thread)
676        {
677        if(!(inds[0] instanceof LongVectorIndividual))
678            state.output.fatal("Trying to produce long vector individuals when you can't!");
679       
680       
681        // check how many sources are provided
682        if(sources.length <= 2)
683            // this method shouldn't be called for just two parents
684            state.output.error("Only two parents specified!");
685
686       
687        // how many individuals should we make?
688        int n = typicalIndsProduced();
689        if (n < min) n = min;
690        if (n > max) n = max;
691           
692       
693       
694        // fill up parents:
695        for(int i = 0;i<parents.length; i++) // parents.length == sources.length
696            {                   
697            // produce one parent from each source
698            sources[i].produce(1,1,i,subpopulation,parents,state,thread);
699            if (!(sources[i] instanceof BreedingPipeline))  // it's a selection method probably
700                parents[i] = (LongVectorIndividual)(parents[i].clone());
701            }
702       
703       
704        VectorSpecies species = (VectorSpecies)inds[0].species; // doesn't really matter if
705        //this is dblvector or vector as long as we
706        // can get the crossover probability
707       
708        // crossover
709        for(int i = 0; i < parents[0].genomeLength(); i++)
710            {
711            if(state.random[thread].nextBoolean(species.crossoverProbability))
712                {               
713                for(int j = parents.length-1; j > 0; j--)
714                    {                       
715                    int swapIndex = state.random[thread].nextInt(j); // not inclusive; don't want to swap with self                     
716                    long temp = ((LongVectorIndividual) parents[j]).genome[i]; // modifying genomes directly. it's okay since they're clones
717                    ((LongVectorIndividual)parents[j]).genome[i] = ((LongVectorIndividual)parents[swapIndex]).genome[i];
718                    ((LongVectorIndividual)parents[swapIndex]).genome[i] = temp;                       
719                    }                       
720                }
721            }
722       
723        // add to population
724        for(int i = 0, q = start; i < parents.length; i++, q++)
725            {         
726            parents[i].evaluated = false;
727            if(q<inds.length) // just in case
728                {           
729                inds[q] = (LongVectorIndividual)parents[i];
730                }
731            }       
732        return n;       
733        }
734   
735     
736    /** Crosses over the Short Vector Individuals using a
737        uniform crossover method.     
738        *
739        * There is no need to call this method separately; produce(...) calls it
740        * whenever necessary by default.
741        */
742    public int multipleShortVectorCrossover(final int min,
743        final int max,
744        final int start,
745        final int subpopulation,
746        final Individual[] inds,
747        final EvolutionState state,
748        final int thread)
749        {
750        if(!(inds[0] instanceof ShortVectorIndividual))
751            state.output.fatal("Trying to produce short vector individuals when you can't!");
752       
753       
754        // check how many sources are provided
755        if(sources.length <= 2)
756            // this method shouldn't be called for just two parents
757            state.output.error("Only two parents specified!");
758
759       
760        // how many individuals should we make?
761        int n = typicalIndsProduced();
762        if (n < min) n = min;
763        if (n > max) n = max;
764           
765       
766       
767        // fill up parents:
768        for(int i = 0;i<parents.length; i++) // parents.length == sources.length
769            {                   
770            // produce one parent from each source
771            sources[i].produce(1,1,i,subpopulation,parents,state,thread);
772            if (!(sources[i] instanceof BreedingPipeline))  // it's a selection method probably
773                parents[i] = (ShortVectorIndividual)(parents[i].clone());
774            }
775       
776       
777        VectorSpecies species = (VectorSpecies)inds[0].species; // doesn't really matter if
778        //this is dblvector or vector as long as we
779        // can get the crossover probability
780
781       
782        // crossover
783        for(int i = 0; i < parents[0].genomeLength(); i++)
784            {
785            if(state.random[thread].nextBoolean(species.crossoverProbability))
786                {               
787                for(int j = parents.length-1; j > 0; j--)
788                    {                       
789                    int swapIndex = state.random[thread].nextInt(j); // not inclusive; don't want to swap with self                     
790                    short temp = ((ShortVectorIndividual) parents[j]).genome[i]; // modifying genomes directly. it's okay since they're clones
791                    ((ShortVectorIndividual)parents[j]).genome[i] = ((ShortVectorIndividual)parents[swapIndex]).genome[i];
792                    ((ShortVectorIndividual)parents[swapIndex]).genome[i] = temp;                       
793                    }                       
794                }
795            }
796       
797        // add to population
798        for(int i = 0, q = start; i < parents.length; i++, q++)
799            {         
800            parents[i].evaluated = false;
801            if(q<inds.length) // just in case
802                {           
803                inds[q] = (ShortVectorIndividual)parents[i];
804                }
805            }       
806        return n;       
807        }
808    }
Note: See TracBrowser for help on using the repository browser.