Changeset 1157 for cpp/frams/genetics/f9/f9_oper.cpp
- Timestamp:
- 10/01/21 22:52:19 (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
cpp/frams/genetics/f9/f9_oper.cpp
r1005 r1157 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999-202 0Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 1999-2021 Maciej Komosinski and Szymon Ulatowski. 3 3 // See LICENSE.txt for details. 4 4 … … 7 7 #include <common/nonstd.h> //rndUint, rndDouble 8 8 #include <string.h> 9 #include <assert.h> 9 10 10 11 … … 13 14 { 14 15 { "Genetics: f9", 1, 1, }, 15 { "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)", },16 { "f9_mut", 0, 0, "Mutation probability", "f 0 1 0", FIELD(mut_prob), "How many genes should be mutated during single mutation (1=all genes, 0.1=ten percent, 0=one gene)", }, 16 17 { 0, }, 17 18 }; … … 47 48 } 48 49 49 ///Very simple mutation 50 void GenoOper_f9::mutate_replace(char *gene, int i) 51 { 52 char oldgene = gene[i]; 53 const char *pos = strchr(turtle_commands_f9, oldgene); 54 if (pos == NULL) //gene not in the set of allowed commands 55 gene[i] = turtle_commands_f9[rndUint(turtle_commands_f9_count)]; 56 else 57 gene[i] = turtle_commands_f9[((pos - turtle_commands_f9) + 1 + rndUint(turtle_commands_f9_count - 1)) % turtle_commands_f9_count]; //always change to a different command 58 //printf("%c %c\n", oldgene, gene[i]); 59 assert(gene[i] != oldgene); 60 } 61 62 void GenoOper_f9::mutate_add_or_del(char *& gene, int len, int add_0_del_1) 63 { 64 string newgeno(gene); 65 if (add_0_del_1 == 0) //add 66 { 67 int p = rndUint(len + 1); //random location 68 //printf("before add: %s\n",(const char*)newgeno); 69 newgeno = newgeno.substr(0, p) + string(turtle_commands_f9 + rndUint(turtle_commands_f9_count), 1) + newgeno.substr(p); 70 //printf("after add: %s\n",(const char*)newgeno); 71 } 72 else //delete 73 { 74 int p = rndUint(len); //random location 75 //printf("before delete: %s\n",(const char*)newgeno); 76 newgeno = newgeno.substr(0, p) + newgeno.substr(p + 1); 77 //printf("after delete: %s\n",(const char*)newgeno); 78 } 79 free(gene); 80 gene = strdup(newgeno.c_str()); //reallocate 81 } 82 83 ///Simple mutation 50 84 int GenoOper_f9::mutate(char *&gene, float &chg, int &method) 51 85 { 52 86 method = 0; 53 87 int changes = 0, len = strlen(gene); 54 int symbols = strlen(turtle_commands_f9);55 88 56 for (int i = 0; i < len; i++) 57 { 58 if (rndDouble(1) < mut_prob) //normalize prob with the length of the genotype 89 if (mut_prob > 0) 90 for (int i = 0; i < len; i++) 59 91 { 60 char oldgene = gene[i]; 61 gene[i] = turtle_commands_f9[rndUint(symbols)]; 62 if (gene[i] != oldgene) changes++; 92 if (rndDouble(1) < mut_prob) //normalize prob with the length of the genotype 93 { 94 mutate_replace(gene, i); 95 changes++; 96 } 63 97 } 64 }65 98 66 99 if (rndDouble(1) < mut_prob) //add or delete a random char 67 100 { 68 SString newgeno(gene); 69 if (rndUint(2) == 0) //add 70 { 71 int symbols = strlen(turtle_commands_f9); 72 int p = rndUint(len + 1); //random location 73 //printf("before add: %s\n",(const char*)newgeno); 74 newgeno = newgeno.substr(0, p) + SString(turtle_commands_f9 + rndUint(symbols), 1) + newgeno.substr(p); 75 //printf("after add: %s\n",(const char*)newgeno); 76 changes++; 77 } 78 else if (len > 1) //delete 79 { 80 int p = rndUint(len); //random location 81 //printf("before delete: %s\n",(const char*)newgeno); 82 newgeno = newgeno.substr(0, p) + newgeno.substr(p + 1); 83 //printf("after delete: %s\n",(const char*)newgeno); 84 changes++; 85 } 86 free(gene); 87 gene = strdup(newgeno.c_str()); //reallocate 101 int change_add_or_del = 1 + (len > 1); //either add a new symbol (1), or delete a random symbol (+(len>1)) 102 int add_0_del_1 = rndUint(change_add_or_del); 103 mutate_add_or_del(gene, len, add_0_del_1); 104 changes++; 105 } 106 107 if (changes == 0) //if nothing changed so far, then fallback to minimal change: always changes one symbol 108 { 109 int change_what = len + 1 + (len > 1); //either replace an existing gene, or add a new symbol (+1), or delete a random symbol (+(len>1)) 110 int change_selected = rndUint(change_what); 111 if (change_selected < len) 112 mutate_replace(gene, change_selected); 113 else 114 mutate_add_or_del(gene, len, change_selected - len); 115 changes++; 88 116 } 89 117 90 118 chg = (float)changes / len; 91 return changes > 0 ? GENOPER_OK : GENOPER_OPFAIL; //no changes => OPFAIL so that GenMan will call mutate again119 return changes > 0 ? GENOPER_OK : GENOPER_OPFAIL; //no changes? (should never happen) => OPFAIL so that GenMan will call mutate again 92 120 } 93 121
Note: See TracChangeset
for help on using the changeset viewer.