Guest User

Untitled

a guest
Apr 19th, 2018
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.28 KB | None | 0 0
  1. /*
  2. * Practicing genetic algoritms
  3. * Daniel Mateos
  4. * Problem: find an equation out of 0-9 *+/- that comes up with 42
  5. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <math.h>
  10.  
  11. #define GENES 10
  12. #define CHROMOSOMES 16
  13. #define TARGETVAL 10 //42
  14.  
  15. struct chromosome {
  16. char *gene[GENES];
  17. float fitness;
  18. };
  19.  
  20. static int binstr2dec(char *binstr);
  21. static void init_chromosomes(struct chromosome c[], int count);
  22. static void kill_chromosomes(struct chromosome c[], int count);
  23. static void print_chromosomes(struct chromosome c[], int count);
  24. static int parse_chromosome(struct chromosome *c, int *resbuff, int bsize);
  25. static float set_fitness(struct chromosome *c);
  26. int main(int argc, char *argv[]);
  27.  
  28. /* Convert a string of chars representing binary into a decimal value. */
  29. static int binstr2dec(char *binstr) {
  30. int i, val, valadd;
  31. val = 0;
  32. valadd = 1;
  33. for(i = strlen(binstr); i > 0; i--) {
  34. if(binstr[i-1] == '1')
  35. val += valadd;
  36. valadd *= 2;
  37. }
  38. return val;
  39. }
  40.  
  41. /* Init an array of chromosome structures with random values. */
  42. static void init_chromosomes(struct chromosome c[], int count) {
  43. int i, y, z;
  44. srand(time(NULL));
  45. /* For each chromosone. */
  46. for(i = 0; i < count; i++) {
  47. c[i].fitness = 0;
  48. /* For each gene. */
  49. for(y = 0; y < GENES; y++) {
  50. c[i].gene[y] = malloc(5); /* Each gene stores 4 bins + a null. */
  51. /* Each gene char. */
  52. for(z = 0; z < 5; z++) {
  53. c[i].gene[y][z] = (rand() % 2) ? '1' : '0';
  54. }
  55. c[i].gene[y][4] = '\0';
  56. }
  57. }
  58. }
  59.  
  60. /* Free up memory allocation of chromosomes, hi valgrind!. */
  61. static void kill_chromosomes(struct chromosome c[], int count) {
  62. int i, y;
  63. for(i = 0; i < count; i++)
  64. for(y = 0; y < GENES; y++)
  65. free(c[i].gene[y]);
  66. }
  67.  
  68. /* Crudely print the chromosome structure and a basic translation of
  69. * its insides. */
  70. static void print_chromosomes(struct chromosome c[], int count) {
  71. int i, y, parsebuff[1024], pcnt;
  72.  
  73. for(i = 0; i < count; i++) {
  74. printf("CHROMOSOME %d/%d fitness: %f\n", i+1, count, c[i].fitness);
  75. pcnt = parse_chromosome(&c[i], parsebuff, sizeof(int) * 1024);
  76.  
  77. for(y = 0; y < GENES; y++) {
  78. printf("%s(%d) ", c[i].gene[y], binstr2dec(c[i].gene[y]));
  79. }
  80. printf("\n");
  81. for(y = 0; y < pcnt; y++)
  82. switch(parsebuff[y]) {
  83. case 10:
  84. printf("+ ");
  85. break;
  86. case 11:
  87. printf("- ");
  88. break;
  89. case 12:
  90. printf("* ");
  91. break;
  92. case 13:
  93. printf("/ ");
  94. break;
  95. default:
  96. printf("%d ", parsebuff[y]);
  97. break;
  98. }
  99. printf("\n");
  100. }
  101. }
  102.  
  103. /* Parse a chromosomes gene buffer into number -> operator pairs,
  104. * note that we disgard anything between that doesnt make sense. */
  105. static int parse_chromosome(struct chromosome *c, int *resbuff, int bsize) {
  106. int operator, count;
  107. int i, genedec, *origb;
  108.  
  109. count = operator = 0;
  110. origb = resbuff;
  111. operator = 1;
  112. memset(resbuff, '\0', bsize);
  113.  
  114. for(i = 0; i < GENES; i++) {
  115. genedec = binstr2dec(c->gene[i]);
  116.  
  117. /* Looking for an operator? */
  118. if(operator) {
  119. /* Is operator. */
  120. if(genedec > 9 && genedec < 14) {
  121. *resbuff = genedec;
  122. resbuff++;
  123. count++;
  124. operator = 0;
  125. }
  126. }
  127. else {
  128. /* Number. */
  129. if(genedec < 9) {
  130. *resbuff = genedec;
  131. resbuff++;
  132. count++;
  133. operator = 1;
  134. }
  135. }
  136. }
  137.  
  138. /* Fix floaitng points. */
  139. for(i = 0; i < count; i++) {
  140. if(origb[i] == 13 && origb[i+1] == 0)
  141. origb[i] = 10;
  142. }
  143. return count;
  144. }
  145.  
  146. /* Sets a fitness level based on how close the chromosomes
  147. * genes are to matching the number wanted. */
  148. static float set_fitness(struct chromosome *c) {
  149. int i, sum, resbuff[1024], rcount;
  150. float fitness;
  151. rcount = parse_chromosome(c, resbuff, sizeof(int) * 1024);
  152. sum = 0;
  153. fitness = 0.0;
  154.  
  155. /* Catch +*-/ and operate the next value upon them. */
  156. for(i = 0; i < rcount; i+=2) {
  157. switch(resbuff[i]) {
  158. case 10:
  159. sum += resbuff[i+1];
  160. break;
  161. case 11:
  162. sum -= resbuff[i+1];
  163. break;
  164. case 12:
  165. sum *= resbuff[i+1];
  166. break;
  167. case 13:
  168. sum /= resbuff[i+1];
  169. break;
  170. }
  171. }
  172.  
  173. /* Fuck yeah target value. */
  174. if(sum == TARGETVAL)
  175. fitness = 999.0;
  176. else
  177. fitness = 1/fabs((TARGETVAL - sum));
  178.  
  179. c->fitness = fitness;
  180. return fitness;
  181. }
  182.  
  183. int main(int argc, char *argv[]) {
  184. int i, resbuff[1024];
  185. struct chromosome chromes[CHROMOSOMES];
  186. memset(chromes, '\0', sizeof(chromes));
  187.  
  188. init_chromosomes(chromes, CHROMOSOMES);
  189.  
  190. for(i = 0; i < CHROMOSOMES; i++)
  191. set_fitness(&chromes[i]);
  192. print_chromosomes(chromes, CHROMOSOMES);
  193.  
  194. kill_chromosomes(chromes, CHROMOSOMES);
  195. return 0;
  196. }
Add Comment
Please, Sign In to add comment