Use a genetic algorithm to evolve populations of bit strings.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

179 lines
4.8 KiB

  1. //
  2. #pragma once
  3. //
  4. #include "BitEvolver/Includes.h"
  5. //
  6. #include <memory>
  7. #include <vector>
  8. #include <mutex>
  9. #include <functional>
  10. //
  11. namespace BitEvolver
  12. {
  13. //
  14. class Population
  15. {
  16. //
  17. public:
  18. //
  19. Population();
  20. //
  21. void Reset();
  22. //
  23. void ClearPopulation();
  24. void InitRandomPopulation(int _population_size, int _bit_length);
  25. void RandomizePopulation(int _bit_length);
  26. //
  27. void PopulationChanged();
  28. //
  29. std::vector<std::shared_ptr<class Chromosome>> GetChromosomes();
  30. void GetChromosomes(std::shared_ptr<std::vector<std::shared_ptr<class Chromosome>>> _chromosomes);
  31. std::shared_ptr<class Chromosome> GetChampion();
  32. //
  33. double GetAverageFitness();
  34. double GetAverageFitness(std::vector<std::shared_ptr<class Chromosome>> _chromosomes);
  35. //
  36. void SetCrossoverType(Enums::CrossoverType t);
  37. Enums::CrossoverType GetCrossoverType();
  38. void SetCrossoverOrder(Enums::CrossoverOrder o);
  39. Enums::CrossoverOrder GetCrossoverOrder();
  40. void SetCrossoverBounds(Enums::CrossoverBounds b);
  41. Enums::CrossoverBounds GetCrossoverBounds();
  42. void SetCrossoverPoint(double p);
  43. double GetCrossoverPoint();
  44. void SetCrossoverPointStandardDeviation(double std);
  45. double GetCrossoverPointStandardDeviation();
  46. //
  47. void SetMutationRate(double r);
  48. double GetMutationRate();
  49. //
  50. void SetElitismType(Enums::ElitismType t);
  51. Enums::ElitismType GetElitismType();
  52. void SetElitismRate(double r);
  53. double GetElitismRate();
  54. void SetElitismCount(int c);
  55. int GetElitismCount();
  56. //
  57. void EvaluateFitness(std::function<double(std::shared_ptr<Chromosome>)> evaluation_callback);
  58. void EvaluateError(std::function<double(std::shared_ptr<Chromosome>)> evaluation_callback);
  59. //
  60. void Evolve();
  61. int GetEvolutionNumber();
  62. //
  63. void PrintPopulation();
  64. void PrintPopulation(std::vector<std::shared_ptr<class Chromosome>> _chromosomes);
  65. // Constants
  66. const static int DEFAULT_POPULATION_SIZE = 100;
  67. const static Enums::ElitismType DEFAULT_ELITISM_TYPE = Enums::ElitismType::Rate;
  68. constexpr static double DEFAULT_ELITISM_RATE = 0.01;
  69. const static int DEFAULT_ELITISM_COUNT = 1;
  70. constexpr static double DEFAULT_MUTATION_RATE = 0.01;
  71. //
  72. const static Enums::CrossoverType DEFAULT_CROSSOVER_TYPE = Enums::CrossoverType::Sexual;
  73. const static Enums::CrossoverOrder DEFAULT_CROSSOVER_ORDER = Enums::CrossoverOrder::MamaPapa;
  74. const static Enums::CrossoverBounds DEFAULT_CROSSOVER_BOUNDS = Enums::CrossoverBounds::Wrap;
  75. constexpr static double DEFAULT_CROSSOVER_POINT = 0.7;
  76. constexpr static double DEFAULT_CROSSOVER_POINT_STD = 0.25;
  77. //
  78. private:
  79. //
  80. std::shared_ptr<class Random> random;
  81. std::shared_ptr<class Breeder> breeder;
  82. //
  83. std::vector<std::shared_ptr<class Chromosome>> chromosomes;
  84. int population_size;
  85. bool population_needs_sorting;
  86. int evolution_number;
  87. //
  88. Enums::CrossoverType crossover_type;
  89. Enums::CrossoverOrder crossover_order;
  90. Enums::CrossoverBounds crossover_bounds;
  91. double crossover_point;
  92. double crossover_point_std;
  93. double mutation_rate;
  94. Enums::ElitismType elitism_type;
  95. double elitism_rate;
  96. int elitism_count;
  97. //
  98. std::shared_ptr<class RouletteWheel> roulette_wheel;
  99. //
  100. std::recursive_mutex
  101. population_modification_mutex,
  102. breed_mutex,
  103. evaluate_fitness_mutex,
  104. copy_chromosomes_mutex
  105. ;
  106. //
  107. void InitRandomGenerator();
  108. void InitRouletteWheel();
  109. void InitBreeder();
  110. //
  111. void EnsureSortedPopulation();
  112. //
  113. void BreedNewPopulation(std::shared_ptr<std::vector<std::shared_ptr<Chromosome>>> population_new, int size);
  114. void BreedNewPopulation_Thread(std::shared_ptr<std::vector<std::shared_ptr<Chromosome>>> population_new, int size);
  115. //
  116. int DetermineEliteCount();
  117. void SeedPopulationWithElites(std::shared_ptr<std::vector<std::shared_ptr<Chromosome>>> population_new);
  118. //
  119. void EvaluateFitness_Thread(
  120. std::shared_ptr<std::vector<std::shared_ptr<Chromosome>>> _chromosomes,
  121. std::function<double(std::shared_ptr<Chromosome>)> evaluation_callback
  122. );
  123. void EvaluateError_Thread(
  124. std::shared_ptr<std::vector<std::shared_ptr<Chromosome>>> _chromosomes,
  125. std::function<double(std::shared_ptr<Chromosome>)> evaluation_callback
  126. );
  127. //
  128. void CopyChromosomes(
  129. std::shared_ptr<std::vector<std::shared_ptr<Chromosome>>> _chromosomes_source,
  130. std::shared_ptr<std::vector<std::shared_ptr<Chromosome>>> _chromosomes_destination
  131. );
  132. void CopyChromosomes_Thread(
  133. std::shared_ptr<std::vector<std::shared_ptr<Chromosome>>> _chromosomes_source,
  134. std::shared_ptr<std::vector<std::shared_ptr<Chromosome>>> _chromosomes_destination
  135. );
  136. //
  137. std::shared_ptr<Chromosome> BreedChild();
  138. //
  139. int GetThreadCountSuggestion();
  140. };
  141. };