From 420ada2dde4af8d71bc1d9c6988311961cf47f1b Mon Sep 17 00:00:00 2001 From: daniel aschauer Date: Fri, 9 Jan 2009 17:23:55 +0000 Subject: svn path=/trunk/externals/algocomp/; revision=10494 --- genetic.c | 218 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100755 genetic.c (limited to 'genetic.c') diff --git a/genetic.c b/genetic.c new file mode 100755 index 0000000..5c908f2 --- /dev/null +++ b/genetic.c @@ -0,0 +1,218 @@ +#include "m_pd.h" +#include +#include +#include + +#define TRUE 1 +#define FALSE 0 +#define MAX_ARRAY_SIZE 256 +//typedef short boolean; + +static t_class *genetic_class; + +typedef struct _individual { + boolean genes[MAX_ARRAY_SIZE]; + float fitness; + t_int length; +} t_individual; + +typedef struct _genetic { + t_object x_obj; + float cumulativeprobability; + t_int individuallength; + t_individual population[MAX_ARRAY_SIZE]; + t_int populationsize; + t_individual targetindividual; + t_atom out[MAX_ARRAY_SIZE]; + t_int chunksize; + t_outlet *outlist; +} t_genetic; + +void randomizeIndividuals(t_genetic *x) { + int i,k; + for (k=0;kpopulationsize;k++) { + for (i=0;iindividuallength;i++) { + x->population[k].genes[i] = ((t_float) rand())/RAND_MAX*2; + } + x->population[k].length = x->individuallength; + } +// x->population[0].genes[0] = 1; +// x->population[0].genes[1] = 0; +} + +void printTarget(t_genetic *x) { + unsigned int out[MAX_ARRAY_SIZE]; + int i; + for (i=0;i< x->targetindividual.length/x->chunksize;i++) { + fast_b2short(&out[i],&x->targetindividual.genes[i*x->chunksize],x->chunksize); + SETFLOAT(&x->out[i],out[i]); + } + outlet_list(x->outlist,&s_list, i, &x->out[0]); +} + + +void randomTargetIndividual(t_genetic *x) { + int i; + for (i=0;iindividuallength;i++) { + x->targetindividual.genes[i] = ((t_float) rand())/RAND_MAX*2; + } + x->targetindividual.length = x->individuallength; + //printTarget(&x->targetindividual,x); +} + +/*float evaluateFitness(t_genetic *x,int index) { + int fitness = 0; + int i; +// post("Fitness eval"); + for (i=0;iindividuallength;i++) { + //if (x->targetindividual.genes[i] == x->population[index].genes[i]) + //if (x->population[index].genes[i] == TRUE) + fitness += x->population[0].genes[0]; + //fitness++; + } + return fitness/x->individuallength; + //return 1; +} +*/ +void startReproduction(t_genetic *x) { + int selectedIndividuals[MAX_ARRAY_SIZE]; + int count = 0; + int i; + float r; + t_individual childs[MAX_ARRAY_SIZE]; + int childindex = 0; + for (count =0; count < x->populationsize/4; count++) { + float sum = 0; + i = 0; + r = ((t_float) rand())/RAND_MAX * x->cumulativeprobability; + while (r > sum) { + sum += x->population[i].fitness; + i++; + } + selectedIndividuals[count] = i; + } + post("parents: %d",count); + i=0; + while (iindividuallength; + for (l=0;lindividuallength;l++) { + if (lpopulation[selectedIndividuals[i]].genes[l]; + else childs[childindex].genes[l] = x->population[selectedIndividuals[i+1]].genes[l]; + } + // mutation + r = ((t_float) rand())/RAND_MAX * x->individuallength; + childs[childindex].genes[(int)r] = 1-childs[childindex].genes[(int)r]; + childindex++; + } + i+=2; + } + for (i=0;ipopulation[i] = childs[i]; + } + post("New childs: %d",childindex); + +} + + +int evaluatePopulation(t_genetic *x) { + int i,k; + int f; + int highestfitnessindex = 0; + float highestfitness = 0; + float mean; + x->cumulativeprobability = 0; + for (k=0; k < x->populationsize; k++) { + float fitness = 0; + for (i=0;iindividuallength;i++) { + //x->population[k].genes[i] = 0; + if (x->targetindividual.genes[i] == x->population[k].genes[i]) + fitness++; +// fitness += x->population[k].genes[i]; + } + x->population[k].fitness = fitness/x->individuallength; + x->population[k].fitness = (fitness/x->individuallength)*(fitness/x->individuallength); + + if (x->population[k].fitness > highestfitness) { + // post("fitness of %d: %f",k,fitness); + highestfitness = x->population[k].fitness; + highestfitnessindex = k; + } + x->cumulativeprobability+=x->population[k].fitness; + } + //recalculate + mean = x->cumulativeprobability/x->populationsize; + x->cumulativeprobability = 0; + for (k=0;k < x->populationsize; k++) { + if (x->population[k].fitness < mean) + x->population[k].fitness = 0; + else x->cumulativeprobability += x->population[k].fitness; + } + post("Highest fitness: %f",highestfitness); + return highestfitnessindex; +} + + +void genetic_setTarget(t_genetic *x,t_symbol *s, int argc, t_atom *argv) { +int i; +post("target called: %d",argc); + for (i=0;i< x->individuallength/x->chunksize;i++) { + if (i >= argc) break; + fast_d2bl(atom_getint(&argv[i]),&x->targetindividual.genes[i*x->chunksize],x->chunksize); + + } + printTarget(x); +} + +void genetic_randomize(t_genetic *x) { +post("Randomize called"); +randomizeIndividuals(x); +} + +void genetic_bang(t_genetic *x) +{ + int selected = 1; + unsigned int out[MAX_ARRAY_SIZE]; + int i; + selected = evaluatePopulation(x); + //post("Selected individual: %d",selected); + for (i=0;i< x->individuallength/x->chunksize;i++) { + //out[i] = ((t_float) rand())/RAND_MAX*2; + fast_b2short(&out[i],&x->population[selected].genes[i*x->chunksize],x->chunksize); + //fast_b2short8(&out[i],&x->population[selected].genes[i*8]); + SETFLOAT(&x->out[i],out[i]); + } + // fast_b2d(&out,&x->population[0].genes[0]); +// fast_b2short(&out,&x->population[0].genes[0]); +// fast_b2d(&out,&test[0]); +// out = 100; +// SETFLOAT(&x->out[1],out); + outlet_list(x->outlist,&s_list, i, &x->out[0]); + startReproduction(x); +} + + +/* + * take argument rule, size, and offset + */ +void *genetic_new(t_float popsize,t_float indsize, t_float chunksize) +{ + t_genetic *x = (t_genetic *)pd_new(genetic_class); + //inlet_new(&x->x_obj, &x->x_obj.ob_pd,gensym("list"), gensym("randomize")); + if ((popsize > 0) && (popsize <= 256)) + x->populationsize = popsize; + else x->populationsize = 256; + if ((indsize > 0) && (indsize <= 256)) + x->individuallength = indsize; + else x->individuallength = 256; + if ((chunksize <= 16) && (chunksize > 0)) + x->chunksize = (int) chunksize; + else x->chunksize = 8; + randomizeIndividuals(x); + randomTargetIndividual(x); + inlet_new(&x->x_obj, &x->x_obj.ob_pd,gensym("list"), gensym("target")); + x->outlist = outlet_new(&x->x_obj,&s_list); + return (void *)x; +} -- cgit v1.2.1