Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OKBJavaConnector/ECJClient/src/ec/parsimony/TarpeianStatistics.java @ 13402

Last change on this file since 13402 was 6152, checked in by bfarka, 14 years ago

added ecj and custom statistics to communicate with the okb services #1441

File size: 5.2 KB
Line 
1/*
2  Copyright 2006 by Sean Luke
3  Licensed under the Academic Free License version 3.0
4  See the file "LICENSE" for more information
5*/
6
7
8package ec.parsimony;
9
10import ec.*;
11import ec.util.*;
12
13/**
14   This Statistics subclass implements Poli's "Tarpeian" method of parsimony control, whereby some
15   <i>kill-proportion</i> of above-average-sized individuals in each subpopulation have their fitnesses
16   set to a very bad value, and marks them as already evaluated (so the Evaluator can skip them). 
17   The specific individuals in this proportion is determined at random.
18       
19   <p>Different Fitnesses have different meanings of the word "bad".  At present, we set the fitness
20   to -Float.MAX_VALUE if it's a SimpleFitness, and set it to Float.MAX_VALUE if it's a KozaFitnesss.
21   If it's any other kind of Fitness, an error is reported.  You can override the "bad-setter" function
22   setMinimumFitness(...) to make other kinds of fitness bad in different ways.  In the future we may
23   revisit how to set Fitnesses to "bad" in a more general way if this becomes an issue.
24       
25   <p>Tarpeian is implemented as a Statistics.  Why?  Because we need to mark individuals as evaluated
26   prior to the Evaluator getting to them, and also need to keep track of the total proportion marked
27   as such.  We considered doing this as a SelectionMethod, as a BreedingPipeline, as a Breeder, and
28   as an Evaluator.  None are good options really -- Evaluator is the best approach but it means we
29   have special Tarpeian Evaluators, so it's no longer orthogonal with other Evaluators.  Eventually
30   we settled on the one object which has the right hooks and can be easily stuck onto the system without
31   modifying anything in a special-purpose way: a Statistics object.
32       
33   <p>All you need to do is add TarpeianStatistics as a child to your existing Statistics chain.  If you
34   have one existing Statistics, then you just add the parameters <tt>stat.num-children=1</tt> and
35   <tt>stat.child.0=ec.parsimony.TarpeianStatistics</tt>  You'll also need to specify the kill proportion
36   (for example, <tt>stat.child.0.kill-proportion=0.2</tt> )
37       
38   <p><b>Parameters</b><br>
39   <table>
40   <tr><td valign=top><i>base</i>.<tt>kill-proportion</tt><br>
41   <font size=-1>0 &lt; int &lt; 1</font></td>
42   <td valign=top>(proportion of above-average-sized individuals killed)</td></tr>
43   </table>
44
45*/
46 
47public class TarpeianStatistics extends Statistics
48    {
49    /** one in n individuals are killed */
50    public static final String P_KILL_PROPORTION = "kill-proportion";
51    float killProportion;
52
53    public void setup( final EvolutionState state, final Parameter base )
54        {
55        super.setup (state, base);
56
57        killProportion = state.parameters.getFloat( base.push(P_KILL_PROPORTION), null, 0.0 );
58        if( killProportion < 0 || killProportion > 1 )
59            state.output.fatal( "Parameter not found, or it has an invalid value (<0 or >1).", base.push(P_KILL_PROPORTION) );
60        }
61
62    /**
63       Marks a proportion (killProportion) of individuals with above-average size (within their own subpopulation) to a minimum value.
64    */
65    public void preEvaluationStatistics(final EvolutionState state)
66        {
67        for( int subpopulation = 0 ; subpopulation < state.population.subpops.length ; subpopulation++ )
68            {
69            double averageSize = 0;
70
71            for( int i = 0 ; i < state.population.subpops[subpopulation].individuals.length ; i++ )
72                averageSize += state.population.subpops[subpopulation].individuals[i].size();
73
74            averageSize /= state.population.subpops[subpopulation].individuals.length;
75
76            for( int i = 0 ; i < state.population.subpops[subpopulation].individuals.length ; i++ )
77                {
78                if( ( state.population.subpops[subpopulation].individuals[i].size() > averageSize ) &&
79                    ( state.random[0].nextFloat() < killProportion ) )
80                    {
81                    Individual ind = state.population.subpops[subpopulation].individuals[i];
82                    setMinimumFitness( state, subpopulation, ind );
83                    ind.evaluated = true;
84                    }
85                }
86            }
87        }
88
89    /**
90       Sets the fitness of an individual to the minimum fitness possible.
91       If the fitness is of type ec.simple.SimpleFitness, that minimum value is -Float.MAX_VALUE;
92       If the fitness is of type ec.gp.koza.KozaFitness, that minimum value is Float.MAX_VALUE;
93       Else, a fatal error is reported.
94
95       You need to override this method if you're using any other type of fitness.
96    */
97    public void setMinimumFitness( final EvolutionState state, int subpopulation, Individual ind )
98        {
99        Fitness fitness = ind.fitness;
100        if( fitness instanceof ec.gp.koza.KozaFitness )
101            ((ec.gp.koza.KozaFitness)fitness).setStandardizedFitness( state, Float.MAX_VALUE );
102        else if( fitness instanceof ec.simple.SimpleFitness )
103            ((ec.simple.SimpleFitness)fitness).setFitness(state,-Float.MAX_VALUE,false);
104        else
105            state.output.fatal( "TarpeianStatistics only accepts individuals with fitness of type ec.simple.SimpleFitness or ec.gp.koza.KozaFitness." );
106        }
107
108    }
Note: See TracBrowser for help on using the repository browser.