GeneralGA.cpp

Go to the documentation of this file.
00001 #include "GeneralGA.h"
00002 #include <cmath>
00003 #include <iostream>
00004 #include <numeric>
00005 #include <sstream>
00006 #include <map>
00007 #include "statutils.h"
00008 #include "VecMat.h"
00009 #include "FatalException.h"
00010 #include <boost/bind.hpp>
00011 #include <algorithm>
00012 #include <cassert>
00013 #include <unistd.h>
00014 #ifdef _OPENMP
00015 #include <omp.h>
00016 #endif
00017 using namespace std;
00018 
00019 namespace gplib
00020   {
00021     //!Copy the objective function within the shared pointer
00022     struct CopyFromPointer
00023       {
00024       boost::shared_ptr<GeneralObjective> operator()(boost::shared_ptr<
00025           GeneralObjective> param)
00026         {
00027           return boost::shared_ptr<GeneralObjective>(param->clone());
00028         }
00029       };
00030 
00031     //! Generate a new copy of the Objective function vector
00032     struct GenObjective
00033       {
00034       GeneralGA::tObjectiveVector operator()(
00035           const GeneralGA::tObjectiveVector &IndObjective)
00036         {
00037           GeneralGA::tObjectiveVector result(IndObjective.size()); //allocate space
00038           transform(IndObjective.begin(), IndObjective.end(), result.begin(),
00039               CopyFromPointer());//copy each objective function into result
00040           return result;
00041         }
00042       };
00043 
00044     //! Generate a unique ID for filenames etc. so we can call generated scripts in parallel
00045     std::string MakeParallelID(const int j, const int i,
00046         const int iterationnumber, const int Programnum)
00047       {
00048         ostringstream filename;
00049         filename << "j" << j << "i" << i << "g" << iterationnumber << "p"
00050             << Programnum;
00051         return filename.str();
00052       }
00053 
00054     GeneralGA::GeneralGA(GeneralPropagation* const LocalPropagation,
00055         GeneralPopulation* const LocalPopulation,
00056         GeneralTranscribe* const LocalTranscribe,
00057         const tObjectiveVector &IndObjective, const int nthreads) :
00058       CombMisFit(LocalPopulation->GetPopsize()), AvgFit(IndObjective.size()),
00059           MaxFit(IndObjective.size()), MinFit(IndObjective.size()), Weights(
00060               IndObjective.size(), 1), nobjective(IndObjective.size()),
00061           Transcribed(LocalPopulation->GetPopsize(),
00062               LocalTranscribe->GetNparams()), MisFit(IndObjective.size(),
00063               LocalPopulation->GetPopsize()), Objective(IndObjective),
00064           Propagation(LocalPropagation), Population(LocalPopulation),
00065           Transcribe(LocalTranscribe)
00066       {
00067         Threads = nthreads;
00068         Elitist = true;
00069         Programnum = getpid();
00070       }
00071 
00072     GeneralGA::~GeneralGA()
00073       {
00074       }
00075 
00076     //Prepare the appropriate parameters for each objective function
00077     void GeneralGA::SetupParams(const ttranscribed &member,
00078         tparamvector &params)
00079       {
00080         for (unsigned int i = 0; i < nobjective; ++i)
00081           for (unsigned int j = 0; j < ParameterIndices.at(i).size(); ++j)
00082             {
00083               params.at(i)(j) = member(ParameterIndices.at(i).at(j));
00084             }
00085       }
00086 
00087     void GeneralGA::SetWeights(const std::vector<double> &LocalWeights)
00088       {
00089         if (LocalWeights.size() != Weights.size()) //Weights has been pre allocated based on the number of objective functions
00090           throw FatalException(
00091               "Configured number of weights does not match number of objective functions !");
00092         Weights = LocalWeights;
00093       }
00094 
00095     void GeneralGA::SetParameterIndices(const tparamindv &Indices)
00096       {
00097         ParameterIndices = Indices;
00098       }
00099 
00100     void GeneralGA::PrintFitStat(std::ostream &output)
00101       {
00102         for (unsigned int i = 0; i < nobjective; ++i)
00103           {
00104             output << MaxFit.at(i) << " " << MinFit.at(i) << " "
00105                 << AvgFit.at(i) << "   ";
00106           }
00107         output << CombMaxFit << " " << CombMinFit << " " << CombAvgFit << "   ";
00108         output << endl << flush;
00109       }
00110 
00111     void GeneralGA::PrintMisfit(std::ostream &output)
00112       {
00113         const unsigned int isize = MisFit.size1();
00114         const unsigned int jsize = MisFit.size2();
00115 
00116         for (unsigned int i = 0; i < isize; ++i)
00117           {
00118             for (unsigned int j = 0; j < jsize; ++j)
00119               output << MisFit(i, j) << " ";
00120             output << endl;
00121           }
00122         copy(CombMisFit.begin(), CombMisFit.end(), ostream_iterator<double> (
00123             output, " "));
00124         output << endl << endl;
00125       }
00126 
00127     void GeneralGA::PrintTranscribed(std::ostream &output)
00128       {
00129         const unsigned int isize = Transcribed.size1();
00130         const unsigned int jsize = Transcribed.size2();
00131         unsigned int i, j;
00132         for (i = 0; i < isize; ++i)
00133           {
00134             for (j = 0; j < jsize; ++j)
00135               output << Transcribed(i, j) << " ";
00136             output << endl;
00137           }
00138         output << endl << flush;
00139       }
00140 
00141     void GeneralGA::PrintBestMisfit(std::ostream &output)
00142       {
00143         std::vector<int> Indices(GetBestModelIndices());
00144         const unsigned int isize = Indices.size();
00145         const unsigned int jsize = MisFit.size1();
00146 
00147         for (unsigned int i = 0; i < isize; ++i)
00148           {
00149             const int currindex = Indices.at(i);
00150             for (unsigned int j = 0; j < jsize; ++j)
00151               output << MisFit(j, currindex) << " ";
00152             output << endl;
00153           }
00154         output << endl << endl;
00155       }
00156 
00157     void GeneralGA::CalcMisfit(const int iterationnumber)
00158       {
00159         int calculatecount = 0;
00160         int newcount = 0;
00161         // popsize cannot be unsigned because loop variables for openmp have to be signed
00162         const int popsize = Population->GetPopsize();
00163         ublas::vector<bool> AlreadyCalculated(popsize);
00164         tfitvec fitvec(nobjective);
00165 
00166         tparamvector LocalParameters(nobjective);
00167         for (unsigned int k = 0; k < nobjective; ++k)
00168           {
00169             LocalParameters.at(k).resize(ParameterIndices.at(k).size(), false);
00170           }
00171 
00172         for (int i = 0; i < popsize; ++i)
00173           {
00174             row(Transcribed, i) = Transcribe->GetValues(row(
00175                 Population->GetPopulation(), i));
00176             AlreadyCalculated(i) = UniquePopHist.Find(row(Transcribed, i),
00177                 fitvec);
00178             if (!AlreadyCalculated(i))
00179               {
00180                 SetupParams(row(Transcribed, i), LocalParameters);
00181                 for (unsigned int j = 0; j < nobjective; ++j)
00182                   {
00183                     Objective.at(j)->SetParallelID(MakeParallelID(j, i,
00184                         iterationnumber, Programnum));
00185                     if (Weights.at(j) != 0)
00186                       {
00187                         MisFit(j, i) = Weights.at(j)
00188                             * Objective.at(j)->CalcPerformance(
00189                                 LocalParameters.at(j));
00190                         CombMisFit.at(i) += MisFit(j, i);
00191                       }
00192                     else
00193                       {
00194                         MisFit(j, i) = 0;
00195                       }
00196                   }
00197                 tfitvec fitvector(column(MisFit, i));
00198                 UniquePopHist.Insert(fitvector, ublas::matrix_row<gplib::rmat>(
00199                     Transcribed, i));
00200                 newcount++;
00201               }
00202             else // if already calculated
00203               {
00204                 column(MisFit, i) = fitvec;
00205                 CombMisFit.at(i) = ublas::sum(fitvec);
00206                 calculatecount++;
00207               }
00208           }
00209         cout << "New models: " << newcount << " Re-used models: "
00210             << calculatecount << endl;
00211       }
00212 
00213     void GeneralGA::DoIteration(const int iterationnumber, const bool last)
00214       {
00215         cout << endl << endl << "Iteration: " << iterationnumber + 1 << endl;
00216         cout << "Calculating Misfit ...";
00217         CalcMisfit(iterationnumber);
00218         cout << " done" << endl << flush;
00219         //cout << "Before Elitism " << endl;
00220         //PrintMisfit(cout);
00221         cout << endl;
00222         if ((iterationnumber >= 1) && Elitist)
00223           {
00224             Elitism(iterationnumber);
00225           }
00226         CalcMisfit(iterationnumber); // we have to update the misfit after elitism
00227         //because we cache the misfit values, the cost is low for this
00228         CalcProbabilities(iterationnumber, MisFit, *Population);
00229         for (unsigned int i = 0; i < nobjective; ++i) // do some statistics on the misfit
00230 
00231           {
00232             ublas::matrix_row<gplib::rmat> mr(MisFit, i);
00233             AvgFit.at(i) = Mean(mr.begin(), mr.end());
00234             MaxFit.at(i) = *max_element(mr.begin(), mr.end());
00235             MinFit.at(i) = *min_element(mr.begin(), mr.end());
00236           }
00237         CombAvgFit = Mean(CombMisFit.begin(), CombMisFit.end());
00238         CombMaxFit = *max_element(CombMisFit.begin(), CombMisFit.end());
00239         CombMinFit = *min_element(CombMisFit.begin(), CombMisFit.end());
00240         if (!last) // if we're not in the last iteration, we store the last population for elitism
00241 
00242           {
00243             Population->StoreOldPopulation();
00244             OldMisFit = MisFit;
00245             Propagation->NextGeneration();
00246           }
00247       }
00248   }

Generated on Tue May 4 16:52:14 2010 for GPLIB++ by  doxygen 1.5.8