summaryrefslogtreecommitdiff
path: root/genalg.example.c
blob: c0f9cf5ee9da4a9f6fca9a26afc4e8e587935abe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "genalg.h"


struct organism_t {
  double fitness, a, b;
};


double randf() {
  return 2.0 * (((double)rand())/RAND_MAX) - 1.0;
}


struct organism_t * org_alloc(int randomize) {
  struct organism_t * org = malloc(sizeof(struct organism_t));
  if (org == NULL) {
    fprintf(stderr, "failed to allocate organism!\n");
    return NULL;
  }

  org->fitness = -1;
  org->a = 0;
  org->b = 0;

  if (randomize) {
    org->a = 20.0 * randf();
    org->b = 20.0 * randf();
  }

  return org;
}


double org_fitness(void *ptr) {
  struct organism_t *org = ptr;
  if (org->fitness >= 0) {
    return org->fitness;
  } else {
    double error = pow(org->a - 14.0, 2) + pow(org->b + 7.0, 2);
    org->fitness = 1.0/(fabs(error)+1);
    return org->fitness;
  }
}


void * create_child(void *ptr) {
  struct organism_t *org = ptr;
  struct organism_t *child = org_alloc(0);
  if (child == NULL) {
    return NULL;
  }
  child->a = org->a + 0.1*randf();
  child->b = org->b + 0.1*randf();
  return child;
}


int main() {
  genalg_t *ga = ga_create(1000, org_fitness, create_child, free);
  for (size_t i=0; i<ga->pop_count; i++) {
    ga->population[i] = org_alloc(1);
  }
  struct genalg_stats_t stats;
  for (int i=0; i<100; i++) {
    ga_replace_population(ga, 60, 50);
    stats = ga_population_statistics(ga);
    struct organism_t *org = stats.best;
    printf(
      "mean: %f, variance: %f\nmin: %f, max: %f\nbest: (%f, %f)\n",
      stats.mean, stats.variance, stats.min, stats.max,
      org->a, org->b
    );
  }
  ga_free(ga);
  return 0;
}