/* Copyright 2006 by Sean Luke and George Mason University Licensed under the Academic Free License version 3.0 See the file "LICENSE" for more information */ package ec.parsimony; import ec.select.*; import ec.*; import ec.util.*; import ec.steadystate.*; /** * * DoubleTournamentSelection.java * * There are 2 tournaments for each selection of an individual. In the first * ("qualifying") tournament, size individuals * are selected and the best one (based on individuals' length if do-length-first * is true, or based on individual's fitness otherwise). This process repeat size2 times, * so we end up with size2 winners on one criteria. Then, there is second "champion" tournament * on the other criteria (fitness if do-length-first is true, size otherwise) among the * size2 individuals, and the best one is the one returned by this selection method. *

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

Parameters
base.size
int >= 1 (default 7)
(the tournament size for the initial ("qualifying") tournament)
base.size2
int >= 1 (default 7)
(the tournament size for the final ("champion") tournament)
base.pick-worst
bool = true or false (default)
(should we pick the worst individual in the initial ("qualifying") tournament instead of the best?)
base.pick-worst2
bool = true or false (default)
(should we pick the worst individual in the final ("champion") tournament instead of the best?)
base.do-length-first
bool = true (default) or false
(should the initial ("qualifying") tournament be based on the length of the individual or (if false) the fitness of the individual? The final ("champion") tournament will be based on the alternative option)

Default Base
select.double-tournament * */ /** * * * @author Sean Luke & Liviu Panait * @version 1.0 * */ public class DoubleTournamentSelection extends SelectionMethod implements SteadyStateBSourceForm { /** default base */ public static final String P_TOURNAMENT = "double-tournament"; public static final String P_PICKWORST = "pick-worst"; public static final String P_PICKWORST2 = "pick-worst2"; public static final String P_DOLENGTHFIRST = "do-length-first"; /** size parameter */ public static final String P_SIZE = "size"; public static final String P_SIZE2 = "size2"; /* Default size */ public static final int DEFAULT_SIZE = 7; /** Size of the tournament*/ public int size; public int size2; /** What's our probability of selection? If 1.0, we always pick the "good" individual. */ public double probabilityOfSelection; public double probabilityOfSelection2; /** Do we pick the worst instead of the best? */ public boolean pickWorst; public boolean pickWorst2; public boolean doLengthFirst; public Parameter defaultBase() { return SelectDefaults.base().push(P_TOURNAMENT); } public void setup(final EvolutionState state, final Parameter base) { super.setup(state,base); Parameter def = defaultBase(); double val = state.parameters.getDouble(base.push(P_SIZE),def.push(P_SIZE),1.0); if (val < 1.0) state.output.fatal("Tournament size must be >= 1.",base.push(P_SIZE),def.push(P_SIZE)); else if (val > 1 && val < 2) // pick with probability { size = 2; probabilityOfSelection = (val/2); } else if (val != (int)val) // it's not an integer state.output.fatal("If >= 2, Tournament size must be an integer.", base.push(P_SIZE), def.push(P_SIZE)); else { size = (int)val; probabilityOfSelection = 1.0; } val = state.parameters.getDouble(base.push(P_SIZE2),def.push(P_SIZE2),1.0); if (val < 1.0) state.output.fatal("Tournament size2 must be >= 1.",base.push(P_SIZE2),def.push(P_SIZE2)); else if (val > 1 && val < 2) // pick with probability { size2 = 2; probabilityOfSelection2 = (val/2); } else if (val != (int)val) // it's not an integer state.output.fatal("If >= 2, Tournament size2 must be an integer.", base.push(P_SIZE2), def.push(P_SIZE2)); else { size2 = (int)val; probabilityOfSelection2 = 1.0; } doLengthFirst = state.parameters.getBoolean(base.push(P_DOLENGTHFIRST),def.push(P_DOLENGTHFIRST),true); pickWorst = state.parameters.getBoolean(base.push(P_PICKWORST),def.push(P_PICKWORST),false); pickWorst2 = state.parameters.getBoolean(base.push(P_PICKWORST2),def.push(P_PICKWORST2),false); } /** Produces the index of a person selected from among several by a tournament. The tournament's criteria is fitness of individuals if doLengthFirst is true, otherwise the size of the individuals. */ public int produce(final int subpopulation, final EvolutionState state, final int thread) { int[] inds = new int[size2]; for(int x=0;x oldinds[i].size()) { bad = i; i = j; } else bad = j; } else { if (oldinds[j].size() < oldinds[i].size()) { bad = i; i = j;} else bad = j; } } if (probabilityOfSelection2 != 1.0 && !state.random[thread].nextBoolean(probabilityOfSelection2)) i = bad; return i; } else { // pick size random individuals, then pick the best. Individual[] oldinds = state.population.subpops[subpopulation].individuals; int i = inds[0]; int bad = i; for (int x=1;x oldinds[i].size()) { bad = i; i = j; } else bad = j; } else { if (oldinds[j].size() < oldinds[i].size()) { bad = i; i = j;} else bad = j; } } if (probabilityOfSelection != 1.0 && !state.random[thread].nextBoolean(probabilityOfSelection)) i = bad; return i; } else { // pick size random individuals, then pick the best. Individual[] oldinds = state.population.subpops[subpopulation].individuals; int i = state.random[thread].nextInt(oldinds.length) ; int bad = i; for (int x=1;x