source: cpp/frams/genetics/f9/oper_f9.cpp @ 166

Last change on this file since 166 was 145, checked in by sz, 11 years ago

Genetics reorganization (affects ALL applications!):

  • Converters/Validators? are now configured/initialized in a more verbose but also less confusing way
  • At the same time, the PreconfiguredGenetics? object will help you avoid the increased complexity by creating the ready-to-use environment that is sufficient in 99% of cases (see the demos)
  • Format F genetics updated (work in progress)
  • Property svn:eol-style set to native
File size: 3.5 KB
Line 
1// This file is a part of the Framsticks GDK.
2// Copyright (C) 2002-2014  Maciej Komosinski and Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.framsticks.com/ for further information.
4
5#include "oper_f9.h"
6#include "conv_f9.h"
7#include <common/nonstd.h> //randomN, rnd01
8
9
10#define FIELDSTRUCT GenoOper_f9
11static ParamEntry GENOf9param_tab[]=
12{
13        {"Genetics: f9",1,1,},
14        {"f9_mut",0,0,"Mutation probability","f 0 1 0.1",FIELD(mut_prob),"How many genes should be mutated during single mutation (1=all genes, 0.1=ten percent)",},
15        {0,},
16};
17#undef FIELDSTRUCT
18
19
20GenoOper_f9::GenoOper_f9()
21{
22        par.setParamTab(GENOf9param_tab);
23        par.select(this);
24        par.setDefault();
25        supported_format='9';
26}
27
28int GenoOper_f9::checkValidity(const char* gene)
29{
30        if (!gene[0]) return 1; //empty is not valid
31        bool ok=true;
32        int i;
33        for(i=0;i<strlen(gene);i++) if (!strchr(turtle_commands_f9,gene[i])) {ok=false; break;}
34        return ok ? GENOPER_OK : i+1;
35}
36
37///Remove all invalid letters from the genotype
38int GenoOper_f9::validate(char *&gene)
39{
40        SString validated; //new genotype (everything except turtle_commands_f9 is skipped)
41        for(int i=0;i<strlen(gene);i++)
42                if (strchr(turtle_commands_f9,gene[i])) validated+=gene[i];  //validated contains only turtle_commands_f9
43        free(gene);
44        gene=strdup(validated); //reallocate
45        return GENOPER_OK;
46}
47
48///Very simple mutation
49int GenoOper_f9::mutate(char *&gene,float &chg,int &method)
50{
51        method=0;
52        int changes=0,len=strlen(gene);
53        int symbols=strlen(turtle_commands_f9);
54
55        for(int i=0;i<len;i++)
56        {
57                if (rnd01<mut_prob) //normalize prob with the length of the genotype
58                {
59                        char oldgene=gene[i];
60                        gene[i]=turtle_commands_f9[randomN(symbols)];
61                        if (gene[i]!=oldgene) changes++;
62                }
63        }
64
65        if (rnd01<mut_prob) //add or delete a random char
66        {
67                SString newgeno(gene);
68                if (randomN(2)==0) //add
69                {
70                        int symbols=strlen(turtle_commands_f9);
71                        int p=randomN(len+1);  //random location
72                        //printf("before add: %s\n",(const char*)newgeno);
73                        newgeno=newgeno.substr(0,p)+SString(turtle_commands_f9+randomN(symbols),1)+newgeno.substr(p);
74                        //printf("after add: %s\n",(const char*)newgeno);
75                        changes++;
76                } else if (len>1) //delete
77                {
78                        int p=randomN(len);  //random location
79                        //printf("before delete: %s\n",(const char*)newgeno);
80                        newgeno=newgeno.substr(0,p)+newgeno.substr(p+1);
81                        //printf("after delete: %s\n",(const char*)newgeno);
82                        changes++;
83                }
84                free(gene);
85                gene=strdup(newgeno); //reallocate
86        }
87
88        chg=(float)changes/len;
89        return changes>0?GENOPER_OK:GENOPER_OPFAIL; //no changes => OPFAIL so that genman will call mutate again
90}
91
92///A simple one-point crossover
93int GenoOper_f9::crossOver(char *&g1,char *&g2,float& chg1,float& chg2)
94{
95        int len1=strlen(g1),len2=strlen(g2);
96        int p1=randomN(len1);  //random cut point for first genotype
97        int p2=randomN(len2);  //random cut point for second genotype
98        char *child1=(char*)malloc(p1+len2-p2+1);
99        char *child2=(char*)malloc(p2+len1-p1+1);
100        strncpy(child1,g1,p1);   strcpy(child1+p1,g2+p2);
101        strncpy(child2,g2,p2);   strcpy(child2+p2,g1+p1);
102        free(g1); g1=child1;
103        free(g2); g2=child2;
104        chg1=(float)p1/strlen(child1);
105        chg2=(float)p2/strlen(child2);
106        return GENOPER_OK;
107}
108
109///Applying some colors and font styles...
110unsigned long GenoOper_f9::style(const char *g, int pos)
111{
112        char ch=g[pos];
113        unsigned long style=GENSTYLE_CS(0,GENSTYLE_INVALID); //default, should be changed below
114        char *ptr=strchr((char*)turtle_commands_f9,ch);
115        if (ptr)
116        {
117                int pos=ptr-turtle_commands_f9;
118                int axis=pos/2;
119                style=GENSTYLE_RGBS(axis==0?200:0,axis==1?200:0,axis==2?200:0,GENSTYLE_NONE);
120        }
121        return style;
122}
Note: See TracBrowser for help on using the repository browser.