/*
  Copyright 2006 by Sean Luke
  Licensed under the Academic Free License version 3.0
  See the file "LICENSE" for more information
*/


package ec.rule.breed;

import ec.rule.*;
import ec.*;
import ec.util.*;

/* 
 * RuleCrossoverPipeline.java
 * 
 * Created: Tue Mar 13 15:03:12 EST 2001
 * By: Sean Luke
 */


/**
 *
 RuleCrossoverPipeline is a BreedingPipeline which implements a simple default crossover
 for RuleIndividuals.  Normally it takes two individuals and returns two crossed-over 
 child individuals.  Optionally, it can take two individuals, cross them over, but throw
 away the second child (a one-child crossover).  RuleCrossoverPipeline works by iteratively taking rulesets
 from each individual, and migrating rules from either to the other with a certain
 per-rule probability.  Rule crossover preserves the min and max rule restrictions.
  
 

Typical Number of Individuals Produced Per produce(...) call
1 or 2

Number of Sources
2

Parameters

base.toss
bool = true or false (default)/td>
(after crossing over with the first new individual, should its second sibling individual be thrown away instead of adding it to the population?)
base.prob
0.0 <= double < 1.0, or 0.5 (default)/td>
(probability that a rule will cross over from one individual to the other)

Default Base
rule.xover * @author Sean Luke * @version 1.0 */ public class RuleCrossoverPipeline extends BreedingPipeline { public static final String P_TOSS = "toss"; public static final String P_CROSSOVER = "xover"; public static final String P_CROSSOVERPROB = "crossover-prob"; public static final int INDS_PRODUCED = 2; public static final int NUM_SOURCES = 2; /** Should the pipeline discard the second parent after crossing over? */ public boolean tossSecondParent; /** What is the probability of a rule migrating? */ public double ruleCrossProbability; /** Temporary holding place for parents */ RuleIndividual parents[]; public RuleCrossoverPipeline() { parents = new RuleIndividual[2]; } public Parameter defaultBase() { return RuleDefaults.base().push(P_CROSSOVER); } /** Returns 2 */ public int numSources() { return NUM_SOURCES; } public Object clone() { RuleCrossoverPipeline c = (RuleCrossoverPipeline)(super.clone()); // deep-cloned stuff c.parents = (RuleIndividual[]) 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); ruleCrossProbability = state.parameters.getDoubleWithDefault(base.push(P_CROSSOVERPROB), def.push(P_CROSSOVERPROB),0.5f); if (ruleCrossProbability > 1.0 || ruleCrossProbability < 0.0) state.output.fatal("Rule cross probability must be between 0 and 1",base.push(P_CROSSOVERPROB), def.push(P_CROSSOVERPROB)); } /** Returns 2 (unless tossing the second sibling, in which case it returns 1) */ public int typicalIndsProduced() { return (tossSecondParent? 1: INDS_PRODUCED); } 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 = (tossSecondParent? 1 : INDS_PRODUCED); 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 RuleInitializer initializer = ((RuleInitializer)state.initializer); for(int q=start;q= parents[0].rulesets[x].constraints(initializer).minSize && temp[0].numRules <= parents[0].rulesets[x].constraints(initializer).maxSize && temp[1].numRules >= parents[1].rulesets[x].constraints(initializer).minSize && temp[1].numRules <= parents[1].rulesets[x].constraints(initializer).maxSize) break; temp = new RuleSet[2]; } // copy the results in the rulesets of the parents parents[0].rulesets[x].copyNoClone(temp[1]); parents[1].rulesets[x].copyNoClone(temp[0]); } parents[0].postprocessIndividual(state,thread); parents[1].postprocessIndividual(state,thread); parents[0].evaluated=false; parents[1].evaluated=false; // add 'em to the population inds[q] = parents[0]; q++; if (q

Ads help maintain this website.