Advertisement
Guest User

Untitled

a guest
Jun 20th, 2019
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.04 KB | None | 0 0
  1. #ifndef DNA_HPP
  2. #define DNA_HPP
  3.  
  4. #include <iostream>
  5. #include <cstdlib>
  6. #include <ctime>
  7. #include <cstring>
  8. #include <random>
  9. #include <memory>
  10.  
  11. std::string sampleSpace("ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz");
  12.  
  13. class DNA {
  14. private:
  15. int length;
  16. std::vector<char> genes;
  17. float fitness;
  18. bool isDone;
  19.  
  20. // Random engine
  21. static std::mt19937 random;
  22.  
  23. public:
  24. DNA() {
  25. length = 0;
  26. genes.resize(length);
  27. fitness = 0;
  28. isDone = false;
  29. }
  30.  
  31. //----------------------------------------------------------------------
  32. void initialize(int len) {
  33. this -> length = len;
  34. this -> genes.resize(length);
  35. this -> fitness = 0;
  36.  
  37. std::uniform_int_distribution<std::size_t> distribution{0, sampleSpace.length() - 1};
  38. for (int i = 0; i < length; i++) {
  39. genes[i] = sampleSpace.at(distribution(random));
  40. }
  41. }
  42.  
  43. //--------------------------------------------------------------------------
  44.  
  45. DNA(const DNA &temp) {
  46. length = temp.length;
  47. fitness = 0;
  48. isDone = false;
  49. genes.clear();
  50. genes.resize(length);
  51. for (size_t i = 0; i < this -> length; i++) {
  52. this -> genes[i] = char(temp.genes[i]);
  53. }
  54. }
  55.  
  56. //-----------------------------------------------------------------------------
  57.  
  58. DNA operator=(const DNA &temp) {
  59. length = temp.length;
  60. fitness = 0;
  61. genes.clear();
  62. genes.resize(length);
  63. for (size_t i = 0; i < this -> length; i++) {
  64. this -> genes[i] = char(temp.genes[i]);
  65. }
  66.  
  67.  
  68. return *this;
  69. }
  70.  
  71. //-----------------------------------------------------------------------
  72.  
  73. void show() {
  74. for (int i = 0; i < length; i++) {
  75. std::cout<<genes[i];
  76. }
  77. std::cout<<"tfitness:"<<fitness;
  78. }
  79.  
  80. //----------------------------------------------------------------------
  81.  
  82. void calculateFitness(std::string target) {
  83. for (size_t i = 0; i < target.length(); i++) {
  84. if (genes[i] == target.at(i))
  85. fitness++;
  86. }
  87.  
  88. if (fitness == target.length()) {
  89. isDone = true;
  90. }
  91. }
  92.  
  93. //-----------------------------------------------------------------------
  94.  
  95. float getFitness() {
  96. return this -> fitness;
  97. }
  98.  
  99. //----------------------------------------------------------------------
  100.  
  101. void mutate(float mutationRate) {
  102. std::uniform_int_distribution<size_t> sampleDist{0, sampleSpace.length() - 1};
  103. std::uniform_real_distribution<> randDist{0, 1};
  104. for (size_t i = 0; i < length; i++) {
  105. if (randDist(random) < mutationRate) {
  106. genes[i] = sampleSpace.at(sampleDist(random));
  107. }
  108. }
  109. }
  110.  
  111. //------------------------------------------------------------------------
  112.  
  113. DNA gimmeBaby() {
  114. return DNA(*this);
  115. }
  116.  
  117. //-------------------------------------------------------------------------
  118.  
  119. bool getStatus() {
  120. return isDone;
  121. }
  122. };
  123.  
  124. std::mt19937 DNA::random{time(NULL)};
  125.  
  126. #endif
  127.  
  128. #ifndef POPULATION_HPP
  129. #define POPULATION_HPP
  130.  
  131. #include <vector>
  132. #include <ctime>
  133.  
  134. class Population {
  135. private :
  136. size_t size;
  137. std::vector<DNA> population;
  138. float mutationRate;
  139. std::string target;
  140. unsigned int fitnessSum;
  141. size_t generations;
  142. bool isDone;
  143. int bestDna;
  144.  
  145. static std::mt19937 random;
  146. public:
  147. Population(size_t length, float mr, std::string t) {
  148. this -> size = length;
  149. this -> mutationRate = mr;
  150. this -> population.resize(size);
  151. this -> target = t;
  152. this -> fitnessSum = 0;
  153. this -> generations = 0;
  154. this -> isDone = false;
  155. this -> bestDna = 0;
  156.  
  157. for (size_t i = 0; i < size; i++) {
  158. population[i].initialize(target.length());
  159. }
  160. }
  161.  
  162. //------------------------------------------------------------------------------
  163.  
  164. void show() {
  165. size_t len = size < 100 ? size : 100;
  166. for (size_t i = 0; i < len; i++) {
  167. population[i].show();
  168. }
  169. }
  170.  
  171. //---------------------------------------------------------------------------------
  172.  
  173. void calculateFitness() {
  174. for (size_t i = 0; i < size; i++) {
  175. population[i].calculateFitness(this -> target);
  176. }
  177. }
  178.  
  179. //-----------------------------------------------------------------------------------
  180.  
  181. void mutate() {
  182. for (size_t i = 0; i < size; i++) {
  183. population[i].mutate(this -> mutationRate);
  184. }
  185. }
  186.  
  187. //--------------------------------------------------------------------------------------
  188.  
  189. void calculateFitnessSum() {
  190. this -> fitnessSum = 0;
  191. for (size_t i = 0; i < size; i++) {
  192. fitnessSum += population[i].getFitness();
  193. }
  194. }
  195.  
  196. //-------------------------------------------------------------------------------------
  197.  
  198. void naturalSelection() {
  199. std::vector<DNA> newPopulation(size);
  200. DNA parent;
  201. //setBestDna();
  202. //newPopulation[0] = population[bestDna];
  203.  
  204. this -> calculateFitnessSum();
  205.  
  206. for (size_t i = 0; i < size; i++) {
  207. // select parent based on fitness
  208. parent = this -> selectParent();
  209.  
  210. // get baby from him
  211. newPopulation[i] = parent.gimmeBaby();
  212. }
  213.  
  214. this -> population = newPopulation;
  215. this -> generations++;
  216. }
  217.  
  218. //---------------------------------------------------------------------------------------
  219.  
  220. DNA selectParent() {
  221. std::uniform_real_distribution<> randDist{0, double(this -> fitnessSum)};
  222. float rand = randDist(random);
  223. size_t runningSum = 0;
  224. for (int i = 0; i < this -> size; i++) {
  225. runningSum += this -> population[i].getFitness();
  226. if (runningSum > rand) {
  227. return this -> population[i];
  228. }
  229. }
  230.  
  231. // should never get to this point
  232. return DNA();
  233. }
  234.  
  235. //-----------------------------------------------------------------------------------------
  236.  
  237. size_t getGeneration() {
  238. return generations;
  239. }
  240.  
  241. //-----------------------------------------------------------------------------------------
  242.  
  243. void isTargetAchieved() {
  244. for (size_t i = 0; i < size; i++) {
  245. if (population[i].getStatus()) {
  246. isDone = true;
  247. break;
  248. }
  249. }
  250. }
  251.  
  252. //----------------------------------------------------------------------------------------------
  253.  
  254. bool getStatus() {
  255. return isDone;
  256. }
  257.  
  258. //---------------------------------------------------------------------------------------------
  259.  
  260. void setBestDna() {
  261. size_t max = 0;
  262. size_t index = 0;
  263. for (size_t i = 0; i < size; i++) {
  264. if (max < population[i].getFitness()) {
  265. max = population[i].getFitness();
  266. index = i;
  267. }
  268. }
  269. bestDna = index;
  270. }
  271.  
  272. //-----------------------------------------------------------------------------------------------
  273.  
  274. void showBest() {
  275. size_t max = 0;
  276. size_t index = 0;
  277. for (size_t i = 0; i < size; i++) {
  278. if (max < population[i].getFitness()) {
  279. max = population[i].getFitness();
  280. index = i;
  281. }
  282. }
  283.  
  284. population[index].show();
  285. std::cout<<"tgen:"<<generations<<std::endl;
  286. }
  287. };
  288. std::mt19937 Population::random{time(NULL)};
  289. #endif
  290.  
  291. #include <iostream>
  292. #include "DNA.hpp"
  293. #include "population.hpp"
  294.  
  295. // genetic algorithm
  296. // initialize the population
  297. // calculate the fitness
  298. // natural selection
  299. // mutation
  300. // new generation
  301.  
  302. void geneticAlgorithm(std::string target) {
  303. Population p(500, 0.01f, target);
  304. while(true) {
  305. p.calculateFitness();
  306. p.isTargetAchieved();
  307.  
  308. p.showBest();
  309. if (p.getStatus()) {
  310. break;
  311. }
  312. p.naturalSelection();
  313. p.mutate();
  314. }
  315. }
  316.  
  317. int main() {
  318. geneticAlgorithm(std::string{"Hardik Sharma"});
  319. return 0;
  320. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement