GeneticAlgorithm.cpp

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