00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <string>
00019 #include <sstream>
00020 #include <iostream>
00021 #include <fstream>
00022 #include <algorithm>
00023 #include <functional>
00024 #include <cmath>
00025 #include <time.h>
00026
00027
00028
00029 #include "evolutionary_algorithm.h"
00030
00031 namespace OpenNN
00032 {
00033
00034
00035
00039
00040 EvolutionaryAlgorithm::EvolutionaryAlgorithm(void) : TrainingAlgorithm()
00041 {
00042 set_default();
00043 }
00044
00045
00046
00047
00052
00053 EvolutionaryAlgorithm::EvolutionaryAlgorithm(PerformanceFunctional* new_performance_functional_pointer)
00054 : TrainingAlgorithm(new_performance_functional_pointer)
00055 {
00056 set_default();
00057 }
00058
00059
00060
00061
00066
00067 EvolutionaryAlgorithm::EvolutionaryAlgorithm(TiXmlElement* evolutionary_algorithm_element)
00068 : TrainingAlgorithm(evolutionary_algorithm_element)
00069 {
00070 set_default();
00071 }
00072
00073
00074
00075
00077
00078 EvolutionaryAlgorithm::~EvolutionaryAlgorithm(void)
00079 {
00080
00081 }
00082
00083
00084
00085
00086
00087
00089
00090 const EvolutionaryAlgorithm::FitnessAssignmentMethod& EvolutionaryAlgorithm::get_fitness_assignment_method(void) const
00091 {
00092 return(fitness_assignment_method);
00093 }
00094
00095
00096
00097
00099
00100 std::string EvolutionaryAlgorithm::write_fitness_assignment_method(void) const
00101 {
00102 switch(fitness_assignment_method)
00103 {
00104 case LinearRanking:
00105 {
00106 return("LinearRanking");
00107 }
00108 break;
00109
00110 default:
00111 {
00112 std::ostringstream buffer;
00113
00114 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
00115 << "std::string write_fitness_assignment_method(void) const method.\n"
00116 << "Unknown fitness assignment method.\n";
00117
00118 throw std::logic_error(buffer.str().c_str());
00119 }
00120 break;
00121 }
00122 }
00123
00124
00125
00126
00128
00129 const EvolutionaryAlgorithm::SelectionMethod& EvolutionaryAlgorithm::get_selection_method(void) const
00130 {
00131 return(selection_method);
00132 }
00133
00134
00135
00136
00138
00139 std::string EvolutionaryAlgorithm::write_selection_method(void) const
00140 {
00141 switch(selection_method)
00142 {
00143 case RouletteWheel:
00144 {
00145 return("RouletteWheel");
00146 }
00147 break;
00148
00149 case StochasticUniversalSampling:
00150 {
00151 return("StochasticUniversalSampling");
00152 }
00153 break;
00154
00155 default:
00156 {
00157 std::ostringstream buffer;
00158
00159 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
00160 << "std::string write_selection_method(void) const method.\n"
00161 << "Unknown selection method.\n";
00162
00163 throw std::logic_error(buffer.str().c_str());
00164 }
00165 break;
00166 }
00167 }
00168
00169
00170
00171
00173
00174 const EvolutionaryAlgorithm::RecombinationMethod& EvolutionaryAlgorithm::get_recombination_method(void) const
00175 {
00176 return(recombination_method);
00177 }
00178
00179
00180
00181
00183
00184 std::string EvolutionaryAlgorithm::write_recombination_method(void) const
00185 {
00186 switch(recombination_method)
00187 {
00188 case Line:
00189 {
00190 return("Line");
00191 }
00192 break;
00193
00194 case Intermediate:
00195 {
00196 return("Intermediate");
00197 }
00198 break;
00199
00200 default:
00201 {
00202 std::ostringstream buffer;
00203
00204 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
00205 << "std::string write_recombination_method(void) const method.\n"
00206 << "Unknown recombination method.\n";
00207
00208 throw std::logic_error(buffer.str().c_str());
00209 }
00210 break;
00211 }
00212 }
00213
00214
00215
00216
00218
00219 const EvolutionaryAlgorithm::MutationMethod& EvolutionaryAlgorithm::get_mutation_method(void) const
00220 {
00221 return(mutation_method);
00222 }
00223
00224
00225
00226
00228
00229 std::string EvolutionaryAlgorithm::write_mutation_method(void) const
00230 {
00231 switch(mutation_method)
00232 {
00233 case Normal:
00234 {
00235 return("Normal");
00236 }
00237 break;
00238
00239 case Uniform:
00240 {
00241 return("Uniform");
00242 }
00243 break;
00244
00245 default:
00246 {
00247 std::ostringstream buffer;
00248
00249 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
00250 << "std::string get_mutation_method_name(void) const method.\n"
00251 << "Unknown mutation method.\n";
00252
00253 throw std::logic_error(buffer.str().c_str());
00254 }
00255 break;
00256 }
00257 }
00258
00259
00260
00261
00263
00264 unsigned int EvolutionaryAlgorithm::get_population_size(void) const
00265 {
00266 return(population.get_rows_number());
00267 }
00268
00269
00270
00271
00273
00274 const Matrix<double>& EvolutionaryAlgorithm::get_population(void) const
00275 {
00276 return(population);
00277 }
00278
00279
00280
00281
00283
00284 const Vector<double>& EvolutionaryAlgorithm::get_performance(void) const
00285 {
00286 return(performance);
00287 }
00288
00289
00290
00291
00293
00294 const Vector<double>& EvolutionaryAlgorithm::get_fitness(void) const
00295 {
00296 return(fitness);
00297 }
00298
00299
00300
00301
00303
00304 const Vector<bool>& EvolutionaryAlgorithm::get_selection(void) const
00305 {
00306 return(selection);
00307 }
00308
00309
00310
00311
00314
00315 const double& EvolutionaryAlgorithm::get_warning_parameters_norm(void) const
00316 {
00317 return(warning_parameters_norm);
00318 }
00319
00320
00321
00322
00325
00326 const double& EvolutionaryAlgorithm::get_error_parameters_norm(void) const
00327 {
00328 return(error_parameters_norm);
00329 }
00330
00331
00332
00333
00335
00336 const double& EvolutionaryAlgorithm::get_minimum_parameters_increment_norm(void) const
00337 {
00338 return(minimum_parameters_increment_norm);
00339 }
00340
00341
00342
00343
00345
00346 const double& EvolutionaryAlgorithm::get_minimum_performance_increase(void) const
00347 {
00348 return(minimum_performance_increase);
00349 }
00350
00351
00352
00353
00356
00357 const double& EvolutionaryAlgorithm::get_performance_goal(void) const
00358 {
00359 return(performance_goal);
00360 }
00361
00362
00363
00364
00366
00367 const unsigned int& EvolutionaryAlgorithm::get_maximum_generalization_evaluation_decreases(void) const
00368 {
00369 return(maximum_generalization_evaluation_decreases);
00370 }
00371
00372
00373
00374
00376
00377 const double& EvolutionaryAlgorithm::get_maximum_time(void) const
00378 {
00379 return(maximum_time);
00380 }
00381
00382
00383
00384
00386
00387 const bool& EvolutionaryAlgorithm::get_reserve_parameters_history(void) const
00388 {
00389 return(reserve_parameters_history);
00390 }
00391
00392
00393
00394
00396
00397 const bool& EvolutionaryAlgorithm::get_reserve_parameters_norm_history(void) const
00398 {
00399 return(reserve_parameters_norm_history);
00400 }
00401
00402
00403
00404
00406
00407 const bool& EvolutionaryAlgorithm::get_reserve_evaluation_history(void) const
00408 {
00409 return(reserve_evaluation_history);
00410 }
00411
00412
00413
00414
00416
00417 const bool& EvolutionaryAlgorithm::get_reserve_elapsed_time_history(void) const
00418 {
00419 return(reserve_elapsed_time_history);
00420 }
00421
00422
00423
00424
00426
00427 const bool& EvolutionaryAlgorithm::get_reserve_generalization_evaluation_history(void) const
00428 {
00429 return(reserve_generalization_evaluation_history);
00430 }
00431
00432
00433
00434
00436
00437 const unsigned int& EvolutionaryAlgorithm::get_display_period(void) const
00438 {
00439 return(display_period);
00440 }
00441
00442
00443
00444
00445
00447
00448 const bool& EvolutionaryAlgorithm::get_reserve_population_history(void) const
00449 {
00450 return(reserve_population_history);
00451 }
00452
00453
00454
00455
00457
00458 const bool& EvolutionaryAlgorithm::get_reserve_best_individual_history(void) const
00459 {
00460 return(reserve_best_individual_history);
00461 }
00462
00463
00464
00465
00467
00468 const bool& EvolutionaryAlgorithm::get_reserve_mean_norm_history(void) const
00469 {
00470 return(reserve_mean_norm_history);
00471 }
00472
00473
00474
00475
00478
00479 const bool& EvolutionaryAlgorithm::get_reserve_standard_deviation_norm_history(void) const
00480 {
00481 return(reserve_standard_deviation_norm_history);
00482 }
00483
00484
00485
00486
00489
00490 const bool& EvolutionaryAlgorithm::get_reserve_best_norm_history(void) const
00491 {
00492 return(reserve_best_norm_history);
00493 }
00494
00495
00496
00497
00499
00500 const bool& EvolutionaryAlgorithm::get_reserve_mean_evaluation_history(void) const
00501 {
00502 return(reserve_mean_evaluation_history);
00503 }
00504
00505
00506
00507
00510
00511 const bool& EvolutionaryAlgorithm::get_reserve_standard_deviation_evaluation_history(void) const
00512 {
00513 return(reserve_standard_deviation_evaluation_history);
00514 }
00515
00516
00517
00518
00520
00521 const bool& EvolutionaryAlgorithm::get_reserve_best_evaluation_history(void) const
00522 {
00523 return(reserve_best_evaluation_history);
00524 }
00525
00526
00527
00528
00531
00532 void EvolutionaryAlgorithm::set(void)
00533 {
00534 performance_functional_pointer = NULL;
00535
00536 set_default();
00537 }
00538
00539
00540
00541
00544
00545 void EvolutionaryAlgorithm::set(PerformanceFunctional* new_performance_functional_pointer)
00546 {
00547 performance_functional_pointer = new_performance_functional_pointer;
00548
00549 set_default();
00550 }
00551
00552
00553
00554
00595
00596 void EvolutionaryAlgorithm::set_default(void)
00597 {
00598 unsigned int parameters_number = 0;
00599
00600 if(performance_functional_pointer)
00601 {
00602 NeuralNetwork* neural_network_pointer = performance_functional_pointer->get_neural_network_pointer();
00603
00604 if(neural_network_pointer)
00605 {
00606 parameters_number = neural_network_pointer->count_parameters_number();
00607 }
00608 }
00609
00610
00611
00612 fitness_assignment_method = LinearRanking;
00613
00614
00615
00616 selection_method = StochasticUniversalSampling;
00617
00618
00619
00620 recombination_method = Intermediate;
00621
00622
00623
00624 mutation_method = Normal;
00625
00626
00627
00628 unsigned int population_size = 10*parameters_number;
00629
00630 elitism = false;
00631 selective_pressure = 1.5;
00632
00633 recombination_size = 0.25;
00634
00635 if(parameters_number != 0)
00636 {
00637 mutation_rate = 1.0/(double)parameters_number;
00638 }
00639 else
00640 {
00641 mutation_rate = 0.0;
00642 }
00643
00644 mutation_range = 0.1;
00645
00646
00647
00648 performance_goal = -1.0e99;
00649 mean_performance_goal = -1.0e99;
00650 standard_deviation_performance_goal = 0.0;
00651
00652 maximum_time = 1.0e6;
00653
00654 maximum_generations_number = 1000;
00655
00656
00657
00658 population.set(population_size, parameters_number);
00659
00660 initialize_population_normal();
00661
00662
00663
00664 performance.set(population_size);
00665
00666
00667
00668 fitness.set(population_size);
00669
00670
00671
00672 selection.set(population_size);
00673
00674
00675
00676 reserve_population_history = false;
00677
00678 reserve_best_individual_history = false;
00679
00680 reserve_mean_norm_history = false;
00681 reserve_standard_deviation_norm_history = false;
00682 reserve_best_norm_history = false;
00683
00684 reserve_mean_evaluation_history = false;
00685 reserve_standard_deviation_evaluation_history = false;
00686 reserve_best_evaluation_history = false;
00687
00688 reserve_elapsed_time_history = false;
00689
00690
00691
00692 display_period = 100;
00693
00694 }
00695
00696
00697
00698
00704
00705 void EvolutionaryAlgorithm::set_population_size(const unsigned int& new_population_size)
00706 {
00707
00708
00709 #ifdef _DEBUG
00710
00711 check();
00712
00713 #endif
00714
00715 const NeuralNetwork* neural_network_pointer = performance_functional_pointer->get_neural_network_pointer();
00716
00717
00718
00719 #ifdef _DEBUG
00720
00721 if(!neural_network_pointer)
00722 {
00723 std::ostringstream buffer;
00724
00725 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
00726 << "void set_population_size(unsigned int) method.\n"
00727 << "Multilayer perceptron pointer is NULL.\n";
00728
00729 throw std::logic_error(buffer.str().c_str());
00730 }
00731
00732 #endif
00733
00734 unsigned int parameters_number = neural_network_pointer->count_parameters_number();
00735
00736 if(new_population_size < 4)
00737 {
00738 std::ostringstream buffer;
00739
00740 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
00741 << "void set_population_size(unsigned int) method.\n"
00742 << "New population size must be equal or greater than 4.\n";
00743
00744 throw std::logic_error(buffer.str().c_str());
00745 }
00746 else if(new_population_size%2 != 0)
00747 {
00748 std::ostringstream buffer;
00749
00750 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
00751 << "void set_population_size(unsigned int) method.\n"
00752 << "New population size is not divisible by 2.\n";
00753
00754 throw std::logic_error(buffer.str().c_str());
00755 }
00756 else
00757 {
00758
00759
00760 population.resize(new_population_size, parameters_number);
00761
00762 initialize_population_normal();
00763
00764
00765
00766 performance.resize(new_population_size);
00767
00768
00769
00770 fitness.resize(new_population_size);
00771
00772
00773
00774 selection.resize(new_population_size);
00775 }
00776 }
00777
00778
00779
00780
00787
00788 void EvolutionaryAlgorithm::set_fitness_assignment_method(const std::string& new_fitness_assignment_method_name)
00789 {
00790 if(new_fitness_assignment_method_name == "LinearRanking")
00791 {
00792 fitness_assignment_method = LinearRanking;
00793 }
00794 else
00795 {
00796 std::ostringstream buffer;
00797
00798 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
00799 << "void set_fitness_assignment_method(const std::string&) method.\n"
00800 << "Unknown fitness assignment method: " << new_fitness_assignment_method_name << ".\n";
00801
00802 throw std::logic_error(buffer.str().c_str());
00803 }
00804 }
00805
00806
00807
00808
00816
00817 void EvolutionaryAlgorithm::set_selection_method(const std::string& new_selection_method_name)
00818 {
00819 if(new_selection_method_name == "RouletteWheel")
00820 {
00821 selection_method = RouletteWheel;
00822 }
00823 else if(new_selection_method_name == "StochasticUniversalSampling")
00824 {
00825 selection_method = StochasticUniversalSampling;
00826 }
00827 else
00828 {
00829 std::ostringstream buffer;
00830
00831 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
00832 << "void set_selection_method(const std::string&) method.\n"
00833 << "Unknown selection method: " << new_selection_method_name << ".\n";
00834
00835 throw std::logic_error(buffer.str().c_str());
00836 }
00837 }
00838
00839
00840
00841
00849
00850 void EvolutionaryAlgorithm::set_recombination_method(const std::string& new_recombination_method_name)
00851 {
00852 if(new_recombination_method_name == "Line")
00853 {
00854 recombination_method = Line;
00855 }
00856 else if(new_recombination_method_name == "Intermediate")
00857 {
00858 recombination_method = Intermediate;
00859 }
00860 else
00861 {
00862 std::ostringstream buffer;
00863
00864 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
00865 << "void set_recombination_method(const std::string&) method.\n"
00866 << "Unknown recombination method: " << new_recombination_method_name << ".\n";
00867
00868 throw std::logic_error(buffer.str().c_str());
00869 }
00870 }
00871
00872
00873
00874
00882
00883 void EvolutionaryAlgorithm::set_mutation_method(const std::string& new_mutation_method_name)
00884 {
00885 if(new_mutation_method_name == "Normal")
00886 {
00887 mutation_method = Normal;
00888 }
00889 else if(new_mutation_method_name == "Uniform")
00890 {
00891 mutation_method = Uniform;
00892 }
00893 else
00894 {
00895 std::ostringstream buffer;
00896
00897 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
00898 << "void set_mutation_method(const std::string&) method.\n"
00899 << "Unknown mutationg method: " << new_mutation_method_name << ".\n";
00900
00901 throw std::logic_error(buffer.str().c_str());
00902 }
00903 }
00904
00905
00906
00907
00911
00912 void EvolutionaryAlgorithm::set_population(const Matrix<double>& new_population)
00913 {
00914
00915
00916 #ifdef _DEBUG
00917
00918 if(performance_functional_pointer == NULL)
00919 {
00920 std::ostringstream buffer;
00921
00922 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
00923 << "void set_population(const Matrix<double>&) method.\n"
00924 << "Objective functional pointer is NULL.\n";
00925
00926 throw std::logic_error(buffer.str().c_str());
00927 }
00928
00929 const NeuralNetwork* neural_network_pointer = performance_functional_pointer->get_neural_network_pointer();
00930
00931 if(!neural_network_pointer)
00932 {
00933 std::ostringstream buffer;
00934
00935 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
00936 << "void set_population(const Matrix<double>&) method.\n"
00937 << "Multilayer perceptron pointer is NULL.\n";
00938
00939 throw std::logic_error(buffer.str().c_str());
00940 }
00941
00942 const unsigned int population_size = get_population_size();
00943 const unsigned int parameters_number = neural_network_pointer->count_parameters_number();
00944
00945 if(new_population.get_rows_number() != population_size)
00946 {
00947 std::ostringstream buffer;
00948
00949 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
00950 << "void set_population(const Matrix<double>&) method.\n"
00951 << "New population size is not equal to population size.\n";
00952
00953 throw std::logic_error(buffer.str().c_str());
00954 }
00955 else if(new_population.get_columns_number() != parameters_number)
00956 {
00957 std::ostringstream buffer;
00958
00959 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
00960 << "void set_population(const Matrix<double>&) method.\n"
00961 << "New number of parameters is not equal to number of parameters.\n";
00962
00963 throw std::logic_error(buffer.str().c_str());
00964 }
00965
00966 #endif
00967
00968
00969
00970 population = new_population;
00971 }
00972
00973
00974
00975
00979
00980 void EvolutionaryAlgorithm::set_performance(const Vector<double>& new_performance)
00981 {
00982
00983
00984 #ifdef _DEBUG
00985
00986 unsigned int population_size = get_population_size();
00987
00988 if(new_performance.size() != population_size)
00989 {
00990 std::ostringstream buffer;
00991
00992 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
00993 << "void set_performance(const Vector<double>&) method.\n"
00994 << "Size is not equal to population size.\n";
00995
00996 throw std::logic_error(buffer.str().c_str());
00997 }
00998
00999 #endif
01000
01001
01002
01003 performance = new_performance;
01004 }
01005
01006
01007
01008
01012
01013 void EvolutionaryAlgorithm::set_fitness(const Vector<double>& new_fitness)
01014 {
01015
01016
01017 #ifdef _DEBUG
01018
01019 unsigned int population_size = get_population_size();
01020
01021 if(new_fitness.size() != population_size)
01022 {
01023 std::ostringstream buffer;
01024
01025 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
01026 << "void set_fitness(Vector<double>) method.\n"
01027 << "Size is not equal to population size.\n";
01028
01029 throw std::logic_error(buffer.str().c_str());
01030 }
01031
01032 #endif
01033
01034
01035
01036 fitness = new_fitness;
01037 }
01038
01039
01040
01041
01045
01046 void EvolutionaryAlgorithm::set_selection(const Vector<bool>& new_selection)
01047 {
01048
01049
01050 #ifdef _DEBUG
01051
01052 unsigned int population_size = get_population_size();
01053
01054 if(new_selection.size() != population_size)
01055 {
01056 std::ostringstream buffer;
01057
01058 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
01059 << "void set_selection(Vector<double>) method.\n"
01060 << "Size is not equal to population size.\n";
01061
01062 throw std::logic_error(buffer.str().c_str());
01063 }
01064
01065 #endif
01066
01067
01068
01069 selection = new_selection;
01070 }
01071
01072
01073
01074
01078
01079 void EvolutionaryAlgorithm::set_reserve_population_history(const bool& new_reserve_population_history)
01080 {
01081 reserve_population_history = new_reserve_population_history;
01082 }
01083
01084
01085
01086
01090
01091 void EvolutionaryAlgorithm::set_reserve_best_individual_history(const bool& new_reserve_best_individual_history)
01092 {
01093 reserve_best_individual_history = new_reserve_best_individual_history;
01094 }
01095
01096
01097
01098
01102
01103 void EvolutionaryAlgorithm::set_reserve_mean_norm_history(const bool& new_reserve_mean_norm_history)
01104 {
01105 reserve_mean_norm_history = new_reserve_mean_norm_history;
01106 }
01107
01108
01109
01110
01115
01116 void EvolutionaryAlgorithm::
01117 set_reserve_standard_deviation_norm_history(const bool& new_reserve_standard_deviation_norm_history)
01118 {
01119 reserve_standard_deviation_norm_history = new_reserve_standard_deviation_norm_history;
01120 }
01121
01122
01123
01124
01128
01129 void EvolutionaryAlgorithm::set_reserve_best_norm_history(const bool& new_reserve_best_norm_history)
01130 {
01131 reserve_best_norm_history = new_reserve_best_norm_history;
01132 }
01133
01134
01135
01136
01141
01142 void EvolutionaryAlgorithm::set_reserve_mean_evaluation_history(const bool& new_reserve_mean_evaluation_history)
01143 {
01144 reserve_mean_evaluation_history = new_reserve_mean_evaluation_history;
01145 }
01146
01147
01148
01149
01154
01155 void EvolutionaryAlgorithm
01156 ::set_reserve_standard_deviation_evaluation_history(const bool& new_reserve_standard_deviation_evaluation_history)
01157 {
01158 reserve_standard_deviation_evaluation_history = new_reserve_standard_deviation_evaluation_history;
01159 }
01160
01161
01162
01163
01168
01169 void EvolutionaryAlgorithm::set_reserve_best_evaluation_history(const bool& new_reserve_best_evaluation_history)
01170 {
01171 reserve_best_evaluation_history = new_reserve_best_evaluation_history;
01172 }
01173
01174
01175
01176
01181
01182 void EvolutionaryAlgorithm::set_reserve_all_training_history(const bool& new_reserve_all_training_history)
01183 {
01184
01185
01186 reserve_population_history = new_reserve_all_training_history;
01187
01188 reserve_best_individual_history = new_reserve_all_training_history;
01189
01190 reserve_mean_norm_history = new_reserve_all_training_history;
01191 reserve_standard_deviation_norm_history = new_reserve_all_training_history;
01192 reserve_best_norm_history = new_reserve_all_training_history;
01193
01194
01195
01196 reserve_mean_evaluation_history = new_reserve_all_training_history;
01197 reserve_standard_deviation_evaluation_history = new_reserve_all_training_history;
01198 reserve_best_evaluation_history = new_reserve_all_training_history;
01199
01200
01201
01202 reserve_elapsed_time_history = new_reserve_all_training_history;
01203 }
01204
01205
01206
01207
01211
01212 Vector<double> EvolutionaryAlgorithm::get_individual(const unsigned int& i) const
01213 {
01214
01215
01216 #ifdef _DEBUG
01217
01218 unsigned int population_size = get_population_size();
01219
01220 if(i >= population_size)
01221 {
01222 std::ostringstream buffer;
01223
01224 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
01225 << "Vector<double> get_individual(const unsigned int&) const method.\n"
01226 << "Index must be less than population size.\n";
01227
01228 throw std::logic_error(buffer.str().c_str());
01229 }
01230
01231 #endif
01232
01233
01234
01235 const Vector<double> individual = population.arrange_row(i);
01236
01237 return(individual);
01238 }
01239
01240
01241
01242
01243
01248
01249 void EvolutionaryAlgorithm::set_individual(const unsigned int& i, const Vector<double>& individual)
01250 {
01251
01252
01253 #ifdef _DEBUG
01254
01255 const unsigned int size = individual.size();
01256
01257 const NeuralNetwork* neural_network_pointer = performance_functional_pointer->get_neural_network_pointer();
01258
01259 const unsigned int parameters_number = neural_network_pointer->count_parameters_number();
01260
01261 const unsigned int population_size = get_population_size();
01262
01263 if(i >= population_size)
01264 {
01265 std::ostringstream buffer;
01266
01267 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
01268 << "set_individual(const unsigned int&, Vector<double>) method.\n"
01269 << "Index must be less than population size.\n";
01270
01271 throw std::logic_error(buffer.str().c_str());
01272 }
01273 else if(size != parameters_number)
01274 {
01275 std::ostringstream buffer;
01276
01277 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
01278 << "set_individual(const unsigned int&, Vector<double>) method.\n"
01279 << "Size must be equal to number of parameters.\n";
01280
01281 throw std::logic_error(buffer.str().c_str());
01282 }
01283
01284 #endif
01285
01286
01287
01288 population.set_row(i, individual);
01289 }
01290
01291
01292
01293
01297
01298 void EvolutionaryAlgorithm::set_warning_parameters_norm(const double& new_warning_parameters_norm)
01299 {
01300
01301
01302 #ifdef _DEBUG
01303
01304 if(new_warning_parameters_norm < 0.0)
01305 {
01306 std::ostringstream buffer;
01307
01308 buffer << "OpenNN Exception: TrainingAlgorithm class.\n"
01309 << "void set_warning_parameters_norm(const double&) method.\n"
01310 << "Warning parameters norm must be equal or greater than 0.\n";
01311
01312 throw std::logic_error(buffer.str().c_str());
01313 }
01314
01315 #endif
01316
01317
01318
01319 warning_parameters_norm = new_warning_parameters_norm;
01320 }
01321
01322
01323
01324
01328
01329 void EvolutionaryAlgorithm::set_error_parameters_norm(const double& new_error_parameters_norm)
01330 {
01331
01332
01333 #ifdef _DEBUG
01334
01335 if(new_error_parameters_norm < 0.0)
01336 {
01337 std::ostringstream buffer;
01338
01339 buffer << "OpenNN Exception: TrainingAlgorithm class.\n"
01340 << "void set_error_parameters_norm(const double&) method.\n"
01341 << "Error parameters norm must be equal or greater than 0.\n";
01342
01343 throw std::logic_error(buffer.str().c_str());
01344 }
01345
01346 #endif
01347
01348
01349
01350 error_parameters_norm = new_error_parameters_norm;
01351 }
01352
01353
01354
01355
01358
01359 void EvolutionaryAlgorithm::set_minimum_parameters_increment_norm(const double& new_minimum_parameters_increment_norm)
01360 {
01361
01362
01363 #ifdef _DEBUG
01364
01365 if(new_minimum_parameters_increment_norm < 0.0)
01366 {
01367 std::ostringstream buffer;
01368
01369 buffer << "OpenNN Exception: TrainingAlgorithm class.\n"
01370 << "void new_minimum_parameters_increment_norm(const double&) method.\n"
01371 << "Minimum parameters increment norm must be equal or greater than 0.\n";
01372
01373 throw std::logic_error(buffer.str().c_str());
01374 }
01375
01376 #endif
01377
01378
01379
01380 minimum_parameters_increment_norm = new_minimum_parameters_increment_norm;
01381 }
01382
01383
01384
01385
01388
01389 void EvolutionaryAlgorithm::set_minimum_performance_increase(const double& new_minimum_performance_increase)
01390 {
01391
01392
01393 #ifdef _DEBUG
01394
01395 if(new_minimum_performance_increase < 0.0)
01396 {
01397 std::ostringstream buffer;
01398
01399 buffer << "OpenNN Exception: TrainingAlgorithm class.\n"
01400 << "void set_minimum_performance_increase(const double&) method.\n"
01401 << "Minimum performance improvement must be equal or greater than 0.\n";
01402
01403 throw std::logic_error(buffer.str().c_str());
01404 }
01405
01406 #endif
01407
01408
01409
01410 minimum_performance_increase = new_minimum_performance_increase;
01411 }
01412
01413
01414
01415
01419
01420 void EvolutionaryAlgorithm::set_performance_goal(const double& new_performance_goal)
01421 {
01422 performance_goal = new_performance_goal;
01423 }
01424
01425
01426
01427
01430
01431 void EvolutionaryAlgorithm::set_maximum_generalization_evaluation_decreases(const unsigned int& new_maximum_generalization_evaluation_decreases)
01432 {
01433
01434
01435 #ifdef _DEBUG
01436
01437 if(new_maximum_generalization_evaluation_decreases < 0)
01438 {
01439 std::ostringstream buffer;
01440
01441 buffer << "OpenNN Exception: TrainingAlgorithm class.\n"
01442 << "void set_maximum_generalization_evaluation_decreases(const unsigned int&) method.\n"
01443 << "Number of generalization performance decreases must be equal or greater than 0.\n";
01444
01445 throw std::logic_error(buffer.str().c_str());
01446 }
01447
01448 #endif
01449
01450
01451
01452 maximum_generalization_evaluation_decreases = new_maximum_generalization_evaluation_decreases;
01453 }
01454
01455
01456
01457
01460
01461 void EvolutionaryAlgorithm::set_maximum_time(const double& new_maximum_time)
01462 {
01463
01464
01465 #ifdef _DEBUG
01466
01467 if(new_maximum_time < 0.0)
01468 {
01469 std::ostringstream buffer;
01470
01471 buffer << "OpenNN Exception: TrainingAlgorithm class.\n"
01472 << "void set_maximum_time(const double&) method.\n"
01473 << "Maximum time must be equal or greater than 0.\n";
01474
01475 throw std::logic_error(buffer.str().c_str());
01476 }
01477
01478 #endif
01479
01480
01481
01482 maximum_time = new_maximum_time;
01483 }
01484
01485
01486
01487
01490
01491 void EvolutionaryAlgorithm::set_reserve_parameters_history(const bool& new_reserve_parameters_history)
01492 {
01493 reserve_parameters_history = new_reserve_parameters_history;
01494 }
01495
01496
01497
01498
01501
01502 void EvolutionaryAlgorithm::set_reserve_parameters_norm_history(const bool& new_reserve_parameters_norm_history)
01503 {
01504 reserve_parameters_norm_history = new_reserve_parameters_norm_history;
01505 }
01506
01507
01508
01509
01512
01513 void EvolutionaryAlgorithm::set_reserve_evaluation_history(const bool& new_reserve_evaluation_history)
01514 {
01515 reserve_evaluation_history = new_reserve_evaluation_history;
01516 }
01517
01518
01519
01520
01524
01525 void EvolutionaryAlgorithm::set_reserve_elapsed_time_history(const bool& new_reserve_elapsed_time_history)
01526 {
01527 reserve_elapsed_time_history = new_reserve_elapsed_time_history;
01528 }
01529
01530
01531
01532
01536
01537 void EvolutionaryAlgorithm::set_reserve_generalization_evaluation_history(const bool& new_reserve_generalization_evaluation_history)
01538 {
01539 reserve_generalization_evaluation_history = new_reserve_generalization_evaluation_history;
01540 }
01541
01542
01543
01544
01548
01549 void EvolutionaryAlgorithm::set_display_period(const unsigned int& new_display_period)
01550 {
01551
01552
01553 #ifdef _DEBUG
01554
01555 if(new_display_period <= 0)
01556 {
01557 std::ostringstream buffer;
01558
01559 buffer << "OpenNN Exception: TrainingAlgorithm class.\n"
01560 << "void set_display_period(const double&) method.\n"
01561 << "First training rate must be greater than 0.\n";
01562
01563 throw std::logic_error(buffer.str().c_str());
01564 }
01565
01566 #endif
01567
01568 display_period = new_display_period;
01569 }
01570
01571
01572
01573
01574
01576
01577 Vector<double> EvolutionaryAlgorithm::calculate_population_norm(void) const
01578 {
01579 unsigned int population_size = get_population_size();
01580
01581 Vector<double> population_norm(population_size);
01582
01583 for(unsigned int i = 0; i < population_size; i++)
01584 {
01585 Vector<double> individual = get_individual(i);
01586
01587 population_norm[i] = individual.calculate_norm();
01588 }
01589
01590 return(population_norm);
01591 }
01592
01593
01594
01595
01597
01598 double EvolutionaryAlgorithm::calculate_mean_performance(void) const
01599 {
01600 return(performance.calculate_mean());
01601 }
01602
01603
01604
01605
01607
01608 double EvolutionaryAlgorithm::calculate_standard_deviation_performance(void) const
01609 {
01610 return(performance.calculate_standard_deviation());
01611 }
01612
01613
01614
01615
01616
01617
01619
01620 const bool& EvolutionaryAlgorithm::get_elitism(void) const
01621 {
01622 return(elitism);
01623 }
01624
01625
01626
01627
01629
01630 const double& EvolutionaryAlgorithm::get_selective_pressure(void) const
01631 {
01632 return(selective_pressure);
01633 }
01634
01635
01636
01637
01639
01640 const double& EvolutionaryAlgorithm::get_recombination_size(void) const
01641 {
01642 return(recombination_size);
01643 }
01644
01645
01646
01647
01649
01650 const double& EvolutionaryAlgorithm::get_mutation_rate(void) const
01651 {
01652 return(mutation_rate);
01653 }
01654
01655
01656
01657
01659
01660 const double& EvolutionaryAlgorithm::get_mutation_range(void) const
01661 {
01662 return(mutation_range);
01663 }
01664
01665
01666
01667
01669
01670 const double& EvolutionaryAlgorithm::get_mean_performance_goal(void) const
01671 {
01672 return(mean_performance_goal);
01673 }
01674
01675
01676
01677
01679
01680 const double& EvolutionaryAlgorithm::get_standard_deviation_performance_goal(void) const
01681 {
01682 return(standard_deviation_performance_goal);
01683 }
01684
01685
01686
01687
01689
01690 const unsigned int& EvolutionaryAlgorithm::get_maximum_generations_number(void) const
01691 {
01692 return(maximum_generations_number);
01693 }
01694
01695
01696
01697
01701
01702 void EvolutionaryAlgorithm::set_elitism(const bool& new_elitism)
01703 {
01704 elitism = new_elitism;
01705 }
01706
01707
01708
01709
01715
01716 void EvolutionaryAlgorithm::set_selective_pressure(const double& new_selective_pressure)
01717 {
01718 switch(fitness_assignment_method)
01719 {
01720 case LinearRanking:
01721 {
01722 if(new_selective_pressure < 1.0 || new_selective_pressure > 2.0)
01723 {
01724 std::ostringstream buffer;
01725
01726 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
01727 << "void set_selective_pressure(const double&) method. "
01728 << "Case linear ranking.\n"
01729 << "Selective pressure must be a value between 1 and 2.\n";
01730
01731 throw std::logic_error(buffer.str().c_str());
01732 }
01733
01734
01735
01736 selective_pressure = new_selective_pressure;
01737 }
01738 break;
01739 }
01740 }
01741
01742
01743
01744
01749
01750 void EvolutionaryAlgorithm::set_recombination_size(const double& new_recombination_size)
01751 {
01752 if(new_recombination_size < 0.0)
01753 {
01754 std::ostringstream buffer;
01755
01756 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
01757 << "void set_recombination_size(const double&) method.\n"
01758 << "Recombination size must be equal or greater than 0.\n";
01759
01760 throw std::logic_error(buffer.str().c_str());
01761 }
01762
01763
01764
01765 recombination_size = new_recombination_size;
01766 }
01767
01768
01769
01770
01775
01776 void EvolutionaryAlgorithm::set_mutation_rate(const double& new_mutation_rate)
01777 {
01778
01779
01780 if(new_mutation_rate < 0.0 || new_mutation_rate > 1.0)
01781 {
01782 std::ostringstream buffer;
01783
01784 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
01785 << "void set_mutation_rate(const double&) method.\n"
01786 << "Mutation rate must be a value between 0 and 1.\n";
01787
01788 throw std::logic_error(buffer.str().c_str());
01789 }
01790
01791
01792
01793 mutation_rate = new_mutation_rate;
01794 }
01795
01796
01797
01798
01803
01804 void EvolutionaryAlgorithm::set_mutation_range(const double& new_mutation_range)
01805 {
01806
01807
01808 if(new_mutation_range < 0.0)
01809 {
01810 std::ostringstream buffer;
01811
01812 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
01813 << "void set_mutation_range(const double&) method.\n"
01814 << "Mutation range must be equal or greater than 0.\n";
01815
01816 throw std::logic_error(buffer.str().c_str());
01817 }
01818
01819
01820
01821 mutation_range = new_mutation_range;
01822 }
01823
01824
01825
01826
01830
01831 void EvolutionaryAlgorithm::set_maximum_generations_number(const unsigned int& new_maximum_generations_number)
01832 {
01833
01834
01835 #ifdef _DEBUG
01836
01837 if(new_maximum_generations_number == 0)
01838 {
01839 std::ostringstream buffer;
01840
01841 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
01842 << "void set_maximum_generations_number(unsigned int) method.\n"
01843 << "Maximum number of generations must be greater than 0.\n";
01844
01845 throw std::logic_error(buffer.str().c_str());
01846 }
01847
01848 #endif
01849
01850
01851
01852 maximum_generations_number = new_maximum_generations_number;
01853 }
01854
01855
01856
01857
01858
01861
01862 void EvolutionaryAlgorithm::set_mean_performance_goal(const double& new_mean_performance_goal)
01863 {
01864 mean_performance_goal = new_mean_performance_goal;
01865 }
01866
01867
01868
01869
01872
01873 void EvolutionaryAlgorithm::set_standard_deviation_performance_goal(const double& new_standard_deviation_performance_goal)
01874 {
01875
01876
01877 #ifdef _DEBUG
01878
01879 if(new_standard_deviation_performance_goal < 0.0)
01880 {
01881 std::ostringstream buffer;
01882
01883 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
01884 << "void set_standard_deviation_performance_goal(const double&) method.\n"
01885 << "Standard deviation of performance goal must be equal or greater than 0.\n";
01886
01887 throw std::logic_error(buffer.str().c_str());
01888 }
01889
01890 #endif
01891
01892
01893
01894 standard_deviation_performance_goal = new_standard_deviation_performance_goal;
01895
01896 }
01897
01898
01899
01902
01903 void EvolutionaryAlgorithm::set_fitness_assignment_method
01904 (const EvolutionaryAlgorithm::FitnessAssignmentMethod& new_fitness_assignment_method)
01905 {
01906 fitness_assignment_method = new_fitness_assignment_method;
01907 }
01908
01909
01910
01911
01915
01916 void EvolutionaryAlgorithm::
01917 set_selection_method(const EvolutionaryAlgorithm::SelectionMethod& new_selection_method)
01918 {
01919 selection_method = new_selection_method;
01920 }
01921
01922
01923
01924
01928
01929 void EvolutionaryAlgorithm
01930 ::set_recombination_method(const EvolutionaryAlgorithm::RecombinationMethod& new_recombination_method)
01931 {
01932 recombination_method = new_recombination_method;
01933 }
01934
01935
01936
01937
01941
01942 void EvolutionaryAlgorithm::set_mutation_method(const EvolutionaryAlgorithm::MutationMethod& new_mutation_method)
01943 {
01944 mutation_method = new_mutation_method;
01945 }
01946
01947
01948
01949
01952
01953 void EvolutionaryAlgorithm::initialize_population(const double& new_value)
01954 {
01955 population.initialize(new_value);
01956 }
01957
01958
01959
01960
01961
01964
01965 void EvolutionaryAlgorithm::initialize_population_uniform(void)
01966 {
01967 population.initialize_uniform();
01968 }
01969
01970
01971
01972
01978
01979 void EvolutionaryAlgorithm::initialize_population_uniform(const double& minimum, const double& maximum)
01980 {
01981 population.initialize_uniform(minimum, maximum);
01982 }
01983
01984
01985
01986
01992
01993 void EvolutionaryAlgorithm::initialize_population_uniform(const Vector<double>& minimum, const Vector<double>& maximum)
01994 {
01995 const NeuralNetwork* neural_network_pointer = performance_functional_pointer->get_neural_network_pointer();
01996
01997 const unsigned int parameters_number = neural_network_pointer->count_parameters_number();
01998
01999
02000
02001 #ifdef _DEBUG
02002
02003 const unsigned int minimum_size = minimum.size();
02004 const unsigned int maximum_size = maximum.size();
02005
02006 if(minimum_size != parameters_number || maximum_size != parameters_number)
02007 {
02008 std::ostringstream buffer;
02009
02010 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
02011 << "void initialize_population_uniform(Vector<double>, Vector<double>).\n"
02012 << "Minimum value and maximum value sizes must be equal to number of parameters.\n";
02013
02014 throw std::logic_error(buffer.str().c_str());
02015 }
02016
02017 #endif
02018
02019 Vector<double> individual(parameters_number);
02020
02021 const unsigned int population_size = get_population_size();
02022
02023 for(unsigned int i = 0; i < population_size; i++)
02024 {
02025 individual.initialize_uniform(minimum, maximum);
02026
02027 set_individual(i, individual);
02028 }
02029 }
02030
02031
02032
02033
02036
02037 void EvolutionaryAlgorithm::initialize_population_normal(void)
02038 {
02039 population.initialize_normal();
02040 }
02041
02042
02043
02044
02050
02051 void EvolutionaryAlgorithm::initialize_population_normal(const double& mean, const double& standard_deviation)
02052 {
02053 population.initialize_normal(mean, standard_deviation);
02054 }
02055
02056
02057
02058
02064
02065 void EvolutionaryAlgorithm::
02066 initialize_population_normal(const Vector<double>& mean, const Vector<double>& standard_deviation)
02067 {
02068 const NeuralNetwork* neural_network_pointer = performance_functional_pointer->get_neural_network_pointer();
02069
02070 const unsigned int parameters_number = neural_network_pointer->count_parameters_number();
02071
02072
02073
02074 #ifdef _DEBUG
02075
02076 const unsigned int mean_size = mean.size();
02077 const unsigned int standard_deviation_size = standard_deviation.size();
02078
02079 if(mean_size != parameters_number || standard_deviation_size != parameters_number)
02080 {
02081 std::ostringstream buffer;
02082
02083 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
02084 << "void initialize_population_normal(Vector<double>, Vector<double>).\n"
02085 << "Mean and standard deviation sizes must be equal to number of parameters.\n";
02086
02087 throw std::logic_error(buffer.str().c_str());
02088 }
02089
02090 #endif
02091
02092 Vector<double> individual(parameters_number);
02093
02094 const unsigned int population_size = get_population_size();
02095
02096 for(unsigned int i = 0; i < population_size; i++)
02097 {
02098 individual.initialize_normal(mean, standard_deviation);
02099
02100 set_individual(i, individual);
02101 }
02102 }
02103
02104
02105
02106
02108
02109 void EvolutionaryAlgorithm::perform_fitness_assignment(void)
02110 {
02111 switch(fitness_assignment_method)
02112 {
02113 case LinearRanking:
02114 {
02115 perform_linear_ranking_fitness_assignment();
02116 }
02117
02118 break;
02119
02120 default:
02121 {
02122 std::ostringstream buffer;
02123
02124 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
02125 << "void perform_fitness_assignment(void).\n"
02126 << "Unknown fitness assignment method.\n";
02127
02128 throw std::logic_error(buffer.str().c_str());
02129 }
02130 break;
02131 }
02132 }
02133
02134
02135
02136
02138
02139 void EvolutionaryAlgorithm::perform_selection(void)
02140 {
02141 switch(selection_method)
02142 {
02143 case RouletteWheel:
02144 {
02145 perform_roulette_wheel_selection();
02146 }
02147 break;
02148
02149 case StochasticUniversalSampling:
02150 {
02151 perform_stochastic_universal_sampling_selection();
02152 }
02153 break;
02154
02155 default:
02156 {
02157 std::ostringstream buffer;
02158
02159 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
02160 << "void perform_selection(void).\n"
02161 << "Unknown selection method.\n";
02162
02163 throw std::logic_error(buffer.str().c_str());
02164 }
02165 break;
02166 }
02167 }
02168
02169
02170
02171
02173
02174 void EvolutionaryAlgorithm::perform_recombination(void)
02175 {
02176 switch(recombination_method)
02177 {
02178 case Intermediate:
02179 {
02180 perform_intermediate_recombination();
02181 }
02182 break;
02183
02184 case Line:
02185 {
02186 perform_line_recombination();
02187 }
02188 break;
02189
02190 default:
02191 {
02192 std::ostringstream buffer;
02193
02194 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
02195 << "void perform_recombination(void).\n"
02196 << "Unknown recombination method.\n";
02197
02198 throw std::logic_error(buffer.str().c_str());
02199 }
02200 break;
02201 }
02202 }
02203
02204
02205
02206
02208
02209 void EvolutionaryAlgorithm::perform_mutation(void)
02210 {
02211 switch(mutation_method)
02212 {
02213 case Normal:
02214 {
02215 perform_normal_mutation();
02216 }
02217 break;
02218
02219 case Uniform:
02220 {
02221 perform_uniform_mutation();
02222 }
02223 break;
02224
02225 default:
02226 {
02227 std::ostringstream buffer;
02228
02229 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
02230 << "void perform_mutationg(void).\n"
02231 << "Unknown mutation method.\n";
02232
02233 throw std::logic_error(buffer.str().c_str());
02234 }
02235 break;
02236 }
02237 }
02238
02239
02240
02241
02243
02244 void EvolutionaryAlgorithm::evolve_population(void)
02245 {
02246
02247
02248 perform_fitness_assignment();
02249
02250
02251
02252 perform_selection();
02253
02254
02255
02256 perform_recombination();
02257
02258
02259
02260 perform_mutation();
02261 }
02262
02263
02264
02265
02268
02269 void EvolutionaryAlgorithm::evaluate_population(void)
02270 {
02271
02272
02273 #ifdef _DEBUG
02274
02275 if(performance_functional_pointer == NULL)
02276 {
02277 std::ostringstream buffer;
02278
02279 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
02280 << "void evaluate_population(void).\n"
02281 << "Objective functional pointer is NULL.\n";
02282
02283 throw std::logic_error(buffer.str().c_str());
02284 }
02285
02286 #endif
02287
02288
02289
02290 const NeuralNetwork* neural_network_pointer = performance_functional_pointer->get_neural_network_pointer();
02291
02292
02293
02294 #ifdef _DEBUG
02295
02296 if(!neural_network_pointer)
02297 {
02298 std::ostringstream buffer;
02299
02300 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
02301 << "void evaluate_population(void).\n"
02302 << "Multilayer perceptron pointer is NULL.\n";
02303
02304 throw std::logic_error(buffer.str().c_str());
02305 }
02306
02307 #endif
02308
02309 const unsigned int parameters_number = neural_network_pointer->count_parameters_number();
02310
02311 Vector<double> individual(parameters_number);
02312
02313
02314
02315 unsigned int population_size = get_population_size();
02316
02317 for(unsigned int i = 0; i < population_size; i++)
02318 {
02319 individual = get_individual(i);
02320
02321 performance[i] = performance_functional_pointer->calculate_evaluation(individual);
02322
02323 if(!(performance[i] > -1.0e99 && performance[i] < 1.0e99))
02324 {
02325 std::ostringstream buffer;
02326
02327 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
02328 << "void evaluate_population(void) method.\n"
02329 << "Performance of individual " << i << " is not a real number.\n";
02330
02331 throw std::logic_error(buffer.str().c_str());
02332 }
02333 }
02334 }
02335
02336
02337
02338
02343
02344 void EvolutionaryAlgorithm::perform_linear_ranking_fitness_assignment(void)
02345 {
02346
02347
02348 unsigned int population_size = get_population_size();
02349
02350 Vector<double> sorted_performance(population_size);
02351
02352 sorted_performance = performance;
02353
02354 std::sort(sorted_performance.begin(), sorted_performance.end(), std::less<double>());
02355
02356
02357
02358 Vector<int> rank(population_size);
02359
02360 for(unsigned int i = 0; i < population_size; i++)
02361 {
02362 for(unsigned int j = 0; j < population_size; j++)
02363 {
02364 if(performance[j] == sorted_performance[i])
02365 {
02366 rank[j] = population_size - i;
02367 }
02368 }
02369 }
02370
02371
02372
02373 for(unsigned int i = 0; i < population_size; i++)
02374 {
02375 fitness[i] = 2.0 - selective_pressure
02376 + 2.0*(selective_pressure - 1.0)*(rank[i] - 1.0)/(population_size - 1.0);
02377
02378 if(!(fitness[i] > -1.0e99 && fitness[i] < 1.0e99))
02379 {
02380 std::ostringstream buffer;
02381
02382 buffer << "Flooe Error: EvolutionaryAlgorithm class.\n"
02383 << "void perform_linear_ranking_fitness_assignment(void) method.\n"
02384 << "Fitness of individual " << i << " is not a real number.\n";
02385
02386 throw std::logic_error(buffer.str().c_str());
02387 }
02388 }
02389 }
02390
02391
02392
02393
02397
02398 void EvolutionaryAlgorithm::perform_roulette_wheel_selection(void)
02399 {
02400
02401
02402 selection.initialize(false);
02403
02404 unsigned int population_size = get_population_size();
02405
02406 unsigned int selected_individuals_number = population_size/2;
02407
02408
02409
02410 Vector<double> cumulative_fitness(population_size);
02411
02412 cumulative_fitness[0] = fitness[0];
02413
02414 for(unsigned int i = 1; i < population_size; i++)
02415 {
02416 cumulative_fitness[i] = cumulative_fitness[i-1] + fitness[i];
02417 }
02418
02419
02420
02421 unsigned int selected_individuals_count = 0;
02422
02423 if(elitism)
02424 {
02425 unsigned int best_individual_index = performance.calculate_minimal_index();
02426
02427 selection[best_individual_index] = true;
02428
02429 selected_individuals_count++;
02430 }
02431
02432 do
02433 {
02434
02435
02436 double random = (double)rand()/(RAND_MAX+1.0);
02437
02438 double pointer = cumulative_fitness[population_size-1]*random;
02439
02440
02441
02442 if(pointer < cumulative_fitness[0])
02443 {
02444 if(selection[0] == false)
02445 {
02446 selection[0] = true;
02447 selected_individuals_count++;
02448 }
02449 }
02450
02451 for(unsigned int i = 1; i < population_size; i++)
02452 {
02453 if(pointer < cumulative_fitness[i] && pointer >= cumulative_fitness[i-1])
02454 {
02455 if(selection[i] == false)
02456 {
02457 selection[i] = true;
02458 selected_individuals_count++;
02459 }
02460 }
02461 }
02462 }while(selected_individuals_count != selected_individuals_number);
02463
02464
02465
02466 if(selected_individuals_count != selected_individuals_number)
02467 {
02468 std::ostringstream buffer;
02469
02470 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
02471 << "void perform_roulette_wheel_selection(void) method.\n"
02472 << "Count number of selected individuals is not equal to number of selected individuals.\n";
02473
02474 throw std::logic_error(buffer.str().c_str());
02475 }
02476 }
02477
02478
02479
02480
02484
02485 void EvolutionaryAlgorithm::perform_stochastic_universal_sampling_selection(void)
02486 {
02487
02488
02489 selection.initialize(false);
02490
02491 unsigned int population_size = get_population_size();
02492
02493 unsigned int selected_individuals_number = population_size/2;
02494
02495 Vector<double> cumulative_fitness(population_size);
02496
02497 Vector<double> pointer(selected_individuals_number);
02498
02499
02500
02501 cumulative_fitness[0] = fitness[0];
02502
02503 for(unsigned int i = 1; i < population_size; i++)
02504 {
02505 cumulative_fitness[i] = cumulative_fitness[i-1] + fitness[i];
02506 }
02507
02508
02509
02510
02511
02512
02513 double random = (double)rand()/(RAND_MAX+1.0);
02514
02515 pointer[0] = random
02516 *cumulative_fitness[population_size-1]/(double)selected_individuals_number;
02517
02518 for(unsigned int i = 1; i < selected_individuals_number; i++)
02519 {
02520 pointer[i] = pointer[i-1]
02521 + cumulative_fitness[population_size-1]/(double)selected_individuals_number;
02522 }
02523
02524
02525
02526 unsigned int selected_individuals_count = 0;
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537 if(pointer[0] <= cumulative_fitness[0])
02538 {
02539 selection[0] = true;
02540 selected_individuals_count++;
02541 }
02542
02543 for(unsigned int i = 0; i < selected_individuals_number; i++)
02544 {
02545 for(unsigned int j = 1; j < population_size; j++)
02546 {
02547 if(pointer[i] <= cumulative_fitness[j] && pointer[i] > cumulative_fitness[j-1])
02548 {
02549 selection[j] = true;
02550 selected_individuals_count++;
02551 }
02552 }
02553 }
02554
02555
02556
02557 if(selected_individuals_count != selected_individuals_number)
02558 {
02559 std::ostringstream buffer;
02560
02561 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
02562 << "void perform_stochastic_universal_sampling_selection(void) method.\n"
02563 << "Count number of selected individuals is not equal to number of selected individuals.\n";
02564
02565 throw std::logic_error(buffer.str().c_str());
02566 }
02567 }
02568
02569
02570
02571
02576
02577 void EvolutionaryAlgorithm::perform_intermediate_recombination(void)
02578 {
02579 unsigned int population_size = get_population_size();
02580
02581 const NeuralNetwork* neural_network_pointer = performance_functional_pointer->get_neural_network_pointer();
02582
02583 const unsigned int parameters_number = neural_network_pointer->count_parameters_number();
02584
02585 Matrix<double> new_population(population_size, parameters_number);
02586
02587 unsigned int count = 0;
02588 for(unsigned int i = 0; i < population_size; i++)
02589 {
02590 if(selection[i] == true)
02591 count ++;
02592 }
02593
02594 Vector<double> parent_1(parameters_number);
02595 Vector<double> parent_2(parameters_number);
02596
02597 Vector<double> offspring(parameters_number);
02598
02599 Matrix<int> recombination(population_size, 2);
02600
02601
02602
02603 unsigned int new_population_size_count = 0;
02604
02605 for(unsigned int i = 0; i < population_size; i++)
02606 {
02607 if(selection[i] == true)
02608 {
02609
02610
02611 parent_1 = get_individual(i);
02612
02613
02614
02615 for(unsigned int j = 0; j < 2; j++)
02616 {
02617
02618
02619 bool parent_2_candidate = false;
02620
02621 do{
02622
02623
02624 double random = (double)rand()/(RAND_MAX+1.0);
02625
02626 unsigned int parent_2_candidate_index = (unsigned int)(population_size*random);
02627
02628
02629
02630 if(selection[parent_2_candidate_index] == true && parent_2_candidate_index != i)
02631 {
02632 parent_2_candidate = true;
02633
02634 recombination[new_population_size_count][0] = i;
02635
02636 recombination[new_population_size_count][1] = parent_2_candidate_index;
02637
02638 parent_2 = get_individual(parent_2_candidate_index);
02639
02640
02641
02642 for(unsigned int j = 0; j < parameters_number; j++)
02643 {
02644
02645
02646
02647
02648 double random = (double)rand()/(RAND_MAX+1.0);
02649
02650 double scaling_factor = -1.0*recombination_size + (1.0 + recombination_size)*random;
02651
02652 offspring[j] = scaling_factor*parent_1[j] + (1.0 - scaling_factor)*parent_2[j];
02653 }
02654
02655
02656
02657 new_population.set_row(new_population_size_count, offspring);
02658
02659 new_population_size_count++;
02660 }
02661 }while(parent_2_candidate != true);
02662 }
02663 }
02664 }
02665
02666
02667
02668 if(new_population_size_count != population_size)
02669 {
02670 std::ostringstream buffer;
02671
02672 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
02673 << "void perform_intermediate_recombination(void) method.\n"
02674 << "Count new population size is not equal to population size.\n";
02675
02676 throw std::logic_error(buffer.str().c_str());
02677 }
02678
02679
02680
02681 population = new_population;
02682 }
02683
02684
02685
02686
02690
02691 void EvolutionaryAlgorithm::perform_line_recombination(void)
02692 {
02693 const unsigned int population_size = get_population_size();
02694
02695 const NeuralNetwork* neural_network_pointer = performance_functional_pointer->get_neural_network_pointer();
02696
02697 const unsigned int parameters_number = neural_network_pointer->count_parameters_number();
02698
02699 Matrix<double> new_population(population_size, parameters_number);
02700
02701 Vector<double> parent_1(parameters_number);
02702 Vector<double> parent_2(parameters_number);
02703
02704 Vector<double> offspring(parameters_number);
02705 Vector<double> parent_1_term(parameters_number);
02706 Vector<double> parent_2_term(parameters_number);
02707
02708 Matrix<int> recombination(population_size, 2);
02709
02710
02711
02712 unsigned int new_population_size_count = 0;
02713
02714 for(unsigned int i = 0; i < population_size; i++)
02715 {
02716 if(selection[i] == true)
02717 {
02718
02719
02720 parent_1 = get_individual(i);
02721
02722
02723
02724 for(unsigned int j = 0; j < 2; j++)
02725 {
02726
02727
02728 bool parent_2_candidate = false;
02729
02730 do
02731 {
02732
02733
02734 double random = (double)rand()/(RAND_MAX + 1.0);
02735
02736 unsigned int parent_2_candidate_index = (unsigned int)(population_size*random);
02737
02738
02739
02740 if(selection[parent_2_candidate_index] == true && parent_2_candidate_index != i)
02741 {
02742 parent_2_candidate = true;
02743
02744 recombination[new_population_size_count][0] = i;
02745 recombination[new_population_size_count][1] = parent_2_candidate_index;
02746
02747 parent_2 = get_individual(parent_2_candidate_index);
02748
02749
02750
02751
02752
02753
02754
02755
02756 double random = (double)rand()/(RAND_MAX+1.0);
02757
02758 double scaling_factor = -1.0*recombination_size
02759 + (1.0 + recombination_size)*random;
02760
02761 parent_1_term = parent_1*scaling_factor;
02762 parent_2_term = parent_2*(1.0 - scaling_factor);
02763
02764 offspring = parent_1_term + parent_2_term;
02765
02766
02767
02768 new_population.set_row(new_population_size_count, offspring);
02769
02770 new_population_size_count++;
02771 }
02772 }while(parent_2_candidate == false);
02773 }
02774 }
02775 }
02776
02777
02778
02779 if(new_population_size_count != population_size)
02780 {
02781 std::ostringstream buffer;
02782
02783 buffer << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
02784 << "void perform_line_recombination(void) method.\n"
02785 << "Count new population size is not equal to population size.\n";
02786
02787 throw std::logic_error(buffer.str().c_str());
02788 }
02789
02790
02791
02792 population = new_population;
02793 }
02794
02795
02796
02797
02800
02801 void EvolutionaryAlgorithm::perform_normal_mutation(void)
02802 {
02803 unsigned int population_size = get_population_size();
02804
02805 const NeuralNetwork* neural_network_pointer = performance_functional_pointer->get_neural_network_pointer();
02806
02807 const unsigned int parameters_number = neural_network_pointer->count_parameters_number();
02808
02809 Vector<double> individual(parameters_number);
02810
02811 for(unsigned int i = 0; i < population_size; i++)
02812 {
02813 individual = get_individual(i);
02814
02815 for(unsigned int j = 0; j < parameters_number; j++)
02816 {
02817
02818
02819 double pointer = calculate_random_uniform(0.0, 1.0);
02820
02821 if(pointer < mutation_rate)
02822 {
02823 individual[j] += calculate_random_normal(0.0, mutation_range);
02824 }
02825 }
02826
02827 set_individual(i, individual);
02828 }
02829 }
02830
02831
02832
02833
02836
02837 void EvolutionaryAlgorithm::perform_uniform_mutation(void)
02838 {
02839 const unsigned int population_size = get_population_size();
02840
02841 const NeuralNetwork* neural_network_pointer = performance_functional_pointer->get_neural_network_pointer();
02842
02843 const unsigned int parameters_number = neural_network_pointer->count_parameters_number();
02844
02845 Vector<double> individual(parameters_number, 0.0);
02846
02847 for(unsigned int i = 0; i < population_size; i++)
02848 {
02849 individual = get_individual(i);
02850
02851 for(unsigned int j = 0; j < parameters_number; j++)
02852 {
02853
02854
02855 double pointer = (double)rand()/(RAND_MAX+1.0);
02856
02857 if(pointer < mutation_rate)
02858 {
02859
02860
02861 double random = (double)rand()/(RAND_MAX+1.0);
02862
02863 double uniformlyDistributedRandomNumber
02864 = (-1.0 + 2.0*random)*mutation_range;
02865
02866 individual[j] += uniformlyDistributedRandomNumber;
02867 }
02868 }
02869
02870 set_individual(i, individual);
02871 }
02872 }
02873
02874
02875
02876
02878
02879 std::string EvolutionaryAlgorithm::EvolutionaryAlgorithmResults::to_string(void) const
02880 {
02881 std::ostringstream buffer;
02882
02883
02884
02885 if(!population_history.empty())
02886 {
02887 if(!population_history[0].empty())
02888 {
02889 buffer << "% Population history:\n"
02890 << population_history << "\n";
02891 }
02892 }
02893
02894
02895
02896 if(!best_individual_history.empty())
02897 {
02898 if(!population_history[0].empty())
02899 {
02900 buffer << "% Best individual history:\n"
02901 << best_individual_history << "\n";
02902 }
02903 }
02904
02905
02906
02907 if(!mean_norm_history.empty())
02908 {
02909 buffer << "% Mean norm history:\n"
02910 << mean_norm_history << "\n";
02911 }
02912
02913
02914
02915 if(!standard_deviation_norm_history.empty())
02916 {
02917 buffer << "% Standard deviation norm history:\n"
02918 << standard_deviation_norm_history << "\n";
02919 }
02920
02921
02922
02923 if(!best_norm_history.empty())
02924 {
02925 buffer << "% Best norm history:\n"
02926 << best_norm_history << "\n";
02927 }
02928
02929
02930
02931 if(!evaluation_history.empty())
02932 {
02933 buffer << "% Evaluation history:\n"
02934 << evaluation_history << "\n";
02935 }
02936
02937
02938
02939 if(!mean_evaluation_history.empty())
02940 {
02941 buffer << "% Mean evaluation history:\n"
02942 << mean_evaluation_history << "\n";
02943 }
02944
02945
02946
02947 if(!standard_deviation_evaluation_history.empty())
02948 {
02949 buffer << "% Standard deviation evaluation history:\n"
02950 << standard_deviation_evaluation_history << "\n";
02951 }
02952
02953
02954
02955 if(!best_evaluation_history.empty())
02956 {
02957 buffer << "% Best evaluation history:\n"
02958 << best_evaluation_history << "\n";
02959 }
02960
02961
02962
02963 if(!generalization_evaluation_history.empty())
02964 {
02965 buffer << "% Generalization evaluation history:\n"
02966 << generalization_evaluation_history << "\n";
02967 }
02968
02969
02970
02971 if(!mean_generalization_evaluation_history.empty())
02972 {
02973 buffer << "% Mean generalization evaluation history:\n"
02974 << mean_generalization_evaluation_history << "\n";
02975 }
02976
02977
02978
02979 if(!standard_deviation_generalization_evaluation_history.empty())
02980 {
02981 buffer << "% Standard deviation generalization evaluation history:\n"
02982 << standard_deviation_generalization_evaluation_history << "\n";
02983 }
02984
02985
02986
02987 if(!best_generalization_evaluation_history.empty())
02988 {
02989 buffer << "% Best generalization evaluation history:\n"
02990 << best_generalization_evaluation_history << "\n";
02991 }
02992
02993
02994
02995 if(!elapsed_time_history.empty())
02996 {
02997 buffer << "% Elapsed time history:\n"
02998 << elapsed_time_history << "\n";
02999 }
03000
03001 return(buffer.str());
03002 }
03003
03004
03005
03006
03009
03010 void EvolutionaryAlgorithm::EvolutionaryAlgorithmResults::resize_training_history(const unsigned int& new_size)
03011 {
03012 population_history.resize(new_size);
03013 best_individual_history.resize(new_size);
03014 mean_norm_history.resize(new_size);
03015 standard_deviation_norm_history.resize(new_size);
03016 best_norm_history.resize(new_size);
03017
03018 evaluation_history.resize(new_size);
03019 mean_evaluation_history.resize(new_size);
03020 standard_deviation_evaluation_history.resize(new_size);
03021 best_evaluation_history.resize(new_size);
03022 generalization_evaluation_history.resize(new_size);
03023 mean_generalization_evaluation_history.resize(new_size);
03024 standard_deviation_generalization_evaluation_history.resize(new_size);
03025 best_generalization_evaluation_history.resize(new_size);
03026
03027 elapsed_time_history.resize(new_size);
03028 }
03029
03030
03031
03032
03036
03037 EvolutionaryAlgorithm::EvolutionaryAlgorithmResults* EvolutionaryAlgorithm::perform_training(void)
03038 {
03039 if(display)
03040 {
03041 std::cout << "Training with the evolutionary algorithm...\n";
03042 }
03043
03044 EvolutionaryAlgorithmResults* evolutionary_algorithm_training_results_pointer = new EvolutionaryAlgorithmResults;
03045
03046 evolutionary_algorithm_training_results_pointer->resize_training_history(1+maximum_generations_number);
03047
03048
03049
03050 #ifdef _DEBUG
03051
03052 if(performance_functional_pointer == NULL)
03053 {
03054 std::ostringstream buffer;
03055
03056 std::cout << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
03057 << "EvolutionaryAlgorithmResults* perform_training(void) method.\n"
03058 << "Pointer to performance functional is NULL.\n";
03059
03060 throw std::logic_error(buffer.str().c_str());
03061 }
03062
03063 #endif
03064
03065
03066
03067 NeuralNetwork* neural_network_pointer = performance_functional_pointer->get_neural_network_pointer();
03068
03069 #ifdef _DEBUG
03070
03071 if(neural_network_pointer == NULL)
03072 {
03073 std::ostringstream buffer;
03074
03075 std::cout << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
03076 << "EvolutionaryAlgorithmResults* perform_training(void) method.\n"
03077 << "Pointer to neural network is NULL.\n";
03078
03079 throw std::logic_error(buffer.str().c_str());
03080 }
03081
03082 #endif
03083
03084
03085 #ifdef _DEBUG
03086
03087 if(population.get_rows_number() == 0)
03088 {
03089 std::ostringstream buffer;
03090
03091 std::cout << "OpenNN Exception: EvolutionaryAlgorithm class.\n"
03092 << "EvolutionaryAlgorithmResults* perform_training(void) method.\n"
03093 << "population matrix is empty.\n";
03094
03095 throw std::logic_error(buffer.str().c_str());
03096 }
03097
03098 #endif
03099
03100
03101 Vector<double> population_norm;
03102
03103 double mean_norm;
03104 double standard_deviation_norm;
03105
03106 Vector<double> best_individual;
03107 double best_norm = 0.0;
03108
03109
03110
03111 double best_performance = 1.0e99;
03112
03113 double generalization_evaluation = 0.0;
03114
03115
03116
03117
03118 unsigned int generalization_evaluation_decreases_count = 0;
03119
03120 time_t beginning_time, current_time;
03121 time(&beginning_time);
03122 double elapsed_time;
03123
03124 bool stop_training = false;
03125
03126
03127
03128 for(unsigned int generation = 0; generation <= maximum_generations_number; generation++)
03129 {
03130
03131
03132 if(reserve_population_history)
03133 {
03134 evolutionary_algorithm_training_results_pointer->population_history[generation] = population;
03135 }
03136
03137 population_norm = calculate_population_norm();
03138
03139
03140
03141 mean_norm = population_norm.calculate_mean();
03142
03143 if(reserve_mean_norm_history)
03144 {
03145 evolutionary_algorithm_training_results_pointer->mean_norm_history[generation] = mean_norm;
03146 }
03147
03148
03149
03150 standard_deviation_norm = population_norm.calculate_standard_deviation();
03151
03152 if(reserve_standard_deviation_norm_history)
03153 {
03154 evolutionary_algorithm_training_results_pointer->standard_deviation_norm_history[generation] = standard_deviation_norm;
03155 }
03156
03157 evaluate_population();
03158
03159 const unsigned int population_size = get_population_size();
03160
03161 for(unsigned int i = 0; i < population_size; i++)
03162 {
03163 if(performance[i] < best_performance)
03164 {
03165 best_individual = get_individual(i);
03166
03167 neural_network_pointer->set_parameters(best_individual);
03168
03169 best_norm = best_individual.calculate_norm();
03170
03171 best_performance = performance[i];
03172
03173
03174
03175 generalization_evaluation = performance_functional_pointer->calculate_generalization_evaluation();
03176 }
03177 }
03178
03179
03180
03181 if(reserve_best_individual_history)
03182 {
03183 evolutionary_algorithm_training_results_pointer->best_individual_history[generation] = best_individual;
03184 }
03185
03186
03187
03188 if(reserve_best_norm_history)
03189 {
03190 evolutionary_algorithm_training_results_pointer->best_norm_history[generation] = best_norm;
03191 }
03192
03193
03194
03195 double mean_performance = performance.calculate_mean();
03196
03197 if(reserve_mean_evaluation_history)
03198 {
03199 evolutionary_algorithm_training_results_pointer->mean_evaluation_history[generation] = mean_performance;
03200 }
03201
03202
03203
03204 double standard_deviation_performance = performance.calculate_standard_deviation();
03205
03206 if(reserve_standard_deviation_evaluation_history)
03207 {
03208 evolutionary_algorithm_training_results_pointer->standard_deviation_evaluation_history[generation] = standard_deviation_performance;
03209 }
03210
03211
03212
03213 if(reserve_best_evaluation_history)
03214 {
03215 evolutionary_algorithm_training_results_pointer->best_evaluation_history[generation] = best_performance;
03216 }
03217
03218
03219
03220 if(reserve_generalization_evaluation_history)
03221 {
03222 evolutionary_algorithm_training_results_pointer->generalization_evaluation_history[generation] = generalization_evaluation;
03223 }
03224
03225
03226
03227 time(¤t_time);
03228 elapsed_time = difftime(current_time, beginning_time);
03229
03230 if(reserve_elapsed_time_history)
03231 {
03232 evolutionary_algorithm_training_results_pointer->elapsed_time_history[generation] = elapsed_time;
03233 }
03234
03235
03236
03237 if(reserve_population_history)
03238 {
03239 evolutionary_algorithm_training_results_pointer->population_history[generation] = population;
03240 }
03241
03242 if(reserve_best_individual_history)
03243 {
03244 evolutionary_algorithm_training_results_pointer->best_individual_history[generation] = best_individual;
03245 }
03246
03247 if(reserve_mean_norm_history)
03248 {
03249 evolutionary_algorithm_training_results_pointer->mean_norm_history[generation] = mean_norm;
03250 }
03251
03252 if(reserve_standard_deviation_norm_history)
03253 {
03254 evolutionary_algorithm_training_results_pointer->standard_deviation_norm_history[generation] = standard_deviation_norm;
03255 }
03256
03257 if(reserve_best_norm_history)
03258 {
03259 evolutionary_algorithm_training_results_pointer->best_norm_history[generation] = best_norm;
03260 }
03261
03262
03263
03264 if(reserve_mean_evaluation_history)
03265 {
03266 evolutionary_algorithm_training_results_pointer->mean_evaluation_history[generation] = mean_performance;
03267 }
03268
03269 if(reserve_standard_deviation_evaluation_history)
03270 {
03271 evolutionary_algorithm_training_results_pointer->standard_deviation_evaluation_history[generation] = standard_deviation_performance;
03272 }
03273
03274 if(reserve_best_evaluation_history)
03275 {
03276 evolutionary_algorithm_training_results_pointer->best_evaluation_history[generation] = best_performance;
03277 }
03278
03279 if(reserve_elapsed_time_history)
03280 {
03281 evolutionary_algorithm_training_results_pointer->elapsed_time_history[generation] = elapsed_time;
03282 }
03283
03284
03285
03286 if(best_performance <= performance_goal)
03287 {
03288 if(display)
03289 {
03290 std::cout << "Generation " << generation << ": Performance goal reached.\n"
03291 << performance_functional_pointer->write_information();
03292 }
03293
03294 stop_training = true;
03295 }
03296
03297 if(mean_performance <= mean_performance_goal)
03298 {
03299 if(display)
03300 {
03301 std::cout << "Generation " << generation << ": Mean performance goal reached.\n";
03302 }
03303
03304 stop_training = true;
03305 }
03306
03307 if(standard_deviation_performance <= standard_deviation_performance_goal)
03308 {
03309 if(display)
03310 {
03311 std::cout << "Generation " << generation << ": Standard deviation of performance goal reached.\n";
03312 }
03313
03314 stop_training = true;
03315 }
03316
03317 else if(generalization_evaluation_decreases_count > maximum_generalization_evaluation_decreases)
03318 {
03319 if(display)
03320 {
03321 std::cout << "Generation " << generation << ": Maximum generalization performance decreases reached.\n";
03322 std::cout << "Generalization performance decreases: "<< generalization_evaluation_decreases_count << std::endl;
03323 }
03324
03325 stop_training = true;
03326 }
03327
03328 else if(elapsed_time >= maximum_time)
03329 {
03330 if(display)
03331 {
03332 std::cout << "Generation " << generation << ": Maximum training time reached.\n";
03333 }
03334
03335 stop_training = true;
03336 }
03337
03338 else if(generation == maximum_generations_number)
03339 {
03340 if(display)
03341 {
03342 std::cout << "Generation " << generation << ": Maximum number of generations reached.\n";
03343 }
03344
03345 break;
03346 }
03347
03348 if(stop_training)
03349 {
03350 evolutionary_algorithm_training_results_pointer->final_mean_norm = mean_norm;
03351 evolutionary_algorithm_training_results_pointer->final_standard_deviation_norm = standard_deviation_norm;
03352 evolutionary_algorithm_training_results_pointer->final_best_norm = best_norm;
03353 evolutionary_algorithm_training_results_pointer->final_mean_performance = mean_performance;
03354 evolutionary_algorithm_training_results_pointer->final_standard_deviation_performance = standard_deviation_performance;
03355 evolutionary_algorithm_training_results_pointer->final_best_performance = best_performance;
03356 evolutionary_algorithm_training_results_pointer->elapsed_time = elapsed_time;
03357
03358 if(display)
03359 {
03360 std::cout << "Mean norm: " << mean_norm << "\n"
03361 << "Standard deviation of norm: " << standard_deviation_norm << "\n"
03362 << "Best norm: " << best_norm << "\n"
03363 << "Mean performance: " << mean_performance << "\n"
03364 << "Standard deviation of performance: " << standard_deviation_performance << "\n"
03365 << "Best performance: " << best_performance << "\n"
03366 << performance_functional_pointer->write_information()
03367 << "Elapsed time: " << elapsed_time << ";\n";
03368 }
03369
03370 break;
03371 }
03372 else if(display && generation % display_period == 0)
03373 {
03374 std::cout << "Generation " << generation << ";\n"
03375 << "Mean norm: " << mean_norm << "\n"
03376 << "Standard deviation of norm: " << standard_deviation_norm << "\n"
03377 << "Best norm: " << best_norm << "\n"
03378 << "Mean performance: " << mean_performance << "\n"
03379 << "Standard deviation of performance: " << standard_deviation_performance << "\n"
03380 << "Best performance: " << best_performance << "\n"
03381 << performance_functional_pointer->write_information()
03382 << "Elapsed time: " << elapsed_time << ";\n";
03383 }
03384
03385
03386
03387
03388
03389 selection.initialize(false);
03390
03391 evolve_population();
03392
03393 }
03394
03395 return(evolutionary_algorithm_training_results_pointer);
03396 }
03397
03398
03399
03400
03401 std::string EvolutionaryAlgorithm::write_training_algorithm_type(void) const
03402 {
03403 return("EVOLUTIONARY_ALGORITHM");
03404 }
03405
03406
03407
03408
03451
03452 TiXmlElement* EvolutionaryAlgorithm::to_XML(void) const
03453 {
03454 std::ostringstream buffer;
03455
03456
03457
03458 TiXmlElement* evolutionary_algorithm_element = new TiXmlElement("EvolutionaryAlgorithm");
03459 evolutionary_algorithm_element->SetAttribute("Version", 4);
03460
03461
03462
03463 TiXmlElement* fitness_assignment_method_element = new TiXmlElement("FitnessAssignmentMethod");
03464 evolutionary_algorithm_element->LinkEndChild(fitness_assignment_method_element);
03465
03466 buffer.str("");
03467 buffer << write_fitness_assignment_method();
03468
03469 TiXmlText* fitness_assignment_method_text = new TiXmlText(buffer.str().c_str());
03470 fitness_assignment_method_element->LinkEndChild(fitness_assignment_method_text);
03471
03472
03473
03474 TiXmlElement* selection_method_element = new TiXmlElement("SelectionMethod");
03475 evolutionary_algorithm_element->LinkEndChild(selection_method_element);
03476
03477 buffer.str("");
03478 buffer << write_selection_method();
03479
03480 TiXmlText* selection_method_text = new TiXmlText(buffer.str().c_str());
03481 selection_method_element->LinkEndChild(selection_method_text);
03482
03483
03484
03485 TiXmlElement* recombination_method_element = new TiXmlElement("RecombinationMethod");
03486 evolutionary_algorithm_element->LinkEndChild(recombination_method_element);
03487
03488 buffer.str("");
03489 buffer << write_recombination_method();
03490
03491 TiXmlText* recombination_method_text = new TiXmlText(buffer.str().c_str());
03492 recombination_method_element->LinkEndChild(recombination_method_text);
03493
03494
03495
03496 TiXmlElement* mutation_method_element = new TiXmlElement("MutationMethod");
03497 evolutionary_algorithm_element->LinkEndChild(mutation_method_element);
03498
03499 buffer.str("");
03500 buffer << write_mutation_method();
03501
03502 TiXmlText* mutation_method_text = new TiXmlText(buffer.str().c_str());
03503 mutation_method_element->LinkEndChild(mutation_method_text);
03504
03505
03506
03507 TiXmlElement* elitism_element = new TiXmlElement("Elitism");
03508 evolutionary_algorithm_element->LinkEndChild(elitism_element);
03509
03510 buffer.str("");
03511 buffer << elitism;
03512
03513 TiXmlText* elitism_text = new TiXmlText(buffer.str().c_str());
03514 elitism_element->LinkEndChild(elitism_text);
03515
03516
03517
03518 TiXmlElement* selective_pressure_element = new TiXmlElement("SelectivePressure");
03519 evolutionary_algorithm_element->LinkEndChild(selective_pressure_element);
03520
03521 buffer.str("");
03522 buffer << selective_pressure;
03523
03524 TiXmlText* selective_pressure_text = new TiXmlText(buffer.str().c_str());
03525 selective_pressure_element->LinkEndChild(selective_pressure_text);
03526
03527
03528
03529 TiXmlElement* recombination_size_element = new TiXmlElement("RecombinationSize");
03530 evolutionary_algorithm_element->LinkEndChild(recombination_size_element);
03531
03532 buffer.str("");
03533 buffer << recombination_size;
03534
03535 TiXmlText* recombination_size_text = new TiXmlText(buffer.str().c_str());
03536 recombination_size_element->LinkEndChild(recombination_size_text);
03537
03538
03539
03540 TiXmlElement* mutation_rate_element = new TiXmlElement("MutationRate");
03541 evolutionary_algorithm_element->LinkEndChild(mutation_rate_element);
03542
03543 buffer.str("");
03544 buffer << mutation_rate;
03545
03546 TiXmlText* mutation_rate_text = new TiXmlText(buffer.str().c_str());
03547 mutation_rate_element->LinkEndChild(mutation_rate_text);
03548
03549
03550
03551 TiXmlElement* mutation_range_element = new TiXmlElement("MutationRange");
03552 evolutionary_algorithm_element->LinkEndChild(mutation_range_element);
03553
03554 buffer.str("");
03555 buffer << mutation_range;
03556
03557 TiXmlText* mutation_range_text = new TiXmlText(buffer.str().c_str());
03558 mutation_range_element->LinkEndChild(mutation_range_text);
03559
03560
03561
03562 TiXmlElement* mean_performance_goal_element = new TiXmlElement("MeanPerformanceGoal");
03563 evolutionary_algorithm_element->LinkEndChild(mean_performance_goal_element);
03564
03565 buffer.str("");
03566 buffer << mean_performance_goal;
03567
03568 TiXmlText* mean_performance_goal_text = new TiXmlText(buffer.str().c_str());
03569 mean_performance_goal_element->LinkEndChild(mean_performance_goal_text);
03570
03571
03572
03573 TiXmlElement* standard_deviation_performance_goal_element = new TiXmlElement("StandardDeviationPerformanceGoal");
03574 evolutionary_algorithm_element->LinkEndChild(standard_deviation_performance_goal_element);
03575
03576 buffer.str("");
03577 buffer << standard_deviation_performance_goal;
03578
03579 TiXmlText* standard_deviation_performance_goal_text = new TiXmlText(buffer.str().c_str());
03580 standard_deviation_performance_goal_element->LinkEndChild(standard_deviation_performance_goal_text);
03581
03582
03583
03584 TiXmlElement* maximum_generations_number_element = new TiXmlElement("MaximumGenerationsNumber");
03585 evolutionary_algorithm_element->LinkEndChild(maximum_generations_number_element);
03586
03587 buffer.str("");
03588 buffer << maximum_generations_number;
03589
03590 TiXmlText* maximum_generations_number_text = new TiXmlText(buffer.str().c_str());
03591 maximum_generations_number_element->LinkEndChild(maximum_generations_number_text);
03592
03593
03594
03595 TiXmlElement* maximum_generalization_evaluation_decreases_element = new TiXmlElement("MaximumGeneralizationPerformanceDeceases");
03596 evolutionary_algorithm_element->LinkEndChild(maximum_generalization_evaluation_decreases_element);
03597
03598 buffer.str("");
03599 buffer << maximum_generalization_evaluation_decreases;
03600
03601 TiXmlText* maximum_generalization_evaluation_decreases_text = new TiXmlText(buffer.str().c_str());
03602 maximum_generalization_evaluation_decreases_element->LinkEndChild(maximum_generalization_evaluation_decreases_text);
03603
03604 return(evolutionary_algorithm_element);
03605 }
03606
03607
03608
03609
03613
03614 void EvolutionaryAlgorithm::from_XML(TiXmlElement* evolutionary_algorithm_element)
03615 {
03616
03617
03618 TiXmlElement* fitness_assignment_method_element = evolutionary_algorithm_element->FirstChildElement("FitnessAssignmentMethod");
03619
03620 if(fitness_assignment_method_element)
03621 {
03622 std::string new_fitness_assignment_method = fitness_assignment_method_element->GetText();
03623
03624 try
03625 {
03626 set_fitness_assignment_method(new_fitness_assignment_method);
03627 }
03628 catch(std::exception& e)
03629 {
03630 std::cout << e.what() << std::endl;
03631 }
03632 }
03633
03634
03635
03636 TiXmlElement* selection_method_element = evolutionary_algorithm_element->FirstChildElement("SelectionMethod");
03637
03638 if(selection_method_element)
03639 {
03640 std::string new_selection_method = selection_method_element->GetText();
03641
03642 try
03643 {
03644 set_selection_method(new_selection_method);
03645 }
03646 catch(std::exception& e)
03647 {
03648 std::cout << e.what() << std::endl;
03649 }
03650 }
03651
03652
03653
03654 TiXmlElement* recombination_method_element = evolutionary_algorithm_element->FirstChildElement("RecombinationMethod");
03655
03656 if(recombination_method_element)
03657 {
03658 std::string new_recombination_method = recombination_method_element->GetText();
03659
03660 try
03661 {
03662 set_recombination_method(new_recombination_method);
03663 }
03664 catch(std::exception& e)
03665 {
03666 std::cout << e.what() << std::endl;
03667 }
03668 }
03669
03670
03671
03672 TiXmlElement* mutation_method_element = evolutionary_algorithm_element->FirstChildElement("MutationMethod");
03673
03674 if(mutation_method_element)
03675 {
03676 std::string new_mutation_method = mutation_method_element->GetText();
03677
03678 try
03679 {
03680 set_mutation_method(new_mutation_method);
03681 }
03682 catch(std::exception& e)
03683 {
03684 std::cout << e.what() << std::endl;
03685 }
03686 }
03687
03688
03689
03690 TiXmlElement* elitism_element = evolutionary_algorithm_element->FirstChildElement("Elitism");
03691
03692 if(elitism_element)
03693 {
03694 std::string new_elitism = elitism_element->GetText();
03695
03696 try
03697 {
03698 set_elitism(new_elitism != "0");
03699 }
03700 catch(std::exception& e)
03701 {
03702 std::cout << e.what() << std::endl;
03703 }
03704 }
03705
03706
03707
03708 TiXmlElement* selective_pressure_element = evolutionary_algorithm_element->FirstChildElement("SelectivePressure");
03709
03710 if(selective_pressure_element)
03711 {
03712 double new_selective_pressure = atof(selective_pressure_element->GetText());
03713
03714 try
03715 {
03716 set_selective_pressure(new_selective_pressure);
03717 }
03718 catch(std::exception& e)
03719 {
03720 std::cout << e.what() << std::endl;
03721 }
03722 }
03723
03724
03725
03726 TiXmlElement* recombination_size_element = evolutionary_algorithm_element->FirstChildElement("RecombinationSize");
03727
03728 if(recombination_size_element)
03729 {
03730 double new_recombination_size = atof(recombination_size_element->GetText());
03731
03732 try
03733 {
03734 set_recombination_size(new_recombination_size);
03735 }
03736 catch(std::exception& e)
03737 {
03738 std::cout << e.what() << std::endl;
03739 }
03740 }
03741
03742
03743
03744 TiXmlElement* mutation_rate_element = evolutionary_algorithm_element->FirstChildElement("MutationRate");
03745
03746 if(mutation_rate_element)
03747 {
03748 double new_mutation_rate = atof(mutation_rate_element->GetText());
03749
03750 try
03751 {
03752 set_mutation_rate(new_mutation_rate);
03753 }
03754 catch(std::exception& e)
03755 {
03756 std::cout << e.what() << std::endl;
03757 }
03758 }
03759
03760
03761
03762 TiXmlElement* mutation_range_element = evolutionary_algorithm_element->FirstChildElement("MutationRange");
03763
03764 if(mutation_rate_element)
03765 {
03766 double new_mutation_range = atof(mutation_range_element->GetText());
03767
03768 try
03769 {
03770 set_mutation_range(new_mutation_range);
03771 }
03772 catch(std::exception& e)
03773 {
03774 std::cout << e.what() << std::endl;
03775 }
03776 }
03777
03778
03779
03780 TiXmlElement* mean_performance_goal_element = evolutionary_algorithm_element->FirstChildElement("MeanPerformanceGoal");
03781
03782 if(mean_performance_goal_element)
03783 {
03784 double new_mean_performance_goal = atof(mean_performance_goal_element->GetText());
03785
03786 try
03787 {
03788 set_mean_performance_goal(new_mean_performance_goal);
03789 }
03790 catch(std::exception& e)
03791 {
03792 std::cout << e.what() << std::endl;
03793 }
03794 }
03795
03796
03797
03798 TiXmlElement* standard_deviation_performance_goal_element = evolutionary_algorithm_element->FirstChildElement("StandardDeviationPerformanceGoal");
03799
03800 if(standard_deviation_performance_goal_element)
03801 {
03802 double new_standard_deviation_performance_goal = atof(standard_deviation_performance_goal_element->GetText());
03803
03804 try
03805 {
03806 set_standard_deviation_performance_goal(new_standard_deviation_performance_goal);
03807 }
03808 catch(std::exception& e)
03809 {
03810 std::cout << e.what() << std::endl;
03811 }
03812 }
03813
03814
03815
03816 TiXmlElement* maximum_generations_number_element = evolutionary_algorithm_element->FirstChildElement("MaximumGenerationsNumber");
03817
03818 if(maximum_generations_number_element)
03819 {
03820 unsigned int new_maximum_generations_number = atoi(maximum_generations_number_element->GetText());
03821
03822 try
03823 {
03824 set_maximum_generations_number(new_maximum_generations_number);
03825 }
03826 catch(std::exception& e)
03827 {
03828 std::cout << e.what() << std::endl;
03829 }
03830 }
03831
03832
03833
03834 TiXmlElement* maximum_generalization_evaluation_decreases_element = evolutionary_algorithm_element->FirstChildElement("MaximumGeneralizationEvaluationDecreases");
03835
03836 if(maximum_generalization_evaluation_decreases_element)
03837 {
03838 unsigned int new_maximum_generalization_evaluation_decreases = atoi(maximum_generalization_evaluation_decreases_element->GetText());
03839
03840 try
03841 {
03842 set_maximum_generalization_evaluation_decreases(new_maximum_generalization_evaluation_decreases);
03843 }
03844 catch(std::exception& e)
03845 {
03846 std::cout << e.what() << std::endl;
03847 }
03848 }
03849 }
03850
03851
03852
03853
03854 double EvolutionaryAlgorithm::calculate_random_uniform(const double& minimum, const double& maximum) const
03855 {
03856 double random = (double)rand()/(RAND_MAX+1.0);
03857
03858 double random_uniform = minimum + (maximum-minimum)*random;
03859
03860 return(random_uniform);
03861 }
03862
03863
03864
03865
03866 double EvolutionaryAlgorithm::calculate_random_normal(const double& mean, const double& standard_deviation) const
03867 {
03868 double random_normal = 0.0;
03869
03870 const double pi = 4.0*atan(1.0);
03871
03872 double random_uniform_1;
03873 double random_uniform_2;
03874
03875 do
03876 {
03877 random_uniform_1 = (double)rand()/(RAND_MAX+1.0);
03878
03879 }while(random_uniform_1 == 0.0);
03880
03881 random_uniform_2 = (double)rand()/(RAND_MAX+1.0);
03882
03883
03884
03885 random_normal = mean + sqrt(-2.0*log(random_uniform_1))*sin(2.0*pi*random_uniform_2)*standard_deviation;
03886
03887 return(random_normal);
03888 }
03889
03890 }
03891
03892
03893
03894
03895
03896
03897
03898
03899
03900
03901
03902
03903
03904
03905
03906
03907
03908