ga.c is not related to gopher clustering. - brcon2024-hackathons - Bitreichcon … | |
git clone git://bitreich.org/brcon2024-hackathons git://enlrupgkhuxnvlhsf6lc3fz… | |
Log | |
Files | |
Refs | |
Tags | |
Submodules | |
--- | |
commit 9cb289429418cc40ef9018ce164351cbd0581530 | |
parent 7227ea069b87678e2804e054e2f49960b4b61145 | |
Author: Christoph Lohmann <[email protected]> | |
Date: Sun, 4 Aug 2024 08:36:30 +0200 | |
ga.c is not related to gopher clustering. | |
Diffstat: | |
D gopher/gopher-clustering/ga.c | 206 -----------------------------… | |
1 file changed, 0 insertions(+), 206 deletions(-) | |
--- | |
diff --git a/gopher/gopher-clustering/ga.c b/gopher/gopher-clustering/ga.c | |
@@ -1,206 +0,0 @@ | |
-#include <stdint.h> | |
-#include <stdio.h> | |
-#include <stddef.h> | |
-#include <stdlib.h> | |
-#include <string.h> | |
- | |
-struct machine { | |
- uint8_t a; | |
- | |
- uint8_t loads; | |
- uint8_t adds; | |
- uint8_t subs; | |
- uint8_t times; | |
- uint8_t noops; | |
- | |
- uint8_t instr; | |
-}; | |
- | |
-enum { | |
- LOAD, | |
- ADD, | |
- SUB, | |
- TIMES, | |
- END, | |
-}; | |
- | |
-#define CODE_LENGTH 16 | |
-#define POOL_LENGTH 16 | |
-struct genome { | |
- uint8_t code[CODE_LENGTH + 1]; /* +1 sentinal (0) */ | |
- uint16_t fitness; | |
-} pool[POOL_LENGTH]; | |
- | |
-uint8_t newcode[CODE_LENGTH]; | |
- | |
-void | |
-execute(struct machine *m, size_t l, uint8_t code[]) | |
-{ | |
- size_t ip; | |
- int16_t c; | |
- | |
- for (ip = 0; ip < l;) { | |
- switch (code[ip++] & 0x7) { | |
- case LOAD: | |
- m->loads++; | |
- m->a = code[ip++]; | |
- break; | |
- case ADD: | |
- m->adds++; | |
- c = (int16_t)m->a + code[ip++]; | |
- if (c > 255) | |
- m->a = 0; | |
- else | |
- m->a = c; | |
- break; | |
- case SUB: | |
- m->subs++; | |
- c = (int16_t)m->a - code[ip++]; | |
- if (c < 0) | |
- m->a = 0; | |
- else | |
- m->a = c; | |
- break; | |
- case TIMES: | |
- m->times++; | |
- m->a = (uint16_t)m->a * code[ip++] / 255; | |
- break; | |
- case END: | |
- m->instr++; | |
- return; | |
- break; | |
- default: | |
- m->noops++; | |
- break; | |
- } | |
- m->instr++; | |
- } | |
-} | |
- | |
-void | |
-mutate(uint8_t code[], size_t l) | |
-{ | |
- uint8_t i, bi, j; | |
- | |
- for (j = 0; j < 4; j++) { | |
- if (rand() % 100 >= 50) | |
- continue; | |
- | |
- i = rand() % CODE_LENGTH; | |
- bi = rand() % 8; | |
- | |
- code[i] ^= 1 << bi; | |
- } | |
-} | |
- | |
-#define min(a, b) (((a) < (b)) ? (a) : (b)) | |
- | |
-void | |
-cross(uint8_t a[], size_t al, uint8_t b[], size_t bl, uint8_t c[], size_t cl) | |
-{ | |
- uint8_t i, si, sl; | |
- uint8_t *one, *two; | |
- | |
- if (rand() % 2) { | |
- one = a; | |
- two = b; | |
- } else { | |
- one = b; | |
- two = a; | |
- } | |
- | |
- si = rand() % (min(al, bl) + 1); | |
- sl = rand() % (min(al, bl) - si + 1); | |
- | |
- for (i = 0; i < si; i++) | |
- c[i] = one[i]; | |
- | |
- for (; i < si + sl; i++) | |
- c[i] = two[i]; | |
- | |
- for (; i < cl; i++) | |
- c[i] = one[i]; | |
-} | |
- | |
-void | |
-cross2(uint8_t a[], size_t al, uint8_t b[], size_t bl, uint8_t c[], size_t cl) | |
-{ | |
- uint8_t i; | |
- | |
- for (i = 0; i < al; i++) | |
- c[i] = a[i] + b[i]; | |
-} | |
- | |
-void | |
-printcode(uint8_t code[], size_t l) | |
-{ | |
- uint8_t i; | |
- | |
- for (i = 0; i < l;) { | |
- switch (code[i++] & 0x7) { | |
- case LOAD: | |
- printf("LOAD %d ", code[i++]); | |
- break; | |
- case ADD: | |
- printf("ADD %d ", code[i++]); | |
- break; | |
- case SUB: | |
- printf("SUB %d ", code[i++]); | |
- break; | |
- case TIMES: | |
- printf("TIMES %d ", code[i++]); | |
- break; | |
- case END: | |
- printf("END "); | |
- return; | |
- break; | |
- default: | |
- printf("NOOP "); | |
- break; | |
- } | |
- } | |
-} | |
- | |
-int | |
-main(void) | |
-{ | |
- struct machine m; | |
- struct genome *g1, *g2, *w1; | |
- size_t i, j; | |
- | |
- for (i = 0; i < POOL_LENGTH; i++) { | |
- for (j = 0; j < CODE_LENGTH; j++) | |
- pool[i].code[j] = rand(); | |
- pool[i].code[j] = 0; | |
- } | |
- | |
- do { | |
- g1 = g2 = w1 = NULL; | |
- | |
- for (i = 0; i < POOL_LENGTH; i++) { | |
- memset(&m, 0, sizeof(m)); | |
- | |
- execute(&m, CODE_LENGTH, pool[i].code); | |
- pool[i].fitness = m.a * 255 / (m.instr + m.loads); | |
- | |
- if (!g1 || g1->fitness < pool[i].fitness) { | |
- g2 = g1; | |
- g1 = &pool[i]; | |
- } else if (!g2 || g2->fitness < pool[i].fitness) { | |
- w1 = g2; | |
- g2 = &pool[i]; | |
- } else if (!w1 || w1->fitness > pool[i].fitness) { | |
- w1 = &pool[i]; | |
- } | |
- } | |
- | |
- printf("g1->fitness = %d, g2->fitness = %d, w1->fitness = %d\n… | |
- cross(g1->code, CODE_LENGTH, g2->code, CODE_LENGTH, newcode, C… | |
- mutate(newcode, CODE_LENGTH); | |
- | |
- printcode(newcode, CODE_LENGTH); | |
- puts(""); | |
- | |
- memcpy(w1->code, newcode, CODE_LENGTH); | |
- } while (1); | |
-} |