/*
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.