EvolutionaryAlgorithm.cpp

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*   E V O L U T I O N A R Y   A L G O R I T H M   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 "EvolutionaryAlgorithm.h"
00021 
00022 namespace Purple
00023 {
00024 
00025 // GENERAL CONSTRUCTOR 
00026 //
00027 /// General constructor. It creates an evolutionary optimization
00028 /// algorithm object associated to an objective function object. 
00029 /// Population is initialized at random within the objective function domain.
00030 /// The constructor also initializes the class members to their default values:
00031 ///
00032 /// Optimization operators:
00033 /// <ul>
00034 /// <li> Fitness assignment method: Linear ranking.
00035 /// <li> Selection method: Stochastic universal sampling.
00036 /// <li> Recombination method: Intermediate.
00037 /// <li> Mutation method: Normal.
00038 /// </ul>
00039 ///
00040 /// Optimization parameters:
00041 /// <ul>
00042 /// <li> Population size: 10 * [number of free parameters].
00043 /// <li> Selective pressure: 1.5.
00044 /// <li> Recombination size: 0.25.
00045 /// <li> Mutation rate: = 1.0 / [number of free parameters].
00046 /// <li> Mutation range: = 0.1
00047 /// </ul>
00048 ///
00049 /// Stopping criteria:
00050 /// <ul> 
00051 /// <li> Evaluation goal: 0.0.
00052 /// <li> Maximum time: 1.0e6.
00053 /// <li> Maximum number of generations: 100.
00054 /// </ul> 
00055 ///  
00056 /// User stuff: 
00057 /// <ul>
00058 /// <li> Generations between showing progress: 10.
00059 /// </ul>
00060 ///
00061 /// @param newObjectiveFunction: Pointer to an objective function object.
00062 
00063 EvolutionaryAlgorithm::EvolutionaryAlgorithm(ObjectiveFunction* newObjectiveFunction)
00064 : OptimizationAlgorithm(newObjectiveFunction)
00065 {
00066    int numberOfVariables = objectiveFunction->getNumberOfVariables();
00067 
00068    // Fitness assignment method
00069 
00070    fitnessAssignmentMethod = LinearRanking;
00071 
00072    // Selection method
00073 
00074    selectionMethod = RouletteWheel;
00075 
00076    // Recombination method
00077 
00078    recombinationMethod = Intermediate;
00079 
00080    // Mutation method
00081 
00082    mutationMethod = Normal;
00083 
00084    // Optimization parameters
00085 
00086    if(numberOfVariables == 0)
00087    {                     
00088       populationSize = 0;
00089 
00090       selectivePressure = 0.0;
00091 
00092       recombinationSize = 0.0;
00093 
00094       mutationRate = 0.0;
00095       mutationRange = 0.0;
00096    }
00097    else
00098    {
00099       populationSize = 10*numberOfVariables;
00100 
00101       selectivePressure = 1.5;
00102 
00103       recombinationSize = 0.25;
00104 
00105       mutationRate = 1.0/numberOfVariables;
00106       mutationRange = 0.1;       
00107    }
00108 
00109    // Stopping criteria
00110 
00111    evaluationGoal = -1.0e69;
00112    maximumTime = 1.0e69;
00113 
00114    maximumNumberOfGenerations = 100;
00115 
00116    showPeriod = 1;
00117 
00118    // Population matrix
00119 
00120    Vector<double> lowerBound = objectiveFunction->getLowerBound();
00121    Vector<double> upperBound = objectiveFunction->getUpperBound();
00122 
00123    Matrix<double> newPopulation(populationSize, numberOfVariables, 0.0);
00124 
00125    for(int i = 0; i < populationSize; i++)
00126    {
00127       for(int j = 0; j < numberOfVariables; j++)
00128       {
00129          double random = (double)rand()/(RAND_MAX+1.0);
00130 
00131          newPopulation[i][j]  
00132          = lowerBound[j] + (upperBound[j] - lowerBound[j])*random;         
00133       }
00134    }
00135 
00136    population = newPopulation;
00137 
00138    // Evaluation vector
00139 
00140    Vector<double> newEvaluation(populationSize, 0.0);
00141 
00142    evaluation = newEvaluation;
00143 
00144    // Fitness vector
00145 
00146    Vector<double> newFitness(populationSize, 0.0);
00147 
00148    fitness = newFitness;
00149 
00150    // Selection vector
00151 
00152    Vector<bool> newSelection(populationSize, false);
00153 
00154    selection = newSelection;
00155 }
00156 
00157 
00158 // DEFAULT CONSTRUCTOR
00159 //
00160 /// Default constructor. It creates an evolutionary algorithm object
00161 /// not associated to any objective function object. 
00162 /// It also initializes the class members to their default values:
00163 ///
00164 /// Optimization operators:
00165 /// <ul>
00166 /// <li> Fitness assignment method: Linear ranking.
00167 /// <li> Selection method: Stochastic universal sampling.
00168 /// <li> Recombination method: Intermediate.
00169 /// <li> Mutation method: Normal.
00170 /// </ul>
00171 ///
00172 /// Optimization parameters:
00173 /// <ul>
00174 /// <li> Population size: 0.
00175 /// <li> Selective pressure: 0.0.
00176 /// <li> Recombination size: 0.0.
00177 /// <li> Mutation rate: = 0.0.
00178 /// <li> Mutation range: = 0.0.
00179 /// </ul>
00180 ///
00181 /// Stopping criteria:
00182 /// <ul> 
00183 /// <li> Evaluation goal: -1.0e69.
00184 /// <li> Maximum time: 1.0e6.
00185 /// <li> Maximum number of generations: 100.
00186 /// </ul> 
00187 ///  
00188 /// User stuff: 
00189 /// <ul>
00190 /// <li> Generations between showing progress: 10.
00191 /// </ul>
00192 
00193 EvolutionaryAlgorithm::EvolutionaryAlgorithm(void) : OptimizationAlgorithm()
00194 {
00195    // Fitness assignment method
00196 
00197    fitnessAssignmentMethod = LinearRanking;
00198 
00199    // Selection method
00200 
00201    selectionMethod = StochasticUniversalSampling;
00202 
00203    // Recombination method
00204 
00205    recombinationMethod = Intermediate;
00206 
00207    // Mutation method
00208 
00209    mutationMethod = Normal;
00210 
00211    // Optimization parameters
00212 
00213    populationSize = 0;
00214 
00215    selectivePressure = 0.0;
00216 
00217    recombinationSize = 0.0;
00218 
00219    mutationRate = 0.0;
00220    mutationRange = 0.0;
00221 
00222    // Stopping criteria
00223 
00224    evaluationGoal = -1.0e69;
00225    maximumTime = 1.0e69;
00226 
00227    maximumNumberOfGenerations = 100;
00228 
00229    showPeriod = 1;
00230 }
00231 
00232 // DESTRUCTOR
00233 
00234 /// Destructor.
00235 
00236 EvolutionaryAlgorithm::~EvolutionaryAlgorithm(void)
00237 {
00238 
00239 }
00240 
00241 
00242 // METHODS
00243 
00244 // int getPopulationSize(void) method
00245 
00246 /// This method returns the number of individuals in the population.
00247 
00248 int EvolutionaryAlgorithm::getPopulationSize(void)
00249 {
00250    return(populationSize);
00251 }
00252 
00253 
00254 // void setMaximumNumberOfGenerations(int) method
00255 
00256 /// This method sets a new maximum number of generations in the evolutionary 
00257 /// algorithm optimization process.
00258 ///
00259 /// @param newMaximumNumberOfGenerations:
00260 /// Maximum number of generations.
00261 
00262 void EvolutionaryAlgorithm
00263 ::setMaximumNumberOfGenerations(int newMaximumNumberOfGenerations)
00264 {
00265    if(newMaximumNumberOfGenerations <= 0)
00266    {
00267       std::cout << std::endl
00268                 << "Error: EvolutionaryAlgorithm class. "
00269                 << "void setMaximumNumberOfGenerations(int) method."
00270                 << std::endl
00271                 << "Maximum number of generations must be greater than 0."
00272                 << std::endl << std::endl;
00273 
00274       exit(1);
00275    }
00276    
00277    // Set maximum number of generations
00278 
00279    maximumNumberOfGenerations = newMaximumNumberOfGenerations;
00280 }
00281 
00282 // void setShowPeriod(int) method
00283 
00284 /// This method sets a new number of generations between the optimization
00285 /// showing progress.
00286 ///
00287 /// @param newShowPeriod:
00288 /// Number of generations between the optimization showing progress.
00289 
00290 void EvolutionaryAlgorithm::setShowPeriod(int newShowPeriod)
00291 {
00292    if(newShowPeriod <= 0)
00293    {
00294       std::cout << std::endl
00295                 << "Error: void setShowPeriod(int) method."
00296                 << std::endl
00297                 << "Show period must be greater than 0."
00298                 << std::endl << std::endl;
00299 
00300       exit(1);
00301    }
00302    
00303    // Set show period
00304    
00305    showPeriod = newShowPeriod;
00306 }
00307 
00308 
00309 // Vector<double> getMeanEvaluationHistory(void) method
00310 
00311 /// This method returns a history with the mean evaluation of the population 
00312 /// during optimization. 
00313 ///
00314 /// @see getBestEvaluationHistory(void).
00315 /// @see getStandardDeviationOfEvaluationHistory(void).
00316 
00317 Vector<double> EvolutionaryAlgorithm::getMeanEvaluationHistory(void)
00318 {
00319    return(meanEvaluationHistory);
00320 }
00321 
00322 
00323 // Vector<double> getStandardDeviationEvaluationHistory(void) method
00324 
00325 /// This method returns a history with the standard deviation of the population  
00326 /// evaluation during optimization. 
00327 ///
00328 /// @see getBestEvaluationHistory(void).
00329 /// @see getMeanEvaluationHistory(void).
00330 
00331 Vector<double> EvolutionaryAlgorithm::getStandardDeviationEvaluationHistory(void)
00332 {
00333    return(standardDeviationEvaluationHistory);
00334 }
00335 
00336 
00337 // Vector<double> getBestEvaluationHistory(void) method
00338 
00339 /// This method returns a history with the evaluation value of the best individual 
00340 /// ever during optimization. 
00341 ///
00342 /// @see getMeanEvaluationHistory(void).
00343 /// @see getStandardDeviationEvaluationHistory(void).
00344 
00345 Vector<double> EvolutionaryAlgorithm::getBestEvaluationHistory(void)
00346 {
00347    return(bestEvaluationHistory);
00348 }
00349 
00350 
00351 // int getShowPeriod(void) method
00352 
00353 /// This method returns the number of generations between the 
00354 /// evolutionary algorithm optimization showing progress. 
00355 
00356 int EvolutionaryAlgorithm::getShowPeriod(void)
00357 {
00358    return(showPeriod);    
00359 }
00360 
00361 
00362 // void setPopulationSize(int) method
00363 //
00364 /// This method sets a new population with a new number of individuals.  
00365 /// The new population size must be an even number equal or greater than four. 
00366 ///
00367 /// @param newPopulationSize: Number of individuals in the population.
00368 /// This must be an even number equal or greater than four. 
00369 
00370 void EvolutionaryAlgorithm::setPopulationSize(int newPopulationSize)
00371 {
00372    if(newPopulationSize < 4)
00373    {
00374       std::cout << std::endl
00375                 << "Error: EvolutionaryAlgorithm class. " << std::endl
00376                 << "void setPopulationSize(int) method." << std::endl
00377                 << "New population size must be equal or greater than 4."
00378                 << std::endl << std::endl;
00379 
00380       exit(1);
00381    }
00382    else if(newPopulationSize%2 != 0)
00383    {
00384       std::cout << std::endl
00385                 << "Error: EvolutionaryAlgorithm class. "
00386                 << "void setPopulationSize(int) method." << std::endl
00387                 << "New population size is not divisible by 2." << std::endl
00388                 << std::endl;
00389 
00390       exit(1);
00391    }
00392 
00393    // Set population size
00394 
00395    populationSize = newPopulationSize;
00396 
00397    // Set population matrix
00398 
00399    Vector<double> lowerBound = objectiveFunction->getLowerBound();
00400    Vector<double> upperBound = objectiveFunction->getUpperBound();
00401 
00402    int numberOfVariables = objectiveFunction->getNumberOfVariables();
00403 
00404    Matrix<double> newPopulation(populationSize, numberOfVariables, 0.0);
00405 
00406    for(int i = 0; i < populationSize; i++)
00407    {
00408       for(int j = 0; j < numberOfVariables; j++)
00409       {
00410          double random = (double)rand()/(RAND_MAX+1.0);
00411 
00412          newPopulation[i][j] = lowerBound[j] 
00413          + (upperBound[j] - lowerBound[j])*random;
00414       }
00415    }
00416 
00417    population = newPopulation;
00418 
00419    // Set evaluation vector
00420 
00421    Vector<double> newEvaluation(populationSize, 0.0);
00422 
00423    evaluation = newEvaluation;
00424 
00425    // Set fitness vector
00426 
00427    Vector<double> newFitness(populationSize, 0.0);
00428 
00429    fitness = newFitness;
00430 
00431    // Set selection vector
00432 
00433    Vector<bool> newSelection(populationSize, false);
00434 
00435    selection = newSelection;
00436 }
00437 
00438 
00439 // Population stuff
00440 
00441 // Matrix<double> getPopulation(void) method
00442 
00443 /// This method returns the population Matrix.
00444 
00445 Matrix<double> EvolutionaryAlgorithm::getPopulation(void)
00446 {
00447    return(population);
00448 }
00449 
00450 
00451 // Vector<double> getEvaluation(void) method
00452 
00453 /// This method returns the actual evaluation value of all individuals in the 
00454 /// population.
00455 ///
00456 /// @see getFitness(void).
00457 /// @see getSelection(void).
00458 
00459 Vector<double> EvolutionaryAlgorithm::getEvaluation(void)
00460 {
00461    return(evaluation);
00462 }
00463 
00464 
00465 // Vector<double> getFitness(void) method
00466 
00467 /// This method returns the actual fitness value of all individuals in the population.
00468 ///
00469 /// @see getEvaluation(void).
00470 /// @see getSelection(void).
00471 
00472 Vector<double> EvolutionaryAlgorithm::getFitness(void)
00473 {
00474    return(fitness);
00475 }
00476 
00477 
00478 // Vector<bool> getSelection(void) method
00479 
00480 /// This method returns the actual selection value of all individuals in the population.
00481 ///
00482 /// @see getEvaluation(void).
00483 /// @see getFitness(void).
00484 
00485 Vector<bool> EvolutionaryAlgorithm::getSelection(void)
00486 {
00487    return(selection);
00488 }
00489 
00490 
00491 // void setPopulation(Matrix<double>) method
00492 
00493 /// This method sets a new population.
00494 ///
00495 /// @param newPopulation: Population Matrix.
00496 
00497 void EvolutionaryAlgorithm::setPopulation(Matrix<double> newPopulation)
00498 {
00499 
00500    int numberOfVariables = objectiveFunction->getNumberOfVariables();
00501 
00502    if(newPopulation.getNumberOfRows() != populationSize)
00503    {
00504       std::cout << std::endl
00505                 << "Error: EvolutionaryAlgorithm class. " << std::endl
00506                 << "void setPopulation(Matrix<double>) method." << std::endl
00507                 << "New population size is not equal to population size."
00508                 << std::endl << std::endl;
00509 
00510       exit(1);
00511    }
00512    else if(newPopulation.getNumberOfColumns() != numberOfVariables)
00513    {
00514       std::cout << std::endl
00515                 << "Error: EvolutionaryAlgorithm class. "
00516                 << "void setPopulation(Matrix<double>) method." << std::endl
00517                 << "New number of free parameters is not equal to "
00518                 << "number of free parameters." << std::endl
00519                 << std::endl;
00520 
00521       exit(1);
00522    }
00523 
00524    // Set population matrix
00525 
00526    population = newPopulation;
00527 }
00528 
00529 
00530 // void setEvaluation(Vector<double>) method
00531 
00532 /// This method sets a new population evaluation Vector.
00533 ///
00534 /// @param newEvaluation: Population evaluation values.
00535 
00536 void EvolutionaryAlgorithm::setEvaluation(Vector<double> newEvaluation)
00537 {
00538    if(newEvaluation.getSize() != populationSize)
00539    {
00540       std::cout << std::endl
00541                 << "Error: EvolutionaryAlgorithm class. " << std::endl
00542                 << "void setEvaluation(Vector<double>) method." << std::endl
00543                 << "Size is not equal to population size." << std::endl;
00544 
00545       exit(1);
00546    }
00547 
00548    // Set evaluation vector
00549 
00550    evaluation = newEvaluation;
00551 }
00552 
00553 
00554 // void setFitness(Vector<double>) method
00555 
00556 /// This method sets a new population fitness Vector.
00557 ///
00558 /// @param newFitness: Population fitness values.
00559 
00560 void EvolutionaryAlgorithm::setFitness(Vector<double> newFitness)
00561 {
00562    if(newFitness.getSize() != populationSize)
00563    {
00564       std::cout << std::endl
00565                 << "Error: EvolutionaryAlgorithm class. " << std::endl
00566                 << "void setFitness(Vector<double>) method." << std::endl
00567                 << "Size is not equal to population size." << std::endl;
00568 
00569       exit(1);
00570    }
00571 
00572    // Set fitness vector
00573 
00574    fitness = newFitness;
00575 }
00576 
00577 
00578 // void setSelection(Vector<bool>) method
00579 
00580 /// This method sets a new population selection Vector.
00581 ///
00582 /// @param newSelection: Population selection values.
00583 
00584 void EvolutionaryAlgorithm::setSelection(Vector<bool> newSelection)
00585 {
00586    if(newSelection.getSize() != populationSize)
00587    {
00588       std::cout << std::endl
00589                 << "Error: EvolutionaryAlgorithm class." << std::endl
00590                 << "void setSelection(Vector<double>) method." << std::endl
00591                 << "Size is not equal to population size." << std::endl
00592                 << std::endl;
00593 
00594       exit(1);
00595    }
00596    
00597    // Set selection vector
00598    
00599    selection = newSelection;
00600 }
00601 
00602 
00603 // Vector<double> getIndividual(int) method
00604 
00605 /// This method returns the Vector of free parameters corresponding to the 
00606 /// individual i in the population.
00607 ///
00608 /// @param i: Index of individual in the population.
00609 
00610 Vector<double> EvolutionaryAlgorithm::getIndividual(int i)
00611 {
00612    int numberOfVariables = objectiveFunction->getNumberOfVariables();
00613 
00614    Vector<double> individual(numberOfVariables, 0.0);
00615 
00616    for(int j = 0; j < numberOfVariables; j++)
00617    {
00618       individual[j] = population[i][j];
00619    }
00620 
00621    return(individual);
00622 }
00623 
00624 
00625 // setIndividual(int, Vector<double>) method
00626 
00627 /// This method sets a new Vector of free parameters to the individual i in the 
00628 /// population. 
00629 ///
00630 /// @param i: Index of individual in the population.
00631 /// @param individual: Vector of free parameters to be assigned to individual i.
00632 
00633 void EvolutionaryAlgorithm::setIndividual(int i, Vector<double> individual)
00634 {
00635    int numberOfVariables = objectiveFunction->getNumberOfVariables();
00636 
00637    for(int j = 0; j < numberOfVariables; j++)
00638    {
00639       population[i][j] = individual[j];
00640    }
00641 }
00642 
00643 
00644 // Optimization parameters
00645 
00646 // double getSelectivePressure(void) method
00647 
00648 /// This method returns the selective pressure value.
00649 ///
00650 /// @see performLinearRankingFitnessAssignment(void).
00651 /// @see performNonLinearRankingFitnessAssignment(void).
00652 
00653 double EvolutionaryAlgorithm::getSelectivePressure(void)
00654 {
00655    return(selectivePressure);
00656 }
00657 
00658 
00659 // double getRecombinationSize(void) method
00660 
00661 /// This method returns the recombination size value.
00662 ///
00663 /// @see performIntermediateRecombination(void)
00664 /// @see performLineRecombination(void).
00665 
00666 double EvolutionaryAlgorithm::getRecombinationSize(void)
00667 {
00668    return(recombinationSize);
00669 }
00670 
00671 
00672 // double getMutationRate(void) method
00673 
00674 /// This method returns the mutation rate value.
00675 ///
00676 ///  @see performNormalMutation(void).
00677 ///  @see performUniformMutation(void).
00678 
00679 double EvolutionaryAlgorithm::getMutationRate(void)
00680 {
00681    return(mutationRate);
00682 }
00683 
00684 
00685 // double getMutationRange(void) method
00686 
00687 /// This method returns the mutation range value.
00688 ///
00689 ///  @see performNormalMutation(void).
00690 ///  @see performUniformMutation(void).
00691 
00692 double EvolutionaryAlgorithm::getMutationRange(void)
00693 {
00694    return(mutationRange);
00695 }
00696 
00697 
00698 // FitnessAssignmentMethod getFitnessAssignmentMethod(void) method
00699 
00700 /// This method returns the fitness assignment method used for optimization.
00701 ///
00702 /// @see performLinearRankingFitnessAssignment(void).
00703 /// @see performNonLinearRankingFitnessAssignment(void).
00704  
00705 EvolutionaryAlgorithm::FitnessAssignmentMethod
00706 EvolutionaryAlgorithm::getFitnessAssignmentMethod(void)
00707 {
00708    return(fitnessAssignmentMethod);
00709 }
00710 
00711 
00712 // SelectionMethod getSelectionMethod(void) method
00713 
00714 /// This method returns the selection method used for optimization.
00715 ///
00716 /// @see performRouletteWheelSelection(void).
00717 /// @see performStochasticUniversalSamplingSelection(void).
00718 
00719 EvolutionaryAlgorithm::SelectionMethod 
00720 EvolutionaryAlgorithm::getSelectionMethod(void)
00721 {
00722    return(selectionMethod);
00723 }
00724 
00725 
00726 // RecombinationMethod getRecombinationMethod(void) method
00727 
00728 /// This method returns the recombination method used for optimization.
00729 ///
00730 /// @see performIntermediateRecombination(void).
00731 /// @see performLineRecombination(void).
00732 
00733 EvolutionaryAlgorithm::RecombinationMethod EvolutionaryAlgorithm::getRecombinationMethod(void)
00734 {
00735    return(recombinationMethod);
00736 }
00737 
00738 
00739 // MutationMethod getMutationMethod(void) method
00740 
00741 /// This method returns the mutation method used for optimization.
00742 ///
00743 /// @see performNormalMutation(void).
00744 /// @see performUniformMutation(void).
00745 
00746 EvolutionaryAlgorithm::MutationMethod EvolutionaryAlgorithm::getMutationMethod(void)
00747 {
00748    return(mutationMethod);
00749 }
00750 
00751 
00752 // void setSelectivePressure(double) method
00753 
00754 /// This method sets a new value for the selective pressure parameter.
00755 /// Linear ranking allows values for the selective pressure between 1 and 2.
00756 /// Non linear ranking allows values for the selective pressure between 1
00757 /// and [population size] - 2.
00758 ///
00759 /// @param newSelectivePressure: Selective pressure value. This must be between 1 and 2 
00760 /// for linear ranking fitness assignment and between 1 1 and [population size] - 2 
00761 /// for non linear ranking fitness assignment. 
00762 ///
00763 /// @see performLinearRankingFitnessAssignment(void).
00764 /// @see performNonLinearRankingFitnessAssignment(void).
00765 
00766 void EvolutionaryAlgorithm::setSelectivePressure(double newSelectivePressure)
00767 {
00768    switch(fitnessAssignmentMethod)
00769    {
00770       case LinearRanking:
00771 
00772          if((newSelectivePressure < 1.0) || (newSelectivePressure > 2.0))
00773          {
00774             std::cout << std::endl
00775                       << "Error: EvolutionaryAlgorithm class. " << std::endl
00776                       << "void setSelectivePressure(double) method. "
00777                       << "Case linear ranking." << std::endl
00778                       << "Selective pressure must be a value between 1 and 2."
00779                       << std::endl << std::endl;
00780 
00781             exit(1);
00782          }
00783 
00784          selectivePressure = newSelectivePressure;
00785 
00786       break;
00787 
00788       case NonLinearRanking:
00789 
00790          if((newSelectivePressure < 1.0) || (newSelectivePressure > populationSize-2))
00791          {
00792             std::cout << std::endl
00793                       << "Error: EvolutionaryAlgorithm class. "
00794                       << "void setSelectivePressure(double) method. "
00795                       << "Case non linear ranking." << std::endl
00796                       << "Selective pressure must be a value between 1 "
00797                       << "and population size - 2."
00798                       << std::endl << std::endl;
00799 
00800             exit(1);
00801          }
00802 
00803          selectivePressure = newSelectivePressure;
00804 
00805       break;
00806    }
00807 }
00808 
00809 
00810 // void setRecombinationSize(double) method
00811 
00812 /// This method sets a new value for the recombination size parameter.
00813 /// The recombination size value must be equal or greater than 0.
00814 ///
00815 /// @param newRecombinationSize: Recombination size value. This must be equal or greater than 0.
00816 ///
00817 /// @see performIntermediateRecombination(void)
00818 /// @see performLineRecombination(void).
00819 
00820 void EvolutionaryAlgorithm::setRecombinationSize(double newRecombinationSize)
00821 {
00822    if(newRecombinationSize < 0.0)
00823    {
00824       std::cout << std::endl
00825                 << "Error: EvolutionaryAlgorithm class." << std::endl
00826                 << "void setRecombinationSize(double) method." << std::endl
00827                 << "Recombination size must be equal or greater than 0." << std::endl
00828                 << std::endl;
00829 
00830       exit(1);
00831    }
00832 
00833    // Set recombination  size
00834 
00835    recombinationSize = newRecombinationSize;
00836 }
00837 
00838 
00839 // void setMutationRate(double) method
00840 
00841 /// This method sets a new value for the mutation rate parameter.
00842 /// The mutation rate value must be between 0 and 1.
00843 ///
00844 /// @param newMutationRate: Mutation rate value. This must be equal or greater than 0
00845 /// less or equal to 1. 
00846 ///
00847 ///  @see performNormalMutation(void).
00848 ///  @see performUniformMutation(void).
00849 
00850 void EvolutionaryAlgorithm::setMutationRate(double newMutationRate)
00851 {
00852    if(newMutationRate < 0.0 || newMutationRate > 1.0)
00853    {
00854       std::cout << std::endl
00855                 << "Error: EvolutionaryAlgorithm class." << std::endl
00856                 << "void setMutationRate(double) method." << std::endl
00857                 << "Mutation rate must be a value between 0 and 1. " << std::endl
00858                 << std::endl;
00859 
00860       exit(1);
00861    }
00862 
00863    // Set mutation rate
00864 
00865    mutationRate = newMutationRate;
00866 }
00867 
00868 
00869 // void setMutationRange(double) method
00870 
00871 /// This method sets a new value for the mutation range parameter.
00872 /// The mutation range value must be 0 or a positive number. 
00873 ///
00874 /// @param newMutationRange: Mutation range value. This must be equal or greater than 0.
00875 ///
00876 ///  @see performNormalMutation(void).
00877 ///  @see performUniformMutation(void).
00878 
00879 void EvolutionaryAlgorithm::setMutationRange(double newMutationRange)
00880 {
00881    if(newMutationRange < 0.0)
00882    {
00883       std::cout << std::endl
00884                 << "Error: EvolutionaryAlgorithm class." << std::endl
00885                 << "void setMutationRange(double) method." << std::endl
00886                 << "Mutation range must be equal or greater than 0. " << std::endl
00887                 << std::endl;
00888 
00889       exit(1);
00890    }
00891 
00892    // Set mutation range
00893 
00894    mutationRange = newMutationRange;
00895 }
00896 
00897 
00898 // void setFitnessAssignmentMethod(FitnessAssignmentMethod) method
00899 
00900 /// This method sets a new fitness assignment method to be used for optimization.
00901 ///
00902 /// @param newFitnessAssignmentMethod: Fitness assignment method chosen for 
00903 /// optimization.
00904 ///
00905 /// @see performLinearRankingFitnessAssignment(void).
00906 /// @see performNonLinearRankingFitnessAssignment(void).
00907 
00908 void EvolutionaryAlgorithm::setFitnessAssignmentMethod
00909 (EvolutionaryAlgorithm::FitnessAssignmentMethod newFitnessAssignmentMethod)
00910 {
00911    fitnessAssignmentMethod = newFitnessAssignmentMethod;
00912 }
00913 
00914 
00915 // void setSelectionMethod(SelectionMethod) method
00916 
00917 /// This method sets a new selection method to be used for optimization.
00918 ///
00919 /// @param newSelectionMethod: Selection method.
00920 ///
00921 /// @see performRouletteWheelSelection(void).
00922 /// @see performStochasticUniversalSamplingSelection(void).
00923 
00924 void EvolutionaryAlgorithm::setSelectionMethod
00925 (EvolutionaryAlgorithm::SelectionMethod newSelectionMethod)
00926 {
00927    selectionMethod = newSelectionMethod;
00928 }
00929 
00930 
00931 // void setRecombinationMethod(RecombinationMethod) method
00932 
00933 /// This method sets a new recombination method to be used for optimization.
00934 ///
00935 /// @param newRecombinationMethod: Recombination method chosen for optimization. 
00936 ///
00937 /// @see performIntermediateRecombination(void).
00938 /// @see performLineRecombination(void).
00939 
00940 void EvolutionaryAlgorithm::setRecombinationMethod
00941 (EvolutionaryAlgorithm::RecombinationMethod newRecombinationMethod)
00942 {
00943    recombinationMethod = newRecombinationMethod;
00944 }
00945 
00946 
00947 // void setMutationMethod(MutationMethod) method
00948 
00949 /// This method sets a new mutation method to be used for optimization.
00950 ///
00951 /// @param newMutationMethod: Mutation method chosen for optimization. 
00952 ///
00953 /// @see performNormalMutation(void).
00954 /// @see performUniformMutation(void).
00955 
00956 
00957 void EvolutionaryAlgorithm::setMutationMethod
00958 (EvolutionaryAlgorithm::MutationMethod newMutationMethod)
00959 {
00960    mutationMethod = newMutationMethod;
00961 }
00962 
00963 
00964 // void initPopulationAtRandom(void) method
00965 //
00966 /// This method initializes all the individuals in the population at 
00967 /// random, with values comprised between -1 and 1.
00968 ///
00969 /// @see initPopulationAtRandom(double, double).
00970 /// @see initPopulationAtRandom(Vector<double>, Vector<double>).
00971 /// @see initPopulationAtRandom(Matrix<double>).
00972 
00973 void EvolutionaryAlgorithm::initPopulationAtRandom(void)
00974 {
00975    int numberOfVariables = objectiveFunction->getNumberOfVariables();
00976 
00977    Vector<double> individual(numberOfVariables, 0.0);
00978 
00979    for(int i = 0; i < populationSize; i++)
00980    {
00981       individual = getIndividual(i);
00982 
00983       for(int j = 0; j < numberOfVariables; j++)
00984       {
00985          double random = (double)rand()/(RAND_MAX+1.0);
00986 
00987          individual[j] = -1.0 + 2.0*random;
00988       }
00989 
00990       setIndividual(i, individual);
00991    }
00992 }
00993 
00994 
00995 // void initPopulationAtRandom(double, double) method
00996 //
00997 /// This method initializes all the individuals in the population at 
00998 /// random, with values comprised between a minimum and a maximum value.
00999 ///
01000 /// @param minimumValue: Minimum initialization value.
01001 /// @param maximumValue: Maximum initialization value.
01002 ///
01003 /// @see initPopulationAtRandom(void).
01004 /// @see initPopulationAtRandom(Vector<double>, Vector<double>).
01005 /// @see initPopulationAtRandom(Matrix<double>).
01006 
01007 void EvolutionaryAlgorithm
01008 ::initPopulationAtRandom(double minimumValue, double maximumValue)
01009 {
01010    int numberOfVariables = objectiveFunction->getNumberOfVariables();
01011 
01012    Vector<double> individual(numberOfVariables, 0.0);
01013 
01014    for(int i = 0; i < populationSize; i++)
01015    {
01016       individual = getIndividual(i);
01017 
01018       for(int j = 0; j < numberOfVariables; j++)
01019       {
01020          double random = (double)rand()/(RAND_MAX+1.0);
01021 
01022          individual[j] = minimumValue + (maximumValue-minimumValue)*random;
01023       }
01024 
01025       setIndividual(i, individual);
01026    }
01027 }
01028 
01029 
01030 // void initPopulationAtRandom(Vector<double>, Vector<double>) method
01031 
01032 /// This method initializes the free parameters of all the individuals in the population at 
01033 /// random, with values comprised between different minimum and maximum values 
01034 /// for each variable.
01035 ///
01036 /// @param minimumValue: Minimum initialization value.
01037 /// @param maximumValue: Maximum initialization value.
01038 ///
01039 /// @see initPopulationAtRandom(void).
01040 /// @see initPopulationAtRandom(double, double).
01041 /// @see initPopulationAtRandom(Matrix<double>).
01042 
01043 void EvolutionaryAlgorithm
01044 ::initPopulationAtRandom(Vector<double> minimumValue, Vector<double> maximumValue)
01045 {
01046    int minimumValueSize = minimumValue.getSize();
01047    int maximumValueSize = maximumValue.getSize();
01048 
01049    int numberOfVariables = objectiveFunction->getNumberOfVariables();
01050 
01051    if(minimumValueSize != numberOfVariables || maximumValueSize != numberOfVariables)
01052    {
01053       std::cout << std::endl
01054                 << "Error: EvolutionaryAlgorithm class." << std::endl
01055                 << "void initPopulationAtRandom(Vector<double>, Vector<double>)."
01056                 << std::endl
01057                 << "Minimum value and maximum value sizes must be equal "
01058                 << "to number of free parameters." 
01059                 << std::endl << std::endl;
01060  
01061       exit(1);
01062    }
01063 
01064    Vector<double> individual(numberOfVariables, 0.0);
01065 
01066    for(int i = 0; i < populationSize; i++)
01067    {
01068       individual = getIndividual(i);
01069 
01070       for(int j = 0; j < numberOfVariables; j++)
01071       {
01072          double random = (double)rand()/(RAND_MAX+1.0);
01073 
01074          individual[j] = minimumValue[j] + (maximumValue[j]-minimumValue[j])*random;
01075       }
01076 
01077       setIndividual(i, individual);
01078    }
01079 }
01080 
01081 // void initPopulationAtRandom(Matrix<double>) method
01082 
01083 /// This method initializes the free parameters of all the individuals in the population at 
01084 /// random, with values comprised between different minimum and maximum values 
01085 /// for each variable and from a single Matrix.
01086 ///
01087 /// @param minimumAndMaximumValues: Minimum and maximum initialization values.
01088 ///
01089 /// @see initPopulationAtRandom(void).
01090 /// @see initPopulationAtRandom(double, double).
01091 /// @see initPopulationAtRandom(Vector<double>, Vector<double>).
01092 
01093 void EvolutionaryAlgorithm
01094 ::initPopulationAtRandom(Matrix<double> minimumAndMaximumValues)
01095 {
01096    int numberOfRows = minimumAndMaximumValues.getNumberOfRows();
01097    int numberOfColumns = minimumAndMaximumValues.getNumberOfColumns();
01098 
01099    int numberOfVariables = objectiveFunction->getNumberOfVariables();
01100 
01101 
01102    if(numberOfRows != 2 || numberOfColumns != numberOfVariables)
01103    {
01104       std::cout << std::endl
01105                 << "Error: EvolutionaryAlgorithm class."  << std::endl
01106                 << "void initPopulationAtRandom(Matrix<double>)." << std::endl
01107                 << "Number of rows must be two and number of columns must be equal to "
01108                 << "number of free parameters." 
01109                 << std::endl << std::endl;
01110  
01111       exit(1);
01112    }
01113 
01114    Vector<double> minimumValue(numberOfVariables, 0.0);
01115    Vector<double> maximumValue(numberOfVariables, 0.0);
01116 
01117    for(int i = 0; i < numberOfVariables; i++)
01118    {
01119       minimumValue[i] = minimumAndMaximumValues[0][i];
01120       maximumValue[i] = minimumAndMaximumValues[1][i];
01121    }
01122 
01123    Vector<double> individual(numberOfVariables, 0.0);
01124 
01125    for(int i = 0; i < populationSize; i++)
01126    {
01127       individual = getIndividual(i);
01128 
01129       for(int j = 0; j < numberOfVariables; j++)
01130       {
01131          double random = (double)rand()/(RAND_MAX+1.0);
01132 
01133          individual[j] = minimumValue[j] + (maximumValue[j]-minimumValue[j])*random;
01134       }
01135 
01136       setIndividual(i, individual);
01137    }
01138 }
01139 
01140 
01141 // void evaluatePopulation(void) method
01142 //
01143 /// This method evaluates the objective function of all individuals in the
01144 /// population. Results are stored in the evaluation Vector.
01145 
01146 void EvolutionaryAlgorithm::evaluatePopulation(void)
01147 {
01148    int numberOfVariables = objectiveFunction->getNumberOfVariables();
01149 
01150    Vector<double> individual(numberOfVariables, 0.0);
01151 
01152    // Evaluate the objective function for all individuals
01153 
01154    for(int i = 0; i < populationSize; i++)
01155    {
01156       individual = getIndividual(i);
01157 
01158       evaluation[i] = objectiveFunction->getEvaluation(individual);
01159       
01160       if(!(evaluation[i] > -1.0e69 && evaluation[i] < 1.0e69))
01161       {
01162          std::cout << std::endl
01163                    << "Error: EvolutionaryAlgorithm class. " << std::endl
01164                    << "void evaluatePopulation(void) method." << std::endl
01165                    << "Evaluation of individual " << i 
01166                    << " is not a real number." << std::endl
01167                    << std::endl;
01168 
01169          exit(1);
01170       }          
01171    }
01172 }
01173 
01174 
01175 // void performLinearRankingFitnessAssignment(void) method
01176 //
01177 /// This method ranks all individuals in the population by their
01178 /// evaluation value, so that the least fit individual has rank 1 and the
01179 /// fittest individual has rank [population size].
01180 /// It then assigns them a fitness value linearly proportional to their
01181 /// rank. Results are stored in the fitness Vector.
01182 ///
01183 /// @see performNonLinearRankingFitnessAssignment(void).
01184 
01185 void EvolutionaryAlgorithm::performLinearRankingFitnessAssignment(void)
01186 {
01187    // Sorted evaluation vector
01188 
01189    Vector<double> sortedEvaluation(populationSize, 0.0);
01190 
01191    sortedEvaluation = evaluation;
01192 
01193    std::sort(sortedEvaluation.begin(), sortedEvaluation.end(), std::less<double>());
01194 
01195    // Rank vector
01196 
01197    Vector<int> rank(populationSize, 0);
01198 
01199    for(int i = 0; i < populationSize; i++)
01200    {
01201       for(int j = 0; j < populationSize; j++)
01202       {
01203          if(evaluation[j] == sortedEvaluation[i])
01204          {
01205             rank[j] = populationSize - i;
01206          }
01207       }
01208    }
01209 
01210    // Perform linear ranking fitness assignment
01211 
01212    for(int i = 0; i < populationSize; i++)
01213    {
01214       fitness[i] = 2.0 - selectivePressure
01215       + 2.0*(selectivePressure - 1.0)*(rank[i] - 1.0)/(populationSize - 1.0);
01216       
01217       if(!(fitness[i] > -1.0e69 && fitness[i] < 1.0e69))
01218       {
01219          std::cout << std::endl
01220                    << "Error: EvolutionaryAlgorithm class. " << std::endl
01221                    << "void performLinearRankingFitnessAssignment(void) method." 
01222                    << std::endl
01223                    << "Fitness of individual " << i 
01224                    << " is not a real number." << std::endl
01225                    << std::endl;
01226 
01227          exit(1);
01228       }          
01229    }
01230 }
01231 
01232 
01233 // void performNonLinearRankingFitnessAssignment(void) method
01234 //
01235 /// This method ranks all individuals in the population by their 
01236 /// evaluation value, so that the least fit individual has rank 1 and the 
01237 /// fittest individual has rank population size.
01238 /// Please, do not use this method. It is not yet implemented.
01239 ///
01240 /// @see performLinearRankingFitnessAssignment(void).
01241 /// @see getMinimalArgument(void).
01242 
01243 void EvolutionaryAlgorithm::performNonLinearRankingFitnessAssignment(void)
01244 {
01245    std::cout << std::endl
01246              << "Error: EvolutionaryAlgorithm class. " << std::endl
01247              << "void performNonLinearRankingFitnessAssignment(void) method." 
01248              << std::endl
01249              << "Sorry, this method is not yet implemented." << std::endl
01250              << std::endl;
01251 
01252    exit(1);
01253 }
01254 
01255 
01256 // void performRouletteWheelSelection(void) method
01257 
01258 /// This metod performs selection with roulette wheel selection. It 
01259 /// selects half of the individuals from the population. Results are
01260 /// stored in the selection Vector. 
01261 ///
01262 /// @see performStochasticUniversalSamplingSelection(void) method
01263 /// @see getMinimalArgument(void).
01264 
01265 void EvolutionaryAlgorithm::performRouletteWheelSelection(void)
01266 {
01267    // Set selection vector to false 
01268 
01269    for(int i = 0; i < populationSize; i++)
01270    {
01271       selection[i] = false;
01272    }
01273 
01274    int numberOfSelectedIndividuals = populationSize/2;
01275 
01276    Vector<double> cumulativeFitness(populationSize, 0.0);
01277 
01278    // Cumulative fitness vector
01279 
01280    cumulativeFitness[0] = fitness[0]; 
01281 
01282    for(int i = 1; i < populationSize; i++)
01283    {
01284       cumulativeFitness[i] = cumulativeFitness[i-1] + fitness[i];
01285    }
01286 
01287    // Select individuals until the desired number of selections is obtained
01288 
01289    int countNumberOfSelectedIndividuals = 0;
01290 
01291    do
01292    {
01293       // Random number between 0 and total cumulative fitness
01294 
01295       double random = (double)rand()/(RAND_MAX+1.0);
01296 
01297       double pointer = cumulativeFitness[populationSize-1]*random;
01298 
01299       // Perform selection
01300 
01301       if(pointer < cumulativeFitness[0])
01302       {
01303          if(selection[0] == false)
01304          {
01305             selection[0] = true;
01306             countNumberOfSelectedIndividuals++;
01307          }
01308       }
01309       
01310       for(int i = 1; i < populationSize; i++)
01311       {
01312          if(pointer < cumulativeFitness[i] && pointer >= cumulativeFitness[i-1])
01313          {
01314             if(selection[i] == false)
01315             {
01316                selection[i] = true;
01317                countNumberOfSelectedIndividuals++;
01318             }
01319          }
01320       }
01321    }while(countNumberOfSelectedIndividuals != numberOfSelectedIndividuals);
01322 
01323    // Control sentence
01324 
01325    if(countNumberOfSelectedIndividuals != numberOfSelectedIndividuals)
01326    {
01327       std::cout << std::endl 
01328                 << "Error: EvolutionaryAlgorithm class. " << std::endl
01329                 << "void performRouletteWheelSelection(void) method."
01330                 << std::endl
01331                 << "Count number of selected individuals is not equal to "
01332                 << "number of selected individuals."
01333                 << std::endl << std::endl;
01334 
01335       exit(1);
01336    }
01337 }
01338 
01339 
01340 // void performStochasticUniversalSamplingSelection(void) method
01341 //
01342 /// This metod performs selection with stochastic universal sampling. It 
01343 /// selects half of the individuals from the population. Results are
01344 /// stored in the selection vector. 
01345 ///
01346 /// @see performRouletteWheelSelection(void) method.
01347 /// @see getMinimalArgument(void).
01348 
01349 void EvolutionaryAlgorithm::performStochasticUniversalSamplingSelection(void)
01350 {
01351    // Set selection vector to false
01352 
01353    for(int i = 0; i < populationSize; i++)
01354    {
01355       selection[i] = false;
01356    }
01357  
01358    int numberOfSelectedIndividuals = populationSize/2;
01359 
01360    Vector<double> cumulativeFitness(populationSize, 0.0);
01361 
01362    Vector<double> pointer(numberOfSelectedIndividuals, 0.0);
01363 
01364    // Cumulative fitness vector
01365 
01366    cumulativeFitness[0] = fitness[0];
01367 
01368    for(int i = 1; i < populationSize; i++)
01369    {  
01370       cumulativeFitness[i] = cumulativeFitness[i-1] + fitness[i];
01371    }
01372 
01373 
01374    // Pointer vector
01375 
01376    // Random number between 0 and 
01377    // totalCumulativeFitnees/numberOfSelectedIndividuals 
01378 
01379    double random = (double)rand()/(RAND_MAX+1.0);
01380 
01381    pointer[0] = random
01382    *cumulativeFitness[populationSize-1]/(double)numberOfSelectedIndividuals;
01383 
01384    for(int i = 1; i < numberOfSelectedIndividuals; i++)
01385    {
01386       pointer[i] = pointer[i-1] 
01387       + cumulativeFitness[populationSize-1]/(double)numberOfSelectedIndividuals;
01388    }
01389 
01390    // Selection vector
01391 
01392    int countNumberOfSelectedIndividuals = 0;
01393 
01394    if(pointer[0] <= cumulativeFitness[0])
01395    {
01396       selection[0] = true;
01397       countNumberOfSelectedIndividuals++;
01398    }
01399 
01400 
01401    for(int i = 0; i < numberOfSelectedIndividuals; i++)
01402    {
01403 
01404       for(int j = 1; j < populationSize; j++)
01405       {
01406          if(pointer[i] <= cumulativeFitness[j] && pointer[i] > cumulativeFitness[j-1])
01407          {
01408             selection[j] = true;
01409             countNumberOfSelectedIndividuals++;
01410          }
01411       }
01412    }
01413 
01414    // Number of selected individuals control sentence 
01415 
01416    if(countNumberOfSelectedIndividuals != numberOfSelectedIndividuals)
01417    {
01418       std::cout << std::endl
01419                 << "Error: EvolutionaryAlgorithm class." << std::endl
01420                 << "void performStochasticUniversalSamplingSelection(void) method."
01421                 << std::endl
01422                 << "Count number of selected individuals is not equal to "
01423                 << "number of selected individuals." 
01424                 << std::endl << std::endl;
01425 
01426       exit(1);
01427    }
01428 }
01429 
01430 
01431 // void performIntermediateRecombination(void) method
01432 
01433 /// This method performs intermediate recombination between pairs
01434 /// of selected individuals to generate a new population. Each selected
01435 /// individual is to be recombined with two other selected individuals
01436 /// chosen at random. Results are stored in the population matrix.
01437 ///
01438 /// @see recombinationSize.
01439 ///
01440 /// @see performLineRecombination(void).
01441 /// @see getMinimalArgument(void).
01442 
01443 void EvolutionaryAlgorithm::performIntermediateRecombination(void)
01444 {
01445    int numberOfVariables = objectiveFunction->getNumberOfVariables();
01446 
01447    Matrix<double> newPopulation(populationSize, numberOfVariables, 0.0);
01448 
01449    int numberOfSelectedIndividuals = populationSize/2;
01450 
01451    int count = 0;
01452    for(int i = 0; i < populationSize; i++)
01453    {
01454       if(selection[i] == true)
01455          count ++;        
01456    }
01457 
01458    Vector<double> parent1(numberOfVariables, 0.0);
01459    Vector<double> parent2(numberOfVariables, 0.0);
01460 
01461    Vector<double> offspring(numberOfVariables, 0.0);
01462 
01463    Matrix<int> recombination(populationSize, 2, 0);
01464 
01465    // Start recombination       
01466 
01467    int countNewPopulationSize = 0;
01468 
01469    for(int i = 0; i < populationSize; i++)
01470    {
01471       if(selection[i] == true)
01472       {
01473          // Set parent 1
01474 
01475          parent1 = getIndividual(i);
01476 
01477          // Generate 2 offspring with parent 1
01478 
01479          for(int j = 0; j < 2; j++)
01480          {
01481             // Choose parent 2 at random among selected individuals     
01482 
01483             bool parent2Candidate = false;
01484 
01485             do{
01486                // Integer random number beteen 0 and population size
01487 
01488                double random = (double)rand()/(RAND_MAX+1.0);
01489 
01490                int parent2CandidateIndex = (int)(populationSize*random);
01491 
01492                // Check if candidate for parent 2 is ok
01493 
01494                if(selection[parent2CandidateIndex] == true 
01495                && parent2CandidateIndex != i)
01496                {
01497                   parent2Candidate = true;
01498 
01499                   recombination[countNewPopulationSize][0] = i;
01500 
01501                   recombination[countNewPopulationSize][1]
01502                   = parent2CandidateIndex;
01503 
01504                   parent2 = getIndividual(parent2CandidateIndex);
01505 
01506                   // Perform intermediate recombination between parent 1
01507                   // and parent 2
01508 
01509                   for(int j = 0; j < numberOfVariables; j++)
01510                   {
01511                      // Choose the scaling factor to be a random number between
01512                      // -recombinationSize and 1+recombinationSize for each
01513                      // variable anew.
01514 
01515                      double random = (double)rand()/(RAND_MAX+1.0);
01516 
01517                      double scalingFactor = -1.0*recombinationSize
01518                      + (1.0 + recombinationSize)*random;
01519 
01520                      offspring[j] = scalingFactor*parent1[j]
01521                      + (1.0 - scalingFactor)*parent2[j];
01522                   }
01523 
01524                   // Add offspring to newPopulation matrix
01525 
01526                   for(int j = 0; j < numberOfVariables; j++)
01527                   {
01528                      newPopulation[countNewPopulationSize][j] = offspring[j];   
01529                   }
01530 
01531                   countNewPopulationSize++;
01532                }
01533             }while(parent2Candidate != true);
01534          }
01535       }
01536    }
01537 
01538    // Count number of new individuals control sentence
01539 
01540    if(countNewPopulationSize != populationSize)
01541    {
01542       std::cout << std::endl 
01543                 << "Error: EvolutionaryAlgorithm class. "
01544                 << "void performIntermediateRecombination(void) method." 
01545                 << std::endl
01546                 << "Count new population size is not equal to population size." 
01547                 << std::endl
01548                 << std::endl;
01549 
01550       exit(1);
01551    }
01552 
01553    // Set new population
01554 
01555    population = newPopulation;
01556 }
01557 
01558 
01559 // void performLineRecombination(void) method
01560 
01561 /// This method performs line recombination between pairs
01562 /// of selected individuals to generate a new population. Each selected
01563 /// individual is to be recombined with two other selected individuals
01564 /// chosen at random. Results are stored in the population matrix.
01565 ///
01566 /// @see recombinationSize.
01567 ///
01568 /// @see performIntermediateRecombination(void).
01569 /// @see getMinimalArgument(void).
01570 
01571 void EvolutionaryAlgorithm::performLineRecombination(void)
01572 {
01573    int numberOfVariables = objectiveFunction->getNumberOfVariables();
01574 
01575    Matrix<double> newPopulation(populationSize, numberOfVariables, 0.0);
01576 
01577    int numberOfSelectedIndividuals = populationSize/2;
01578 
01579    Vector<double> parent1(numberOfVariables, 0.0);
01580    Vector<double> parent2(numberOfVariables, 0.0);
01581 
01582    Vector<double> offspring(numberOfVariables, 0.0);
01583 
01584    Matrix<int> recombination(populationSize, 2, 0);
01585 
01586    // Start recombination       
01587 
01588    int countNewPopulationSize = 0;
01589 
01590    for(int i = 0; i < populationSize; i++)
01591    {
01592       if(selection[i] == true)
01593       {
01594 
01595          // Set parent 1
01596 
01597          parent1 = getIndividual(i);
01598 
01599          // Generate 2 offspring with parent 1
01600 
01601          for(int j = 0; j < 2; j++)
01602          {
01603             // Choose parent 2 at random among selected individuals     
01604 
01605             bool parent2Candidate = false;
01606 
01607             do
01608             {
01609                // Integer random number beteen 0 and population size
01610 
01611                double random = (double)rand()/(RAND_MAX + 1.0);
01612 
01613                int parent2CandidateIndex = (int)(populationSize*random);
01614 
01615                // Check if candidate for parent 2 is ok
01616 
01617                if(selection[parent2CandidateIndex] == true && parent2CandidateIndex != i)
01618                {
01619                   parent2Candidate = true;
01620 
01621                   recombination[countNewPopulationSize][0] = i;
01622                   recombination[countNewPopulationSize][1] = parent2CandidateIndex;
01623 
01624                   parent2 = getIndividual(parent2CandidateIndex);
01625 
01626                   // Perform intermediate recombination between parent 1
01627                   // and parent 2
01628 
01629                   // Choose the scaling factor to be a random number between
01630                   // -recombinationSize and 1+recombinationSize for all
01631                   // variables.
01632 
01633                   double random = (double)rand()/(RAND_MAX+1.0);
01634 
01635                   double scalingFactor = -1.0*recombinationSize 
01636                   + (1.0 + recombinationSize)*random;
01637 
01638                   for(int j = 0; j < numberOfVariables; j++)
01639                   {
01640                      offspring[j] = scalingFactor*parent1[j]
01641                      + (1.0 - scalingFactor)*parent2[j];
01642                   }
01643 
01644                   // Add offspring to newPopulation matrix
01645 
01646                   for(int j = 0; j < numberOfVariables; j++)
01647                   {
01648                      newPopulation[countNewPopulationSize][j] = offspring[j];   
01649                   }
01650 
01651                   countNewPopulationSize++;
01652                }
01653             }while(parent2Candidate == false);
01654          }
01655       }
01656    }
01657 
01658    // Count new population size control sentence
01659 
01660    if(countNewPopulationSize != populationSize)
01661    {
01662       std::cout << std::endl
01663                 << "Error:  EvolutionaryAlgorithm class. " << std::endl
01664                 << "void performLineRecombination(void) method."
01665                 << std::endl
01666                 << "Count new population size is not equal to population size."
01667                 << std::endl << std::endl;
01668 
01669       exit(1);
01670    }
01671 
01672    // Set new population
01673 
01674    population = newPopulation;
01675 }
01676 
01677 
01678 // void performNormalMutation(void) method
01679 
01680 /// This method performs normal mutation to all individuals in order to generate
01681 /// a new population. It uses the Box-Muller transformation to generate
01682 /// random numbers with normal distribution. Results are stored in the
01683 /// population matrix.
01684 ///
01685 /// @see mutationRate.
01686 /// @see mutationRange.
01687 ///
01688 /// @see performUniformMutation(void).
01689 /// @see getMinimalArgument(void).
01690 
01691 void EvolutionaryAlgorithm::performNormalMutation(void)
01692 {
01693    const double pi = 3.141592654;
01694 
01695    int numberOfVariables = objectiveFunction->getNumberOfVariables();
01696 
01697    Vector<double> individual(numberOfVariables, 0.0);
01698 
01699    for(int i = 0; i < populationSize; i++)
01700    {
01701       individual = getIndividual(i);
01702 
01703       for(int j = 0; j < numberOfVariables; j++)
01704       {
01705          // Random number between 0 and 1
01706 
01707          double pointer = (double)rand()/(RAND_MAX+1.0);
01708 
01709          if(pointer < mutationRate)
01710          {
01711             // Random numbers between 0 and 1
01712 
01713             double random1 = 0.0;
01714             
01715             do // random1 cannot be zero
01716             {
01717                random1 = (double)rand()/(RAND_MAX+1.0);
01718             
01719             }while(random1 == 0);
01720 
01721             double random2 = (double)rand()/(RAND_MAX+1.0);
01722 
01723             // Box-Muller transformation
01724 
01725             double mean = 0.0;
01726             double standardDeviation = mutationRange;
01727 
01728             double normallyDistributedRandomNumber 
01729             = mean + sqrt(-2.0*log(random1))*sin(2.0*pi*random2)*standardDeviation;
01730 
01731             individual[j] += normallyDistributedRandomNumber;
01732          }
01733       }
01734 
01735       setIndividual(i, individual);
01736    }
01737 }  
01738 
01739 
01740 // void performUniformMutation(void) method
01741 
01742 /// This method performs uniform mutation to all individuals in order to generate
01743 /// a new population. Results are stored in the population matrix.
01744 ///
01745 /// @see mutationRate.
01746 /// @see mutationRange.
01747 ///
01748 /// @see performNormalMutation(void).
01749 /// @see getMinimalArgument(void).
01750 
01751 void EvolutionaryAlgorithm::performUniformMutation(void)
01752 {
01753    int numberOfVariables = objectiveFunction->getNumberOfVariables();
01754 
01755    Vector<double> individual(numberOfVariables, 0.0);
01756 
01757    for(int i = 0; i < populationSize; i++)
01758    {
01759       individual = getIndividual(i);
01760 
01761       for(int j = 0; j < numberOfVariables; j++)
01762       {
01763          // random number between 0 and 1
01764 
01765          double pointer = (double)rand()/(RAND_MAX+1.0);
01766 
01767          if(pointer < mutationRate)
01768          {
01769             // random number between 0 and 1
01770 
01771             double random = (double)rand()/(RAND_MAX+1.0);
01772 
01773             double uniformlyDistributedRandomNumber
01774             = (-1.0 + 2.0*random)*mutationRange;
01775 
01776             individual[j] += uniformlyDistributedRandomNumber;
01777          }
01778       }
01779 
01780       setIndividual(i, individual);
01781    }
01782 }
01783 
01784 
01785 // Vector<double> EvolutionaryAlgorithm::getMinimalArgument(void) method
01786 
01787 /// This method optimizes the objective function with the evolutionary algorithm.
01788 /// This process occurs according to the optimization operators and their related
01789 /// parameters.
01790 ///
01791 /// @see FitnessAssignmentMethod.
01792 /// @see SelectionMethod.
01793 /// @see RecombinationMethod.
01794 /// @see MutationMethod.
01795 
01796 Vector<double> EvolutionaryAlgorithm::getMinimalArgument(void)
01797 {
01798    int numberOfVariables = objectiveFunction->getNumberOfVariables();
01799 
01800    Vector<double> minimalArgument(numberOfVariables, 0.0);
01801 
01802    // Mean evaluation history vector
01803 
01804    Vector<double> newMeanEvaluationHistory(maximumNumberOfGenerations+1, 0.0);
01805 
01806    meanEvaluationHistory = newMeanEvaluationHistory;
01807 
01808    // Standard deviation of evaluation history vector
01809 
01810    Vector<double> newStandardDeviationEvaluationHistory(maximumNumberOfGenerations+1, 0.0);
01811 
01812    standardDeviationEvaluationHistory = newStandardDeviationEvaluationHistory;
01813 
01814    // Best evaluation history vector
01815 
01816    Vector<double> newBestEvaluationHistory(maximumNumberOfGenerations+1, 0.0);
01817 
01818    bestEvaluationHistory = newBestEvaluationHistory;
01819 
01820    Vector<double> bestIndividual(numberOfVariables, 0.0);
01821 
01822    double bestEvaluation = 1.0e69;
01823 
01824    time_t beginningTime, currentTime;
01825 
01826    double elapsedTime = 0.0;
01827 
01828    // Set beginning time
01829 
01830    time(&beginningTime);
01831 
01832    std::cout << std::endl
01833              << "Getting minimal argument with evolutionary algorithm..." 
01834              << std::endl;
01835 
01836    // Evaluation of population
01837 
01838    evaluatePopulation();
01839 
01840    // Check for best individual
01841 
01842    for(int i = 0; i < populationSize; i++)
01843    {
01844       if(evaluation[i] < bestEvaluation)
01845       {
01846          bestEvaluation = evaluation[i];
01847 
01848          bestIndividual = getIndividual(i);
01849       }
01850    }
01851 
01852    bestEvaluationHistory[0] = bestEvaluation;
01853 
01854    // Calculate mean population evaluation
01855 
01856    double meanEvaluation = 0.0;
01857 
01858    double sum1 = 0.0;
01859 
01860    for(int i = 0; i < populationSize; i++)
01861    {
01862       sum1 += evaluation[i];
01863    }
01864 
01865    meanEvaluation = sum1/(double)populationSize;
01866 
01867    meanEvaluationHistory[0] = meanEvaluation;
01868 
01869    // Calculate standard deviation of evaluation
01870 
01871    double standardDeviationEvaluation = 0.0;
01872 
01873    double sum2 = 0.0;
01874 
01875    for(int i = 0; i < populationSize; i++)
01876    {
01877       sum2 += pow(evaluation[i] - meanEvaluation, 2);
01878    }
01879 
01880    standardDeviationEvaluation = sqrt(sum2/(double)populationSize);
01881 
01882    standardDeviationEvaluationHistory[0] = standardDeviationEvaluation;
01883 
01884    if(bestEvaluation <= evaluationGoal)
01885    {          
01886       std::cout << std::endl
01887                 << "Initial evaluation is less than goal." << std::endl
01888                 << "Initial evaluation: " << bestEvaluation << std::endl;
01889 
01890       objectiveFunction->print(bestIndividual);
01891       
01892       minimalArgument = bestIndividual;
01893 
01894       // Print minimal argument to screen
01895 
01896       std::cout << std::endl
01897                 << "Minimal argument:" << std::endl;
01898    
01899       for(int i = 0; i < numberOfVariables; i++)
01900       {
01901          std::cout << minimalArgument[i] << " ";        
01902       }
01903       
01904       return(minimalArgument);        
01905    }
01906    else
01907    {
01908       std::cout << std::endl
01909                    << "Initial Population:" << std::endl
01910                    << "Mean evaluation: " << meanEvaluation << std::endl
01911                    << "Standard deviation of evaluation: " << standardDeviationEvaluation
01912                    << std::endl
01913                    << "Best individual: " << std::endl
01914                    << "Evaluation: " << bestEvaluation << ";" << std::endl;
01915 
01916       objectiveFunction->print(bestIndividual);
01917    }
01918 
01919    // Main loop
01920 
01921    for(int generation = 1; generation <= maximumNumberOfGenerations; generation++)
01922    {
01923       // Fitness assignment
01924 
01925       switch(fitnessAssignmentMethod)
01926       {
01927          case LinearRanking:
01928 
01929             performLinearRankingFitnessAssignment();
01930 
01931             break;
01932 
01933          case NonLinearRanking:
01934 
01935             performNonLinearRankingFitnessAssignment();
01936 
01937             break;
01938       }
01939 
01940       // Selection
01941 
01942       switch(selectionMethod)
01943       {
01944          case RouletteWheel:
01945 
01946             performRouletteWheelSelection();
01947 
01948             break;
01949 
01950          case StochasticUniversalSampling:
01951 
01952             performStochasticUniversalSamplingSelection();
01953 
01954             break;
01955       }
01956 
01957       // Recombination
01958 
01959       switch(recombinationMethod)
01960       {
01961          case Intermediate:
01962 
01963             performIntermediateRecombination();
01964 
01965             break;
01966 
01967          case Line:
01968 
01969             performLineRecombination();
01970 
01971             break;
01972       }
01973 
01974       // Mutation
01975 
01976       switch(mutationMethod)
01977       {
01978          case Normal:
01979 
01980             performNormalMutation();
01981 
01982             break;
01983 
01984          case Uniform:
01985 
01986             performUniformMutation();
01987 
01988             break;
01989       }
01990 
01991 
01992       // Evaluation of population
01993 
01994       evaluatePopulation();
01995 
01996       // Check for best individual
01997 
01998       for(int i = 0; i < populationSize; i++)
01999       {
02000          if(evaluation[i] < bestEvaluation)
02001          {
02002             bestEvaluation = evaluation[i];
02003 
02004             bestIndividual = getIndividual(i);
02005          }
02006       }
02007 
02008       bestEvaluationHistory[generation] = bestEvaluation;
02009 
02010       // Calculate mean population evaluation
02011 
02012       double meanEvaluation = 0.0;
02013 
02014       double sum1 = 0.0;
02015 
02016       for(int i = 0; i < populationSize; i++)
02017       {
02018          sum1 += evaluation[i];
02019       }
02020 
02021       meanEvaluation = sum1/(double)populationSize;
02022 
02023       meanEvaluationHistory[generation] = meanEvaluation;
02024 
02025       // Calculate standard deviation of evaluation
02026 
02027       double standardDeviationEvaluation = 0.0;
02028 
02029       double sum2 = 0.0;
02030 
02031       for(int i = 0; i < populationSize; i++)
02032       {
02033          sum2 += pow(evaluation[i] - meanEvaluation, 2);
02034       }
02035 
02036       standardDeviationEvaluation = sqrt(sum2/(double)populationSize);
02037 
02038       standardDeviationEvaluationHistory[generation] = standardDeviationEvaluation;
02039 
02040       // Stopping Criteria
02041 
02042       // Evaluation goal 
02043 
02044       if (bestEvaluation <= evaluationGoal)
02045       {
02046          std::cout << std::endl
02047                    << "Generation " << generation << ": "
02048                    << "Evaluation goal reached." << std::endl;
02049 
02050          std::cout << "Final evaluation:" << std::endl;
02051 
02052          std::cout << "Evaluation: " << bestEvaluation << ";" << std::endl;
02053          
02054          objectiveFunction->print(bestIndividual);
02055 
02056          break;
02057       }
02058 
02059       // Maximum time
02060 
02061       time(&currentTime);
02062 
02063       elapsedTime = difftime(currentTime, beginningTime);
02064 
02065       if (elapsedTime >= maximumTime)
02066       {
02067          std::cout << std::endl
02068                    << "Generation " << generation << ": "
02069                    << "Maximum time reached."
02070                    << std::endl;
02071 
02072          std::cout << "Final evaluation:" << std::endl;
02073 
02074          std::cout << "Evaluation: " << bestEvaluation << ";" << std::endl;
02075 
02076          objectiveFunction->print(bestIndividual);
02077 
02078          break;
02079       }
02080 
02081       // Maximum number of generations
02082 
02083       if (generation == maximumNumberOfGenerations)
02084       {
02085          std::cout << std::endl
02086                    << "Generation " << generation << ": "
02087                    << "Maximum number of generations reached."
02088                    << std::endl;
02089 
02090          std::cout << "Final evaluation:" << std::endl;
02091 
02092          std::cout << "Evaluation: " << bestEvaluation << ";" << std::endl;
02093 
02094          objectiveFunction->print(bestIndividual);
02095 
02096          break;
02097       }
02098 
02099       // Progress
02100 
02101       if(generation % showPeriod == 0)
02102       {
02103          std::cout << std::endl
02104                    << "Generation " << generation << "; " << std::endl
02105                    << "Population: " << std::endl
02106                    << "Mean evaluation: " << meanEvaluation << std::endl
02107                    << "Standard deviation of evaluation: " << standardDeviationEvaluation
02108                    << std::endl
02109                    << "Best individual: " << std::endl;
02110 
02111          std::cout << "Evaluation: " << bestEvaluation << ";" << std::endl;
02112          
02113          objectiveFunction->print(bestIndividual);
02114       }
02115 
02116 
02117       // Reset selection vector
02118 
02119       Vector<bool> newSelection(populationSize, false);
02120 
02121       selection = newSelection;
02122    }
02123 
02124    // Set minimal argument
02125 
02126    minimalArgument = bestIndividual;
02127 
02128    // Print minimal argument to screen
02129 
02130    std::cout << std::endl
02131              << "Minimal argument:" << std::endl;
02132    
02133    for(int i = 0; i < numberOfVariables; i++)
02134    {
02135       std::cout << minimalArgument[i] << " ";        
02136    }
02137 
02138    std::cout << std::endl; 
02139 
02140    return(minimalArgument);
02141 }
02142 
02143 
02144 // void print(void) method
02145 
02146 /// This method prints to the screen the members of the evolutionary algorithm 
02147 /// object.
02148 ///
02149 /// Optimization operators:
02150 /// <ul>
02151 /// <li> Fitness assignment method.
02152 /// <li> Selection method.
02153 /// <li> Recombination method.
02154 /// <li> Mutation method.
02155 /// </ul>
02156 ///
02157 /// Optimization parameters:
02158 /// <ul>
02159 /// <li> Population size.
02160 /// <li> Selective pressure.
02161 /// <li> Recombination size.
02162 /// <li> Mutation rate.
02163 /// <li> Mutation range.
02164 /// </ul>
02165 ///
02166 /// Stopping criteria:
02167 /// <ul> 
02168 /// <li> Evaluation goal.
02169 /// <li> Maximum time.
02170 /// <li> Maximum number of generations.
02171 /// </ul> 
02172 ///  
02173 /// User stuff: 
02174 /// <ul>
02175 /// <li> Generations between showing progress.
02176 /// </ul>
02177 
02178 void EvolutionaryAlgorithm::print(void)
02179 {
02180    int numberOfVariables = objectiveFunction->getNumberOfVariables();
02181 
02182    std::cout << std::endl
02183              << "Flood Neural Network. Evolutionary Algorithm Object." 
02184              << std::endl;
02185 
02186    std::cout << std::endl
02187              << "Population size: " << std::endl
02188              << populationSize << std::endl
02189              << "Number of free parameters: " << std::endl
02190              << numberOfVariables  << std::endl;
02191 
02192    // Optimization operators
02193 
02194    std::cout << std::endl
02195              << "Optimization operators:" << std::endl;
02196 
02197    // Fitness assingment method
02198 
02199    std::cout << "Fitness assignment method:" << std::endl;
02200 
02201    if(fitnessAssignmentMethod == LinearRanking)
02202    {
02203       std::cout << "Linear ranking" << std::endl;
02204    }
02205    else if(fitnessAssignmentMethod == NonLinearRanking)
02206    {
02207       std::cout << "Non linear ranking" << std::endl;
02208    }
02209 
02210    // Selection method
02211 
02212    std::cout << "Selection method:" << std::endl;
02213 
02214    if(selectionMethod == RouletteWheel)
02215    {
02216       std::cout << "Roulette wheel" << std::endl;
02217    }
02218    else if(selectionMethod == StochasticUniversalSampling)
02219    {
02220       std::cout << "Stochastic universal sampling" << std::endl;
02221    }
02222 
02223    // Recombination method
02224 
02225    std::cout << "Recombination method:" << std::endl;
02226 
02227    if(recombinationMethod == Line)
02228    {
02229       std::cout << "Line" << std::endl;
02230    }
02231    else if(recombinationMethod == Intermediate)
02232    {
02233       std::cout << "Intermediate" << std::endl;
02234    }
02235 
02236    // Mutation method
02237 
02238    std::cout << "Mutation method:" << std::endl;
02239 
02240    if(mutationMethod == Normal)
02241    {
02242       std::cout << "Normal" << std::endl;
02243    }
02244    else if(mutationMethod == Uniform)
02245    {
02246       std::cout << "Uniform" << std::endl;
02247    }
02248 
02249 
02250    // Optimization parameters
02251 
02252    std::cout << std::endl
02253              << "Optimization parameters: " << std::endl
02254              << "Selective pressure: " << std::endl
02255              << selectivePressure << std::endl
02256              << "Recombination size: " << std::endl
02257              << recombinationSize << std::endl
02258              << "Mutation rate: " << std::endl
02259              << mutationRate << std::endl
02260              << "Mutation range: " << std::endl
02261              << mutationRange << std::endl;
02262 
02263    // Stopping criteria
02264 
02265    std::cout << std::endl
02266              << "Stopping criteria: " << std::endl
02267              << "Evaluation goal: " << std::endl
02268              << evaluationGoal << std::endl
02269              << "Maximum time: " << std::endl
02270              << maximumTime << std::endl
02271              << "Maximum number of generations: " << std::endl
02272              << maximumNumberOfGenerations << std::endl;
02273 
02274    // User stuff
02275 
02276    std::cout << std::endl
02277              << "User stuff: " << std::endl
02278              << "Show period: " << showPeriod
02279              << std::endl;
02280 
02281    Vector<double> individual(numberOfVariables, 0.0);
02282 
02283    std::cout << std::endl
02284              << "Population:" << std::endl;
02285 
02286    for(int i = 0; i < populationSize; i++)
02287    {
02288       individual = getIndividual(i);
02289 
02290       std::cout << "Individual " << i << ":" << std::endl; 
02291 
02292       for(int j = 0; j < numberOfVariables; j++)
02293       {
02294          std::cout << individual[j] << " ";
02295       }
02296 
02297       std::cout << std::endl;
02298    }
02299 }
02300 
02301 
02302 // void save(char*) method
02303 
02304 /// This method saves the evolutionary algorithm object to a data file. 
02305 ///
02306 /// Optimization operators:
02307 /// <ul>
02308 /// <li> Fitness assignment method.
02309 /// <li> Selection method.
02310 /// <li> Recombination method.
02311 /// <li> Mutation method.
02312 /// </ul>
02313 ///
02314 /// Optimization parameters:
02315 /// <ul>
02316 /// <li> Population size.
02317 /// <li> Selective pressure.
02318 /// <li> Recombination size.
02319 /// <li> Mutation rate.
02320 /// <li> Mutation range.
02321 /// </ul>
02322 ///
02323 /// Stopping criteria:
02324 /// <ul> 
02325 /// <li> Evaluation goal.
02326 /// <li> Maximum time.
02327 /// <li> Maximum number of generations.
02328 /// </ul> 
02329 ///  
02330 /// User stuff: 
02331 /// <ul>
02332 /// <li> Generations between showing progress.
02333 /// </ul>
02334 ///
02335 /// @param filename: Filename.
02336 ///
02337 /// @see load(char*).
02338 
02339 void EvolutionaryAlgorithm::save(char* filename)
02340 {
02341    int numberOfVariables = objectiveFunction->getNumberOfVariables();
02342 
02343    // File
02344 
02345    std::fstream file;
02346 
02347    file.open(filename, std::ios::out);
02348 
02349    if(!file.is_open())
02350    {
02351       std::cout << std::endl 
02352                 << "Error: EvolutionaryAlgorithm class." << std::endl
02353                 << "void save(char*) method." 
02354                 << std::endl
02355                 << "Cannot open evolutionary algorithm object data file."  
02356                 << std::endl
02357                 << std::endl;
02358 
02359       exit(1);
02360    }
02361    else
02362    {
02363       std::cout << std::endl
02364                 << "Saving evolutionary algorithm object to data file..." 
02365                 << std::endl;
02366    }
02367 
02368    // Write file header
02369 
02370    // Write file header
02371 
02372    file << "% Purple: An Open Source Numerical Optimization C++ Library." 
02373         << std::endl 
02374         << "% Newton Method Object." << std::endl; 
02375 
02376    file << "PopulationSize:" << std::endl
02377         << populationSize << std::endl
02378         << "NumberOfVariables:" << std::endl
02379         << numberOfVariables  << std::endl;
02380 
02381    // Optimization operators
02382 
02383    // Fitness assingment method
02384 
02385    file << "FitnessAssignmentMethod:" << std::endl;
02386 
02387    if(fitnessAssignmentMethod == LinearRanking)
02388    {
02389       file << "LinearRanking" << std::endl;
02390    }
02391    else if(fitnessAssignmentMethod == NonLinearRanking)
02392    {
02393       file << "NonLinearRanking" << std::endl;
02394    }
02395 
02396    // Selection method
02397 
02398    file << "SelectionMethod:" << std::endl;
02399 
02400    if(selectionMethod == RouletteWheel)
02401    {
02402       file << "RouletteWheel" << std::endl;
02403    }
02404    else if(selectionMethod == StochasticUniversalSampling)
02405    {
02406       file << "StochasticUniversalSampling" << std::endl;
02407    }
02408 
02409    // Recombination method
02410 
02411    file << "RecombinationMethod:" << std::endl;
02412 
02413    if(recombinationMethod == Line)
02414    {
02415       file << "Line" << std::endl;
02416    }
02417    else if(recombinationMethod == Intermediate)
02418    {
02419       file << "Intermediate" << std::endl;
02420    }
02421 
02422    // Mutation method
02423 
02424    file << "MutationMethod:" << std::endl;
02425 
02426    if(mutationMethod == Normal)
02427    {
02428       file << "Normal" << std::endl;
02429    }
02430    else if(mutationMethod == Uniform)
02431    {
02432       file << "Uniform" << std::endl;
02433    }
02434 
02435    // Optimization parameters
02436 
02437    file << "SelectivePressure:" << std::endl
02438         << selectivePressure << std::endl
02439         << "RecombinationSize:" << std::endl
02440         << recombinationSize << std::endl
02441         << "MutationRate:" << std::endl
02442         << mutationRate << std::endl
02443         << "MutationRange: " << std::endl
02444         << mutationRange << std::endl;
02445 
02446    // Stopping criteria
02447 
02448    file << "EvaluationGoal: " << std::endl
02449         << evaluationGoal << std::endl
02450         << "MaximumTime: " << std::endl
02451         << maximumTime << std::endl
02452         << "MaximumNumberOfGenerations: " << std::endl
02453         << maximumNumberOfGenerations << std::endl;
02454 
02455    // User stuff
02456 
02457    file << "ShowPeriod: " << std::endl
02458         << showPeriod << std::endl;
02459 
02460    Vector<double> individual(numberOfVariables, 0.0);
02461 
02462    file << "Population:" << std::endl;
02463 
02464    for(int i = 0; i < populationSize; i++)
02465    {
02466       individual = getIndividual(i);
02467 
02468       file << "Individual" << i << ":" << std::endl; 
02469 
02470       for(int j = 0; j < numberOfVariables; j++)
02471       {
02472          file << individual[j] << " ";
02473       }
02474 
02475       file << std::endl;
02476    }
02477 
02478    file.close();
02479 }
02480 
02481 
02482 // void load(char*) method
02483 
02484 /// This method loads an evolutionary $algorithm object from a data file. 
02485 /// Please mind about the file format, wich is specified in the User's Guide. 
02486 ///
02487 /// Optimization operators:
02488 /// <ul>
02489 /// <li> Fitness assignment method.
02490 /// <li> Selection method.
02491 /// <li> Recombination method.
02492 /// <li> Mutation method.
02493 /// </ul>
02494 ///
02495 /// Optimization parameters:
02496 /// <ul>
02497 /// <li> Population size.
02498 /// <li> Selective pressure.
02499 /// <li> Recombination size.
02500 /// <li> Mutation rate.
02501 /// <li> Mutation range.
02502 /// </ul>
02503 ///
02504 /// Stopping criteria:
02505 /// <ul> 
02506 /// <li> Evaluation goal.
02507 /// <li> Maximum time.
02508 /// <li> Maximum number of generations.
02509 /// </ul> 
02510 ///  
02511 /// User stuff: 
02512 /// <ul>
02513 /// <li> Generations between showing progress.
02514 /// </ul>
02515 ///
02516 /// @param filename: Filename.
02517 ///
02518 /// @see save(char*).
02519 
02520 void EvolutionaryAlgorithm::load(char* filename)
02521 {
02522    int numberOfVariables = objectiveFunction->getNumberOfVariables();
02523 
02524    // File
02525 
02526    std::fstream file;
02527 
02528    file.open(filename, std::ios::in);
02529 
02530    if(!file.is_open())
02531    {
02532       std::cout << std::endl
02533                 << "Error: EvolutionaryAlgorithm class." << std::endl
02534                 << "void load(char*) method." 
02535                 << std::endl
02536                 << "Cannot open evolutionary algorithm object data file."  
02537                 << std::endl;
02538 
02539       exit(1);
02540    }
02541    else
02542    {
02543       std::cout << std::endl
02544                 << "Loading evolutionary algorithm object from data file..."  
02545                 << std::endl;
02546    }
02547 
02548    // Load new number of individuals and new number of free parameters form
02549    // file
02550 
02551    int newPopulationSize = 0;
02552    int newNumberOfVariables = 0;
02553 
02554    std::string word;
02555 
02556    // Optimization parameters
02557 
02558    // Population size
02559 
02560    while(word != "PopulationSize:")
02561    {
02562       file >> word;
02563    }
02564 
02565    file >> newPopulationSize;
02566 
02567    if(newPopulationSize != populationSize)
02568    {
02569       std::cout << std::endl
02570                 << "Error: EvolutionaryAlgorithm class." << std::endl
02571                 << "void load(char*) method." << std::endl
02572                 << "New population size is not equal to population size." << std::endl
02573                 << std::endl;
02574 
02575       exit(1);
02576    }
02577 
02578    // Number of free parameters
02579 
02580    file >> word;
02581 
02582    file >> newNumberOfVariables;
02583 
02584    if(newNumberOfVariables != numberOfVariables)
02585    {
02586       std::cout << std::endl
02587                 << "Error: EvolutionaryAlgorithm class." << std::endl
02588                 << "void load(char*) method." << std::endl
02589                 << "New number of free parameters is not equal to number of free parameters."
02590                 << std::endl << std::endl;
02591 
02592       exit(1);
02593    }
02594 
02595 
02596    // Optimization operators
02597 
02598    // Fitness assingment method
02599 
02600    file >> word;
02601 
02602    file >> word;
02603 
02604    if(word == "LinearRanking")
02605    {
02606       fitnessAssignmentMethod = LinearRanking;
02607    }
02608    else if(word == "NonLinearRanking")
02609    {
02610       fitnessAssignmentMethod = NonLinearRanking;
02611    }
02612  
02613    // Selection method
02614  
02615    file >> word;
02616 
02617    file >> word;
02618 
02619    if(word == "RouletteWheel")
02620    {
02621       selectionMethod = RouletteWheel;
02622    }
02623    else if(word == "StochasticUniversalSampling")
02624    {
02625       selectionMethod = StochasticUniversalSampling;
02626    } 
02627 
02628    // Recombination method
02629 
02630    file >> word;
02631 
02632    file >> word;
02633 
02634    if(word == "Line")
02635    {
02636       recombinationMethod = Line;
02637    }
02638    else if(word == "Intermediate")
02639    {
02640       recombinationMethod = Intermediate;
02641    } 
02642 
02643    // Mutation method
02644 
02645    file >> word;
02646 
02647    file >> word;
02648 
02649    if(word == "Normal")
02650    {
02651       mutationMethod = Normal;
02652    }
02653    else if(word == "Uniform")
02654    {
02655       mutationMethod = Uniform;
02656    } 
02657 
02658    // Optimization parameters
02659 
02660    // Selective pressure
02661 
02662    file >> word;
02663 
02664    file >> selectivePressure;
02665 
02666    // Recombination size
02667 
02668    file >> word;
02669 
02670    file >> recombinationSize;
02671 
02672    // Mutation rate
02673 
02674    file >> word;
02675 
02676    file >> mutationRate;
02677 
02678    // Mutation range
02679  
02680    file >> word;
02681 
02682    file >> mutationRange;
02683 
02684    // Stopping criteria: 
02685 
02686    // Evaluation goal
02687 
02688    file >> word;
02689 
02690    file >> evaluationGoal;
02691 
02692    // Maximum time
02693 
02694    file >> word;
02695 
02696    file >> maximumTime;
02697    
02698    // Maximum number of generations
02699 
02700    file >> word;
02701 
02702    file >> maximumNumberOfGenerations;
02703 
02704    // User stuff: 
02705 
02706    // Show period
02707 
02708    file >> word;
02709 
02710    file >> showPeriod;
02711 
02712    // Population
02713 
02714    file >> word;
02715 
02716    for (int i = 0; i < populationSize; i++)
02717    {
02718       file >> word;
02719 
02720       for (int j = 0; j < numberOfVariables; j++)
02721       {
02722          file >> population[i][j];
02723       }
02724    }
02725 
02726    // Close file
02727 
02728    file.close();
02729 }
02730 
02731 
02732 // void saveOptimizationHistory(char*) method
02733 
02734 /// This method saves the optimization history to a data file:
02735 ///
02736 /// <ol>
02737 /// <li> Generation.
02738 /// <li> Mean evaluation.
02739 /// <li> Standard deviation of evaluation.
02740 /// <li> Best evaluation ever.
02741 /// </ol>
02742 ///
02743 /// @param filename: Filename.
02744 
02745 void EvolutionaryAlgorithm::saveOptimizationHistory(char* filename)
02746 {
02747    int numberOfVariables = objectiveFunction->getNumberOfVariables();
02748 
02749    int numberOfGenerations = meanEvaluationHistory.getSize();
02750 
02751    std::fstream file; 
02752 
02753    file.open(filename, std::ios::out);
02754 
02755    if(!file.is_open())
02756    {
02757       std::cout << std::endl 
02758                 << "Error: EvolutionaryAlgorithm class. " << std::endl
02759                 << "void saveOptimizationHistory(char*) method." << std::endl
02760                 << "Cannot open optimization history data file." << std::endl
02761                 << std::endl;
02762 
02763               exit(1);
02764    }
02765    else
02766    {
02767       std::cout << std::endl 
02768                 << "Saving optimization history to data file..." << std::endl;
02769    }
02770 
02771    // Write file header
02772 
02773    file << "% Purple: An Open Source Numerical Optimization C++ Library." 
02774         << std::endl 
02775         << "% Evolutionary Algorithm Optimization History." << std::endl
02776         << "% 1 - Generation." << std::endl
02777         << "% 2 - Standard Deviation of Evaluation." << std::endl
02778         << "% 3 - Best Evaluation Ever." << std::endl;
02779 
02780    // Write file data
02781 
02782    int size = bestEvaluationHistory.getSize();
02783 
02784    for (int i = 0; i < size; i++)
02785    {
02786       file << i << " "
02787            << meanEvaluationHistory[i] << " "
02788            << standardDeviationEvaluationHistory[i] << " "
02789            << bestEvaluationHistory[i] << std::endl;
02790    }
02791 
02792    file << std::endl;
02793 
02794    file.close();
02795 }
02796 
02797 }
02798 
02799 
02800 // Purple: An Open Source Numerical Optimization C++ Library.
02801 // Copyright (C) 2005 Roberto Lopez 
02802 //
02803 // This library is free software; you can redistribute it and/or
02804 // modify it under the terms of the GNU Lesser General Public
02805 // License as published by the Free Software Foundation; either
02806 // version 2.1 of the License, or any later version.
02807 //
02808 // This library is distributed in the hope that it will be useful,
02809 // but WITHOUT ANY WARRANTY; without even the implied warranty of
02810 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
02811 // Lesser General Public License for more details.
02812 
02813 // You should have received a copy of the GNU Lesser General Public
02814 // License along with this library; if not, write to the Free Software
02815 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

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