freEvolutionaryStrategySOOptimizerController.cxx

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: freEvolutionaryStrategySOOptimizerController.cxx,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 
00023 #include "freEvolutionaryStrategySOOptimizerController.h"
00024 #include "freExceptions.h"
00025 
00026 #include "freEvolutionaryStrategyOptimizerController.h"
00027 
00028 #include "freESParentSelectorControllerBase.h"
00029 #include "freESRecombinatorControllerBase.h"
00030 #include "freESMutationControllerBase.h"
00031 #include "freESSelectionControllerBase.h"
00032 
00033 namespace FREE
00034 {
00035 
00039 
00040 
00041 DefineParameterMacro(EvolutionaryStrategySOOptimizerController,MutateIntitialPopulation,"MutateIntitialPopulation","Indicates if the starting population will be mutated one time befor beginning the evolutionary process. Usefull if the population is generated automatically.");
00042 DefineParameterMacro(EvolutionaryStrategySOOptimizerController,IntitialPopulation,"IntitialPopulation","The starting population for the optimization process. Every layer is one individuals, the values are the objective parameters. If the initial population is empty the initial position of the transform will be used to generate the starting population.");
00043 DefineParameterMacro(EvolutionaryStrategySOOptimizerController,NumberOfParents,"NumberOfParents","Number of parents in every generation. Equals the term Mu in evolutionary strategies.");
00044 DefineParameterMacro(EvolutionaryStrategySOOptimizerController,NumberOfChildren,"NumberOfChildren","Number of parents in every generation. Equals the term lambda in evolutionary strategies.");
00045 DefineParameterMacro(EvolutionaryStrategySOOptimizerController,Threshold,"Threshold","Threshold for the best individual in the population. If this treshold is reached, the optimization process will stop.");
00046 
00047 EvolutionaryStrategySOOptimizerController::
00048 EvolutionaryStrategySOOptimizerController()
00049 {
00050   //Profile settings
00051   this->UpdateControllerID(ControllerID::EvolutionaryStrategySOOptimizerController);
00052   this->m_Description = "Optimizes registration setups by Powell optimizer approach using Brent line search.";
00053 };
00054 
00055 void
00056 EvolutionaryStrategySOOptimizerController::
00057 GenerateProfile(CtrlProfile::ControllerProfile& profile,
00058                   const SessionComponentCache* pComponentCache,
00059                   bool bRegardOldSetup) const
00060 {
00061   Superclass::GenerateProfile(profile,pComponentCache,bRegardOldSetup);
00062 
00063   //Parameters
00064   profile.Parameters().AddParameter(cParam_Iterations,Parameter::PVTInteger,cParamDsc_Iterations,1,"100",-1,true);
00065   profile.Parameters().AddParameter(cParam_MutateIntitialPopulation,CtrlProfile::Parameter::PVTBool,cParamDsc_MutateIntitialPopulation,1,"false");
00066   profile.Parameters().AddParameter(cParam_IntitialPopulation,CtrlProfile::Parameter::PVTDouble,cParamDsc_IntitialPopulation,1,"0",-1);
00067   profile.Parameters().AddParameter(cParam_Threshold,CtrlProfile::Parameter::PVTDouble,cParam_Threshold,1,"0.0001");
00068   profile.Parameters().AddParameter(cParam_NumberOfParents,Parameter::PVTULong,cParamDsc_NumberOfParents,1,"2");
00069   profile.Parameters().AddParameter(cParam_NumberOfChildren,Parameter::PVTULong,cParamDsc_NumberOfChildren,1,"5");
00070 
00071   //Subcomponents
00072   profile.SubComponents().AddSubComponent("ParentSelector",1,csUndefinedController,"Selection of the parents for the generation of a new indivudual.");
00073   profile.SubComponents().AddSubComponent("Recombinator",1,csUndefinedController,"Recombination of selected parents to a new individual.");
00074   profile.SubComponents().AddSubComponent("Mutation",1,csUndefinedController,"Mutation of new individuals.");
00075   profile.SubComponents().AddSubComponent("Selection",1,csUndefinedController,"Selection of the whole population, including the new individual, to generate the next generation.");
00076 
00077   //Requirements
00078         CtrlProfile::ProfileOption* pOption;
00079     //parent selector
00080         pOption = profile.Requirements().AddRequirement("ParentSelector")->AddProfileOption();
00081         pOption->Inheritance().AddAncestor(ControllerID::ESParentSelectorControllerBase);
00082         pOption->CheckForInheritance();
00083 
00084     //recombinator
00085         pOption = profile.Requirements().AddRequirement("Recombinator")->AddProfileOption();
00086         pOption->Inheritance().AddAncestor(ControllerID::ESRecombinatorControllerBase);
00087         pOption->CheckForInheritance();
00088 
00089     //mutation
00090         pOption = profile.Requirements().AddRequirement("Mutation")->AddProfileOption();
00091         pOption->Inheritance().AddAncestor(ControllerID::ESMutationControllerBase);
00092         pOption->CheckForInheritance();
00093 
00094     //selection
00095         pOption = profile.Requirements().AddRequirement("Selection")->AddProfileOption();
00096         pOption->Inheritance().AddAncestor(ControllerID::ESSelectionControllerBase);
00097         pOption->CheckForInheritance();
00098 };
00099 
00100 long
00101 EvolutionaryStrategySOOptimizerController::
00102 GetMaxIterationCount(const SessionComponentCache* pComponentCache, unsigned int iResolutionLevel) const
00103 {
00104         if (!pComponentCache) throwCtrlExceptionMacro("","Passed pComponentCache is NULL.");
00105         if (!pComponentCache->SetupIsAssigned()) throwCtrlExceptionMacro("","Cache has no setup assigned.");
00106 
00107   long lResult = 1;
00108   try
00109   {
00110     SessionAccessor::GetParameterValue(pComponentCache,cParam_Iterations,lResult);
00111   }
00112   catchAllNPassMacro("Unknown error while retrieving max interation count.");
00113 
00114   return lResult;
00115 };
00116 
00117 GenericComponentType*
00118 EvolutionaryStrategySOOptimizerController::
00119 GetSubComponentCasted(ComponentType* pMainComponent, const ComponentID& compID,
00120                       SessionComponentCache* pMainComponentCache) const
00121 {
00122         if (compID == "ParentSelector") return pMainComponent->GetParentSelector();
00123         if (compID == "Recombinator") return pMainComponent->GetRecombinator();
00124         if (compID == "Mutation") return pMainComponent->GetMutation();
00125         if (compID == "Selection") return pMainComponent->GetSelection();
00126         return Superclass::GetSubComponentCasted(pMainComponent, compID, pMainComponentCache);
00127 }; 
00128 
00129 void
00130 EvolutionaryStrategySOOptimizerController::
00131 SetSubComponentCasted(GenericComponentType* pSubComponent,
00132                                                                                                                                                  ComponentType* pMainComponent,
00133                                                                                                                                                  const ComponentID compID,
00134                                      SessionComponentCache* pMainComponentCache) const
00135 {
00136         if (compID == "ParentSelector") pMainComponent->SetParentSelector(dynamic_cast<ComponentType::ParentSelectorType*>(pSubComponent));
00137         if (compID == "Recombinator") pMainComponent->SetRecombinator(dynamic_cast<ComponentType::RecombinatorType*>(pSubComponent));
00138         if (compID == "Mutation") pMainComponent->SetMutation(dynamic_cast<ComponentType::MutationType*>(pSubComponent));
00139         if (compID == "Selection") pMainComponent->SetSelection(dynamic_cast<ComponentType::SelectionType*>(pSubComponent));
00140   else Superclass::SetSubComponentCasted(pSubComponent, pMainComponent, compID, pMainComponentCache);
00141 };
00142 
00143 void
00144 EvolutionaryStrategySOOptimizerController::
00145 ActualizeMainComponent(ComponentType* pMainComponent,
00146                        SessionComponentCache* pComponentCache, SessionInfo* pSessionInfo,
00147                                                                                          const unsigned int& iActLevel) const
00148 {
00149         Superclass::ActualizeMainComponent(pMainComponent, pComponentCache,
00150                                                                                                                                                  pSessionInfo, iActLevel);
00151 
00152   int iNrOfIterations;
00153   bool bMutateIntitialPopulation;
00154   double dThreshold;
00155   unsigned long lNumberOfParents;
00156   unsigned long lNumberOfChildren;
00157 
00158   try
00159   {
00160     SessionAccessor::GetParameterValue(pComponentCache,cParam_Iterations,iNrOfIterations,0,iActLevel,true);
00161     SessionAccessor::GetParameterValue(pComponentCache,cParam_MutateIntitialPopulation,bMutateIntitialPopulation);
00162     SessionAccessor::GetParameterValue(pComponentCache,cParam_Threshold,dThreshold);
00163     SessionAccessor::GetParameterValue(pComponentCache,cParam_NumberOfParents,lNumberOfParents);
00164     SessionAccessor::GetParameterValue(pComponentCache,cParam_NumberOfChildren,lNumberOfChildren);
00165   }
00166   catchAllNPassMacro("Error while retrieving parameter values.");
00167 
00168   pMainComponent->SetMaximumIteration(iNrOfIterations);
00169   pMainComponent->SetMutateIntitialPopulation(bMutateIntitialPopulation);
00170   pMainComponent->SetThreshold(dThreshold);
00171   pMainComponent->SetNumberOfParents(lNumberOfParents);
00172   pMainComponent->SetNumberOfChildren(lNumberOfChildren);
00173 
00174   Parameter::Pointer smpInitialPopulation = SessionAccessor::GetParameter(pComponentCache,cParam_IntitialPopulation);
00175 
00176   if (smpInitialPopulation.IsNull()) throwCtrlExceptionMacro("","Error; cannot find parameter for initial population");
00177 
00178   if (smpInitialPopulation->LayerCount()>0)
00179   {
00180     /*there is an initial population*/
00181     if (smpInitialPopulation->LayerCount()!=lNumberOfParents) throwCtrlExceptionMacro("","Error; size of initial population is not equal to number of parents per generation. Please check validity of setup. Parent number: "<< lNumberOfParents <<"; Size of initial population: "<< smpInitialPopulation->LayerCount());
00182   
00183     /*insert initial population */
00184 
00185     ComponentType::PopulationPointer population = ComponentType::PopulationType::New();
00186 
00187     population->Reserve(lNumberOfParents);
00188 
00189     for (unsigned long index = 0; index<smpInitialPopulation->LayerCount(); index++)
00190     {
00191       ParameterLayer* pLayer = smpInitialPopulation->GetParameterLayer(index);
00192       ComponentType::IndividualType::Pointer individual = ComponentType::IndividualType::New();
00193 
00194       for (unsigned long iPos = 0; iPos<pLayer->Size(); iPos++)
00195       {
00196         double dValue;
00197         pLayer->GetValue(dValue,iPos);
00198         individual->ObjectiveParameters().push_back(dValue);
00199       }
00200 
00201       individual->SetIndividualID(population->GenerateUniqueIndividualID());
00202       individual->SetGenerationID(population->GetGenerationID());
00203 
00204       population->InsertElement(index, individual);
00205     }
00206 
00207     pMainComponent->Initialize(*(population.GetPointer()));
00208   }
00209 
00210         //get metric "orientation"
00211   Parameter::Pointer param = SessionAccessor::GetParameterByIDPath(pComponentCache,cIDPParent+IDPath(cComp_MainMetric)+IDPath::Parameter(cParam_MetricMinimize));
00212         bool bMin = true;
00213         if (param.IsNotNull())
00214         {
00215                 param->GetParameterValue(bMin);
00216         }
00217         pMainComponent->SetMaximize(!bMin);
00218 };
00219 
00220 void
00221 EvolutionaryStrategySOOptimizerController::
00222 SetStatisticEntryMainComponent(StatisticEntry& rStatisticEntry,
00223                                              ComponentType* pMainComponent,
00224                                              SessionComponentCache* pMainComponentCache,
00225                                              SessionInfo* pSessionInfo,
00226                                              StatisticDictionary& rDictionary) const
00227 {
00228   std::string sIDPath = pMainComponentCache->GetIDPath();
00229   StatisticValueDefinition* pValueDef = rDictionary.GetValueDefinitionByName(sIDPath, "ID");
00230   StatisticValueDefinition* pValueDef_Best = rDictionary.GetValueDefinitionByName(sIDPath, "BestFitness");
00231     
00232   if (!pValueDef) //Entry is not recorded yet, so do so.
00233   {
00234     pValueDef = rDictionary.AddValueDefinition(sIDPath,"ID","ID of an individual");
00235   }
00236 
00237   if (!pValueDef_Best) //Entry is not recorded yet, so do so.
00238   {
00239     pValueDef_Best = rDictionary.AddValueDefinition(sIDPath,"BestFitness","Best fitness value in this generation.");
00240     rDictionary.AddValueDefinition(sIDPath,"BestIndividual","Best individual in this generation.");
00241     rDictionary.AddValueDefinition(sIDPath,"BestFitnessEver","Best fitness value ever occured.");
00242     rDictionary.AddValueDefinition(sIDPath,"BestIndividualEver","Best individual ever occured.");
00243   }
00244 
00245   StatisticEntryDefinition* pEntryDef = rDictionary.GetEntryDefinitionByName(sIDPath, "NewChild");
00246     
00247   if (!pEntryDef) //Entry is not recorded yet, so do so.
00248   {
00249     pEntryDef = rDictionary.AddEntryDefinition(sIDPath,"NewChild",pMainComponentCache->GetControllerID(),"a new Child of this generation.");
00250     rDictionary.AddEntryDefinition(sIDPath,"Next Generation",pMainComponentCache->GetControllerID(),"IDs of the individuals that remain in the population.");
00251     rDictionary.AddEntryDefinition(sIDPath,"Victims",pMainComponentCache->GetControllerID(),"IDs of the individuals removed by the selection.");
00252   }
00253 
00254   /* get heritage map and use it when generating child info*/
00255   const ComponentType::HeritageMapType& parentSelections = pMainComponent->GetRecentParentSelections();
00256 
00257   /* generate new children info*/
00258   const ComponentType::PopulationPointer& children = pMainComponent->GetNewChildren();
00259   if (children.IsNotNull())
00260   {
00261     StatisticValueDefinition* pValueDef_Child = rDictionary.GetValueDefinitionByName(sIDPath, "Value");
00262     StatisticValueDefinition* pValueDef_Objective = rDictionary.GetValueDefinitionByName(sIDPath, "Objectiv #0");
00263     StatisticValueDefinition* pValueDef_Strategic = rDictionary.GetValueDefinitionByName(sIDPath, "Strategic #0");
00264     StatisticValueDefinition* pValueDef_DeComp = rDictionary.GetValueDefinitionByName(sIDPath, "Decomposed Value #0");
00265     
00266     for (unsigned long index= 0; index<children->Size(); index++)
00267     {
00268       ComponentType::IndividualPointer child = children->ElementAt(index);
00269       ComponentType::DecomposedMeasureType decomposedChildValue = pMainComponent->GetDecomposedIndividualValue(child->GetIndividualID());
00270 
00271       //check of value definitions for children already exist, if not add them
00272       if (!pValueDef_Child)
00273       {
00274         pValueDef_Child = rDictionary.AddValueDefinition(sIDPath,"Value","value of the child");
00275         rDictionary.AddValueDefinition(sIDPath,"Parents","ID of the parents");
00276 
00277         if (child->ObjectiveParameters().size()>0)
00278         {
00279           pValueDef_Objective = rDictionary.AddValueDefinition(sIDPath,"Objectiv #0","objective parameter of the individual");
00280           for (long index2= 1; index2<child->ObjectiveParameters().size(); index2++)
00281           {
00282             rDictionary.AddValueDefinition(sIDPath,"Objectiv #"+Convert::ToStr(index2),"objective parameter of the individual");
00283           }
00284         }
00285         if (child->StrategicParameters().size()>0)
00286         {
00287           pValueDef_Strategic = rDictionary.AddValueDefinition(sIDPath,"Strategic #0","strategic parameter of the individual");
00288           for (long index2= 1; index2<child->StrategicParameters().size(); index2++)
00289           {
00290             rDictionary.AddValueDefinition(sIDPath,"Strategic #"+Convert::ToStr(index2),"strategic parameter of the individual");
00291           }
00292         }
00293         if (decomposedChildValue.size()>0)
00294         {
00295           pValueDef_DeComp = rDictionary.AddValueDefinition(sIDPath,"Decomposed Value #0","decomposed values result as a weightened sum the value of the individual (meaning depends on the metric of the optimization)");
00296           for (long index2= 1; index2<decomposedChildValue.size(); index2++)
00297           {
00298             rDictionary.AddValueDefinition(sIDPath,"Decomposed Value #"+Convert::ToStr(index2),"decomposed values result as a weightened sum the value of the individual (meaning depends on the metric of the optimization)");
00299           }
00300         }
00301       }
00302 
00303       //generate entry for new child
00304       StatisticEntry* pNewChildEntry = rStatisticEntry.CreateChildEntry();
00305       pNewChildEntry->SetRefID(pEntryDef->GetRefID());
00306 
00307       pNewChildEntry->AddValue(Convert::ToStr(child->GetIndividualID()),pValueDef->GetRefID());
00308 
00309       //objective value
00310       pNewChildEntry->AddValue(Convert::ToStr(child->GetObjectiveValue()),pValueDef_Child->GetRefID());
00311 
00312       //compile parental info
00313       std::string sParents = "";
00314       ComponentType::HeritageMapType::const_iterator parentFinding = parentSelections.find(child->GetIndividualID());
00315       if (parentFinding ==parentSelections.end()) throwCtrlExceptionMacro("","Cannot find parents of new child individual. Please ensure valid session and setup. Child ID: "<<child->GetIndividualID());
00316       ComponentType::IndividualSelectionType parents = parentFinding->second;
00317 
00318       for (long index2= 0; index2<parents.size(); index2++)
00319       {
00320         sParents += Convert::ToStr(parents[index2]);
00321         if (index2<parents.size()-1) sParents += ", ";
00322       }
00323       pNewChildEntry->AddValue(sParents,pValueDef_Child->GetRefID()+1);
00324 
00325       //objective parameters
00326       for (long index2= 0; index2<child->ObjectiveParameters().size(); index2++)
00327       {
00328         pNewChildEntry->AddValue(Convert::ToStr((child->ObjectiveParameters())[index2]),pValueDef_Objective->GetRefID()+index2);
00329       }
00330 
00331       //strategic parameters
00332       for (long index2= 0; index2<child->StrategicParameters().size(); index2++)
00333       {
00334         pNewChildEntry->AddValue(Convert::ToStr(((child->StrategicParameters())[index2])->GetValue()),pValueDef_Strategic->GetRefID()+index2);
00335       }
00336 
00337       //decomposed values
00338       for (long index2= 0; index2<decomposedChildValue.size(); index2++)
00339       {
00340         pNewChildEntry->AddValue(Convert::ToStr(decomposedChildValue[index2]),pValueDef_DeComp->GetRefID()+index2);
00341       }
00342 
00343       pNewChildEntry->CloseEntry();
00344     }
00345   }
00346 
00347 
00348   /*Next generation*/
00349   StatisticEntry* pGenerationEntry = rStatisticEntry.CreateChildEntry();
00350   pGenerationEntry->SetRefID(pEntryDef->GetRefID()+1);
00351 
00352   const ComponentType::PopulationPointer& nextGen = pMainComponent->GetPopulation();
00353   if (nextGen.IsNotNull())
00354   {
00355     for (long index= 0; index<nextGen->size(); index++)
00356     {
00357       ComponentType::IndividualPointer nextGenIndividual = nextGen->ElementAt(index);
00358       if (nextGenIndividual.IsNotNull()) pGenerationEntry->AddValue(Convert::ToStr(nextGenIndividual->GetIndividualID()),pValueDef->GetRefID());
00359     }
00360   }
00361   pGenerationEntry->CloseEntry();
00362 
00363   /*Victims*/
00364   StatisticEntry* pVictimsEntry = rStatisticEntry.CreateChildEntry();
00365   pVictimsEntry->SetRefID(pEntryDef->GetRefID()+2);
00366 
00367   const ComponentType::PopulationPointer& victims = pMainComponent->GetRecentPopulationSelections();
00368   if (victims.IsNotNull())
00369   {
00370     for (long index= 0; index<victims->size(); index++)
00371     {
00372       ComponentType::IndividualPointer victim = victims->ElementAt(index);
00373       if (victim.IsNotNull()) pVictimsEntry->AddValue(Convert::ToStr(victim->GetIndividualID()),pValueDef->GetRefID());
00374     }
00375   }
00376   pVictimsEntry->CloseEntry();
00377 
00378   /*Best fitness*/
00379   rStatisticEntry.AddValue(Convert::ToStr(pMainComponent->GetCurrentValue()),pValueDef_Best->GetRefID());
00380 
00381   /*Best individual*/
00382   rStatisticEntry.AddValue(Convert::ToStr(pMainComponent->GetBestIndividual()->GetIndividualID()),pValueDef_Best->GetRefID()+1);
00383 
00384   /*Best fitness ever*/
00385   rStatisticEntry.AddValue(Convert::ToStr(pMainComponent->GetBestIndividualEver()->GetObjectiveValue()),pValueDef_Best->GetRefID()+2);
00386 
00387   /*Best individual ever*/
00388   rStatisticEntry.AddValue(Convert::ToStr(pMainComponent->GetBestIndividualEver()->GetIndividualID()),pValueDef_Best->GetRefID()+3);
00389 };
00390 
00391 } //end of namespace free

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