/* Copyright 2006 by Sean Luke Licensed under the Academic Free License version 3.0 See the file "LICENSE" for more information */ package org.kevoree.library.reasoner.ecj; import ec.vector.*; import ec.*; import ec.util.*; public class KevoreeCrossoverPipeline extends BreedingPipeline { public static final String P_TOSS = "toss"; public static final String P_CROSSOVER = "xover"; public static final int NUM_SOURCES = 2; /** Should the pipeline discard the second parent after crossing over? */ public boolean tossSecondParent; /** Temporary holding place for parents */ KevoreeIndividual parents[]; public KevoreeCrossoverPipeline() { parents = new KevoreeIndividual[2]; } public Parameter defaultBase() { return VectorDefaults.base().push(P_CROSSOVER); } /** Returns 2 */ public int numSources() { return NUM_SOURCES; } public Object clone() { KevoreeCrossoverPipeline c = (KevoreeCrossoverPipeline)(super.clone()); // deep-cloned stuff c.parents = (KevoreeIndividual[]) parents.clone(); return c; } public void setup(final EvolutionState state, final Parameter base) { super.setup(state,base); Parameter def = defaultBase(); tossSecondParent = state.parameters.getBoolean(base.push(P_TOSS), def.push(P_TOSS),false); } /** Returns 2 * minimum number of typical individuals produced by any sources, else 1* minimum number if tossSecondParent is true. */ public int typicalIndsProduced() { return (tossSecondParent? minChildProduction(): minChildProduction()*2); } public int produce(final int min, final int max, final int start, final int subpopulation, final Individual[] inds, final EvolutionState state, final int thread) { // how many individuals should we make? int n = typicalIndsProduced(); if (n < min) n = min; if (n > max) n = max; // should we bother? if (!state.random[thread].nextBoolean(likelihood)) return reproduce(n, start, subpopulation, inds, state, thread, true); // DO produce children from source -- we've not done so already for(int q=start;q<n+start; /* no increment */) // keep on going until we're filled up { // grab two individuals from our sources if (sources[0]==sources[1]) // grab from the same source { sources[0].produce(2,2,0,subpopulation,parents,state,thread); if (!(sources[0] instanceof BreedingPipeline)) // it's a selection method probably { parents[0] = (KevoreeIndividual)(parents[0].clone()); parents[1] = (KevoreeIndividual)(parents[1].clone()); } } else // grab from different sources { sources[0].produce(1,1,0,subpopulation,parents,state,thread); sources[1].produce(1,1,1,subpopulation,parents,state,thread); if (!(sources[0] instanceof BreedingPipeline)) // it's a selection method probably parents[0] = (KevoreeIndividual)(parents[0].clone()); if (!(sources[1] instanceof BreedingPipeline)) // it's a selection method probably parents[1] = (KevoreeIndividual)(parents[1].clone()); } // at this point, parents[] contains our two selected individuals, // AND they're copied so we own them and can make whatever modifications // we like on them. // so we'll cross them over now. Since this is the default pipeline, // we'll just do it by calling defaultCrossover on the first child parents[0].defaultCrossover(state,thread,parents[1]); parents[0].evaluated=false; parents[1].evaluated=false; // add 'em to the population inds[q] = parents[0]; q++; if (q<n+start && !tossSecondParent) { inds[q] = parents[1]; q++; } } return n; } }