dooooooduo

Practice - Genetic Algorithm - String Matching

Feb 12th, 2017
145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.09 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4.  
  5. #define POPSIZE    1000
  6. #define MUTATERATE 1
  7.  
  8. char target[]   = "To be or not to be";
  9. int  target_len = sizeof(target) - 1;
  10.  
  11. struct INDIVIDUAL {
  12.     int  fitness;
  13.     char *dna;
  14. };
  15.  
  16. float randFloat (float min, float max) {
  17.     return (max - min) * ((float) rand() / RAND_MAX) + min;
  18. }
  19.  
  20. char generateChar () {
  21.     char rand_char = (rand() % (0x7E - 0x20 + 1)) + 0x20;
  22.     return rand_char;
  23. }
  24.  
  25. void generatePopulation (struct INDIVIDUAL population[POPSIZE]) {
  26.     int i, j;
  27.     for (i = 0; i < POPSIZE; i++) {
  28.         population[i].dna = malloc(sizeof(char) * target_len);
  29.         for (j = 0; j < target_len; j++) {
  30.             population[i].dna[j] = generateChar();
  31.         }
  32.     }
  33. }
  34.  
  35. void calculateFitness (struct INDIVIDUAL *ind) {
  36.     int i;
  37.     ind->fitness = 0;
  38.     for (i = 0; i < target_len; i++) {
  39.         if (target[i] == ind->dna[i]) ind->fitness++;
  40.     }
  41. }
  42.  
  43. int generateRandomIndex(struct INDIVIDUAL population[POPSIZE], int max_fitness) {
  44.     int max_iteration = 999999;
  45.     int i = 0;
  46.     while (i++ < max_iteration) {
  47.         int rand_index = rand() % POPSIZE;
  48.         if (randFloat(0, 1) >= population[rand_index].fitness / max_fitness) continue;
  49.         return rand_index;
  50.     }
  51.     return 0;
  52. }
  53.  
  54. int evolve (struct INDIVIDUAL population[POPSIZE]) {
  55.     // Calculating fitness and copy them into a new array;
  56.     int i;
  57.     int max_fitness   = -999;
  58.     int total_fitness = 0;
  59.     int max_index     = -1;
  60.     for (i = 0; i < POPSIZE; i++) {
  61.         calculateFitness(&population[i]);
  62.         if (population[i].fitness > max_fitness) {
  63.             max_fitness = population[i].fitness;
  64.             max_index   = i;
  65.         }
  66.     }
  67.     printf("%s\n", population[max_index].dna);
  68.  
  69.     int j;
  70.     struct INDIVIDUAL new_population[POPSIZE];
  71.     for (i = 0; i < POPSIZE; i++) {
  72.         // Cross over & mutate
  73.         struct INDIVIDUAL child;
  74.         struct INDIVIDUAL parent_a = population[generateRandomIndex(population, max_fitness)];
  75.         struct INDIVIDUAL parent_b = population[generateRandomIndex(population, max_fitness)];
  76.         int rand_cut = rand() % POPSIZE;
  77.         child.dna = malloc(sizeof(char) * target_len);
  78.         for (j = 0; j < target_len; j++) {
  79.             //child.dna[j] = (rand() % 100) < MUTATERATE ? generateChar() : (j <= rand_cut ? parent_a.dna[j] : parent_b.dna[j]);
  80.             child.dna[j] = (rand() % 100) < MUTATERATE ? generateChar() : (rand() % 2 == 0 ? parent_a.dna[j] : parent_b.dna[j]);
  81.         }
  82.         new_population[i] = child;
  83.     }
  84.  
  85.     // Finished evolving
  86.     for (i = 0; i < POPSIZE; i++) {
  87.         population[i] = new_population[i];
  88.     }
  89.  
  90.     return max_fitness;
  91. }
  92.  
  93. int main () {
  94.  
  95.     srand(time(NULL));
  96.  
  97.     struct INDIVIDUAL population[POPSIZE];
  98.     generatePopulation(population);
  99.  
  100.     int i = 0;
  101.     while (++i) {
  102.         int max_fitness = evolve(population);
  103.         if (max_fitness == target_len) {
  104.             printf("%s\n", target);
  105.             printf("Generations: %d\n", i - 1);
  106.             break;
  107.         }
  108.     }
  109.  
  110.     return 0;
  111. }
Add Comment
Please, Sign In to add comment