/* Copyright 2006 by Sean Luke Licensed under the Academic Free License version 3.0 See the file "LICENSE" for more information */ package ec.select; import ec.util.*; import ec.*; /* * SigmaScalingSelection.java * * Created: Fri Jun 5 2009 * By: Jack Compton */ /** * Similar to FitProportionateSelection, but with adjustments to scale up/exaggerate differences in fitness for selection when true fitness values are very close to * eachother across the population. This addreses a common problem with FitProportionateSelection wherein selection approaches random selection during * late runs when fitness values do not differ by much. * *

* Like FitProportionateSelection this is not appropriate for steady-state evolution. * If you're not familiar with the relative advantages of * selection methods and just want a good one, * use TournamentSelection instead. Not appropriate for * multiobjective fitnesses. * *

* Note: Fitnesses must be non-negative. 0 is assumed to be the worst fitness. *

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

Parameters
base.scaled-fitness-floor
double = some small number (defaults to 0.1)
(The sigma scaling formula sometimes returns negative values. This is unacceptable for fitness proportionate style selection so we must substitute the fitnessFloor (some value >= 0) for the sigma scaled fitness when that sigma scaled fitness <= fitnessFloor.)

Default Base
select.sigma-scaling * * @author Jack Compton * @version 1.0 */ public class SigmaScalingSelection extends FitProportionateSelection { /** Default base */ public static final String P_SIGMA_SCALING = "sigma-scaling"; /** Scaled fitness floor */ // Used as a cut-off point when negative valued scaled fitnesses are encountered (negative fitness values are not compatible with fitness proportionate style selection methods) public static final String P_SCALED_FITNESS_FLOOR = "scaled-fitness-floor"; /** Floor for sigma scaled fitnesses **/ private float fitnessFloor; public Parameter defaultBase() { return SelectDefaults.base().push(P_SIGMA_SCALING); } public void setup(final EvolutionState state, final Parameter base) { super.setup(state,base); Parameter def = defaultBase(); fitnessFloor = state.parameters.getFloatWithDefault(base.push(P_SCALED_FITNESS_FLOOR),def.push(P_SCALED_FITNESS_FLOOR),0.1); // default scaled fitness floor of 0.1 according to Tanese (1989) if (fitnessFloor < 0) { //Hey! you gotta cool! Set your cooling rate to a positive value! state.output.fatal("The scaled-fitness-floor must be a non-negative value.",base.push(P_SCALED_FITNESS_FLOOR),def.push(P_SCALED_FITNESS_FLOOR)); } } // completely override FitProportionateSelection.prepareToProduce public void prepareToProduce(final EvolutionState s, final int subpopulation, final int thread) { // load fitnesses fitnesses = new float[s.population.subpops[subpopulation].individuals.length]; double sigma; double meanFitness; double meanSum = 0; double squaredDeviationsSum = 0; for(int x=0;x= 0) when a sigma scaled fitness <= fitnessFloor is encountered. if (fitnesses[x] < fitnessFloor) fitnesses[x] = fitnessFloor; } // organize the distribution. All zeros in fitness is fine RandomChoice.organizeDistribution(fitnesses, true); } private double sigmaScaledValue(double fitness, double meanFitness, double sigma, final EvolutionState s) { if (sigma != 0) return 1+(fitness-meanFitness)/(2*sigma); return 1.0; } }