freEvolutionaryStrategyOptimizer.txx

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   F.R.E.E. - flexible registration evaluation engine
00004   Version:   v.1.0.0
00005   Date:      $Date: 2006/09/01 12:00:00 $
00006   Module:    $RCSfile: freEvolutionaryStrategyOptimizer.txx,v $
00007   Language:  C++
00008 
00009 
00010 
00011   Copyright (c) 2007 Ralf o Floca (Department of Medical Informatics,
00012   Institute for Medical Biometry and Informatics, University of Heidelberg,
00013   Germany). All rights reserved.
00014   See FREECopyright.txt or http://www.mi.med.uni-hd.de/free/copyright.htm
00015   for details.
00016 
00017      This software is distributed WITHOUT ANY WARRANTY; without even 
00018      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
00019      PURPOSE.  See the above copyright notices for more information.
00020 
00021 =========================================================================*/
00022 #ifndef _freEvolutionaryStrategyOptimizer_txx
00023 #define _freEvolutionaryStrategyOptimizer_txx
00024 
00025 #include "freEvolutionaryStrategyOptimizer.h"
00026 
00027 namespace FREE
00028 {
00029   namespace ES
00030   {
00031 
00032     template <class TIndividual>
00033     EvolutionaryStrategyOptimizer<TIndividual>
00034       ::EvolutionaryStrategyOptimizer()
00035     {
00036       m_ParentSelector = 0;
00037       m_Recombinator = 0;
00038       m_Mutation = 0;
00039       m_Selection = 0;
00040       m_NumberOfParents = 1;
00041       m_NumberOfChildren = 1;
00042       m_PopulationIsInitialized = false;
00043       m_MutateIntitialPopulation = false;
00044       m_CurrentChild = 0;
00045       m_SelectionVictims = 0;
00046       m_NewChildren = 0;
00047       this->MaximizeOn();
00048     }
00049 
00050     template <class TIndividual>
00051     EvolutionaryStrategyOptimizer<TIndividual>
00052       ::~EvolutionaryStrategyOptimizer() 
00053     {
00054     }
00055 
00056     template <class TIndividual>
00057     void
00058       EvolutionaryStrategyOptimizer<TIndividual>::
00059       SetParentSelector( ParentSelectorType * pParentSelector )
00060     {
00061       if ( m_ParentSelector != pParentSelector )
00062       {
00063         m_ParentSelector = pParentSelector ;
00064         this->Modified() ;
00065       }
00066     };
00067 
00068     template <class TIndividual>
00069     void
00070       EvolutionaryStrategyOptimizer<TIndividual>::
00071       SetRecombinator( RecombinatorType * pRecombinator )
00072     {
00073       if ( m_Recombinator != pRecombinator )
00074       {
00075         m_Recombinator = pRecombinator ;
00076         this->Modified() ;
00077       }
00078     };
00079 
00080     template <class TIndividual>
00081     void
00082       EvolutionaryStrategyOptimizer<TIndividual>::
00083       SetMutation( MutationType * pMutation )
00084     {
00085       if ( m_Mutation != pMutation )
00086       {
00087         m_Mutation = pMutation ;
00088         this->Modified() ;
00089       }
00090     };
00091 
00092     template <class TIndividual>
00093     void
00094       EvolutionaryStrategyOptimizer<TIndividual>::
00095       SetSelection( SelectionType * pSelection )
00096     {
00097       if ( m_Selection != pSelection )
00098       {
00099         m_Selection = pSelection ;
00100         this->Modified() ;
00101       }
00102     };
00103 
00104     template <class TIndividual>
00105     void
00106       EvolutionaryStrategyOptimizer<TIndividual>::
00107       PrintSelf(std::ostream& os, itk::Indent indent) const
00108     {
00109 
00110       Superclass::PrintSelf(os,indent);
00111 
00112       os << indent << "Number of parents " << m_NumberOfParents << std::endl;
00113       os << indent << "Numver of children " << m_NumberOfChildren << std::endl;
00114 
00115       os << indent << "Parent selector:  ";
00116       if (m_ParentSelector.IsNotNull())
00117       {
00118         os << std::endl;
00119         m_ParentSelector->Print(os, indent.GetNextIndent());
00120         os << std::endl;
00121       }
00122       else
00123       {
00124         os << indent << " none " << std::endl;
00125       }
00126 
00127       os << indent << "Recombinator:  ";
00128       if (m_Recombinator.IsNotNull())
00129       {
00130         os << std::endl;
00131         m_Recombinator->Print(os, indent.GetNextIndent());
00132         os << std::endl;
00133       }
00134       else
00135       {
00136         os << indent << " none " << std::endl;
00137       }
00138 
00139       os << indent << "Mutation:  ";
00140       if (m_Mutation.IsNotNull())
00141       {
00142         os << std::endl;
00143         m_Mutation->Print(os, indent.GetNextIndent());
00144         os << std::endl;
00145       }
00146       else
00147       {
00148         os << indent << " none " << std::endl;
00149       }
00150 
00151       os << indent << "Selection:  ";
00152       if (m_Selection.IsNotNull())
00153       {
00154         os << std::endl;
00155         m_Selection->Print(os, indent.GetNextIndent());
00156         os << std::endl;
00157       }
00158       else
00159       {
00160         os << indent << " none " << std::endl;
00161       }
00162     }
00163 
00164     template <class TIndividual>
00165     void
00166       EvolutionaryStrategyOptimizer<TIndividual>::
00167       Initialize(const PopulationType& population)
00168     {
00169       if (population.Size() != m_NumberOfParents) throwExceptionMacro("Error. Passed population has wrong size. NumberOfParents: "<<m_NumberOfParents<<"; population size: "<<population.Size());
00170       if ( m_ParentSelector.IsNull() ) throwExceptionMacro("Error: Parent selector is undefined (reference is NULL).");
00171       if ( m_Recombinator.IsNull() ) throwExceptionMacro("Error: Recombinator is undefined (reference is NULL).");
00172       if ( m_Mutation.IsNull() ) throwExceptionMacro("Error: Mutation is undefined (reference is NULL).");
00173       if ( m_Selection.IsNull() ) throwExceptionMacro("Error: Selection is undefined (reference is NULL).");
00174 
00175       if (m_Population.GetPointer()!=&population) m_Population = population.Clone();
00176 
00177       m_CurrentChild = 0;
00178       m_SelectionVictims = 0;
00179       m_NewChildren = 0;
00180 
00181       for (typename PopulationType::iterator pos = m_Population->begin(); pos!=m_Population->end(); ++pos)
00182       {
00183         (*pos)->ResetStrategicParameters();
00184 
00185         m_ParentSelector->RegisterStrategicIndividualParameters(*(*pos));
00186         m_Recombinator->RegisterStrategicIndividualParameters(*(*pos));
00187         m_Mutation->RegisterStrategicIndividualParameters(*(*pos));
00188         m_Selection->RegisterStrategicIndividualParameters(*(*pos));
00189       };
00190 
00191       m_ParentSelector->RegisterStrategicPopulationParameters(*(m_Population.GetPointer()));
00192       m_Recombinator->RegisterStrategicPopulationParameters(*(m_Population.GetPointer()));
00193       m_Mutation->RegisterStrategicPopulationParameters(*(m_Population.GetPointer()));
00194       m_Selection->RegisterStrategicPopulationParameters(*(m_Population.GetPointer()));
00195 
00196       m_PopulationIsInitialized = true;
00197     };
00198 
00199     template <class TIndividual>
00200     void
00201       EvolutionaryStrategyOptimizer<TIndividual>::
00202       Initialize()
00203     {
00204       if (!m_PopulationIsInitialized)
00205       {
00206         //generate template individual
00207         IndividualPointer templateIndividual = IndividualType::New();
00208         m_Population = PopulationType::New();
00209         m_Population->Reserve(m_NumberOfParents);
00210 
00211         for (unsigned long index = 0; index<this->GetInitialPosition().Size(); index++)
00212         {
00213           templateIndividual->ObjectiveParameters().push_back(this->GetInitialPosition()[index]);
00214         }
00215 
00216         for (unsigned long count = 0; count<m_NumberOfParents; count++)
00217         {
00218           IndividualPointer individual = templateIndividual->Clone();
00219           individual->SetIndividualID(m_Population->GenerateUniqueIndividualID());
00220           individual->SetGenerationID(m_Population->GetGenerationID());
00221 
00222           m_Population->InsertElement(count, individual);
00223         }
00224 
00225         Initialize(*(m_Population.GetPointer()));
00226 
00227         if (m_MutateIntitialPopulation)
00228         {
00229           for (unsigned long index = 0; index<m_NumberOfParents; index++)
00230           {
00231             m_Mutation->Mutate(m_Population->GetElement(index).GetPointer(),m_Population.GetPointer());
00232           }
00233         }
00234       }
00235     };
00236 
00237     template <class TIndividual>
00238     void
00239       EvolutionaryStrategyOptimizer<TIndividual>::
00240       StartOptimization()
00241     {
00242       if ( m_CostFunction.IsNull() )
00243       {
00244         return ;
00245       }
00246 
00247       if ( m_ParentSelector.IsNull() ) throwExceptionMacro("Error: Parent selector is undefined (reference is NULL).");
00248       if ( m_Recombinator.IsNull() ) throwExceptionMacro("Error: Recombinator is undefined (reference is NULL).");
00249       if ( m_Mutation.IsNull() ) throwExceptionMacro("Error: Mutation is undefined (reference is NULL).");
00250       if ( m_Selection.IsNull() ) throwExceptionMacro("Error: Selection is undefined (reference is NULL).");
00251 
00252       m_Stop = false ;
00253 
00254       unsigned int spaceDimension = m_CostFunction->GetNumberOfParameters();
00255       const Optimizer::ScalesType& scales = this->GetScales() ;
00256 
00257       // Make sure the scales have been set properly
00258       if (scales.size() != spaceDimension)
00259       {
00260         itkExceptionMacro(<< "The size of Scales is "
00261           << scales.size()
00262           << ", but the NumberOfParameters for the CostFunction is "
00263           << spaceDimension
00264           << ".");
00265       }
00266 
00267       m_Mutation->SetGeneralObjectiveScales(scales);
00268       m_Selection->SetMaximumIsBest(this->GetMaximize());
00269 
00270       this->Initialize();
00271 
00272       this->InvokeEvent( itk::StartEvent() );
00273 
00274       //Evaluate the first generation of parents.
00275       this->EvaluatePopulation(m_Population);
00276 
00277       this->SetBestIndividual(m_Population);
00278 
00279       this->SetCurrentPosition( this->ConvertIndividualToParameter(this->GetBestIndividual()));
00280 
00281       this->InvokeEvent( itk::IterationEvent() );   
00282 
00283       //begin with evolution
00284       m_CurrentIteration = 0 ;
00285 
00286       m_Started = true;
00287 
00288       if (!m_Stop)
00289       {
00290         ResumeOptimization();
00291       }
00292       else
00293       {
00294         this->InvokeEvent( itk::EndEvent() );
00295       }
00296     };
00297 
00298     template <class TIndividual>
00299     void
00300       EvolutionaryStrategyOptimizer<TIndividual>::
00301       ResumeOptimization()
00302     {
00303       Superclass::ResumeOptimization();
00304 
00305       //resume evolution
00306       for (; m_CurrentIteration < GetMaximumIteration() ; m_CurrentIteration++) 
00307       {
00308         if ( m_Stop )
00309         {
00310           break ;
00311         }
00312 
00313         //start new population cycle
00314         m_SelectionVictims = 0;
00315         m_ParentSelections.clear();
00316 
00317         m_NewChildren = PopulationType::New();
00318         m_NewChildren->SetGenerationID(m_Population->GetGenerationID()+1);
00319         m_NewChildren->Reserve(m_NumberOfChildren);
00320 
00321         //mutate strategic population parameters
00322         m_ParentSelector->MutateStrategicPopulationParameters(*(m_Population.GetPointer()));
00323         m_Recombinator->MutateStrategicPopulationParameters(*(m_Population.GetPointer()));
00324         m_Mutation->MutateStrategicPopulationParameters(*(m_Population.GetPointer()));
00325         m_Selection->MutateStrategicPopulationParameters(*(m_Population.GetPointer()));
00326 
00327         //generate new children
00328         for (unsigned long count = 0; count < m_NumberOfChildren; count++)
00329         {
00330           //select the parents from the generation
00331           typename ParentSelectorType::ParentSelectionType parents = m_ParentSelector->Select(*(m_Population.GetPointer()));
00332 
00333           //recombine parents to new child.
00334           m_CurrentChild = m_Recombinator->Recombine(parents);
00335 
00336           m_CurrentChild->SetGenerationID(m_Population->GetGenerationID()+1);
00337           m_CurrentChild->SetIndividualID(m_Population->GenerateUniqueIndividualID());
00338 
00339           //mutate the child
00340             //mutate strategic parameters
00341           m_ParentSelector->MutateStrategicIndividualParameters(*(m_CurrentChild.GetPointer()), *(m_Population.GetPointer()));
00342           m_Recombinator->MutateStrategicIndividualParameters(*(m_CurrentChild.GetPointer()), *(m_Population.GetPointer()));
00343           m_Mutation->MutateStrategicIndividualParameters(*(m_CurrentChild.GetPointer()), *(m_Population.GetPointer()));
00344           m_Selection->MutateStrategicIndividualParameters(*(m_CurrentChild.GetPointer()), *(m_Population.GetPointer()));
00345             //mutate objective parameters
00346           m_Mutation->Mutate(m_CurrentChild.GetPointer(),m_Population.GetPointer());
00347 
00348           this->InvokeEvent(NewChildGenerationEvent());
00349 
00350           //evaluate the child
00351           this->EvaluateIndividual(m_CurrentChild.GetPointer());
00352 
00353           this->InvokeEvent(NewChildEvaluationEvent());
00354 
00355           m_NewChildren->InsertElement(count, m_CurrentChild);
00356 
00357           //generate parent selection vector and heritage map for protocol etc.
00358           IndividualSelectionType selectedIDs;
00359           for (typename ParentSelectorType::ParentSelectionType::const_iterator pos = parents.begin(); pos!= parents.end(); ++pos)
00360           {
00361             selectedIDs.push_back((*pos)->GetIndividualID());
00362           }
00363 
00364           typedef std::pair<IndividualIDType,IndividualSelectionType> HeritageMapPairType;
00365           m_ParentSelections.insert(HeritageMapPairType(m_CurrentChild->GetIndividualID(),selectedIDs));
00366           
00367           m_CurrentChild = 0;
00368         }
00369 
00370         //Add children to population
00371         for (unsigned long index = 0; index < m_NewChildren->Size(); index++)
00372         {
00373           m_Population->InsertElement(m_Population->Size(), m_NewChildren->GetElement(index));
00374         }
00375 
00376         //Select the population for the next generation
00377         m_SelectionVictims = m_Selection->Select(m_Population, m_NumberOfParents);
00378 
00379         //increase population generation
00380         m_Population->SetGenerationID(m_Population->GetGenerationID()+1);
00381 
00382         //check for best individual
00383         this->SetBestIndividual(m_Population);
00384 
00385         this->SetCurrentPosition(this->ConvertIndividualToParameter(this->GetBestIndividual()));
00386         m_CurrentCost = this->GetBestIndividual()->GetObjectiveValue();
00387         
00388         this->InvokeEvent( itk::IterationEvent() );   
00389         itkDebugMacro(<< "Current position: " << this->GetCurrentPosition()) ;
00390 
00391         if (!m_Stop)
00392         {
00393           if (this->GetMaximize())
00394           {
00395             m_Stop = m_CurrentCost>=m_Threshold;
00396           }
00397           else
00398           {
00399             m_Stop = m_CurrentCost<=m_Threshold;
00400           }
00401         }
00402       }
00403       m_Started = false;
00404       this->InvokeEvent( itk::EndEvent() );
00405     };
00406 
00407     template <class TIndividual>
00408     void
00409       EvolutionaryStrategyOptimizer<TIndividual>::
00410       EvaluatePopulation(PopulationType* pPopulation) const
00411     {
00412       for (typename PopulationType::iterator pos = pPopulation->begin(); pos!=pPopulation->end(); ++pos)
00413       {
00414         if (!((*pos)->GetObjectiveValueIsSet()))
00415         { //Calculate objective value
00416           EvaluateIndividual(*pos);
00417         }
00418       }
00419     };
00420 
00421     template <class TIndividual>
00422     void
00423       EvolutionaryStrategyOptimizer<TIndividual>::
00424       EvaluateIndividual(IndividualType* pIndividual) const
00425     {
00426       typedef typename IndividualType::ObjectiveValueType IndividualObjectiveValueType;
00427 
00428       if (pIndividual)
00429       { //Calculate objective value
00430         try
00431         {
00432           CostFunctionParametersType param = ConvertIndividualToParameter(pIndividual);
00433           IndividualObjectiveValueType value = (IndividualObjectiveValueType) this->GetCostFunction()->GetValue( param );
00434           pIndividual->SetObjectiveValue(value);
00435         }
00436         catch(...)
00437         { //error while try to evaluate child (e.g. metric cannot evaluate
00438           //because all points mapped outside the image region).
00439           //thus set the objective value to the worsest value possible.
00440           this->InvokeEvent(InvalidChildEvaluationEvent());
00441           if (this->GetMaximize())
00442           {
00443             pIndividual->SetObjectiveValue(itk::NumericTraits< IndividualObjectiveValueType >::NonpositiveMin());
00444           }
00445           else
00446           {
00447             pIndividual->SetObjectiveValue(itk::NumericTraits< IndividualObjectiveValueType >::max());
00448           }
00449         }
00450       }
00451     };
00452 
00453     template <class TIndividual>
00454     typename EvolutionaryStrategyOptimizer<TIndividual>::IndividualPointer
00455       EvolutionaryStrategyOptimizer<TIndividual>::
00456       FindBestIndividual(PopulationType* pPopulation) 
00457     {
00458       typename IndividualType::ObjectiveValueType bestValue;
00459       IndividualPointer bestIndividual;
00460       typename PopulationType::iterator pos = pPopulation->begin();
00461 
00462       if (pos!=pPopulation->end())
00463       {
00464         bestIndividual = *pos;
00465         bestValue = (*pos)->GetObjectiveValue();
00466 
00467         for (++pos; pos!=pPopulation->end(); ++pos)
00468         {
00469           typename IndividualType::ObjectiveValueType value = (*pos)->GetObjectiveValue();
00470 
00471           if ((this->GetMaximize() && (value>bestValue)) ||
00472             (this->GetMinimize() && (value<bestValue)))
00473           {
00474             bestIndividual = *pos;
00475             bestValue = (*pos)->GetObjectiveValue();
00476           }
00477         }
00478       }
00479       return bestIndividual;
00480     };
00481 
00482     template <class TIndividual>
00483     void
00484       EvolutionaryStrategyOptimizer<TIndividual>::
00485       SetBestIndividual(PopulationType* pPopulation)
00486     {
00487       IndividualPointer bestGenerationIndividual = FindBestIndividual(pPopulation);
00488 
00489       pPopulation->SetBestIndividual(bestGenerationIndividual);
00490 
00491       if (!pPopulation->GetBestIndividualEver())
00492       {
00493         pPopulation->SetBestIndividualEver(bestGenerationIndividual);
00494       }
00495       else
00496       {
00497         if ((this->GetMaximize() && (bestGenerationIndividual->GetObjectiveValue()>pPopulation->GetBestIndividualEver()->GetObjectiveValue())) ||
00498           (this->GetMinimize() && (bestGenerationIndividual->GetObjectiveValue()<pPopulation->GetBestIndividualEver()->GetObjectiveValue())))
00499         {
00500           pPopulation->SetBestIndividualEver(bestGenerationIndividual);
00501         }
00502       }
00503     };
00504 
00505     template <class TIndividual>
00506     typename EvolutionaryStrategyOptimizer<TIndividual>::CostFunctionParametersType
00507       EvolutionaryStrategyOptimizer<TIndividual>::
00508       ConvertIndividualToParameter(const IndividualType* pIndividual) const
00509     {
00510       if (!pIndividual) throwExceptionMacro("Error. Passed individual is NULL.");
00511 
00512       CostFunctionParametersType params(pIndividual->ObjectiveParameters().size());
00513 
00514       for (unsigned int index=0; index<params.Size(); index++)
00515       {
00516         params.SetElement(index,pIndividual->ObjectiveParameters()[index]);
00517       }
00518 
00519       return params;
00520     };
00521 
00522     template <class TIndividual>
00523     const typename EvolutionaryStrategyOptimizer<TIndividual>::HeritageMapType&
00524       EvolutionaryStrategyOptimizer<TIndividual>::
00525       GetRecentParentSelections() const
00526     {
00527       return m_ParentSelections;
00528     };
00529 
00530     template <class TIndividual>
00531     const typename EvolutionaryStrategyOptimizer<TIndividual>::PopulationPointer&
00532       EvolutionaryStrategyOptimizer<TIndividual>::
00533       GetRecentPopulationSelections() const
00534     {
00535       return m_SelectionVictims;
00536     };
00537 
00538     template <class TIndividual>
00539     const typename EvolutionaryStrategyOptimizer<TIndividual>::PopulationPointer&
00540       EvolutionaryStrategyOptimizer<TIndividual>::
00541       GetNewChildren() const
00542     {
00543       return m_NewChildren;
00544     };
00545 
00546     template <class TIndividual>
00547     const typename EvolutionaryStrategyOptimizer<TIndividual>::IndividualType*
00548       EvolutionaryStrategyOptimizer<TIndividual>::
00549       GetBestIndividualEver() const
00550     {
00551       if (m_Population.IsNotNull())
00552       {
00553         return m_Population->GetBestIndividualEver();
00554       }
00555       return 0;
00556     };
00557 
00558     template <class TIndividual>
00559     const typename EvolutionaryStrategyOptimizer<TIndividual>::IndividualType*
00560       EvolutionaryStrategyOptimizer<TIndividual>::
00561       GetBestIndividual() const
00562     {
00563       if (m_Population.IsNotNull())
00564       {
00565         return m_Population->GetBestIndividual();
00566       }
00567       return 0;
00568     };
00569 
00570   } // end of namespace ES
00571 } // end of namespace free
00572 #endif

Generated at Sat Oct 13 15:53:48 2007 for f.r.e.e. - Flexible Registration and Evaluation Engine by doxygen 1.5.3 written by Dimitri van Heesch, © 1997-2000