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