Advertisement
BeneFager

Untitled

Dec 13th, 2022
172
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.85 KB | None | 0 0
  1. #include "Darwin.h"
  2. #include <iostream>
  3. #include <string>
  4.  
  5. Darwin::Darwin()
  6. {
  7.     hf = new HelperFuncs();
  8. }
  9.  
  10. Darwin::~Darwin()
  11. {
  12.     delete hf;
  13.     hf = nullptr;
  14. }
  15.  
  16. #pragma region genome methods
  17.  
  18. std::vector<Gene> Darwin::InitGenes(int topology)
  19. {
  20.     std::vector<int> layers = { layerGeneCount[0], layerGeneCount[1], layerGeneCount[2], layerGeneCount[3] };
  21.     std::vector<Gene> genePerPop;
  22.  
  23.     for(size_t i = 0; i < topology; i++)
  24.     {
  25.         Gene g;
  26.         g.fitness = 0;
  27.         g.index = i;
  28.  
  29.         for(int j = 0; j < hf->GetNumWeights(layers); j++) // fix with proper vector.
  30.         {
  31.             g.weight.push_back(hf->GetRandomNumber(j));
  32.         }
  33.         genePerPop.push_back(g);
  34.  
  35.     }
  36.  
  37.     hf->Save("ReadWriteTest.txt", genePerPop);
  38.     return genePerPop;
  39. }
  40.  
  41. std::vector<Gene> Darwin::LoadGenes(int topology)
  42. {
  43.     std::vector<int> layers = { layerGeneCount[0], layerGeneCount[1], layerGeneCount[2], layerGeneCount[3] };
  44.     std::vector<Gene> genePerPop;
  45.  
  46.     for(size_t i = 0; i < topology; i++)
  47.     {
  48.         Gene g;
  49.         g.fitness = 0;
  50.         g.index = i;
  51.     }
  52.     genePerPop = hf->Load("ReadWriteTest.txt", genePerPop, hf->GetNumWeights(layers));
  53.     return genePerPop;
  54. }
  55.  
  56. std::vector<Gene> Darwin::ByMutation(Population source)
  57. {
  58.     std::vector<Gene> gene = source.genes;
  59.     for(int i = 0; i < gene.size(); i++)
  60.     {
  61.         if(hf->GetRandomNumber(i) < source.mutRate)
  62.         {
  63.             for(int j = 0; j < gene[i].weight.size(); j++)
  64.             {
  65.                 gene[i].weight[j] += hf->GetRandomNumber() * source.mutMax;
  66.                 gene[i].weight[j] -= hf->GetRandomNumber(i) * source.mutMax;
  67.  
  68.                 //clamp value
  69.                 gene[i].weight[j] > 1 ? 1 : gene[i].weight[j];
  70.                 gene[i].weight[j] < -1 ? -1 : gene[i].weight[j];
  71.  
  72.             }
  73.         }
  74.     }
  75.  
  76.     return gene;
  77. }
  78.  
  79. std::vector<Gene> Darwin::ByCrossover(Population mother, Population father)
  80. {
  81.     std::vector<Gene> genes;
  82.     int length = mother.genes.size();
  83.     int point = hf->GetRandomNumber();
  84.     genes.resize(length);
  85.     if(length != father.genes.size())
  86.         return std::vector<Gene>();
  87.     for(int i = 0; i < length; i++)
  88.     {
  89.         if(i < point)
  90.             genes[i] = mother.genes[i];
  91.         else
  92.             genes[i] = father.genes[i];
  93.     }
  94.     return genes;
  95. }
  96.  
  97. #pragma endregion
  98.  
  99. #pragma region population methods
  100.  
  101. void Darwin::InitPopulation(int popSize)
  102. {
  103.     Population p;
  104.     p.avgFitness = 0;
  105.     p.maxFitness = 0;
  106.     p.minFitness = 0;
  107.     p.totalFitness = 0;
  108.     p.mutMax = 0.5f;
  109.     p.mutRate = 0.2f;
  110.     p.numElites = 2;
  111.     p.crossRate = 0.7f;
  112.  
  113.     p.selection = hf->GetRandomSelection();
  114.     p.name = "";
  115.     p.genes = InitGenes(popSize);
  116.  
  117.     activePopulation = p;
  118. }
  119.  
  120. Population Darwin::InitNewPopulation(int popsize)
  121. {
  122.     Population p;
  123.     p.avgFitness = 0;
  124.     p.maxFitness = 0;
  125.     p.minFitness = 0;
  126.     p.totalFitness = 0;
  127.     p.mutMax = 0.5f;
  128.     p.mutRate = 0.2f;
  129.     p.numElites = 2;
  130.     p.crossRate = 0.7f;
  131.  
  132.     p.selection = hf->GetRandomSelection();
  133.     p.name = "";
  134.     p.genes = InitGenes(popsize);
  135.  
  136.     activePopulation = p;
  137.  
  138.     return p;
  139. }
  140.  
  141. void Darwin::LoadPopulation(int popSize)
  142. {
  143.     Population p;
  144.  
  145.     p.mutMax = 0.5f;
  146.     p.mutRate = 0.2f;
  147.     p.numElites = 2;
  148.     p.crossRate = 0.7f;
  149.  
  150.  
  151.     p.selection = hf->GetRandomSelection();
  152.     p.name = "";
  153.     p.genes = LoadGenes(popSize);
  154.  
  155.     activePopulation = p;
  156. }
  157.  
  158. Gene Darwin::SelectGenome(Population pop)
  159. {
  160.  
  161.     std::vector<Gene> selectedGenome;
  162.     selectedGenome.resize(pop.genes.size());
  163.  
  164.     if(pop.selection == E_Selection::roulette)
  165.     {
  166.         float target = hf->GetRandomNumber() * pop.totalFitness;
  167.         float passedFitness = 0;
  168.         for(int i = 0; i < pop.genes.size(); i++)
  169.         {
  170.             passedFitness += pop.genes[i].fitness;
  171.             if(passedFitness >= target)
  172.             {
  173.                 selectedGenome.push_back(pop.genes[i]);
  174.                 break;
  175.             }
  176.         }
  177.     }
  178.     else if(pop.selection == E_Selection::tournament)
  179.     {
  180.         for(int i = 0; i < 3; i++)
  181.         {
  182.             selectedGenome.push_back(pop.genes[hf->GetRandomNumber(i)]);
  183.         }
  184.         hf->SortGenes(selectedGenome); //Otestat
  185.     }
  186.     return selectedGenome.back();
  187. }
  188.  
  189. void Darwin::RecalculatePopulationFitness(Population pop)
  190. {
  191.     float tempMinFit = 10000; //big because might use float max later
  192.     float tempMaxFit = -1; //might use epsilon later
  193.  
  194.     for(int i = 0; i < pop.genes.size(); i++)
  195.     {
  196.         pop.totalFitness += pop.genes[i].fitness;
  197.  
  198.         if(pop.genes[i].fitness > tempMaxFit)
  199.             tempMaxFit = pop.genes[i].fitness;
  200.         if(pop.genes[i].fitness < tempMinFit)
  201.             tempMinFit = pop.genes[i].fitness;
  202.     }
  203.     if(pop.totalFitness != 0)
  204.         pop.avgFitness = pop.totalFitness / pop.genes.size();
  205.  
  206.     pop.maxFitness = tempMaxFit;
  207.     pop.minFitness = tempMinFit;
  208.     hf->SortGenes(pop.genes); //Otestat
  209.  
  210. }
  211.  
  212. void Darwin::EvolvePopulation(Population elites)
  213. {
  214.  
  215.     Population newPopulation;
  216.     int numElites = elites.numElites;
  217.  
  218.     // copy elites
  219.     Population mutated = InitNewPopulation(30);
  220.     for(int i = 0; i < numElites; i++)
  221.     {
  222.         newPopulation.genes.push_back(elites.genes[i]);
  223.         Population mother = InitNewPopulation(30);
  224.         Population father = InitNewPopulation(30);
  225.         Population child;
  226.         mother.genes[mother.genes.size() - 1] = SelectGenome(elites);
  227.         father.genes[father.genes.size() - 1] = SelectGenome(elites);
  228.         child = mother;
  229.  
  230.         if(hf->GetRandomNumber() < elites.crossRate)
  231.             child.genes = ByCrossover(mother, father);
  232.  
  233.         mutated.genes = ByMutation(child);
  234.  
  235.         newPopulation = mutated;
  236.     }
  237.  
  238.  
  239.     elites.genes = newPopulation.genes;
  240.     generations++;
  241. }
  242. #pragma endregion
  243.  
  244. #pragma region gettersNsetters
  245. Population Darwin::GetActivePopulation()
  246. {
  247.     return activePopulation;
  248. }
  249.  
  250.  
  251. int Darwin::GetGeneration()
  252. {
  253.     return generations;
  254. }
  255. std::string Darwin::GetGenerationString(Population pop)
  256. {
  257.     std::string generationString = "Generations: ";
  258.     generationString += std::to_string(generations);
  259.     generationString += " max: ";
  260.     generationString += std::to_string(pop.maxFitness);
  261.     generationString += " avg: ";
  262.     generationString += std::to_string(pop.avgFitness);
  263.     return generationString;
  264. }
  265. Gene Darwin::GetBestGenome(Population pop)
  266. {
  267.     return pop.genes[0];
  268. }
  269. Gene Darwin::GetWorstGenome(Population pop)
  270. {
  271.     return pop.genes.back();
  272. }
  273. #pragma endregion
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement