Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OKBJavaConnector/ECJClient/src/ec/app/regression/Regression.java @ 6152

Last change on this file since 6152 was 6152, checked in by bfarka, 13 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.app.regression;
9import ec.util.*;
10import ec.*;
11import ec.gp.*;
12import ec.gp.koza.*;
13import ec.simple.*;
14
15/*
16 * Regression.java
17 *
18 * Created: Mon Nov  1 15:46:19 1999
19 * By: Sean Luke
20 */
21
22/**
23 * Regression implements the Koza (quartic) Symbolic Regression problem.
24 *
25 * <p>The equation to be regressed is y = x^4 + x^3 + x^2 + x, {x in [-1,1]}
26 * <p>This equation was introduced in J. R. Koza, GP II, 1994.
27 *
28 <p><b>Parameters</b><br>
29 <table>
30 <tr><td valign=top><i>base</i>.<tt>data</tt><br>
31 <font size=-1>classname, inherits or == ec.app.regression.RegressionData</font></td>
32 <td valign=top>(the class for the prototypical GPData object for the Regression problem)</td></tr>
33 <tr><td valign=top><i>base</i>.<tt>size</tt><br>
34 <font size=-1>int >= 1</font></td>
35 <td valign=top>(the size of the training set)</td></tr>
36 </table>
37
38 <p><b>Parameter bases</b><br>
39 <table>
40 <tr><td valign=top><i>base</i>.<tt>data</tt></td>
41 <td>species (the GPData object)</td></tr>
42 </table>
43 *
44 * @author Sean Luke
45 * @version 1.0
46 */
47
48public class Regression extends GPProblem implements SimpleProblemForm
49    {
50    public static final String P_SIZE = "size";
51
52    public double currentValue;
53    public int trainingSetSize;
54   
55    // these are read-only during evaluation-time, so
56    // they can be just light-cloned and not deep cloned.
57    // cool, huh?
58   
59    public double inputs[];
60    public double outputs[];
61
62    // we'll need to deep clone this one though.
63    public RegressionData input;
64
65    public double func(double x)
66        { return x*x*x*x + x*x*x + x*x + x; }
67
68    public Object clone()
69        {
70        // don't bother copying the inputs and outputs; they're read-only :-)
71        // don't bother copying the currentValue; it's transitory
72        // but we need to copy our regression data
73        Regression myobj = (Regression) (super.clone());
74
75        myobj.input = (RegressionData)(input.clone());
76        return myobj;
77        }
78
79    public void setup(final EvolutionState state,
80        final Parameter base)
81        {
82        // very important, remember this
83        super.setup(state,base);
84
85        trainingSetSize = state.parameters.getInt(base.push(P_SIZE),null,1);
86        if (trainingSetSize<1) state.output.fatal("Training Set Size must be an integer greater than 0", base.push(P_SIZE));
87
88        // Compute our inputs so they can be copied with clone later
89       
90        inputs = new double[trainingSetSize];
91        outputs = new double[trainingSetSize];
92       
93        for(int x=0;x<trainingSetSize;x++)
94            {
95            inputs[x] = state.random[0].nextDouble() * 2.0 - 1.0;
96            outputs[x] = func(inputs[x]);
97            state.output.message("{" + inputs[x] + "," + outputs[x] + "},");
98            }
99
100        // set up our input -- don't want to use the default base, it's unsafe
101        input = (RegressionData) state.parameters.getInstanceForParameterEq(
102            base.push(P_DATA), null, RegressionData.class);
103        input.setup(state,base.push(P_DATA));
104        }
105
106
107    public void evaluate(final EvolutionState state,
108        final Individual ind,
109        final int subpopulation,
110        final int threadnum)
111        {
112        if (!ind.evaluated)  // don't bother reevaluating
113            {
114            int hits = 0;
115            double sum = 0.0;
116            double result;
117            for (int y=0;y<trainingSetSize;y++)
118                {
119                currentValue = inputs[y];
120                ((GPIndividual)ind).trees[0].child.eval(
121                    state,threadnum,input,stack,((GPIndividual)ind),this);
122
123                // It's possible to get NaN because cos(infinity) and
124                // sin(infinity) are undefined (hence cos(exp(3000)) zings ya!)
125                // So since NaN is NOT =,<,>,etc. any other number, including
126                // NaN, we're CAREFULLY wording our cutoff to include NaN.
127                // Interesting that this has never been reported before to
128                // my knowledge.
129
130                final double HIT_LEVEL = 0.01;
131                final double PROBABLY_ZERO = 1.11E-15;
132                final double BIG_NUMBER = 1.0e15;  // the same as lilgp uses
133
134                result = Math.abs(outputs[y] - input.x);
135
136                if (! (result < BIG_NUMBER ) )   // *NOT* (input.x >= BIG_NUMBER)
137                    result = BIG_NUMBER;
138
139                // very slight math errors can creep in when evaluating
140                // two equivalent by differently-ordered functions, like
141                // x * (x*x*x + x*x)  vs. x*x*x*x + x*x
142
143                else if (result<PROBABLY_ZERO)  // slightly off
144                    result = 0.0;
145                   
146                if (result <= HIT_LEVEL) hits++;  // whatever!
147
148                sum += result;              }
149               
150            // the fitness better be KozaFitness!
151            KozaFitness f = ((KozaFitness)ind.fitness);
152            f.setStandardizedFitness(state,(float)sum);
153            f.hits = hits;
154            ind.evaluated = true;
155            }
156        }
157    }
Note: See TracBrowser for help on using the repository browser.