Changeset 969 for cpp/frams/genetics/fS/fS_oper.cpp
- Timestamp:
- 06/30/20 00:32:56 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified cpp/frams/genetics/fS/fS_oper.cpp ¶
r967 r969 15 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 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_add_joint", 0, 0, "Add joint", "f 0 100 10", FIELD(prob[FS_ADD_JOINT]), "mutation: probability of adding a joint",}, 18 {"fS_mut_rem_joint", 0, 0, "Remove joint", "f 0 100 10", FIELD(prob[FS_REM_JOINT]), "mutation: probability of removing a joint",}, 17 {"fS_mut_change_joint", 0, 0, "Change joint", "f 0 100 10", FIELD(prob[FS_CHANGE_JOINT]), "mutation: probability of changing a joint",}, 19 18 {"fS_mut_add_param", 0, 0, "Add param", "f 0 100 10", FIELD(prob[FS_ADD_PARAM]), "mutation: probability of adding a parameter",}, 20 19 {"fS_mut_rem_param", 0, 0, "Remove param", "f 0 100 10", FIELD(prob[FS_REM_PARAM]), "mutation: probability of removing a parameter",}, … … 41 40 par.select(this); 42 41 par.setDefault(); 43 supported_format = "S";42 supported_format = 'S'; 44 43 } 45 44 … … 53 52 { 54 53 logPrintf("GenoOper_fS", "checkValidity", LOG_ERROR, "Invalid part size"); 55 return 1 +errorPosition;54 return errorPosition; 56 55 } 57 56 } … … 92 91 result = changePartType(genotype, availableTypes); 93 92 break; 94 case FS_ADD_JOINT: 95 result = addJoint(genotype); 96 break; 97 case FS_REM_JOINT: 98 result = removeJoint(genotype); 93 case FS_CHANGE_JOINT: 94 result = changeJoint(genotype); 99 95 break; 100 96 case FS_ADD_PARAM: … … 214 210 const char* GenoOper_fS::getSimplest() 215 211 { 216 return " S:C{x=0.80599;y=0.80599;z=0.80599}";212 return "C{x=0.80599;y=0.80599;z=0.80599}"; 217 213 } 218 214 … … 233 229 style = GENSTYLE_RGBS(0, 200, 0, GENSTYLE_NONE); 234 230 } 235 else if (isdigit(ch) || strchr(". =", ch)) // Numerical value231 else if (isdigit(ch) || strchr(".", ch)) // Numerical value 236 232 { 237 233 style = GENSTYLE_RGBS(200, 0, 0, GENSTYLE_NONE); 238 234 } 239 else if(strchr("()_;[], ", ch))235 else if(strchr("()_;[],=", ch)) 240 236 { 241 237 style = GENSTYLE_CS(0, GENSTYLE_BOLD); // Important char … … 292 288 293 289 Substring substring(&partType, 0, 1); 294 Node *newNode = new Node(substring, node ->modifierMode, node->paramMode, node->cycleMode, node);290 Node *newNode = new Node(substring, node); 295 291 // Add random rotation 296 292 string rotationParams[]{ROT_X, ROT_Y, ROT_Z}; … … 298 294 { 299 295 for(int i=0; i < 3; i++) 300 newNode->params[rotationParams[i]] = RndGen.Uni(- 90, 90);296 newNode->params[rotationParams[i]] = RndGen.Uni(-M_PI / 2, M_PI / 2); 301 297 } 302 298 else 303 299 { 304 300 string selectedParam = rotationParams[rndUint(3)]; 305 newNode->params[selectedParam] = RndGen.Uni(- 90, 90);301 newNode->params[selectedParam] = RndGen.Uni(-M_PI / 2, M_PI / 2); 306 302 } 307 303 string rParams[]{RX, RY, RZ}; … … 309 305 { 310 306 for(int i=0; i < 3; i++) 311 newNode->params[rParams[i]] = RndGen.Uni(- 90, 90);307 newNode->params[rParams[i]] = RndGen.Uni(-M_PI / 2, M_PI / 2); 312 308 } 313 309 else 314 310 { 315 311 string selectedParam = rParams[rndUint(3)]; 316 newNode->params[selectedParam] = RndGen.Uni(- 90, 90);312 newNode->params[selectedParam] = RndGen.Uni(-M_PI / 2, M_PI / 2); 317 313 } 318 314 // Assign part size to default value … … 324 320 double relativeVolume = volume / volumeMultiplier; // Volume without applying modifiers 325 321 326 double newRadius = Node::calculateRadiusFromVolume(newNode->partType, relativeVolume);322 double newRadius = std::cbrt(relativeVolume / volumeMultipliers.at(newNode->partType)); 327 323 newNode->params[SIZE_X] = newRadius; 328 324 newNode->params[SIZE_Y] = newRadius; … … 333 329 { 334 330 geno.getState(); 335 newNode->changeSizeParam(SIZE_X, fS_Genotype::randomParamMultiplier(),true);336 newNode->changeSizeParam(SIZE_Y, fS_Genotype::randomParamMultiplier(),true);337 newNode->changeSizeParam(SIZE_Z, fS_Genotype::randomParamMultiplier(),true);331 newNode->changeSizeParam(SIZE_X, true); 332 newNode->changeSizeParam(SIZE_Y, true); 333 newNode->changeSizeParam(SIZE_Z, true); 338 334 } 339 335 return true; … … 374 370 int index = rndUint(availTypesLength); 375 371 if (availTypes[index] == SHAPETYPE_TO_GENE.at(randomNode->partType)) 376 index = (index + 1 + rndUint(availTypesLength )) % availTypesLength;372 index = (index + 1 + rndUint(availTypesLength - 1)) % availTypesLength; 377 373 char newTypeChr = availTypes[index]; 378 374 … … 385 381 #endif 386 382 387 if (ensureCircleSection) 388 { 389 geno.getState(); 390 if (randomNode->partType == Part::Shape::SHAPE_CUBOID 391 || (randomNode->partType == Part::Shape::SHAPE_CYLINDER && newType == Part::Shape::SHAPE_ELLIPSOID)) 392 { 393 double sizeMultiplier = randomNode->getParam(SIZE) * randomNode->state->s; 394 double relativeVolume = randomNode->calculateVolume() / pow(sizeMultiplier, 3.0); 395 double newRelativeRadius = Node::calculateRadiusFromVolume(newType, relativeVolume); 396 randomNode->params[SIZE_X] = newRelativeRadius; 397 randomNode->params[SIZE_Y] = newRelativeRadius; 398 randomNode->params[SIZE_Z] = newRelativeRadius; 399 } 383 geno.getState(); 384 double sizeMultiplier = randomNode->getParam(SIZE) * randomNode->state->s; 385 double relativeVolume = randomNode->calculateVolume() / pow(sizeMultiplier, 3.0); 386 387 if(!ensureCircleSection || newType == Part::Shape::SHAPE_CUBOID || (randomNode->partType == Part::Shape::SHAPE_ELLIPSOID && newType == Part::Shape::SHAPE_CYLINDER)) 388 { 389 double radiusQuotient = std::cbrt(volumeMultipliers.at(randomNode->partType) / volumeMultipliers.at(newType)); 390 randomNode->params[SIZE_X] = randomNode->getParam(SIZE_X) * radiusQuotient; 391 randomNode->params[SIZE_Y] = randomNode->getParam(SIZE_Y) * radiusQuotient; 392 randomNode->params[SIZE_Z] = randomNode->getParam(SIZE_Z) * radiusQuotient; 393 } 394 else if(randomNode->partType == Part::Shape::SHAPE_CUBOID && newType == Part::Shape::SHAPE_CYLINDER) 395 { 396 double newRadius = 0.5 * (randomNode->getParam(SIZE_X) + randomNode->getParam(SIZE_Y)); 397 randomNode->params[SIZE_X] = newRadius; 398 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) 402 { 403 double newRelativeRadius = cbrt(relativeVolume / volumeMultipliers.at(newType)); 404 randomNode->params[SIZE_X] = newRelativeRadius; 405 randomNode->params[SIZE_Y] = newRelativeRadius; 406 randomNode->params[SIZE_Z] = newRelativeRadius; 407 } 408 else 409 { 410 throw fS_Exception("Invalid part type", 1); 400 411 } 401 412 randomNode->partType = newType; … … 405 416 } 406 417 407 bool GenoOper_fS:: addJoint(fS_Genotype &geno)418 bool GenoOper_fS::changeJoint(fS_Genotype &geno) 408 419 { 409 420 if (geno.startNode->children.empty()) 410 421 return false; 411 422 412 Node *randomNode; 413 for (int i = 0; i < mutationTries; i++) 414 { 415 char randomJoint = JOINTS[rndUint(JOINT_COUNT)]; 416 randomNode = geno.chooseNode(1); // First part does not have joints 417 if (randomNode->joint == DEFAULT_JOINT) 418 { 419 randomNode->joint = randomJoint; 420 return true; 421 } 422 } 423 return false; 424 } 425 426 427 bool GenoOper_fS::removeJoint(fS_Genotype &geno) 428 { 429 // This operator may can lower success rate that others, as it does not work when there is only one node 430 if (geno.startNode->children.size() < 1) // Only one node; there are no joints 431 return false; 432 433 // Choose a node with joints 434 for (int i = 0; i < mutationTries; i++) 435 { 436 Node *randomNode = geno.chooseNode(1); // First part does not have joints 437 if (randomNode->joint != DEFAULT_JOINT) 438 { 439 randomNode->joint = DEFAULT_JOINT; 440 return true; 441 } 442 } 443 return false; 423 Node *randomNode = geno.chooseNode(1); // First part does not have joints 424 int jointLen = ALL_JOINTS.length(); 425 int index = rndUint(jointLen); 426 if (ALL_JOINTS[index] == randomNode->joint) 427 index = (index + 1 + rndUint(jointLen - 1)) % jointLen; 428 429 randomNode->joint = ALL_JOINTS[index]; 430 return true; 444 431 } 445 432 … … 450 437 if (paramCount == int(PARAMS.size())) 451 438 return false; 452 string selectedParam = PARAMS[rndUint(PARAMS.size())]; 453 // Not allow 'j' parameter when the cycle mode is not on 454 if (selectedParam == JOINT_DISTANCE && !geno.startNode->cycleMode) 455 return false; 456 if (randomNode->params.count(selectedParam) > 0) 439 string key = PARAMS[rndUint(PARAMS.size())]; 440 if (randomNode->params.count(key) > 0) 457 441 return false; 458 442 // Do not allow invalid changes in part size 459 bool isRadiusOfBase = selectedParam == SIZE_X || selectedParam== SIZE_Y;460 bool isRadius = isRadiusOfBase || selectedParam== SIZE_Z;443 bool isRadiusOfBase = key == SIZE_X || key == SIZE_Y; 444 bool isRadius = isRadiusOfBase || key == SIZE_Z; 461 445 if (ensureCircleSection && isRadius) 462 446 { … … 467 451 } 468 452 // Add modified default value for param 469 randomNode->params[ selectedParam] = defaultParamValues.at(selectedParam);453 randomNode->params[key] = mutateCreep('f', defaultValues.at(key), minValues.at(key), maxValues.at(key), true); 470 454 return true; 471 455 } … … 501 485 advance(it, rndUint(paramCount)); 502 486 503 double multiplier = fS_Genotype::randomParamMultiplier();504 505 506 487 // Do not allow invalid changes in part size 507 488 if (it->first != SIZE_X && it->first != SIZE_Y && it->first != SIZE_Z) 508 489 { 509 it->second *= multiplier;490 it->second = GenoOperators::mutateCreep('f', it->second, minValues.at(it->first), maxValues.at(it->first), true); 510 491 return true; 511 492 } else 512 return randomNode->changeSizeParam(it->first, multiplier,ensureCircleSection);493 return randomNode->changeSizeParam(it->first, ensureCircleSection); 513 494 } 514 495 } … … 607 588 advance(it, rndUint(inputCount)); 608 589 609 it->second = GenoOperators::getMutatedNeuro ClassProperty(it->second, selectedNeuron, -1);590 it->second = GenoOperators::getMutatedNeuronConnectionWeight(it->second); 610 591 return true; 611 592 } … … 673 654 674 655 fS_Neuron *neu = neurons[rndUint(neurons.size())]; 675 SyntParam par = neu->classProperties(); 676 677 if (par.getPropCount() > 0) 678 { 679 int i = rndUint(par.getPropCount()); 680 if (*par.type(i) == 'f') 681 { 682 double change = GenoOperators::getMutatedNeuroClassProperty(par.getDouble(i), neu, GenoOperators::NEUROCLASS_PROP_OFFSET + i); 683 par.setDouble(i, change); 684 } 685 SString line; 686 int tmp = 0; 687 par.update(&line); 688 SString props; 689 line.getNextToken(tmp, props, '\n'); // removal of newline character 690 if (props != "") 691 { 692 SString det = neu->getClass()->name + ": " + props; 693 neu->setDetails(det); 694 return true; 695 } 696 } 697 698 return false; 699 } 656 return GenoOperators::mutateRandomNeuroClassProperty(neu); 657 }
Note: See TracChangeset
for help on using the changeset viewer.