Changeset 1000 for cpp/frams/genetics/fS/fS_oper.cpp
- Timestamp:
- 07/13/20 13:53:25 (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
cpp/frams/genetics/fS/fS_oper.cpp
r974 r1000 12 12 { 13 13 {"Genetics: fS", 1, FS_OPCOUNT + 5,}, 14 {"fS_mut_add_part", 0, 0, "Add part", "f 0 100 10", FIELD(prob[FS_ADD_PART]), "mutation: probability of adding a part",},15 {"fS_mut_rem_part", 0, 0, "Remove part", "f 0 100 10", FIELD(prob[FS_REM_PART]), "mutation: probability of deleting a part",},16 {"fS_mut_mod_part", 0, 0, "Modify part", "f 0 100 10", FIELD(prob[FS_MOD_PART]), "mutation: probability of changing the part type",},17 {"fS_mut_change_joint", 0, 0, "Change joint", "f 0 100 10", FIELD(prob[FS_CHANGE_JOINT]),"mutation: probability of changing a joint",},18 {"fS_mut_add_param", 0, 0, "Add param", "f 0 100 10", FIELD(prob[FS_ADD_PARAM]), "mutation: probability of adding a parameter",},19 {"fS_mut_rem_param", 0, 0, "Remove param", "f 0 100 10", FIELD(prob[FS_REM_PARAM]), "mutation: probability of removing a parameter",},20 {"fS_mut_mod_param", 0, 0, "Modify param", "f 0 100 10", FIELD(prob[FS_MOD_PARAM]), "mutation: probability of modifying a parameter",},21 {"fS_mut_mod_mod", 0, 0, "Modify modifier", "f 0 100 10", FIELD(prob[FS_MOD_MOD]), "mutation: probability of modifying a modifier",},22 {"fS_mut_add_neuro", 0, 0, "Add neuron", "f 0 100 10", FIELD(prob[FS_ADD_NEURO]), "mutation: probability of adding a neuron",},23 {"fS_mut_rem_neuro", 0, 0, "Remove neuron", "f 0 100 10", FIELD(prob[FS_REM_NEURO]), "mutation: probability of removing a neuron",},24 {"fS_mut_mod_neuro_conn", 0, 0, "Modify neuron connection","f 0 100 10", FIELD(prob[FS_MOD_NEURO_CONNECTION]), "mutation: probability of changing a neuron connection",},25 {"fS_mut_add_neuro_conn", 0, 0, "Add neuron connection", "f 0 100 10", FIELD(prob[FS_ADD_NEURO_CONNECTION]), "mutation: probability of adding a neuron connection",},26 {"fS_mut_rem neuro_conn", 0, 0, "Remove neuron connection", "f 0 100 10", FIELD(prob[FS_REM_NEURO_CONNECTION]), "mutation: probability of removing a neuron connection",},27 {"fS_mut_mod_neuro_params", 0, 0, "Modify neuron params", "f 0 100 10", FIELD(prob[FS_MOD_NEURO_PARAMS]), "mutation: probability of changing a neuron param",},28 {"fS_circle_section", 0, 0, "Ensure circle section", "d 0 1 1", FIELD(ensureCircleSection), "Ensure that ellipsoids and cylinders have circle cross-section"},29 {"fS_use_elli", 0, 0, "Use ellipsoids in mutations", "d 0 1 1", FIELD(useElli),"Use ellipsoids in mutations"},30 {"fS_use_cub", 0, 0, "Use cuboids in mutations", "d 0 1 1", FIELD(useCub),"Use cuboids in mutations"},31 {"fS_use_cyl", 0, 0, "Use cylinders in mutations", "d 0 1 1", FIELD(useCyl),"Use cylinders in mutations"},32 {"fS_mut_add_part_strong", 0, 0, "Strong add part mutation", "d 0 1 1", FIELD(strongAddPart),"Add part mutation will produce more parametrized parts"},14 {"fS_mut_add_part", 0, 0, "Add part", "f 0 100 10", FIELD(prob[FS_ADD_PART]), "mutation: probability of adding a part",}, 15 {"fS_mut_rem_part", 0, 0, "Remove part", "f 0 100 10", FIELD(prob[FS_REM_PART]), "mutation: probability of deleting a part",}, 16 {"fS_mut_mod_part", 0, 0, "Modify part", "f 0 100 10", FIELD(prob[FS_MOD_PART]), "mutation: probability of changing the part type",}, 17 {"fS_mut_change_joint", 0, 0, "Change joint", "f 0 100 10", FIELD(prob[FS_CHANGE_JOINT]), "mutation: probability of changing a joint",}, 18 {"fS_mut_add_param", 0, 0, "Add param", "f 0 100 10", FIELD(prob[FS_ADD_PARAM]), "mutation: probability of adding a parameter",}, 19 {"fS_mut_rem_param", 0, 0, "Remove param", "f 0 100 10", FIELD(prob[FS_REM_PARAM]), "mutation: probability of removing a parameter",}, 20 {"fS_mut_mod_param", 0, 0, "Modify param", "f 0 100 10", FIELD(prob[FS_MOD_PARAM]), "mutation: probability of modifying a parameter",}, 21 {"fS_mut_mod_mod", 0, 0, "Modify modifier", "f 0 100 10", FIELD(prob[FS_MOD_MOD]), "mutation: probability of modifying a modifier",}, 22 {"fS_mut_add_neuro", 0, 0, "Add neuron", "f 0 100 10", FIELD(prob[FS_ADD_NEURO]), "mutation: probability of adding a neuron",}, 23 {"fS_mut_rem_neuro", 0, 0, "Remove neuron", "f 0 100 10", FIELD(prob[FS_REM_NEURO]), "mutation: probability of removing a neuron",}, 24 {"fS_mut_mod_neuro_conn", 0, 0, "Modify neuron connection", "f 0 100 10", FIELD(prob[FS_MOD_NEURO_CONNECTION]), "mutation: probability of changing a neuron connection",}, 25 {"fS_mut_add_neuro_conn", 0, 0, "Add neuron connection", "f 0 100 10", FIELD(prob[FS_ADD_NEURO_CONNECTION]), "mutation: probability of adding a neuron connection",}, 26 {"fS_mut_rem neuro_conn", 0, 0, "Remove neuron connection", "f 0 100 10", FIELD(prob[FS_REM_NEURO_CONNECTION]), "mutation: probability of removing a neuron connection",}, 27 {"fS_mut_mod_neuro_params", 0, 0, "Modify neuron params", "f 0 100 10", FIELD(prob[FS_MOD_NEURO_PARAMS]), "mutation: probability of changing a neuron param",}, 28 {"fS_circle_section", 0, 0, "Ensure circle section", "d 0 1 1", FIELD(ensureCircleSection), "Ensure that ellipsoids and cylinders have circle cross-section"}, 29 {"fS_use_elli", 0, 0, "Use ellipsoids in mutations", "d 0 1 1", FIELD(useElli), "Use ellipsoids in mutations"}, 30 {"fS_use_cub", 0, 0, "Use cuboids in mutations", "d 0 1 1", FIELD(useCub), "Use cuboids in mutations"}, 31 {"fS_use_cyl", 0, 0, "Use cylinders in mutations", "d 0 1 1", FIELD(useCyl), "Use cylinders in mutations"}, 32 {"fS_mut_add_part_strong", 0, 0, "Strong add part mutation", "d 0 1 1", FIELD(strongAddPart), "Add part mutation will produce more parametrized parts"}, 33 33 }; 34 34 35 35 #undef FIELDSTRUCT 36 37 38 39 const std::map<string, double> minValues = { 40 {INGESTION, 0},//Model::getMinPart().ingest}, 41 {FRICTION, 0},//Model::getMinPart().friction}, 42 {STIFFNESS, 0.1}, 43 {ROT_X, -M_PI}, 44 {ROT_Y, -M_PI}, 45 {ROT_Z, -M_PI}, 46 {RX, -M_PI}, 47 {RY, -M_PI}, 48 {RZ, -M_PI}, 49 {SIZE, 0.01}, 50 {SIZE_X, 0},//Model::getMinPart().scale.x}, 51 {SIZE_Y, 0},//Model::getMinPart().scale.y}, 52 {SIZE_Z, 0}//Model::getMinPart().scale.z} 53 }; 54 55 const std::map<string, double> maxValues = { 56 {INGESTION, 1},//Model::getMaxPart().ingest}, 57 {FRICTION, 1},//Model::getMaxPart().friction}, 58 {STIFFNESS, 0.5}, 59 {ROT_X, M_PI}, 60 {ROT_Y, M_PI}, 61 {ROT_Z, M_PI}, 62 {RX, M_PI}, 63 {RY, M_PI}, 64 {RZ, M_PI}, 65 {SIZE, 100.0}, 66 {SIZE_X, 1},//Model::getMaxPart().scale.x}, 67 {SIZE_Y, 1},//Model::getMaxPart().scale.y}, 68 {SIZE_Z, 1}//Model::getMaxPart().scale.z} 69 }; 70 36 71 37 72 GenoOper_fS::GenoOper_fS() … … 49 84 fS_Genotype genotype(geno); 50 85 int errorPosition = genotype.checkValidityOfPartSizes(); 51 if (errorPosition != 0)52 { 53 logPrintf("GenoOper_fS", "checkValidity", LOG_ ERROR, "Invalid part size");86 if (errorPosition != 0) 87 { 88 logPrintf("GenoOper_fS", "checkValidity", LOG_WARN, "Invalid part size"); 54 89 return errorPosition; 55 90 } … … 57 92 catch (fS_Exception &e) 58 93 { 59 logPrintf("GenoOper_fS", "checkValidity", LOG_ ERROR, e.what());94 logPrintf("GenoOper_fS", "checkValidity", LOG_WARN, e.what()); 60 95 return 1 + e.errorPosition; 61 96 } … … 66 101 int GenoOper_fS::mutate(char *&geno, float &chg, int &method) 67 102 { 68 fS_Genotype genotype(geno); 69 70 // Calculate available part types 71 string availableTypes; 72 if(useElli) 73 availableTypes += ELLIPSOID; 74 if(useCub) 75 availableTypes += CUBOID; 76 if(useCyl) 77 availableTypes += CYLINDER; 78 79 // Select a mutation 80 bool result = false; 81 method = GenoOperators::roulette(prob, FS_OPCOUNT); 82 switch (method) 83 { 84 case FS_ADD_PART: 85 result = addPart(genotype, availableTypes); 86 break; 87 case FS_REM_PART: 88 result = removePart(genotype); 89 break; 90 case FS_MOD_PART: 91 result = changePartType(genotype, availableTypes); 92 break; 93 case FS_CHANGE_JOINT: 94 result = changeJoint(genotype); 95 break; 96 case FS_ADD_PARAM: 97 result = addParam(genotype); 98 break; 99 case FS_REM_PARAM: 100 result = removeParam(genotype); 101 break; 102 case FS_MOD_PARAM: 103 result = changeParam(genotype); 104 break; 105 case FS_MOD_MOD: 106 result = changeModifier(genotype); 107 break; 108 case FS_ADD_NEURO: 109 result = addNeuro(genotype); 110 break; 111 case FS_REM_NEURO: 112 result = removeNeuro(genotype); 113 break; 114 case FS_MOD_NEURO_CONNECTION: 115 result = changeNeuroConnection(genotype); 116 break; 117 case FS_ADD_NEURO_CONNECTION: 118 result = addNeuroConnection(genotype); 119 break; 120 case FS_REM_NEURO_CONNECTION: 121 result = removeNeuroConnection(genotype); 122 break; 123 case FS_MOD_NEURO_PARAMS: 124 result = changeNeuroParam(genotype); 125 break; 126 } 127 128 if (result) 129 { 130 free(geno); 131 geno = strdup(genotype.getGeno().c_str()); 132 return GENOPER_OK; 133 } 134 return GENOPER_OPFAIL; 103 try 104 { 105 fS_Genotype genotype(geno); 106 107 // Calculate available part types 108 vector <Part::Shape> availablePartShapes; 109 if (useElli) 110 availablePartShapes.push_back(Part::Shape::SHAPE_ELLIPSOID); 111 if (useCub) 112 availablePartShapes.push_back(Part::Shape::SHAPE_CUBOID); 113 if (useCyl) 114 availablePartShapes.push_back(Part::Shape::SHAPE_CYLINDER); 115 116 // Select a mutation 117 bool result = false; 118 method = GenoOperators::roulette(prob, FS_OPCOUNT); 119 switch (method) 120 { 121 case FS_ADD_PART: 122 result = addPart(genotype, availablePartShapes); 123 break; 124 case FS_REM_PART: 125 result = removePart(genotype); 126 break; 127 case FS_MOD_PART: 128 result = changePartType(genotype, availablePartShapes); 129 break; 130 case FS_CHANGE_JOINT: 131 result = changeJoint(genotype); 132 break; 133 case FS_ADD_PARAM: 134 result = addParam(genotype); 135 break; 136 case FS_REM_PARAM: 137 result = removeParam(genotype); 138 break; 139 case FS_MOD_PARAM: 140 result = changeParam(genotype); 141 break; 142 case FS_MOD_MOD: 143 result = changeModifier(genotype); 144 break; 145 case FS_ADD_NEURO: 146 result = addNeuro(genotype); 147 break; 148 case FS_REM_NEURO: 149 result = removeNeuro(genotype); 150 break; 151 case FS_MOD_NEURO_CONNECTION: 152 result = changeNeuroConnection(genotype); 153 break; 154 case FS_ADD_NEURO_CONNECTION: 155 result = addNeuroConnection(genotype); 156 break; 157 case FS_REM_NEURO_CONNECTION: 158 result = removeNeuroConnection(genotype); 159 break; 160 case FS_MOD_NEURO_PARAMS: 161 result = changeNeuroParam(genotype); 162 break; 163 } 164 165 if (result) 166 { 167 free(geno); 168 geno = strdup(genotype.getGeno().c_str()); 169 return GENOPER_OK; 170 } 171 return GENOPER_OPFAIL; 172 } 173 catch (fS_Exception &e) 174 { 175 logPrintf("GenoOper_fS", "mutate", LOG_WARN, e.what()); 176 return GENOPER_OPFAIL; 177 } 135 178 } 136 179 137 180 int GenoOper_fS::crossOver(char *&g0, char *&g1, float &chg0, float &chg1) 138 181 { 139 assert(PARENT_COUNT == 2); // Cross over works only for 2 parents 140 fS_Genotype *parents[PARENT_COUNT] = {new fS_Genotype(g0), new fS_Genotype(g1)}; 141 142 // Choose random subtrees that have similar size 143 Node *selected[PARENT_COUNT]; 144 vector<Node*> allNodes0 = parents[0]->getAllNodes(); 145 vector<Node*> allNodes1 = parents[1]->getAllNodes(); 146 147 double bestQuotient = DBL_MAX; 148 for (int i = 0; i < crossOverTries; i++) 149 { 150 Node *tmp0 = allNodes0[rndUint(allNodes0.size())]; 151 Node *tmp1 = allNodes1[rndUint(allNodes1.size())]; 152 // Choose this pair if it is the most similar 153 double quotient = double(tmp0->getNodeCount()) / double(tmp1->getNodeCount()); 154 if(quotient < 1.0) 155 quotient = 1.0 / quotient; 156 if (quotient < bestQuotient) 157 { 158 bestQuotient = quotient; 159 selected[0] = tmp0; 160 selected[1] = tmp1; 161 } 162 if (bestQuotient == 1.0) 163 break; 164 } 165 166 // Compute gene percentages in children 167 double subtreeSizes[PARENT_COUNT], restSizes[PARENT_COUNT]; 168 for (int i = 0; i < PARENT_COUNT; i++) 169 { 170 171 subtreeSizes[i] = selected[i]->getNodeCount(); 172 restSizes[i] = parents[i]->getNodeCount() - subtreeSizes[i]; 173 } 174 chg0 = restSizes[0] / (restSizes[0] + subtreeSizes[1]); 175 chg1 = restSizes[1] / (restSizes[1] + subtreeSizes[0]); 176 177 // Rearrange neurons before crossover 178 int subOldStart[PARENT_COUNT] {-1, -1}; 179 rearrangeConnectionsBeforeCrossover(parents[0], selected[0], subOldStart[0]); 180 rearrangeConnectionsBeforeCrossover(parents[1], selected[1], subOldStart[1]); 181 182 // Swap the subtress 183 for(int i=0; i<PARENT_COUNT; i++) 184 { 185 Node *other = selected[1 - i]; 186 Node *p = selected[i]->parent; 187 if (p != nullptr) 188 { 189 size_t index = std::distance(p->children.begin(), std::find(p->children.begin(), p->children.end(), selected[i])); 190 p->children[index] = other; 191 } else 192 parents[i]->startNode = other; 193 } 194 195 // Rearrange neurons after crossover 196 rearrangeConnectionsAfterCrossover(parents[0], selected[1], subOldStart[0]); 197 rearrangeConnectionsAfterCrossover(parents[1], selected[0], subOldStart[1]); 198 199 // Clenup, assign children to result strings 200 free(g0); 201 free(g1); 202 g0 = strdup(parents[0]->getGeno().c_str()); 203 g1 = strdup(parents[1]->getGeno().c_str()); 204 205 delete parents[0]; 206 delete parents[1]; 182 try 183 { 184 assert(PARENT_COUNT == 2); // Cross over works only for 2 parents 185 fS_Genotype *parents[PARENT_COUNT] = {new fS_Genotype(g0), new fS_Genotype(g1)}; 186 187 // Choose random subtrees that have similar size 188 Node *selected[PARENT_COUNT]; 189 vector < Node * > allNodes0 = parents[0]->getAllNodes(); 190 vector < Node * > allNodes1 = parents[1]->getAllNodes(); 191 192 double bestQuotient = DBL_MAX; 193 for (int i = 0; i < crossOverTries; i++) 194 { 195 Node *tmp0 = allNodes0[rndUint(allNodes0.size())]; 196 Node *tmp1 = allNodes1[rndUint(allNodes1.size())]; 197 // Choose this pair if it is the most similar 198 double quotient = double(tmp0->getNodeCount()) / double(tmp1->getNodeCount()); 199 if (quotient < 1.0) 200 quotient = 1.0 / quotient; 201 if (quotient < bestQuotient) 202 { 203 bestQuotient = quotient; 204 selected[0] = tmp0; 205 selected[1] = tmp1; 206 } 207 if (bestQuotient == 1.0) 208 break; 209 } 210 211 // Compute gene percentages in children 212 double subtreeSizes[PARENT_COUNT], restSizes[PARENT_COUNT]; 213 for (int i = 0; i < PARENT_COUNT; i++) 214 { 215 216 subtreeSizes[i] = selected[i]->getNodeCount(); 217 restSizes[i] = parents[i]->getNodeCount() - subtreeSizes[i]; 218 } 219 chg0 = restSizes[0] / (restSizes[0] + subtreeSizes[1]); 220 chg1 = restSizes[1] / (restSizes[1] + subtreeSizes[0]); 221 222 // Rearrange neurons before crossover 223 int subOldStart[PARENT_COUNT] {-1, -1}; 224 rearrangeConnectionsBeforeCrossover(parents[0], selected[0], subOldStart[0]); 225 rearrangeConnectionsBeforeCrossover(parents[1], selected[1], subOldStart[1]); 226 227 // Swap the subtress 228 for (int i = 0; i < PARENT_COUNT; i++) 229 { 230 Node *other = selected[1 - i]; 231 Node *p = selected[i]->parent; 232 if (p != nullptr) 233 { 234 size_t index = std::distance(p->children.begin(), std::find(p->children.begin(), p->children.end(), selected[i])); 235 p->children[index] = other; 236 } else 237 parents[i]->startNode = other; 238 } 239 240 // Rearrange neurons after crossover 241 rearrangeConnectionsAfterCrossover(parents[0], selected[1], subOldStart[0]); 242 rearrangeConnectionsAfterCrossover(parents[1], selected[0], subOldStart[1]); 243 244 // Clenup, assign children to result strings 245 free(g0); 246 free(g1); 247 g0 = strdup(parents[0]->getGeno().c_str()); 248 g1 = strdup(parents[1]->getGeno().c_str()); 249 250 delete parents[0]; 251 delete parents[1]; 252 } 253 catch (fS_Exception &e) 254 { 255 logPrintf("GenoOper_fS", "crossOver", LOG_WARN, e.what()); 256 return GENOPER_OPFAIL; 257 } 207 258 return GENOPER_OK; 208 259 } 209 260 210 const char *GenoOper_fS::getSimplest()211 { 212 return " C{x=0.80599;y=0.80599;z=0.80599}";261 const char *GenoOper_fS::getSimplest() 262 { 263 return "1.1:C{x=0.80599;y=0.80599;z=0.80599}"; 213 264 } 214 265 … … 220 271 { 221 272 style = GENSTYLE_RGBS(0, 0, 200, GENSTYLE_BOLD); 222 } 223 else if(JOINTS.find(ch) != string::npos) // Joint type 273 } else if (JOINTS.find(ch) != string::npos) // Joint type 224 274 { 225 275 style = GENSTYLE_RGBS(0, 200, 200, GENSTYLE_BOLD); 226 } 227 else if(MODIFIERS.find(ch) != string::npos) // Modifier 276 } else if (MODIFIERS.find(ch) != string::npos) // Modifier 228 277 { 229 278 style = GENSTYLE_RGBS(0, 200, 0, GENSTYLE_NONE); 230 } 231 else if (isdigit(ch) || strchr(".", ch)) // Numerical value 279 } else if (isdigit(ch) || strchr(".", ch)) // Numerical value 232 280 { 233 281 style = GENSTYLE_RGBS(200, 0, 0, GENSTYLE_NONE); 234 } 235 else if(strchr("()_;[],=", ch)) 282 } else if (strchr("()_;[],=", ch)) 236 283 { 237 284 style = GENSTYLE_CS(0, GENSTYLE_BOLD); // Important char … … 243 290 void GenoOper_fS::rearrangeConnectionsBeforeCrossover(fS_Genotype *geno, Node *sub, int &subStart) 244 291 { 245 vector <fS_Neuron*> genoNeurons = geno->getAllNeurons();246 vector <fS_Neuron*> subNeurons = fS_Genotype::extractNeurons(sub);292 vector < fS_Neuron * > genoNeurons = geno->getAllNeurons(); 293 vector < fS_Neuron * > subNeurons = fS_Genotype::extractNeurons(sub); 247 294 248 295 if (!subNeurons.empty()) … … 255 302 void GenoOper_fS::rearrangeConnectionsAfterCrossover(fS_Genotype *geno, Node *sub, int subOldStart) 256 303 { 257 vector <fS_Neuron*> genoNeurons = geno->getAllNeurons();258 vector <fS_Neuron*> subNeurons = fS_Genotype::extractNeurons(sub);304 vector < fS_Neuron * > genoNeurons = geno->getAllNeurons(); 305 vector < fS_Neuron * > subNeurons = fS_Genotype::extractNeurons(sub); 259 306 260 307 // Shift the inputs right … … 281 328 } 282 329 283 bool GenoOper_fS::addPart(fS_Genotype &geno, string availableTypes, bool mutateSize)330 bool GenoOper_fS::addPart(fS_Genotype &geno, const vector <Part::Shape> &availablePartShapes, bool mutateSize) 284 331 { 285 332 geno.getState(); 286 333 Node *node = geno.chooseNode(); 287 char partType = availableTypes[rndUint(availableTypes.length())];334 char partType = SHAPETYPE_TO_GENE.at(availablePartShapes[rndUint(availablePartShapes.size())]); 288 335 289 336 Substring substring(&partType, 0, 1); 290 Node *newNode = new Node(substring, node );337 Node *newNode = new Node(substring, node, node->genotypeParams); 291 338 // Add random rotation 292 string rotationParams[] {ROT_X, ROT_Y, ROT_Z};293 if (strongAddPart)294 { 295 for (int i=0; i < 3; i++)339 string rotationParams[] {ROT_X, ROT_Y, ROT_Z}; 340 if (strongAddPart) 341 { 342 for (int i = 0; i < 3; i++) 296 343 newNode->params[rotationParams[i]] = RndGen.Uni(-M_PI / 2, M_PI / 2); 297 } 298 else 344 } else 299 345 { 300 346 string selectedParam = rotationParams[rndUint(3)]; 301 347 newNode->params[selectedParam] = RndGen.Uni(-M_PI / 2, M_PI / 2); 302 348 } 303 string rParams[] {RX, RY, RZ};304 if (strongAddPart)305 { 306 for (int i=0; i < 3; i++)349 string rParams[] {RX, RY, RZ}; 350 if (strongAddPart) 351 { 352 for (int i = 0; i < 3; i++) 307 353 newNode->params[rParams[i]] = RndGen.Uni(-M_PI / 2, M_PI / 2); 308 } 309 else 354 } else 310 355 { 311 356 string selectedParam = rParams[rndUint(3)]; … … 329 374 { 330 375 geno.getState(); 331 newNode-> changeSizeParam(SIZE_X, true);332 newNode-> changeSizeParam(SIZE_Y, true);333 newNode-> changeSizeParam(SIZE_Z, true);376 newNode->mutateSizeParam(SIZE_X, true); 377 newNode->mutateSizeParam(SIZE_Y, true); 378 newNode->mutateSizeParam(SIZE_Z, true); 334 379 } 335 380 return true; … … 362 407 } 363 408 364 bool GenoOper_fS::changePartType(fS_Genotype &geno, string availTypes)365 { 366 int avail TypesLength = availTypes.length();409 bool GenoOper_fS::changePartType(fS_Genotype &geno, const vector <Part::Shape> &availablePartShapes) 410 { 411 int availShapesLen = availablePartShapes.size(); 367 412 for (int i = 0; i < mutationTries; i++) 368 413 { 369 414 Node *randomNode = geno.chooseNode(); 370 int index = rndUint(availTypesLength); 371 if (availTypes[index] == SHAPETYPE_TO_GENE.at(randomNode->partType)) 372 index = (index + 1 + rndUint(availTypesLength - 1)) % availTypesLength; 373 char newTypeChr = availTypes[index]; 374 375 auto itr = GENE_TO_SHAPETYPE.find(newTypeChr); 376 Part::Shape newType = itr->second; 415 int index = rndUint(availShapesLen); 416 if (availablePartShapes[index] == randomNode->partType) 417 index = (index + 1 + rndUint(availShapesLen - 1)) % availShapesLen; 418 Part::Shape newType = availablePartShapes[index]; 377 419 378 420 #ifdef _DEBUG … … 385 427 double relativeVolume = randomNode->calculateVolume() / pow(sizeMultiplier, 3.0); 386 428 387 if (!ensureCircleSection || newType == Part::Shape::SHAPE_CUBOID || (randomNode->partType == Part::Shape::SHAPE_ELLIPSOID && newType == Part::Shape::SHAPE_CYLINDER))429 if (!ensureCircleSection || newType == Part::Shape::SHAPE_CUBOID || (randomNode->partType == Part::Shape::SHAPE_ELLIPSOID && newType == Part::Shape::SHAPE_CYLINDER)) 388 430 { 389 431 double radiusQuotient = std::cbrt(volumeMultipliers.at(randomNode->partType) / volumeMultipliers.at(newType)); … … 391 433 randomNode->params[SIZE_Y] = randomNode->getParam(SIZE_Y) * radiusQuotient; 392 434 randomNode->params[SIZE_Z] = randomNode->getParam(SIZE_Z) * radiusQuotient; 393 } 394 else if(randomNode->partType == Part::Shape::SHAPE_CUBOID && newType == Part::Shape::SHAPE_CYLINDER) 435 } else if (randomNode->partType == Part::Shape::SHAPE_CUBOID && newType == Part::Shape::SHAPE_CYLINDER) 395 436 { 396 437 double newRadius = 0.5 * (randomNode->getParam(SIZE_X) + randomNode->getParam(SIZE_Y)); 397 randomNode->params[SIZE_X] = newRadius;438 randomNode->params[SIZE_X] = 0.5 * relativeVolume / (M_PI * newRadius * newRadius); 398 439 randomNode->params[SIZE_Y] = newRadius; 399 randomNode->params[SIZE_Z] = 0.5 * relativeVolume / (M_PI * newRadius * newRadius); 400 } 401 else if(newType == Part::Shape::SHAPE_ELLIPSOID) 440 randomNode->params[SIZE_Z] = newRadius; 441 } else if (newType == Part::Shape::SHAPE_ELLIPSOID) 402 442 { 403 443 double newRelativeRadius = cbrt(relativeVolume / volumeMultipliers.at(newType)); … … 405 445 randomNode->params[SIZE_Y] = newRelativeRadius; 406 446 randomNode->params[SIZE_Z] = newRelativeRadius; 407 } 408 else 447 } else 409 448 { 410 449 throw fS_Exception("Invalid part type", 1); … … 422 461 423 462 Node *randomNode = geno.chooseNode(1); // First part does not have joints 424 int jointLen 463 int jointLen = ALL_JOINTS.length(); 425 464 int index = rndUint(jointLen); 426 465 if (ALL_JOINTS[index] == randomNode->joint) … … 441 480 return false; 442 481 // Do not allow invalid changes in part size 443 bool isRadiusOfBase = key == SIZE_ X || key == SIZE_Y;444 bool isRadius = isRadiusOfBase || key == SIZE_ Z;482 bool isRadiusOfBase = key == SIZE_Y || key == SIZE_Z; 483 bool isRadius = isRadiusOfBase || key == SIZE_X; 445 484 if (ensureCircleSection && isRadius) 446 485 { … … 486 525 487 526 // Do not allow invalid changes in part size 488 if ( it->first != SIZE_X && it->first != SIZE_Y && it->first != SIZE_Z)527 if (std::find(SIZE_PARAMS.begin(), SIZE_PARAMS.end(), it->first) == SIZE_PARAMS.end()) 489 528 { 490 529 it->second = GenoOperators::mutateCreep('f', it->second, minValues.at(it->first), maxValues.at(it->first), true); 491 530 return true; 492 531 } else 493 return randomNode-> changeSizeParam(it->first, ensureCircleSection);532 return randomNode->mutateSizeParam(it->first, ensureCircleSection); 494 533 } 495 534 } … … 516 555 Node *randomNode = geno.chooseNode(); 517 556 fS_Neuron *newNeuron; 518 NeuroClass *rndclass = GenoOperators::getRandomNeuroClass(Model::SHAPE _SOLIDS);519 if (rndclass->preflocation == 2&& randomNode == geno.startNode)557 NeuroClass *rndclass = GenoOperators::getRandomNeuroClass(Model::SHAPETYPE_SOLIDS); 558 if (rndclass->preflocation == NeuroClass::PREFER_JOINT && randomNode == geno.startNode) 520 559 return false; 521 560 … … 526 565 { 527 566 // Create as many connections for the neuron as possible (at most prefinputs) 528 vector <fS_Neuron*> allNeurons = geno.getAllNeurons();567 vector < fS_Neuron * > allNeurons = geno.getAllNeurons(); 529 568 vector<int> neuronsWithOutput; 530 569 for (int i = 0; i < int(allNeurons.size()); i++) … … 574 613 bool GenoOper_fS::changeNeuroConnection(fS_Genotype &geno) 575 614 { 576 vector <fS_Neuron*> neurons = geno.getAllNeurons();615 vector < fS_Neuron * > neurons = geno.getAllNeurons(); 577 616 if (neurons.empty()) 578 617 return false; … … 597 636 bool GenoOper_fS::addNeuroConnection(fS_Genotype &geno) 598 637 { 599 vector <fS_Neuron*> neurons = geno.getAllNeurons();638 vector < fS_Neuron * > neurons = geno.getAllNeurons(); 600 639 if (neurons.empty()) 601 640 return false; … … 627 666 bool GenoOper_fS::removeNeuroConnection(fS_Genotype &geno) 628 667 { 629 vector <fS_Neuron*> neurons = geno.getAllNeurons();668 vector < fS_Neuron * > neurons = geno.getAllNeurons(); 630 669 if (neurons.empty()) 631 670 return false; … … 649 688 bool GenoOper_fS::changeNeuroParam(fS_Genotype &geno) 650 689 { 651 vector <fS_Neuron*> neurons = geno.getAllNeurons();690 vector < fS_Neuron * > neurons = geno.getAllNeurons(); 652 691 if (neurons.empty()) 653 692 return false; … … 656 695 return GenoOperators::mutateRandomNeuroClassProperty(neu); 657 696 } 697 698 bool Node::mutateSizeParam(string key, bool ensureCircleSection) 699 { 700 double oldValue = getParam(key); 701 double volume = calculateVolume(); 702 double valueAtMinVolume, valueAtMaxVolume; 703 if(key == SIZE) 704 { 705 valueAtMinVolume = oldValue * std::cbrt(Model::getMinPart().volume / volume); 706 valueAtMaxVolume = oldValue * std::cbrt(Model::getMaxPart().volume / volume); 707 } 708 else 709 { 710 valueAtMinVolume = oldValue * Model::getMinPart().volume / volume; 711 valueAtMaxVolume = oldValue * Model::getMaxPart().volume / volume; 712 } 713 714 double min = std::max(minValues.at(key), valueAtMinVolume); 715 double max = std::min(maxValues.at(key), valueAtMaxVolume); 716 717 params[key] = GenoOperators::mutateCreep('f', getParam(key), min, max, true); 718 719 if (!ensureCircleSection || isPartSizeValid()) 720 return true; 721 else 722 { 723 params[key] = oldValue; 724 return false; 725 } 726 }
Note: See TracChangeset
for help on using the changeset viewer.