// @(#)root/tmva $Id$   
// Author: Andreas Hoecker, Joerg Stelzer, Helge Voss, Krzysztof Danielowski, Kamil Kraszewski, Maciej Kruk

/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
 * Package: TMVA                                                                  *
 * Class  : SimulatedAnnealing                                                    *
 * Web    : http://tmva.sourceforge.net                                           *
 *                                                                                *
 * Description:                                                                   *
 *      Implementation (see header for description)                               *
 *                                                                                *
 * Authors (alphabetical):                                                        *
 *      Krzysztof Danielowski <danielow@cern.ch>       - IFJ & AGH, Poland        *
 *      Kamil Kraszewski      <kalq@cern.ch>           - IFJ & UJ, Poland         *
 *      Maciej Kruk           <mkruk@cern.ch>          - IFJ & AGH, Poland        *
 *                                                                                *
 * Copyright (c) 2008:                                                            *
 *      IFJ-Krakow, Poland                                                        *
 *      CERN, Switzerland                                                         * 
 *      MPI-K Heidelberg, Germany                                                 * 
 *                                                                                *
 * Redistribution and use in source and binary forms, with or without             *
 * modification, are permitted according to the terms listed in LICENSE           *
 * (http://tmva.sourceforge.net/LICENSE)                                          *
 **********************************************************************************/

//_______________________________________________________________________
//
// Implementation of Simulated Annealing fitter
//_______________________________________________________________________
#include "TMVA/SimulatedAnnealing.h"

#include "TRandom3.h"
#include "TMath.h"

#include "TMVA/Interval.h"
#include "TMVA/IFitterTarget.h"
#include "TMVA/GeneticRange.h"
#include "TMVA/Timer.h"
#include "TMVA/MsgLogger.h"

ClassImp(TMVA::SimulatedAnnealing)

//_______________________________________________________________________
TMVA::SimulatedAnnealing::SimulatedAnnealing( IFitterTarget& target, const std::vector<Interval*>& ranges )
   : fKernelTemperature     (kIncreasingAdaptive),
     fFitterTarget          ( target ),
     fRandom                ( new TRandom3(100) ),
     fRanges                ( ranges ),
     fMaxCalls              ( 500000 ),
     fInitialTemperature    ( 1000 ),
     fMinTemperature        ( 0 ),
     fEps                   ( 1e-10 ),
     fTemperatureScale      ( 0.06 ),
     fAdaptiveSpeed         ( 1.0 ),
     fTemperatureAdaptiveStep( 0.0 ),
     fUseDefaultScale       ( kFALSE ),
     fUseDefaultTemperature ( kFALSE ),
     fLogger( new MsgLogger("SimulatedAnnealing") ),
     fProgress(0.0)
{
   // constructor
   fKernelTemperature = kIncreasingAdaptive;
}

//_______________________________________________________________________
void TMVA::SimulatedAnnealing::SetOptions( Int_t    maxCalls,
                                           Double_t initialTemperature,
                                           Double_t minTemperature,
                                           Double_t eps,
                                           TString  kernelTemperatureS,
                                           Double_t temperatureScale,
                                           Double_t adaptiveSpeed,
                                           Double_t temperatureAdaptiveStep,
                                           Bool_t   useDefaultScale,
                                           Bool_t   useDefaultTemperature)   
{
   // option setter

   fMaxCalls = maxCalls;
   fInitialTemperature = initialTemperature;
   fMinTemperature = minTemperature;
   fEps = eps;

   if      (kernelTemperatureS == "IncreasingAdaptive") {
      fKernelTemperature = kIncreasingAdaptive; 
      Log() << kINFO << "Using increasing adaptive algorithm" << Endl;
   }
   else if (kernelTemperatureS == "DecreasingAdaptive") {
      fKernelTemperature = kDecreasingAdaptive; 
      Log() << kINFO << "Using decreasing adaptive algorithm" << Endl;
   }
   else if (kernelTemperatureS == "Sqrt") {
      fKernelTemperature = kSqrt; 
      Log() << kINFO << "Using \"Sqrt\" algorithm" << Endl;
   }
   else if (kernelTemperatureS == "Homo") {
      fKernelTemperature = kHomo; 
      Log() << kINFO << "Using \"Homo\" algorithm" << Endl;
   }
   else if (kernelTemperatureS == "Log") {
      fKernelTemperature = kLog;  
      Log() << kINFO << "Using \"Log\" algorithm" << Endl;
   }
   else if (kernelTemperatureS == "Sin") {
      fKernelTemperature = kSin;
      Log() << kINFO << "Using \"Sin\" algorithm" << Endl;
   }

   fTemperatureScale        = temperatureScale;
   fAdaptiveSpeed           = adaptiveSpeed;
   fTemperatureAdaptiveStep = temperatureAdaptiveStep;

   fUseDefaultScale         = useDefaultScale;
   fUseDefaultTemperature   = useDefaultTemperature;
}
//_______________________________________________________________________
TMVA::SimulatedAnnealing::~SimulatedAnnealing()
{
   // destructor
}

//_______________________________________________________________________
void TMVA::SimulatedAnnealing::FillWithRandomValues( std::vector<Double_t>& parameters )
{
   // random starting parameters
   for (UInt_t rIter = 0; rIter < parameters.size(); rIter++) {
      parameters[rIter] = fRandom->Uniform(0.0,1.0)*(fRanges[rIter]->GetMax() - fRanges[rIter]->GetMin()) + fRanges[rIter]->GetMin();
   }
}

//_______________________________________________________________________
void TMVA::SimulatedAnnealing::ReWriteParameters( std::vector<Double_t>& from, std::vector<Double_t>& to)
{
   // copy parameters
   for (UInt_t rIter = 0; rIter < from.size(); rIter++) to[rIter] = from[rIter];
}

//_______________________________________________________________________
void TMVA::SimulatedAnnealing::GenerateNeighbour( std::vector<Double_t>& parameters, std::vector<Double_t>& oldParameters, 
                                                  Double_t currentTemperature )
{
   // generate adjacent parameters
   ReWriteParameters( parameters, oldParameters );

   for (UInt_t rIter=0;rIter<parameters.size();rIter++) {
      Double_t uni,distribution,sign;
      do {
         uni = fRandom->Uniform(0.0,1.0);
         sign = (uni - 0.5 >= 0.0) ? (1.0) : (-1.0);
         distribution = currentTemperature * (TMath::Power(1.0 + 1.0/currentTemperature, TMath::Abs(2.0*uni - 1.0)) -1.0)*sign;
         parameters[rIter] = oldParameters[rIter] +  (fRanges[rIter]->GetMax()-fRanges[rIter]->GetMin())*0.1*distribution;
      }
      while (parameters[rIter] < fRanges[rIter]->GetMin() || parameters[rIter] > fRanges[rIter]->GetMax() );
   }
}
//_______________________________________________________________________
std::vector<Double_t> TMVA::SimulatedAnnealing::GenerateNeighbour( std::vector<Double_t>& parameters, Double_t currentTemperature )
{
   // generate adjacent parameters
   std::vector<Double_t> newParameters( fRanges.size() );   

   for (UInt_t rIter=0; rIter<parameters.size(); rIter++) {
      Double_t uni,distribution,sign;
      do {
         uni = fRandom->Uniform(0.0,1.0);
         sign = (uni - 0.5 >= 0.0) ? (1.0) : (-1.0);
         distribution = currentTemperature * (TMath::Power(1.0 + 1.0/currentTemperature, TMath::Abs(2.0*uni - 1.0)) -1.0)*sign;
         newParameters[rIter] = parameters[rIter] +  (fRanges[rIter]->GetMax()-fRanges[rIter]->GetMin())*0.1*distribution;
      }
      while (newParameters[rIter] < fRanges[rIter]->GetMin() || newParameters[rIter] > fRanges[rIter]->GetMax() );
   }

   return newParameters;
}

//_______________________________________________________________________
void TMVA::SimulatedAnnealing::GenerateNewTemperature( Double_t& currentTemperature, Int_t Iter )
{
   // generate new temperature
   if      (fKernelTemperature == kSqrt) {
         currentTemperature = fInitialTemperature/(Double_t)TMath::Sqrt(Iter+2) * fTemperatureScale;
   }
   else if (fKernelTemperature == kLog) {
      currentTemperature = fInitialTemperature/(Double_t)TMath::Log(Iter+2) * fTemperatureScale;
   }
   else if (fKernelTemperature == kHomo) {
      currentTemperature = fInitialTemperature/(Double_t)(Iter+2) * fTemperatureScale;
   }
   else if (fKernelTemperature == kSin) {
      currentTemperature = (TMath::Sin( (Double_t)Iter / fTemperatureScale ) + 1.0 )/ (Double_t)(Iter+1.0) * fInitialTemperature + fEps;
   }
   else if (fKernelTemperature == kGeo) {
      currentTemperature = currentTemperature*fTemperatureScale;
   }
   else if (fKernelTemperature == kIncreasingAdaptive) {
      currentTemperature = fMinTemperature + fTemperatureScale*TMath::Log(1.0+fProgress*fAdaptiveSpeed);
   }
   else if (fKernelTemperature == kDecreasingAdaptive) {
      currentTemperature = currentTemperature*fTemperatureScale;
   }
   else Log() << kFATAL << "No such kernel!" << Endl;
}

//________________________________________________________________________
Bool_t TMVA::SimulatedAnnealing::ShouldGoIn( Double_t currentFit, Double_t localFit, Double_t currentTemperature )
{
   // result checker
   if (currentTemperature < fEps) return kFALSE;
   Double_t lim  = TMath::Exp( -TMath::Abs( currentFit - localFit ) / currentTemperature );
   Double_t prob = fRandom->Uniform(0.0, 1.0);
   return (prob < lim) ? kTRUE : kFALSE;
}

//_______________________________________________________________________
void TMVA::SimulatedAnnealing::SetDefaultScale()
{
   // setting of default scale
   if      (fKernelTemperature == kSqrt) fTemperatureScale = 1.0;
   else if (fKernelTemperature == kLog)  fTemperatureScale = 1.0;
   else if (fKernelTemperature == kHomo) fTemperatureScale = 1.0;
   else if (fKernelTemperature == kSin)  fTemperatureScale = 20.0;
   else if (fKernelTemperature == kGeo)  fTemperatureScale = 0.99997;
   else if (fKernelTemperature == kDecreasingAdaptive) {
      fTemperatureScale = 1.0;
      while (TMath::Abs(TMath::Power(fTemperatureScale,fMaxCalls) * fInitialTemperature - fMinTemperature) >
             TMath::Abs(TMath::Power(fTemperatureScale-0.000001,fMaxCalls) * fInitialTemperature - fMinTemperature)) {
         fTemperatureScale -= 0.000001;
      }
   }
   else if (fKernelTemperature == kIncreasingAdaptive) fTemperatureScale = 0.15*( 1.0 / (Double_t)(fRanges.size() ) );
   else Log() << kFATAL << "No such kernel!" << Endl;
}

//_______________________________________________________________________
Double_t TMVA::SimulatedAnnealing::GenerateMaxTemperature( std::vector<Double_t>& parameters  )
{
   // maximum temperature
   Int_t equilibrium;
   Bool_t stopper = 0; 
   Double_t t, dT, cold, delta, deltaY, y, yNew, yBest, yOld;
   std::vector<Double_t> x( fRanges.size() ), xNew( fRanges.size() ), xBest( fRanges.size() ), xOld( fRanges.size() );
   t = fMinTemperature;
   deltaY = cold = 0.0;
   dT = fTemperatureAdaptiveStep;
   for (UInt_t rIter = 0; rIter < x.size(); rIter++)
      x[rIter] = ( fRanges[rIter]->GetMax() + fRanges[rIter]->GetMin() ) / 2.0;
   y = yBest = 1E10;
   for (Int_t i=0; i<fMaxCalls/50; i++) {
      if ((i>0) && (deltaY>0.0)) {
         cold = deltaY;
         stopper = 1;
      }
      t += dT*i;
      x = xOld = GenerateNeighbour(x,t);
      y = yOld = fFitterTarget.EstimatorFunction( xOld );   
      equilibrium = 0;
      for ( Int_t k=0; (k<30) && (equilibrium<=12); k++ ) {
         xNew = GenerateNeighbour(x,t);
         //"energy"
         yNew = fFitterTarget.EstimatorFunction( xNew );
         deltaY = yNew - y;
         if (deltaY < 0.0) {     // keep xnew if energy is reduced
            std::swap(x,xNew);
            std::swap(y,yNew);
            if (y < yBest) {
               xBest = x;
               yBest = y;
            }
            delta = TMath::Abs( deltaY );
            if      (y    != 0.0) delta /= y;
            else if (yNew != 0.0) delta /= y;

            // equilibrium is defined as a 10% or smaller change in 10 iterations 
            if (delta < 0.1) equilibrium++;
            else             equilibrium = 0;
         }
         else equilibrium++;
      }

      // "energy"
      yNew = fFitterTarget.EstimatorFunction( xNew ); 
      deltaY = yNew - yOld;
      if ( (deltaY < 0.0 )&&( yNew < yBest)) {
         xBest=x;
         yBest = yNew;
      }
      y = yNew;
      if ((stopper) && (deltaY >= (100.0 * cold))) break;  // phase transition with another parameter to change
   }
   parameters = xBest;
   return t;
}

//_______________________________________________________________________
Double_t TMVA::SimulatedAnnealing::Minimize( std::vector<Double_t>& parameters )
{
   // minimisation algorithm
   std::vector<Double_t> bestParameters(fRanges.size());
   std::vector<Double_t> oldParameters (fRanges.size());

   Double_t currentTemperature, bestFit, currentFit;
   Int_t optimizeCalls, generalCalls, equals;

   equals = 0;

   if (fUseDefaultTemperature) {
      if (fKernelTemperature == kIncreasingAdaptive) {
         fMinTemperature = currentTemperature = 1e-06; 
         FillWithRandomValues( parameters );
      }
      else fInitialTemperature = currentTemperature = GenerateMaxTemperature( parameters );
   }
   else {
      if (fKernelTemperature == kIncreasingAdaptive)
         currentTemperature = fMinTemperature; 
      else
         currentTemperature = fInitialTemperature;
      FillWithRandomValues( parameters ); 
   }

   if (fUseDefaultScale) SetDefaultScale();

   Log() << kINFO
           << "Temperatur scale = "      << fTemperatureScale  
           << ", current temperature = " << currentTemperature  << Endl;

   bestParameters = parameters;
   bestFit        = currentFit = fFitterTarget.EstimatorFunction( bestParameters );

   optimizeCalls = fMaxCalls/100;             //use 1% calls to optimize best founded minimum
   generalCalls  = fMaxCalls - optimizeCalls; //and 99% calls to found that one
   fProgress = 0.0;

   Timer timer( fMaxCalls, fLogger->GetSource().c_str() );

   for (Int_t sample = 0; sample < generalCalls; sample++) {
      GenerateNeighbour( parameters, oldParameters, currentTemperature );
      Double_t localFit = fFitterTarget.EstimatorFunction( parameters );
      
      if (localFit < currentFit || TMath::Abs(currentFit-localFit) < fEps) { // if not worse than last one
         if (TMath::Abs(currentFit-localFit) < fEps) { // if the same as last one
            equals++;
            if (equals >= 3) //if we still at the same level, we should increase temperature
               fProgress+=1.0;
         }
         else {
            fProgress = 0.0;
            equals = 0;
         }
         
         currentFit = localFit;
         
         if (currentFit < bestFit) {
            ReWriteParameters( parameters, bestParameters );
            bestFit = currentFit;
         }
      }
      else {
         if (!ShouldGoIn(localFit, currentFit, currentTemperature))
            ReWriteParameters( oldParameters, parameters );
         else
            currentFit = localFit;
         
         fProgress+=1.0;
         equals = 0;
      }
      
      GenerateNewTemperature( currentTemperature, sample );
      
      if ((fMaxCalls<100) || sample%Int_t(fMaxCalls/100.0) == 0) timer.DrawProgressBar( sample );
   }

   // get elapsed time   
   Log() << kINFO << "Elapsed time: " << timer.GetElapsedTime() 
           << "                            " << Endl;  
   
   // supose this minimum is the best one, now just try to improve it

   Double_t startingTemperature = fMinTemperature*(fRanges.size())*2.0; 
   currentTemperature = startingTemperature;

   Int_t changes = 0;
   for (Int_t sample=0;sample<optimizeCalls;sample++) {
      GenerateNeighbour( parameters, oldParameters, currentTemperature );
      Double_t localFit = fFitterTarget.EstimatorFunction( parameters );
      
      if (localFit < currentFit) { //if better than last one
         currentFit = localFit;
         changes++;
         
         if (currentFit < bestFit) {
            ReWriteParameters( parameters, bestParameters );
            bestFit = currentFit;
         }
      }
      else ReWriteParameters( oldParameters, parameters ); //we never try worse parameters

      currentTemperature-=(startingTemperature - fEps)/optimizeCalls;
   }

   ReWriteParameters( bestParameters, parameters );

   return bestFit; 
}

 SimulatedAnnealing.cxx:1
 SimulatedAnnealing.cxx:2
 SimulatedAnnealing.cxx:3
 SimulatedAnnealing.cxx:4
 SimulatedAnnealing.cxx:5
 SimulatedAnnealing.cxx:6
 SimulatedAnnealing.cxx:7
 SimulatedAnnealing.cxx:8
 SimulatedAnnealing.cxx:9
 SimulatedAnnealing.cxx:10
 SimulatedAnnealing.cxx:11
 SimulatedAnnealing.cxx:12
 SimulatedAnnealing.cxx:13
 SimulatedAnnealing.cxx:14
 SimulatedAnnealing.cxx:15
 SimulatedAnnealing.cxx:16
 SimulatedAnnealing.cxx:17
 SimulatedAnnealing.cxx:18
 SimulatedAnnealing.cxx:19
 SimulatedAnnealing.cxx:20
 SimulatedAnnealing.cxx:21
 SimulatedAnnealing.cxx:22
 SimulatedAnnealing.cxx:23
 SimulatedAnnealing.cxx:24
 SimulatedAnnealing.cxx:25
 SimulatedAnnealing.cxx:26
 SimulatedAnnealing.cxx:27
 SimulatedAnnealing.cxx:28
 SimulatedAnnealing.cxx:29
 SimulatedAnnealing.cxx:30
 SimulatedAnnealing.cxx:31
 SimulatedAnnealing.cxx:32
 SimulatedAnnealing.cxx:33
 SimulatedAnnealing.cxx:34
 SimulatedAnnealing.cxx:35
 SimulatedAnnealing.cxx:36
 SimulatedAnnealing.cxx:37
 SimulatedAnnealing.cxx:38
 SimulatedAnnealing.cxx:39
 SimulatedAnnealing.cxx:40
 SimulatedAnnealing.cxx:41
 SimulatedAnnealing.cxx:42
 SimulatedAnnealing.cxx:43
 SimulatedAnnealing.cxx:44
 SimulatedAnnealing.cxx:45
 SimulatedAnnealing.cxx:46
 SimulatedAnnealing.cxx:47
 SimulatedAnnealing.cxx:48
 SimulatedAnnealing.cxx:49
 SimulatedAnnealing.cxx:50
 SimulatedAnnealing.cxx:51
 SimulatedAnnealing.cxx:52
 SimulatedAnnealing.cxx:53
 SimulatedAnnealing.cxx:54
 SimulatedAnnealing.cxx:55
 SimulatedAnnealing.cxx:56
 SimulatedAnnealing.cxx:57
 SimulatedAnnealing.cxx:58
 SimulatedAnnealing.cxx:59
 SimulatedAnnealing.cxx:60
 SimulatedAnnealing.cxx:61
 SimulatedAnnealing.cxx:62
 SimulatedAnnealing.cxx:63
 SimulatedAnnealing.cxx:64
 SimulatedAnnealing.cxx:65
 SimulatedAnnealing.cxx:66
 SimulatedAnnealing.cxx:67
 SimulatedAnnealing.cxx:68
 SimulatedAnnealing.cxx:69
 SimulatedAnnealing.cxx:70
 SimulatedAnnealing.cxx:71
 SimulatedAnnealing.cxx:72
 SimulatedAnnealing.cxx:73
 SimulatedAnnealing.cxx:74
 SimulatedAnnealing.cxx:75
 SimulatedAnnealing.cxx:76
 SimulatedAnnealing.cxx:77
 SimulatedAnnealing.cxx:78
 SimulatedAnnealing.cxx:79
 SimulatedAnnealing.cxx:80
 SimulatedAnnealing.cxx:81
 SimulatedAnnealing.cxx:82
 SimulatedAnnealing.cxx:83
 SimulatedAnnealing.cxx:84
 SimulatedAnnealing.cxx:85
 SimulatedAnnealing.cxx:86
 SimulatedAnnealing.cxx:87
 SimulatedAnnealing.cxx:88
 SimulatedAnnealing.cxx:89
 SimulatedAnnealing.cxx:90
 SimulatedAnnealing.cxx:91
 SimulatedAnnealing.cxx:92
 SimulatedAnnealing.cxx:93
 SimulatedAnnealing.cxx:94
 SimulatedAnnealing.cxx:95
 SimulatedAnnealing.cxx:96
 SimulatedAnnealing.cxx:97
 SimulatedAnnealing.cxx:98
 SimulatedAnnealing.cxx:99
 SimulatedAnnealing.cxx:100
 SimulatedAnnealing.cxx:101
 SimulatedAnnealing.cxx:102
 SimulatedAnnealing.cxx:103
 SimulatedAnnealing.cxx:104
 SimulatedAnnealing.cxx:105
 SimulatedAnnealing.cxx:106
 SimulatedAnnealing.cxx:107
 SimulatedAnnealing.cxx:108
 SimulatedAnnealing.cxx:109
 SimulatedAnnealing.cxx:110
 SimulatedAnnealing.cxx:111
 SimulatedAnnealing.cxx:112
 SimulatedAnnealing.cxx:113
 SimulatedAnnealing.cxx:114
 SimulatedAnnealing.cxx:115
 SimulatedAnnealing.cxx:116
 SimulatedAnnealing.cxx:117
 SimulatedAnnealing.cxx:118
 SimulatedAnnealing.cxx:119
 SimulatedAnnealing.cxx:120
 SimulatedAnnealing.cxx:121
 SimulatedAnnealing.cxx:122
 SimulatedAnnealing.cxx:123
 SimulatedAnnealing.cxx:124
 SimulatedAnnealing.cxx:125
 SimulatedAnnealing.cxx:126
 SimulatedAnnealing.cxx:127
 SimulatedAnnealing.cxx:128
 SimulatedAnnealing.cxx:129
 SimulatedAnnealing.cxx:130
 SimulatedAnnealing.cxx:131
 SimulatedAnnealing.cxx:132
 SimulatedAnnealing.cxx:133
 SimulatedAnnealing.cxx:134
 SimulatedAnnealing.cxx:135
 SimulatedAnnealing.cxx:136
 SimulatedAnnealing.cxx:137
 SimulatedAnnealing.cxx:138
 SimulatedAnnealing.cxx:139
 SimulatedAnnealing.cxx:140
 SimulatedAnnealing.cxx:141
 SimulatedAnnealing.cxx:142
 SimulatedAnnealing.cxx:143
 SimulatedAnnealing.cxx:144
 SimulatedAnnealing.cxx:145
 SimulatedAnnealing.cxx:146
 SimulatedAnnealing.cxx:147
 SimulatedAnnealing.cxx:148
 SimulatedAnnealing.cxx:149
 SimulatedAnnealing.cxx:150
 SimulatedAnnealing.cxx:151
 SimulatedAnnealing.cxx:152
 SimulatedAnnealing.cxx:153
 SimulatedAnnealing.cxx:154
 SimulatedAnnealing.cxx:155
 SimulatedAnnealing.cxx:156
 SimulatedAnnealing.cxx:157
 SimulatedAnnealing.cxx:158
 SimulatedAnnealing.cxx:159
 SimulatedAnnealing.cxx:160
 SimulatedAnnealing.cxx:161
 SimulatedAnnealing.cxx:162
 SimulatedAnnealing.cxx:163
 SimulatedAnnealing.cxx:164
 SimulatedAnnealing.cxx:165
 SimulatedAnnealing.cxx:166
 SimulatedAnnealing.cxx:167
 SimulatedAnnealing.cxx:168
 SimulatedAnnealing.cxx:169
 SimulatedAnnealing.cxx:170
 SimulatedAnnealing.cxx:171
 SimulatedAnnealing.cxx:172
 SimulatedAnnealing.cxx:173
 SimulatedAnnealing.cxx:174
 SimulatedAnnealing.cxx:175
 SimulatedAnnealing.cxx:176
 SimulatedAnnealing.cxx:177
 SimulatedAnnealing.cxx:178
 SimulatedAnnealing.cxx:179
 SimulatedAnnealing.cxx:180
 SimulatedAnnealing.cxx:181
 SimulatedAnnealing.cxx:182
 SimulatedAnnealing.cxx:183
 SimulatedAnnealing.cxx:184
 SimulatedAnnealing.cxx:185
 SimulatedAnnealing.cxx:186
 SimulatedAnnealing.cxx:187
 SimulatedAnnealing.cxx:188
 SimulatedAnnealing.cxx:189
 SimulatedAnnealing.cxx:190
 SimulatedAnnealing.cxx:191
 SimulatedAnnealing.cxx:192
 SimulatedAnnealing.cxx:193
 SimulatedAnnealing.cxx:194
 SimulatedAnnealing.cxx:195
 SimulatedAnnealing.cxx:196
 SimulatedAnnealing.cxx:197
 SimulatedAnnealing.cxx:198
 SimulatedAnnealing.cxx:199
 SimulatedAnnealing.cxx:200
 SimulatedAnnealing.cxx:201
 SimulatedAnnealing.cxx:202
 SimulatedAnnealing.cxx:203
 SimulatedAnnealing.cxx:204
 SimulatedAnnealing.cxx:205
 SimulatedAnnealing.cxx:206
 SimulatedAnnealing.cxx:207
 SimulatedAnnealing.cxx:208
 SimulatedAnnealing.cxx:209
 SimulatedAnnealing.cxx:210
 SimulatedAnnealing.cxx:211
 SimulatedAnnealing.cxx:212
 SimulatedAnnealing.cxx:213
 SimulatedAnnealing.cxx:214
 SimulatedAnnealing.cxx:215
 SimulatedAnnealing.cxx:216
 SimulatedAnnealing.cxx:217
 SimulatedAnnealing.cxx:218
 SimulatedAnnealing.cxx:219
 SimulatedAnnealing.cxx:220
 SimulatedAnnealing.cxx:221
 SimulatedAnnealing.cxx:222
 SimulatedAnnealing.cxx:223
 SimulatedAnnealing.cxx:224
 SimulatedAnnealing.cxx:225
 SimulatedAnnealing.cxx:226
 SimulatedAnnealing.cxx:227
 SimulatedAnnealing.cxx:228
 SimulatedAnnealing.cxx:229
 SimulatedAnnealing.cxx:230
 SimulatedAnnealing.cxx:231
 SimulatedAnnealing.cxx:232
 SimulatedAnnealing.cxx:233
 SimulatedAnnealing.cxx:234
 SimulatedAnnealing.cxx:235
 SimulatedAnnealing.cxx:236
 SimulatedAnnealing.cxx:237
 SimulatedAnnealing.cxx:238
 SimulatedAnnealing.cxx:239
 SimulatedAnnealing.cxx:240
 SimulatedAnnealing.cxx:241
 SimulatedAnnealing.cxx:242
 SimulatedAnnealing.cxx:243
 SimulatedAnnealing.cxx:244
 SimulatedAnnealing.cxx:245
 SimulatedAnnealing.cxx:246
 SimulatedAnnealing.cxx:247
 SimulatedAnnealing.cxx:248
 SimulatedAnnealing.cxx:249
 SimulatedAnnealing.cxx:250
 SimulatedAnnealing.cxx:251
 SimulatedAnnealing.cxx:252
 SimulatedAnnealing.cxx:253
 SimulatedAnnealing.cxx:254
 SimulatedAnnealing.cxx:255
 SimulatedAnnealing.cxx:256
 SimulatedAnnealing.cxx:257
 SimulatedAnnealing.cxx:258
 SimulatedAnnealing.cxx:259
 SimulatedAnnealing.cxx:260
 SimulatedAnnealing.cxx:261
 SimulatedAnnealing.cxx:262
 SimulatedAnnealing.cxx:263
 SimulatedAnnealing.cxx:264
 SimulatedAnnealing.cxx:265
 SimulatedAnnealing.cxx:266
 SimulatedAnnealing.cxx:267
 SimulatedAnnealing.cxx:268
 SimulatedAnnealing.cxx:269
 SimulatedAnnealing.cxx:270
 SimulatedAnnealing.cxx:271
 SimulatedAnnealing.cxx:272
 SimulatedAnnealing.cxx:273
 SimulatedAnnealing.cxx:274
 SimulatedAnnealing.cxx:275
 SimulatedAnnealing.cxx:276
 SimulatedAnnealing.cxx:277
 SimulatedAnnealing.cxx:278
 SimulatedAnnealing.cxx:279
 SimulatedAnnealing.cxx:280
 SimulatedAnnealing.cxx:281
 SimulatedAnnealing.cxx:282
 SimulatedAnnealing.cxx:283
 SimulatedAnnealing.cxx:284
 SimulatedAnnealing.cxx:285
 SimulatedAnnealing.cxx:286
 SimulatedAnnealing.cxx:287
 SimulatedAnnealing.cxx:288
 SimulatedAnnealing.cxx:289
 SimulatedAnnealing.cxx:290
 SimulatedAnnealing.cxx:291
 SimulatedAnnealing.cxx:292
 SimulatedAnnealing.cxx:293
 SimulatedAnnealing.cxx:294
 SimulatedAnnealing.cxx:295
 SimulatedAnnealing.cxx:296
 SimulatedAnnealing.cxx:297
 SimulatedAnnealing.cxx:298
 SimulatedAnnealing.cxx:299
 SimulatedAnnealing.cxx:300
 SimulatedAnnealing.cxx:301
 SimulatedAnnealing.cxx:302
 SimulatedAnnealing.cxx:303
 SimulatedAnnealing.cxx:304
 SimulatedAnnealing.cxx:305
 SimulatedAnnealing.cxx:306
 SimulatedAnnealing.cxx:307
 SimulatedAnnealing.cxx:308
 SimulatedAnnealing.cxx:309
 SimulatedAnnealing.cxx:310
 SimulatedAnnealing.cxx:311
 SimulatedAnnealing.cxx:312
 SimulatedAnnealing.cxx:313
 SimulatedAnnealing.cxx:314
 SimulatedAnnealing.cxx:315
 SimulatedAnnealing.cxx:316
 SimulatedAnnealing.cxx:317
 SimulatedAnnealing.cxx:318
 SimulatedAnnealing.cxx:319
 SimulatedAnnealing.cxx:320
 SimulatedAnnealing.cxx:321
 SimulatedAnnealing.cxx:322
 SimulatedAnnealing.cxx:323
 SimulatedAnnealing.cxx:324
 SimulatedAnnealing.cxx:325
 SimulatedAnnealing.cxx:326
 SimulatedAnnealing.cxx:327
 SimulatedAnnealing.cxx:328
 SimulatedAnnealing.cxx:329
 SimulatedAnnealing.cxx:330
 SimulatedAnnealing.cxx:331
 SimulatedAnnealing.cxx:332
 SimulatedAnnealing.cxx:333
 SimulatedAnnealing.cxx:334
 SimulatedAnnealing.cxx:335
 SimulatedAnnealing.cxx:336
 SimulatedAnnealing.cxx:337
 SimulatedAnnealing.cxx:338
 SimulatedAnnealing.cxx:339
 SimulatedAnnealing.cxx:340
 SimulatedAnnealing.cxx:341
 SimulatedAnnealing.cxx:342
 SimulatedAnnealing.cxx:343
 SimulatedAnnealing.cxx:344
 SimulatedAnnealing.cxx:345
 SimulatedAnnealing.cxx:346
 SimulatedAnnealing.cxx:347
 SimulatedAnnealing.cxx:348
 SimulatedAnnealing.cxx:349
 SimulatedAnnealing.cxx:350
 SimulatedAnnealing.cxx:351
 SimulatedAnnealing.cxx:352
 SimulatedAnnealing.cxx:353
 SimulatedAnnealing.cxx:354
 SimulatedAnnealing.cxx:355
 SimulatedAnnealing.cxx:356
 SimulatedAnnealing.cxx:357
 SimulatedAnnealing.cxx:358
 SimulatedAnnealing.cxx:359
 SimulatedAnnealing.cxx:360
 SimulatedAnnealing.cxx:361
 SimulatedAnnealing.cxx:362
 SimulatedAnnealing.cxx:363
 SimulatedAnnealing.cxx:364
 SimulatedAnnealing.cxx:365
 SimulatedAnnealing.cxx:366
 SimulatedAnnealing.cxx:367
 SimulatedAnnealing.cxx:368
 SimulatedAnnealing.cxx:369
 SimulatedAnnealing.cxx:370
 SimulatedAnnealing.cxx:371
 SimulatedAnnealing.cxx:372
 SimulatedAnnealing.cxx:373
 SimulatedAnnealing.cxx:374
 SimulatedAnnealing.cxx:375
 SimulatedAnnealing.cxx:376
 SimulatedAnnealing.cxx:377
 SimulatedAnnealing.cxx:378
 SimulatedAnnealing.cxx:379
 SimulatedAnnealing.cxx:380
 SimulatedAnnealing.cxx:381
 SimulatedAnnealing.cxx:382
 SimulatedAnnealing.cxx:383
 SimulatedAnnealing.cxx:384
 SimulatedAnnealing.cxx:385
 SimulatedAnnealing.cxx:386
 SimulatedAnnealing.cxx:387
 SimulatedAnnealing.cxx:388
 SimulatedAnnealing.cxx:389
 SimulatedAnnealing.cxx:390
 SimulatedAnnealing.cxx:391
 SimulatedAnnealing.cxx:392
 SimulatedAnnealing.cxx:393
 SimulatedAnnealing.cxx:394
 SimulatedAnnealing.cxx:395
 SimulatedAnnealing.cxx:396
 SimulatedAnnealing.cxx:397
 SimulatedAnnealing.cxx:398
 SimulatedAnnealing.cxx:399
 SimulatedAnnealing.cxx:400
 SimulatedAnnealing.cxx:401
 SimulatedAnnealing.cxx:402
 SimulatedAnnealing.cxx:403
 SimulatedAnnealing.cxx:404
 SimulatedAnnealing.cxx:405
 SimulatedAnnealing.cxx:406
 SimulatedAnnealing.cxx:407