summaryrefslogtreecommitdiff
path: root/genalg.example.c
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2025-10-25 11:09:32 -0500
committersanine <sanine.not@pm.me>2025-10-25 11:09:32 -0500
commitcc69389d79e4bed927e9aa29b8769c2ad4f90d8c (patch)
tree50034136ed2db13d3256b2b24f5271970f138433 /genalg.example.c
create simple genetic algorithm in c
Diffstat (limited to 'genalg.example.c')
-rw-r--r--genalg.example.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/genalg.example.c b/genalg.example.c
new file mode 100644
index 0000000..cfd7d4c
--- /dev/null
+++ b/genalg.example.c
@@ -0,0 +1,78 @@
+#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
+ );
+ }
+ return 0;
+}