Changeset 969
- Timestamp:
- 06/30/20 00:32:56 (4 years ago)
- Location:
- cpp/frams/genetics/fS
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
cpp/frams/genetics/fS/fS_general.cpp
r958 r969 10 10 #include "frams/util/rndutil.h" 11 11 #include "frams/neuro/neurolibrary.h" 12 12 #include "../genooperators.h" 13 13 14 14 int fS_Genotype::precision = 4; 15 16 17 double round2(double var) 18 { 19 double value = (int) (var * 100 + .5); 20 return (double) value / 100; 21 } 15 bool fS_Genotype::TURN_WITH_ROTATION = false; 16 22 17 23 18 double fS_stod(const string& str, int start, size_t* size) … … 30 25 { 31 26 throw fS_Exception("Invalid numeric value", start); 27 } 28 catch(const std::out_of_range& ex) 29 { 30 throw fS_Exception("Invalid numeric value; out of range", start); 32 31 } 33 32 } … … 39 38 fr = _state->fr; 40 39 s = _state->s; 40 stif = _state->stif; 41 41 } 42 42 … … 55 55 { 56 56 Orient rotmatrix = Orient_1; 57 rotmatrix.rotate(Pt3D( 58 Convert::toRadians(rotation.x), 59 Convert::toRadians(rotation.y), 60 Convert::toRadians(rotation.z) 61 )); 57 rotmatrix.rotate(rotation); 62 58 vector = rotmatrix.transform(vector); 63 59 } … … 115 111 } 116 112 117 Node::Node(Substring &restOfGeno, bool _modifierMode, bool _paramMode, bool _cycleMode,Node *_parent)113 Node::Node(Substring &restOfGeno, Node *_parent) 118 114 { 119 115 parent = _parent; 120 modifierMode = _modifierMode;121 paramMode = _paramMode;122 cycleMode = _cycleMode;123 116 partDescription = new Substring(restOfGeno); 124 117 … … 293 286 return item->second; 294 287 else 295 return default ParamValues.at(key);288 return defaultValues.at(key); 296 289 } 297 290 … … 415 408 } 416 409 417 double getDistance(Pt3D radiiParent, Pt3D radii, Pt3D vector, Pt3D rotationParent, Pt3D rotation) 418 { 410 double Node::getDistance() 411 { 412 Pt3D size = calculateSize(); 413 Pt3D parentSize = parent->calculateSize(); // Here we are sure that parent is not nullptr 419 414 int parentSphereCount, sphereCount; 420 415 double parentSphereRadius, sphereRadius; 421 Pt3D *centersParent = findSphereCenters(parentSphereCount, parentSphereRadius, radiiParent, rotationParent);422 Pt3D *centers = findSphereCenters(sphereCount, sphereRadius, radii, rotation);416 Pt3D *centersParent = findSphereCenters(parentSphereCount, parentSphereRadius, parentSize, parent->getRotation()); 417 Pt3D *centers = findSphereCenters(sphereCount, sphereRadius, size, getRotation()); 423 418 424 419 double distanceThreshold = sphereRadius + parentSphereRadius; 425 420 double minDistance = 0.0; 426 double maxDistance = 2 * (max3( radiiParent) + max3(radii));421 double maxDistance = 2 * (max3(parentSize) + max3(size)); 427 422 double currentDistance = avg(maxDistance, minDistance); 428 423 int result = -1; 424 int iterationNo = 0; 429 425 while (result != ADJACENT) 430 426 { 431 Pt3D currentVector = vector * currentDistance; 427 iterationNo++; 428 Pt3D currentVector = state->v * currentDistance; 432 429 result = isCollision(centersParent, centers, parentSphereCount, sphereCount, currentVector, distanceThreshold); 430 433 431 if (result == DISJOINT) 434 432 { … … 440 438 currentDistance = avg(maxDistance, currentDistance); 441 439 } 440 441 if(maxDistance <= 0 || iterationNo > 1000) 442 throw fS_Exception("Computing of distances between parts failed", 0); 442 443 if (currentDistance > maxDistance) 444 { 443 445 throw fS_Exception("Internal error; then maximal distance between parts exceeded.", 0); 446 } 444 447 if (currentDistance < minDistance) 445 448 throw fS_Exception("Internal error; the minimal distance between parts exceeded.", 0); … … 449 452 delete[] centersParent; 450 453 delete[] centers; 451 return round2(currentDistance);452 } 453 454 void Node::getState(State *_state , const Pt3D &parentSize)454 return currentDistance; 455 } 456 457 void Node::getState(State *_state) 455 458 { 456 459 if (state != nullptr) … … 473 476 else if (mod == MODIFIERS[2]) 474 477 state->s *= multiplier; 475 } 476 477 Pt3D size = calculateSize(); 478 else if (mod == MODIFIERS[3]) 479 state->stif *= multiplier; 480 } 481 478 482 if (parent != nullptr) 479 483 { … … 481 485 state->rotate(getVectorRotation()); 482 486 483 double distance = getDistance( parentSize, size, state->v, getRotation(), getRotation());487 double distance = getDistance(); 484 488 state->addVector(distance); 485 489 } 486 490 for (int i = 0; i < int(children.size()); i++) 487 children[i]->getState(state , size);491 children[i]->getState(state); 488 492 } 489 493 … … 493 497 for (int i = 0; i < int(branches.size()); i++) 494 498 { 495 children.push_back(new Node(branches[i], modifierMode, paramMode, cycleMode,this));499 children.push_back(new Node(branches[i], this)); 496 500 } 497 501 } … … 593 597 Pt3D Node::getVectorRotation() 594 598 { 595 double rx = getParam(ROT_X); 596 double ry = getParam(ROT_Y); 597 double rz = getParam(ROT_Z); 598 return Pt3D(rx, ry, rz); 599 return Pt3D(getParam(ROT_X), getParam(ROT_Y), getParam(ROT_Z)); 599 600 } 600 601 601 602 Pt3D Node::getRotation() 602 603 { 603 double rx = getParam(RX);604 double ry = getParam(RY);605 double rz = getParam(RZ);606 return Pt3D(rx, ry, rz);604 Pt3D rotation = Pt3D(getParam(RX), getParam(RY), getParam(RZ)); 605 if(fS_Genotype::TURN_WITH_ROTATION) 606 rotation += getVectorRotation(); 607 return rotation; 607 608 } 608 609 … … 614 615 addJointsToModel(model, parent); 615 616 616 617 617 for (int i = 0; i < int(neurons.size()); i++) 618 618 { … … 639 639 { 640 640 part = new Part(partType); 641 part->p = Pt3D( round2(state->location.x),642 round2(state->location.y),643 round2(state->location.z));644 645 part->friction = round2(getParam(FRICTION) * state->fr);646 part->ingest = round2(getParam(INGESTION) * state->ing);641 part->p = Pt3D(state->location.x, 642 state->location.y, 643 state->location.z); 644 645 part->friction = getParam(FRICTION) * state->fr; 646 part->ingest = getParam(INGESTION) * state->ing; 647 647 Pt3D size = calculateSize(); 648 part->scale.x = round2(size.x);649 part->scale.y = round2(size.y);650 part->scale.z = round2(size.z);648 part->scale.x = size.x; 649 part->scale.y = size.y; 650 part->scale.z = size.z; 651 651 part->setRot(getRotation()); 652 652 } … … 655 655 { 656 656 Joint *j = new Joint(); 657 j->stif = getParam(STIFFNESS) * state->stif; 658 j->rotstif = j->stif; 659 657 660 j->attachToParts(parent->part, part); 658 661 switch (joint) … … 698 701 if (i != 0) 699 702 result += NEURON_SEPARATOR; 700 if (n->getClassName() != "N") 701 { 702 result += n->getDetails(); 703 if (!n->inputs.empty()) 704 result += NEURON_INTERNAL_SEPARATOR; 705 } 703 704 result += n->getDetails(); 705 if (!n->inputs.empty()) 706 result += NEURON_INTERNAL_SEPARATOR; 707 706 708 for (auto it = n->inputs.begin(); it != n->inputs.end(); ++it) 707 709 { … … 714 716 result += SString::valueOf(it->second); 715 717 } 716 717 718 } 718 719 } … … 754 755 755 756 756 bool Node::changeSizeParam(string paramKey, double multiplier, bool ensureCircleSection)757 { 758 double oldValue = getParam( paramKey);759 params[ paramKey] = oldValue * multiplier;757 bool Node::changeSizeParam(string key, bool ensureCircleSection) 758 { 759 double oldValue = getParam(key); 760 params[key] = GenoOperators::mutateCreep('f', params[key], minValues.at(key), maxValues.at(key), true); 760 761 if (!ensureCircleSection || isPartSizeValid()) 761 762 return true; 762 763 else 763 764 { 764 params[ paramKey] = oldValue;765 params[key] = oldValue; 765 766 return false; 766 767 } … … 786 787 { 787 788 string geno = genotype.c_str(); 788 // M - modifier mode, S - standard mode 789 size_t modeSeparatorIndex = geno.find(':'); 790 if (modeSeparatorIndex == string::npos) 791 throw fS_Exception("No mode separator", 0); 792 793 string modeStr = geno.substr(0, modeSeparatorIndex).c_str(); 794 bool modifierMode = modeStr.find(MODIFIER_MODE) != string::npos; 795 bool paramMode = modeStr.find(PARAM_MODE) != string::npos; 796 bool cycleMode = modeStr.find(CYCLE_MODE) != string::npos; 797 798 int actualGenoStart = modeSeparatorIndex + 1; 799 Substring substring(geno.c_str(), actualGenoStart, geno.length() - actualGenoStart); 800 startNode = new Node(substring, modifierMode, paramMode, cycleMode, nullptr); 789 Substring substring(geno.c_str(), 0, geno.length()); 790 startNode = new Node(substring, nullptr); 801 791 validateNeuroInputs(); 802 792 } … … 816 806 { 817 807 State *initialState = new State(Pt3D(0), Pt3D(1, 0, 0)); 818 startNode->getState(initialState, Pt3D(1.0)); 819 } 820 821 double fS_Genotype::randomParamMultiplier() 822 { 823 double multiplier = 1 + fabs(RndGen.GaussStd()); 824 if (multiplier > PARAM_MAX_MULTIPLIER) 825 multiplier = PARAM_MAX_MULTIPLIER; 826 if (rndUint(2) == 0) 827 multiplier = 1.0 / multiplier; 828 return multiplier; 808 startNode->getState(initialState); 829 809 } 830 810 … … 833 813 getState(); 834 814 startNode->buildModel(model, nullptr); 835 836 815 buildNeuroConnections(model); 837 838 // Additional joints839 vector<Node*> allNodes = getAllNodes();840 for (int i = 0; i < int(allNodes.size()); i++)841 {842 Node *node = allNodes[i];843 if (node->params.find(JOINT_DISTANCE) != node->params.end())844 {845 Node *otherNode = getNearestNode(allNodes, node);846 if (otherNode != nullptr)847 {848 // If other node is close enough, add a joint849 double distance = node->state->location.distanceTo(otherNode->state->location);850 if (distance < node->params[JOINT_DISTANCE])851 {852 Joint *joint = new Joint();853 joint->attachToParts(node->part, otherNode->part);854 855 joint->shape = Joint::Shape::SHAPE_FIXED;856 model.addJoint(joint);857 }858 }859 }860 }861 816 } 862 817 … … 905 860 SString geno; 906 861 geno.memoryHint(100); // Provide a small buffer from the start to improve performance 907 908 if (startNode->modifierMode)909 geno += MODIFIER_MODE;910 if (startNode->paramMode)911 geno += PARAM_MODE;912 if (startNode->cycleMode)913 geno += CYCLE_MODE;914 915 geno += ':';916 862 startNode->getGeno(geno); 917 863 return geno; … … 1010 956 if (!nodes[i]->isPartSizeValid()) 1011 957 { 1012 return nodes[i]->partDescription->start;958 return 1 + nodes[i]->partDescription->start; 1013 959 } 1014 960 } -
cpp/frams/genetics/fS/fS_general.h
r958 r969 14 14 #include "frams/util/multirange.h" 15 15 16 /** @name Names of genotype modes */17 //@{18 #define MODIFIER_MODE 'M'19 #define PARAM_MODE 'S'20 #define CYCLE_MODE 'J'21 //@}22 23 16 /** @name Values of constants used in encoding */ 24 17 //@{ 25 18 #define BRANCH_START '(' 26 19 #define BRANCH_END ')' 27 #define BRANCH_SEPARATOR ' ,'20 #define BRANCH_SEPARATOR '^' 28 21 #define PARAM_START '{' 29 22 #define PARAM_END '}' … … 45 38 /** @name Every modifier changes the underlying value by this multiplier */ 46 39 const double MODIFIER_MULTIPLIER = 1.1; 47 /** @name In mutation parameters will be multiplied by at most this value */48 const double PARAM_MAX_MULTIPLIER = 1.5;49 50 40 /** 51 41 * Used in finding the proper distance between the parts … … 70 60 #define INGESTION "i" 71 61 #define FRICTION "f" 62 #define STIFFNESS "st" 72 63 #define SIZE "s" 73 64 #define SIZE_X "x" … … 80 71 #define RY "ry" 81 72 #define RZ "rz" 82 #define JOINT_DISTANCE "j"83 73 //@} 84 74 /** @name Macros and values used in collision detection */ … … 113 103 const char DEFAULT_JOINT = 'a'; 114 104 const string JOINTS = "bc"; 105 const string ALL_JOINTS = "abc"; 115 106 const int JOINT_COUNT = JOINTS.length(); 116 const string MODIFIERS = "IFS ";107 const string MODIFIERS = "IFST"; 117 108 const char SIZE_MODIFIER = 's'; 118 109 const vector<string> PARAMS {INGESTION, FRICTION, ROT_X, ROT_Y, ROT_Z, RX, RY, RZ, SIZE, SIZE_X, SIZE_Y, SIZE_Z, 119 JOINT_DISTANCE};110 STIFFNESS}; 120 111 121 112 /** @name Default values of node parameters*/ 122 113 static const Part defPart = Model::getDefPart(); 123 const std::map<string, double> defaultParamValues = { 114 static const Joint defJoint = Model::getDefJoint(); 115 const std::map<Part::Shape, double> volumeMultipliers = { 116 {Part::Shape::SHAPE_CUBOID, 8.0}, 117 {Part::Shape::SHAPE_CYLINDER, 2.0 * M_PI}, 118 {Part::Shape::SHAPE_ELLIPSOID, (4.0 / 3.0) * M_PI}, 119 }; 120 const std::map<string, double> defaultValues = { 124 121 {INGESTION, defPart.ingest}, 125 122 {FRICTION, defPart.friction}, 123 {STIFFNESS, defJoint.stif}, 126 124 {ROT_X, 0.0}, 127 125 {ROT_Y, 0.0}, … … 133 131 {SIZE_X, 1.0}, 134 132 {SIZE_Y, 1.0}, 135 {SIZE_Z, 1.0}, 136 {JOINT_DISTANCE, 1.0} 133 {SIZE_Z, 1.0} 134 }; 135 136 const std::map<string, double> minValues = { 137 {INGESTION, 0}, 138 {FRICTION, 0}, 139 {STIFFNESS, 0.0}, 140 {ROT_X, -M_PI}, 141 {ROT_Y, -M_PI}, 142 {ROT_Z, -M_PI}, 143 {RX, -M_PI}, 144 {RY, -M_PI}, 145 {RZ, -M_PI}, 146 {SIZE, 0.01}, 147 {SIZE_X, 0.01}, 148 {SIZE_Y, 0.01}, 149 {SIZE_Z, 0.01} 150 }; 151 152 const std::map<string, double> maxValues = { 153 {INGESTION, 1.0}, 154 {FRICTION, 1.0}, 155 {STIFFNESS, 0.0}, 156 {ROT_X, M_PI}, 157 {ROT_Y, M_PI}, 158 {ROT_Z, M_PI}, 159 {RX, M_PI}, 160 {RY, M_PI}, 161 {RZ, M_PI}, 162 {SIZE, 100.0}, 163 {SIZE_X, 100.0}, 164 {SIZE_Y, 100.0}, 165 {SIZE_Z, 100.0} 137 166 }; 138 167 … … 252 281 double ing = 1.0; /// Ingestion multiplier 253 282 double s = 1.0; /// Size multipliers 283 double stif = 1.0; /// Stiffness multipliers 254 284 255 285 State(State *_state); /// Derive the state from parent … … 301 331 private: 302 332 Substring *partDescription = nullptr; 303 bool cycleMode, modifierMode, paramMode; /// Possible modes304 333 Node *parent; 305 334 Part *part; /// A part object built from node. Used in building the Model … … 309 338 vector<Node *> children; /// Vector of all direct children 310 339 std::map<char, int> modifiers; /// Vector of all modifiers 311 char joint = DEFAULT_JOINT; /// Set of all joints312 340 vector<fS_Neuron *> neurons; /// Vector of all the neurons 313 341 314 static double calculateRadiusFromVolume(Part::Shape partType, double volume) 315 { 316 double result; 317 switch (partType) 318 { 319 case Part::Shape::SHAPE_CUBOID: 320 result = std::cbrt(volume / 8.0); 321 break; 322 case Part::Shape::SHAPE_CYLINDER: 323 result = std::cbrt(volume / (2.0 * M_PI)); 324 break; 325 case Part::Shape::SHAPE_ELLIPSOID: 326 result = std::cbrt(volume / ((4.0 / 3.0) * M_PI)); 327 break; 328 default: 329 logMessage("fS", "calculateVolume", LOG_ERROR, "Invalid part type"); 330 } 331 return result; 332 } 342 double getDistance(); 333 343 334 344 void cleanUp(); … … 384 394 * @param _state state of the parent 385 395 */ 386 void getState(State *_state , const Pt3D &parentSize);396 void getState(State *_state); 387 397 388 398 /** … … 419 429 420 430 public: 431 char joint = DEFAULT_JOINT; /// Set of all joints 421 432 Part::Shape partType; /// The type of the part 422 433 State *state = nullptr; /// The phenotypic state that inherits from ancestors 423 434 424 Node(Substring &genotype, bool _modifierMode, bool _paramMode, bool _cycleMode,Node *parent);435 Node(Substring &genotype, Node *parent); 425 436 426 437 ~Node(); … … 452 463 * @return True if the parameter value was change, false otherwise 453 464 */ 454 bool changeSizeParam(string paramKey, double multiplier,bool ensureCircleSection);465 bool changeSizeParam(string paramKey, bool ensureCircleSection); 455 466 456 467 /** … … 501 512 502 513 static int precision; 514 static bool TURN_WITH_ROTATION; 503 515 504 516 /** … … 511 523 512 524 void getState(); 513 514 /**515 * Get a random multiplier for parameter mutation516 * @return Random parameter multiplier517 */518 static double randomParamMultiplier();519 525 520 526 /** -
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 } -
cpp/frams/genetics/fS/fS_oper.h
r958 r969 15 15 #define FS_REM_PART 1 16 16 #define FS_MOD_PART 2 17 #define FS_ADD_JOINT 3 18 #define FS_REM_JOINT 4 19 #define FS_ADD_PARAM 5 20 #define FS_REM_PARAM 6 21 #define FS_MOD_PARAM 7 22 #define FS_MOD_MOD 8 23 #define FS_ADD_NEURO 9 24 #define FS_REM_NEURO 10 25 #define FS_MOD_NEURO_CONNECTION 11 26 #define FS_ADD_NEURO_CONNECTION 12 27 #define FS_REM_NEURO_CONNECTION 13 28 #define FS_MOD_NEURO_PARAMS 14 29 #define FS_OPCOUNT 15 17 #define FS_CHANGE_JOINT 3 18 #define FS_ADD_PARAM 4 19 #define FS_REM_PARAM 5 20 #define FS_MOD_PARAM 6 21 #define FS_MOD_MOD 7 22 #define FS_ADD_NEURO 8 23 #define FS_REM_NEURO 9 24 #define FS_MOD_NEURO_CONNECTION 10 25 #define FS_ADD_NEURO_CONNECTION 11 26 #define FS_REM_NEURO_CONNECTION 12 27 #define FS_MOD_NEURO_PARAMS 13 28 #define FS_OPCOUNT 14 30 29 //@} 31 30 … … 90 89 91 90 /** 92 * Performs add joint mutation on genotype91 * Changes the type of one joint in genotype 93 92 * @return true if mutation succeeded, false otherwise 94 93 */ 95 bool addJoint(fS_Genotype &geno); 96 97 /** 98 * Performs remove mutation on genotype 99 * @return true if mutation succeeded, false otherwise 100 */ 101 bool removeJoint(fS_Genotype &geno); 94 bool changeJoint(fS_Genotype &geno); 102 95 103 96 /**
Note: See TracChangeset
for help on using the changeset viewer.