1 /*
2  *  Open BEAGLE
3  *  Copyright (C) 2001-2007 by Christian Gagne and Marc Parizeau
4  *
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Lesser General Public
7  *  License as published by the Free Software Foundation; either
8  *  version 2.1 of the License, or (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public
16  *  License along with this library; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  *  Contact:
20  *  Laboratoire de Vision et Systemes Numeriques
21  *  Departement de genie electrique et de genie informatique
22  *  Universite Laval, Quebec, Canada, G1K 7P4
23  *  http://vision.gel.ulaval.ca
24  *
25  */
26 
27 /*!
28  *  \file   SpambaseEvalOp.cpp
29  *  \brief  Implementation of the class SpambaseEvalOp.
30  *  \author Christian Gagne
31  *  \author Marc Parizeau
32  *  $Revision: 1.9.2.1 $
33  *  $Date: 2007/05/09 01:51:24 $
34  */
35 
36 #include "beagle/GP.hpp"
37 #include "SpambaseEvalOp.hpp"
38 
39 #include <cmath>
40 #include <fstream>
41 #include <algorithm>
42 
43 using namespace Beagle;
44 
45 
46 /*!
47  *  \brief Construct a new spambase evaluation operator.
48  *  \param inFilename Default filename used.
49  */
SpambaseEvalOp(Beagle::string inFilename)50 SpambaseEvalOp::SpambaseEvalOp(Beagle::string inFilename) :
51   GP::EvaluationOp("SpambaseEvalOp"),
52   mFilename(NULL),
53   mFilenameDefault(inFilename)
54 { }
55 
56 
57 /*!
58  *  \brief Initialize the spambase evaluation operator.
59  *  \param ioSystem System of the evolution.
60  */
initialize(Beagle::System & ioSystem)61 void SpambaseEvalOp::initialize(Beagle::System& ioSystem)
62 {
63   Beagle::GP::EvaluationOp::initialize(ioSystem);
64 
65   if(ioSystem.getRegister().isRegistered("spambase.filename")) {
66     mFilename = castHandleT<String>(ioSystem.getRegister()["spambase.filename"]);
67   } else {
68     mFilename = new String(mFilenameDefault);
69     Register::Description lDescription(
70       "Filename of spambase",
71       "String",
72       mFilenameDefault,
73       "Name of the file containing the spambase."
74     );
75     ioSystem.getRegister().addEntry("spambase.filename", mFilename, lDescription);
76   }
77 }
78 
79 
80 /*!
81  *  \brief Evaluate the individual fitness for the spambase problem.
82  *  \param inIndividual Individual to evaluate.
83  *  \param ioContext Evolutionary context.
84  *  \return Handle to the fitness measure,
85  */
evaluate(GP::Individual & inIndividual,GP::Context & ioContext)86 Fitness::Handle SpambaseEvalOp::evaluate(GP::Individual& inIndividual, GP::Context& ioContext)
87 {
88   unsigned int lGoodOutput = 0;
89   std::random_shuffle(mShuffledTable.begin(), mShuffledTable.end(),
90                       ioContext.getSystem().getRandomizer());
91   for(unsigned int i=0; i<Spambase_TestSize; i++) {
92     unsigned int lIndex = mShuffledTable[i];
93     for(unsigned int j=0; j<mInputs[lIndex].size(); j++) {
94       Beagle::string lName = "IN";
95       lName += uint2str(j);
96       setValue(lName, mInputs[lIndex][j], ioContext);
97     }
98     Bool lResult;
99     inIndividual.run(lResult, ioContext);
100     if(lResult.getWrappedValue() == mOutputs[lIndex].getWrappedValue()) lGoodOutput++;
101   }
102   double lFitness = double(lGoodOutput) / Spambase_TestSize;
103   return new FitnessSimple(lFitness);
104 }
105 
106 
107 /*!
108  *  \brief Post-initialization hook the spambase evaluation operator.
109  *  \param ioSystem System of the evolution.
110  */
postInit(Beagle::System & ioSystem)111 void SpambaseEvalOp::postInit(Beagle::System& ioSystem)
112 {
113    GP::EvaluationOp::postInit(ioSystem);
114 
115   if((mFilename!=NULL) && (mFilename->getWrappedValue().empty()==false)) {
116     Beagle_LogBasicM(
117       ioSystem.getLogger(),
118       "evaluation", "SpambaseEvalOp",
119       Beagle::string("Reading spambase data from file \"")+mFilename->getWrappedValue()+"\""
120     );
121     readData(mFilename->getWrappedValue(), Spambase_DataSize);
122   }
123 }
124 
125 
126 /*!
127  *  \brief Read data of the spambase problem.
128  *  \param inFilename Name of the file in which the spambase problem data are.
129  *  \param inSizeData Number of entry in the data base.
130  *  \throw InternalException When the file format is not valid.
131  */
readData(Beagle::string inFilename,unsigned int inSizeData)132 void SpambaseEvalOp::readData(Beagle::string inFilename, unsigned int inSizeData)
133 {
134   mInputs.resize(inSizeData);
135   mOutputs.resize(inSizeData);
136   std::ifstream lDataIS(inFilename.c_str());
137   if(!lDataIS) {
138     Beagle::string lMessage = "Could not open spambase data file \"";
139     lMessage += inFilename;
140     lMessage += "\".";
141     throw Beagle_InternalExceptionM(lMessage);
142   }
143   for(unsigned int i=0; i<inSizeData; i++) {
144     Beagle::string lStringData;
145     if(!lDataIS) {
146       Beagle::string lMessage = "Could not open spambase data file \"";
147       lMessage += inFilename;
148       lMessage += "\".";
149       throw Beagle_InternalExceptionM(lMessage);
150     }
151     lDataIS >> lStringData;
152     unsigned int lStringPos = 0;
153     mInputs[i].resize(57);
154     for(unsigned int j=0; j<mInputs[i].size(); j++) {
155       unsigned int lFoundPos = lStringData.find(',', lStringPos);
156       if(lFoundPos >= lStringData.size()) {
157         Beagle::string lMessage = "Bad format of spambase data file \"";
158         lMessage += inFilename;
159         lMessage += "\".";
160         throw Beagle_InternalExceptionM(lMessage);
161       }
162       Beagle::string lBuffer(lStringData, lStringPos, lFoundPos-lStringPos);
163       mInputs[i][j] = str2dbl(lBuffer);
164       lStringPos = lFoundPos + 1;
165     }
166     Beagle::string lBuffer2(lStringData, lStringPos, 1);
167     mOutputs[i] = (bool)str2uint(lBuffer2);
168   }
169   lDataIS.close();
170   mShuffledTable.clear();
171   for(unsigned int i=0; i<inSizeData; i++) mShuffledTable.push_back(i);
172 }
173 
174