RandomSearch.cpp

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*   R A N D O M   S E A R C H   C L A S S                                    */
00004 /*                                                                            */ 
00005 /*   Roberto Lopez                                                            */ 
00006 /*   International Center for Numerical Methods in Engineering (CIMNE)        */
00007 /*   Technical University of Catalonia (UPC)                                  */
00008 /*   Barcelona, Spain                                                         */
00009 /*   E-mail: rlopez@cimne.upc.edu                                             */ 
00010 /*                                                                            */
00011 /******************************************************************************/
00012 
00013 #include <iostream>
00014 #include <fstream>
00015 #include <algorithm>
00016 #include <functional>
00017 #include <math.h>
00018 #include <time.h>
00019 
00020 #include "RandomSearch.h"
00021 
00022 
00023 namespace Purple
00024 {
00025 
00026 // GENERAL CONSTRUCTOR 
00027 
00028 /// General constructor. It creates a random search optimization
00029 /// algorithm object associated to an objective function object. 
00030 /// It also initializes the class members to their default values:
00031 ///
00032 /// Stopping criteria:
00033 /// <ul> 
00034 /// <li> Evaluation goal: -1.0e69.
00035 /// <li> Maximum time: 1.0e6.
00036 /// <li> Maximum number of iterations: 100. 
00037 /// </ul> 
00038 ///  
00039 /// User stuff: 
00040 /// <ul>
00041 /// <li> Show period: 10. 
00042 /// </ul>
00043 ///
00044 /// @param newObjectiveFunction: Pointer to an objective function object.
00045 
00046 RandomSearch::RandomSearch(ObjectiveFunction* newObjectiveFunction)
00047 : OptimizationAlgorithm(newObjectiveFunction)
00048 {   
00049    // Stopping criteria
00050 
00051    evaluationGoal = -1.0e69;
00052    maximumTime = 1.0e6;
00053    maximumNumberOfIterations = 100; 
00054    
00055    // User stuff
00056    
00057    showPeriod = 10;
00058 }
00059 
00060 
00061 // DEFAULT CONSTRUCTOR
00062 
00063 /// Default constructor. It creates a random search optimization algorithm 
00064 ///object not associated to any objective function object. 
00065 /// It also initializes the class members to their default values:
00066 ///
00067 /// Stopping criteria:
00068 /// <ul> 
00069 /// <li> Evaluation goal: -1.0e69.
00070 /// <li> Maximum time: 1.0e6.
00071 /// <li> Maximum number of evaluations: 100. 
00072 /// </ul> 
00073 ///  
00074 /// User stuff: 
00075 /// <ul>
00076 /// <li> Show period: 10. 
00077 /// </ul>
00078 
00079 RandomSearch::RandomSearch(void) : OptimizationAlgorithm()
00080 {
00081    // Stopping criteria
00082 
00083    evaluationGoal = -1.0e69;
00084    maximumTime = 1.0e6;
00085    maximumNumberOfIterations = 100; 
00086    
00087    // User stuff
00088    
00089    showPeriod = 10;
00090 }
00091 
00092 
00093 // DESTRUCTOR
00094 
00095 /// Destructor.
00096 
00097 RandomSearch::~RandomSearch(void)
00098 {
00099 
00100 }
00101 
00102 // METHODS
00103 
00104 // int getMaximumNumberOfIterations(void) method
00105 
00106 /// This method returns the maximum number of iterations in the optimization
00107 /// process.
00108 
00109 int RandomSearch::getMaximumNumberOfIterations(void)
00110 {
00111    return(maximumNumberOfIterations);
00112 }
00113 
00114 
00115 // int getShowPeriod(void) method
00116 
00117 /// This method returns the number of iterations between the optimization 
00118 /// showing progress. 
00119 
00120 int RandomSearch::getShowPeriod(void)
00121 {
00122    return(showPeriod);    
00123 }
00124 
00125 
00126 // void setMaximumNumberOfIterations(int) method
00127 
00128 /// This method sets a maximum number of iterations for optimization. 
00129 /// Each iteration with the random search optimization algorithms costs one 
00130 /// objective function evaluation.
00131 ///
00132 /// @param newMaximumNumberOfIterations: 
00133 /// Maximum number of iterations for optimization.
00134 
00135 void RandomSearch
00136 ::setMaximumNumberOfIterations(int newMaximumNumberOfIterations)
00137 {
00138    if(newMaximumNumberOfIterations <= 0)
00139    {
00140       std::cout << std::endl
00141                 << "Error: RandomSearch Class." << std::endl
00142                 << "void setMaximumNumberOfIterations(int) method."
00143                 << std::endl
00144                 << "Maximum number of iterations must be greater than 0."
00145                 << std::endl
00146                 << std::endl;
00147 
00148       exit(1);
00149    }
00150 
00151    // Set maximum number of iterations
00152 
00153    maximumNumberOfIterations = newMaximumNumberOfIterations;
00154 }
00155 
00156 
00157 // void setShowPeriod(int) method
00158 
00159 /// This method sets a new number of iterations between the optimization
00160 /// showing progress.
00161 ///
00162 /// @param newShowPeriod: Show period.
00163 
00164 void RandomSearch::setShowPeriod(int newShowPeriod)
00165 {
00166    if(newShowPeriod <= 0)
00167    {
00168       std::cout << std::endl
00169                 << "Error: RandomSearch class." << std::endl
00170                 << "void setShowPeriod(int) method."
00171                 << std::endl
00172                 << "Show period must be greater than 0."
00173                 << std::endl << std::endl;
00174 
00175       exit(1);
00176    }
00177 
00178    // Set show period
00179 
00180    showPeriod = newShowPeriod;
00181 }
00182 
00183 
00184 // void getMinimalArgument(void) method
00185 
00186 /// This method returns the miminal argument of the associated 
00187 /// objective function according to the random search optimization algorithm.
00188 /// Optimization occurs according to the optimization parameters. 
00189 
00190 Vector<double> RandomSearch::getMinimalArgument(void)
00191 {
00192    int numberOfVariables = objectiveFunction->getNumberOfVariables();   
00193 
00194    Vector<double> minimalArgument(numberOfVariables, 0.0);
00195 
00196    double bestEvaluation = 0.0;
00197    
00198    Vector<double> argument(numberOfVariables, 0.0);
00199         
00200    double evaluation = 0.0;
00201    
00202    // Evaluation history vector
00203 
00204    Vector<double> newEvaluationHistory(maximumNumberOfIterations, 0.0);
00205 
00206    evaluationHistory = newEvaluationHistory;
00207 
00208    // Objective function domain   
00209    
00210    Vector<double> lowerBound = objectiveFunction->getLowerBound();
00211    Vector<double> upperBound = objectiveFunction->getUpperBound();
00212     
00213    time_t beginningTime, currentTime;
00214 
00215    double elapsedTime = 0.0;
00216 
00217    // Set beginning time 
00218 
00219    time(&beginningTime);
00220 
00221    std::cout << std::endl
00222              << "Getting minimal argument with random search..." 
00223              << std::endl;
00224  
00225    // Initial objective function evaluation
00226 
00227    for(int i = 0; i < numberOfVariables; i++)
00228    {
00229       double random = (double)rand()/(RAND_MAX+1.0);
00230 
00231       argument[i] = lowerBound[i] + (upperBound[i]- lowerBound[i])*random;
00232    }
00233       
00234    evaluation = objectiveFunction->getEvaluation(argument);
00235 
00236    // Set best evaluation and minimal argument
00237 
00238    bestEvaluation = evaluation;
00239    minimalArgument = argument;
00240 
00241    evaluationHistory[0] = evaluation;
00242 
00243    if(bestEvaluation <= evaluationGoal)
00244    {          
00245       std::cout << std::endl
00246                 << "Initial evaluation is less than goal." << std::endl
00247                 << "Initial evaluation: " << bestEvaluation << std::endl;
00248 
00249       // Print minimal argument to screen
00250 
00251       std::cout << std::endl
00252                 << "Minimal argument:" << std::endl;
00253    
00254       for(int i = 0; i < numberOfVariables; i++)
00255       {
00256          std::cout << minimalArgument[i] << " ";        
00257       }
00258       
00259       std::cout << std::endl;
00260       
00261       return(minimalArgument);        
00262    }
00263    else
00264    {
00265       std::cout << "Initial evaluation: " <<  bestEvaluation << std::endl;      
00266    }
00267 
00268    // Main loop
00269 
00270    for(int iteration = 1; iteration < maximumNumberOfIterations; iteration++)
00271    {
00272       for(int i = 0; i < numberOfVariables; i++)
00273       {
00274          double random = (double)rand()/(RAND_MAX+1.0);
00275 
00276          argument[i] = lowerBound[i] + (upperBound[i]- lowerBound[i])*random;
00277       }
00278 
00279       evaluation = objectiveFunction->getEvaluation(argument);
00280 
00281       if(evaluation < bestEvaluation)
00282       {
00283          // Set best evaluation              
00284                     
00285          bestEvaluation = evaluation;
00286 
00287          // Set minimal argument
00288 
00289          minimalArgument = argument;         
00290       }
00291 
00292       evaluationHistory[iteration] = bestEvaluation;
00293 
00294       // Stopping Criteria
00295 
00296       // Evaluation goal 
00297 
00298       if (evaluation <= evaluationGoal)
00299       {
00300          std::cout << "Iteration " << iteration << ": " 
00301                    << "Evaluation goal reached." << std::endl; 
00302 
00303          std::cout << "Final evaluation: " << bestEvaluation << ";" << std::endl;
00304 
00305          objectiveFunction->print(argument);
00306 
00307          break;
00308       }
00309 
00310       // Maximum time
00311 
00312       time(&currentTime);
00313 
00314       elapsedTime = difftime(currentTime, beginningTime);
00315 
00316       if (elapsedTime >= maximumTime)
00317       {
00318          std::cout << "Iteration " << iteration << ": "
00319                    << "Maximum time reached." 
00320                    << std::endl;
00321 
00322          std::cout << "Final evaluation: " << bestEvaluation << ";" << std::endl;
00323 
00324          objectiveFunction->print(argument);
00325 
00326          break;
00327       }
00328 
00329       // Maximum number of iterations
00330 
00331       if (iteration == maximumNumberOfIterations-1)
00332       {
00333          std::cout << "Iteration " << iteration << ": " 
00334                    << "Maximum number of iterations reached." 
00335                    << std::endl;
00336 
00337          std::cout << "Final evaluation: " << bestEvaluation << ";" << std::endl;
00338 
00339          objectiveFunction->print(argument);
00340 
00341          break;
00342       }
00343 
00344       // Progress
00345 
00346       if(iteration % showPeriod == 0)                   
00347       {
00348          std::cout << "Iteration " << iteration << "; " << std::endl
00349                    << "Best evaluation: " << bestEvaluation << std::endl;
00350 
00351          objectiveFunction->print(argument);
00352       }
00353    }
00354 
00355    // Print minimal argument to screen
00356 
00357    std::cout << std::endl
00358              << "Minimal argument:" << std::endl;
00359    
00360    for(int i = 0; i < numberOfVariables; i++)
00361    {
00362       std::cout << minimalArgument[i] << " ";        
00363    }
00364    
00365    std::cout << std::endl;
00366    
00367    return(minimalArgument);
00368 }
00369 
00370 
00371 // void print(void) method
00372 
00373 /// This method prints to the screen 
00374 /// the optimization parameters concerning the random search object:
00375 ///
00376 /// Stopping criteria:
00377 /// <ul> 
00378 /// <li> Evaluation goal.
00379 /// <li> Gradient norm goal.
00380 /// <li> Maximum time.
00381 /// <li> Maximum number of iterations. 
00382 /// </ul> 
00383 ///  
00384 /// User stuff: 
00385 /// <ul>
00386 /// <li> Show period. 
00387 /// </ul>
00388 
00389 void RandomSearch::print(void)
00390 {
00391    std::cout << std::endl
00392              << "RandomSearch Object." << std::endl;
00393 
00394    // Stopping criteria
00395 
00396    std::cout << std::endl
00397              << "Stopping criteria: " << std::endl
00398              << "Evaluation goal: " << std::endl
00399              << evaluationGoal << std::endl
00400              << "Maximum time: " << std::endl
00401              << maximumTime << std::endl
00402              << "Maximum number of iterations: " << std::endl
00403              << maximumNumberOfIterations << std::endl;
00404 
00405    // User stuff
00406 
00407    std::cout << std::endl
00408              << "User stuff: " << std::endl
00409              << "Show period: " << std::endl
00410              << showPeriod
00411              << std::endl;
00412 }
00413 
00414 
00415 
00416 // void save(char*) method
00417 
00418 /// This method saves the random search object to a data file. 
00419 ///
00420 /// Stopping criteria:
00421 /// <ul> 
00422 /// <li> Evaluation goal.
00423 /// <li> Maximum time.
00424 /// <li> Maximum number of evaluations. 
00425 /// </ul> 
00426 ///  
00427 /// User stuff: 
00428 /// <ul>
00429 /// <li> Evaluations between showing progress. 
00430 /// </ul>
00431 ///
00432 /// @param filename: Filename.
00433 ///
00434 /// @see load(char*).
00435 
00436 void RandomSearch::save(char* filename)
00437 {
00438 
00439    int numberOfVariables = objectiveFunction->getNumberOfVariables();   
00440 
00441    // File
00442 
00443    std::fstream file;
00444 
00445    file.open(filename, std::ios::out);
00446 
00447    if(!file.is_open())
00448    {
00449       std::cout << std::endl 
00450                 << "Error: RandomSearch class." << std::endl
00451                 << "void save(char*) method." << std::endl
00452                 << "Cannot open random search object data file."  << std::endl
00453                 << std::endl;
00454 
00455       exit(1);
00456    }
00457    else
00458    {
00459       std::cout << std::endl
00460                 << "Saving random search object to data file..." << std::endl;
00461    }
00462 
00463    // Write file header
00464 
00465    file << "% Purple: An Open Source Numerical Optimization C++ Library." 
00466         << std::endl 
00467         << "% Random Search Object." << std::endl; 
00468 
00469    // Stopping criteria
00470 
00471    file << "EvaluationGoal:" << std::endl
00472         << evaluationGoal << std::endl
00473         << "MaximumTime: " << std::endl
00474         << maximumTime << std::endl
00475         << "MaximumNumberOfEvaluations: " << std::endl
00476         << maximumNumberOfIterations << std::endl;
00477 
00478    // User stuff
00479 
00480    file << "ShowPeriod: " << std::endl
00481         << showPeriod << std::endl;
00482 
00483    file.close();
00484 }
00485 
00486 
00487 // void load(char*) method
00488 
00489 /// This method loads a random search object from a data file. 
00490 /// Please mind about the file format, wich is specified in the User's Guide. 
00491 ///
00492 /// Stopping criteria:
00493 /// <ul> 
00494 /// <li> Evaluation goal.
00495 /// <li> Maximum time.
00496 /// <li> Maximum number of evaluations. 
00497 /// </ul> 
00498 ///  
00499 /// User stuff: 
00500 /// <ul>
00501 /// <li> Evaluations between showing progress. 
00502 /// </ul>
00503 ///
00504 /// @param filename: Filename.
00505 ///
00506 /// @see save(char*).
00507 
00508 void RandomSearch::load(char* filename)
00509 {
00510    // File
00511 
00512    std::fstream file;
00513 
00514    file.open(filename, std::ios::in);
00515 
00516    if(!file.is_open())
00517    {
00518       std::cout << std::endl
00519                 << "Error: RandomSearch class." << std::endl
00520                 << "void load(char*) method." << std::endl
00521                 << "Cannot open random search object data file."  << std::endl;
00522 
00523       exit(1);
00524    }
00525    else
00526    {
00527       std::cout << std::endl
00528                 << "Loading random seach object from data file..."  << std::endl;
00529    }
00530 
00531    std::string word;
00532 
00533 
00534    // Stopping criteria: 
00535 
00536    // Initial argument
00537 
00538    while(word != "EvaluationGoal:")
00539    {
00540       file >> word;
00541    }
00542 
00543    file >> evaluationGoal;
00544 
00545    // Maximum time
00546 
00547    file >> word;
00548 
00549    file >> maximumTime;
00550 
00551    // Maximum number of iterations
00552 
00553    file >> word;
00554 
00555    file >> maximumNumberOfIterations;
00556 
00557    // User stuff: 
00558 
00559    // Iterations between showing progress
00560 
00561    file >> word;
00562 
00563    file >> showPeriod;
00564 
00565    // Close file
00566 
00567    file.close();
00568 }
00569 
00570 
00571 // void saveOptimizationHistory(char*) method 
00572 
00573 /// This method saves the optimization history to a data file. 
00574 ///
00575 /// <ol>
00576 /// <li> Iteration.
00577 /// <li> Objective function evaluation.
00578 /// </ol>
00579 ///
00580 /// @param filename: Filename.
00581 
00582 void RandomSearch::saveOptimizationHistory(char* filename)
00583 {
00584    std::fstream file; 
00585 
00586    file.open(filename, std::ios::out);
00587 
00588    if(!file.is_open())
00589    {
00590       std::cout << std::endl 
00591                 << "Error: RandomSearch class. "
00592                 << "void saveOptimizationHistory(char*) method." << std::endl
00593                 << "Cannot open optimization history data file." << std::endl
00594                 << std::endl;
00595 
00596       exit(1);
00597    }
00598    else
00599    {
00600       std::cout << std::endl 
00601                 << "Saving optimization history to data file..." << std::endl;
00602    }
00603 
00604    // Write file header
00605 
00606    file << "% Purple: An Open Source Numerical Optimization C++ Library." 
00607         << std::endl 
00608         << "% Gradient Descent Optimization History." << std::endl
00609         << "% 1 - Iteration." << std::endl
00610         << "% 2 - Objective function evaluation." << std::endl;
00611 
00612    // Write file data
00613 
00614    int size = evaluationHistory.getSize();
00615 
00616    for (int i = 0; i < size; i++)
00617    {
00618       file << i << " "
00619            << evaluationHistory[i] << std::endl;
00620    }
00621 
00622    file << std::endl;
00623 
00624    file.close();
00625 }
00626 
00627 }
00628 
00629 
00630 // Purple: An Open Source Numerical Optimization C++ Library.
00631 // Copyright (C) 2006 Roberto Lopez 
00632 //
00633 // This library is free software; you can redistribute it and/or
00634 // modify it under the terms of the GNU Lesser General Public
00635 // License as published by the Free Software Foundation; either
00636 // version 2.1 of the License, or any later version.
00637 //
00638 // This library is distributed in the hope that it will be useful,
00639 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00640 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00641 // Lesser General Public License for more details.
00642 
00643 // You should have received a copy of the GNU Lesser General Public
00644 // License along with this library; if not, write to the Free Software
00645 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

Generated on Wed Jun 21 13:10:38 2006 for Purple by  doxygen 1.4.7