fitness.h

00001 /*
00002     This library is free software; you can redistribute it and/or modify
00003     it under the terms of the GNU General Public License as published by
00004     the Free Software Foundation; either version 2 of the License, or
00005     (at your option) any later version.
00006 
00007     This library is distributed in the hope that it will be useful,
00008     but WITHOUT ANY WARRANTY; without even the implied warranty of
00009     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00010     Lesser General Public License for more details.
00011 
00012     You should have received a copy of the GNU General Public License
00013     along with this library; if not, write to the Free Software
00014     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00015 
00016     Contact: todos@geneura.ugr.es, http://geneura.ugr.es
00017              jeggermo@liacs.nl
00018 */
00019 
00020 #ifndef _FITNESS_FUNCTION_H
00021 #define _FITNESS_FUNCTION_H
00022 
00023 #include <gp/eoParseTree.h>
00024 #include <eo>
00025 
00026 #include <cmath>
00027 #include "parameters.h"
00028 #include "node.h"
00029 
00030 using namespace gp_parse_tree;
00031 using namespace std;
00032 
00033 
00034 
00035 // the first fitness is the normal goal fitness
00036 // the second fitness is the tree size (we prefer smaller trees)
00037 // lets use names to define the different fitnesses
00038 #define NORMAL 0      // Stepwise Adaptation of Weights Fitness
00039 #define SMALLESTSIZE 1  // The size of the tree, we want to minimize this one -- statistics will tell us the smallest tree size
00040 
00041 
00042 // Look: overloading the maximization without overhead (thing can be inlined)
00043 class MinimizingFitnessTraits : public eoParetoFitnessTraits
00044 {
00045   public :
00046   static bool maximizing(int which) { return false;} // we want to minimize both fitnesses
00047   static unsigned nObjectives()          { return 2;} // the number of fitnesses }
00048 };
00049 
00050 // Lets define our MultiObjective FitnessType
00051 typedef eoParetoFitness<MinimizingFitnessTraits> FitnessType;
00052 
00053 
00054 // John Koza's sextic polynomial (our example problem)
00055 
00056 double sextic_polynomial(double x)
00057 {
00058         double result=0;
00059         result = pow(x,6) - (2*pow(x,4)) + pow(x,2);
00060         return result;
00061 };
00062 
00063 // we use the following functions for the basic math functions
00064 
00065 double _plus(double arg1, double arg2)
00066 {
00067         return arg1 + arg2;
00068 }
00069 
00070 double _minus(double arg1, double arg2)
00071 {
00072         return arg1 - arg2;
00073 }
00074 
00075 double _multiplies(double arg1, double arg2)
00076 {
00077         return arg1 * arg2;
00078 }
00079 
00080 // the function for a protected divide looks a little bit different
00081 double _divides(double arg1, double arg2)
00082 {
00083         if (arg2 ==0)
00084                 return 0;
00085         else
00086                 return arg1 / arg2;
00087 }
00088 
00089 double _negate(double arg1)
00090 {
00091         return -arg1;
00092 }
00093 
00094 
00095 
00096 // now let's define our tree nodes
00097 
00098 void init(vector<Node> &initSequence)
00099 {
00100 
00101                 // we have only one variable (X)
00102                 Operation varX( (unsigned int) 0, string("X") );
00103 
00104 
00105                 // the main binary operators
00106                 Operation OpPLUS ( _plus, string("+"));
00107                 Operation OpMINUS( _minus,string("-"));
00108                 Operation OpMULTIPLIES(_multiplies,string("*"));
00109                 // We can use a protected divide function.
00110                 Operation OpDIVIDE( _divides, string("/") );
00111 
00112 
00113                 // Now the functions as binary functions
00114                 Operation PLUS( string("plus"), _plus);
00115                 Operation MINUS( string("minus"), _minus);
00116                 Operation MULTIPLIES( string("multiply"), _multiplies);
00117                 Operation DIVIDE( string("divide"), _divides);
00118 
00119 
00120                 // and some unary  functions
00121                 Operation NEGATE( _negate,string("-"));
00122                 Operation SIN ( sin, string("sin"));
00123                 Operation COS ( cos, string("cos"));
00124 
00125                 // Now we are ready to add the possible nodes to our initSequence (which is used by the eoDepthInitializer)
00126 
00127                 // so lets start with our variable
00128                 initSequence.push_back(varX);
00129 
00130                 // followed by the constants 2, 4, 6
00131                 for(unsigned int i=2; i <= 6; i+=2)
00132                 {
00133                         char text[255];
00134                         sprintf(text, "%i", i);
00135                         Operation op(i*1.0, text);
00136                         initSequence.push_back( op );
00137                         // and we add the variable again (so we have get lots of variables);
00138                         initSequence.push_back( varX );
00139                 }
00140 
00141                 // next we add the unary functions
00142 
00143                 initSequence.push_back( NEGATE );
00144                 initSequence.push_back( SIN );
00145                 initSequence.push_back( COS );
00146 
00147                 // and the binary functions
00148                 initSequence.push_back( PLUS);
00149                 initSequence.push_back( MINUS );
00150                 initSequence.push_back( MULTIPLIES );
00151                 initSequence.push_back( DIVIDE );
00152 
00153                 // and the binary operators
00154                 initSequence.push_back( OpPLUS);
00155                 initSequence.push_back( OpMINUS );
00156 
00157                 initSequence.push_back( OpMULTIPLIES );
00158                 initSequence.push_back( OpDIVIDE );
00159 
00160 
00161 };
00162 
00163 
00164 
00165 class RegFitness: public eoEvalFunc< eoParseTree<FitnessType, Node> >
00166 {
00167         public:
00168 
00169                 typedef eoParseTree<FitnessType, Node> EoType;
00170 
00171                 void operator()(EoType &_eo)
00172                 {
00173 
00174                                 vector< double > input(1); // the input variable(s)
00175                                 double output(0.);
00176                                 double target;
00177                                 FitnessType fitness;
00178 
00179 
00180                                 float x=0;
00181                                 double fit=0;
00182                                 for(x=-1; x <= 1; x+=0.1)
00183                                 {
00184                                         input[0] = x;
00185                                         target = sextic_polynomial(x);
00186                                         _eo.apply(output,input);
00187 
00188                                         fit += pow(target - output, 2);
00189                                 }
00190 
00191                                 fitness[NORMAL] = fit;
00192 
00193                                 fitness[SMALLESTSIZE] =  _eo.size() / (1.0*parameter.MaxSize);
00194                                 _eo.fitness(fitness);
00195 
00196                                 if (fitness[NORMAL] < best[NORMAL])
00197                                 {
00198                                         best[NORMAL] = fitness[NORMAL];
00199                                         tree="";
00200                                         _eo.apply(tree);
00201                                 }
00202 
00203                 }
00204 
00205 
00206 
00207                 RegFitness(eoValueParam<unsigned> &_generationCounter, vector< Node > &initSequence, Parameters &_parameter) : eoEvalFunc<EoType>(), generationCounter(_generationCounter), parameter(_parameter)
00208                 {
00209                         init(initSequence);
00210                         best[NORMAL] = 1000;
00211                         tree= "not found";
00212                 };
00213 
00214                 ~RegFitness()
00215                 {
00216                         cerr << "Best Fitness= " << best[NORMAL] << endl;
00217                         cerr << tree << endl;
00218                 };
00219 
00220         private:
00221                 eoValueParam<unsigned> &generationCounter; // so we know the current generation
00222                 Parameters &parameter; // the parameters
00223                 FitnessType best;       // the best found fitness
00224                 string tree;
00225 };
00226 
00227 #endif
00228 

Generated on Thu Oct 19 05:06:39 2006 for EO by  doxygen 1.3.9.1