Changeset 1273


Ignore:
Timestamp:
09/09/23 15:10:49 (15 months ago)
Author:
Maciej Komosinski
Message:

fH, fB, fL: improved default parameter values, syntax coloring and code logic

Location:
cpp/frams/genetics
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/genetics/fB/fB_oper.cpp

    r1130 r1273  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2021  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2023  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
     4
     5//TODO parsing quotes/neurons seems too relaxed, for example the genotype aag"S""acalaaaafbc is considered valid
     6//TODO Same with numbers: "----1.23" is valid
     7//TODO reconsider: Horizontal gene transfer - copying a single random gene from each parent to the beginning of the other parent: should the gene be copied (seems to cause bloat!) or rather moved?
     8//Neurons ("N") can grow even without using quotes and providing neuron classname in the genotype, for example aaaaabbccvaaapdgfddaalaandwddbaajt (this works likely as designed, but investigate and reconsider); also valid neuron definitions inside the genotype are sometimes not expressed
    49
    510#include <frams/util/sstring.h>
     
    1924        { "Genetics: fB: Mutation", },
    2025        { "Genetics: fB: Crossover", },
    21         { "fB_mut_substitution", 1, 0, "Substitution", "f 0 1 0.6", FIELD(mutationprobs[FB_SUBSTITUTION]), "Probability of mutation by changing single random letter in genotype", },
    22         { "fB_mut_insertion", 1, 0, "Insertion", "f 0 1 0.095", FIELD(mutationprobs[FB_INSERTION]), "Probability of mutation by inserting characters in random place of genotype", },
    23         { "fB_mut_nclassins", 1, 0, "Insertion of neuron class definition", "f 0 1 0.005", FIELD(mutationprobs[FB_NCLASSINS]), "Probability of mutation by inserting neuron class definition in random place of genotype", },
    24         { "fB_mut_deletion", 1, 0, "Deletion", "f 0 1 0.1", FIELD(mutationprobs[FB_DELETION]), "Probability of mutation by deleting random characters in genotype", },
    25         { "fB_mut_duplication", 1, 0, "Duplication", "f 0 1 0.0", FIELD(mutationprobs[FB_DUPLICATION]), "Probability of mutation by copying single *gene* of genotype and appending it to the beginning of this genotype", },
    26         { "fB_mut_translocation", 1, 0, "Translocation", "f 0 1 0.15", FIELD(mutationprobs[FB_TRANSLOCATION]), "Probability of mutation by replacing two substrings in genotype", },
    27         { "fB_cross_gene_transfer", 2, 0, "Horizontal gene transfer", "f 0 1 0.0", FIELD(crossoverprobs[FB_GENE_TRANSFER]), "Probability of crossing over by transferring single genes from both parents to beginning of each other", },
    28         { "fB_cross_crossover", 2, 0, "Crossing over", "f 0 1 1.0", FIELD(crossoverprobs[FB_CROSSING_OVER]), "Probability of crossing over by random distribution of genes from both parents to both children", },
     26        { "fB_mut_substitute", 1, 0, "Substitution", "f 0 100 1", FIELD(mutationprobs[FB_SUBSTITUTION]), "Relative probability of changing a single random character (or a neuron) in the genotype", },
     27        { "fB_mut_insert", 1, 0, "Insertion", "f 0 100 3", FIELD(mutationprobs[FB_INSERTION]), "Relative probability of inserting a random character in a random place of the genotype", },
     28        { "fB_mut_insert_neuron", 1, 0, "Insertion of a neuron", "f 0 100 3", FIELD(mutationprobs[FB_INSERTION_NEURON]), "Relative probability of inserting a neuron in a random place of genotype", },
     29        { "fB_mut_delete", 1, 0, "Deletion", "f 0 100 4", FIELD(mutationprobs[FB_DELETION]), "Relative probability of deleting a random character (or a neuron) in the genotype", },
     30        { "fB_mut_duplicate", 1, 0, "Duplication", "f 0 100 0", FIELD(mutationprobs[FB_DUPLICATION]), "Relative probability of copying a single *gene* of the genotype and appending it to the beginning of this genotype", },
     31        { "fB_mut_translocate", 1, 0, "Translocation", "f 0 100 4", FIELD(mutationprobs[FB_TRANSLOCATION]), "Relative probability of swapping two substrings in the genotype", },
     32        { "fB_cross_gene_transfer", 2, 0, "Horizontal gene transfer", "f 0 100 0", FIELD(crossoverprobs[FB_GENE_TRANSFER]), "Relative probability of crossing over by copying a single random gene from each parent to the beginning of the other parent", },
     33        { "fB_cross_crossover", 2, 0, "Crossing over", "f 0 100 100", FIELD(crossoverprobs[FB_CROSSING_OVER]), "Relative probability of crossing over by a random distribution of genes from both parents to both children", },
    2934        { 0, },
    3035};
     
    128133        if (!genotype.getNextToken(pos, strdims, '\n'))
    129134        {
    130                 return GENOPER_OPFAIL;
     135                return GENOPER_OK;
    131136        }
    132137        // parse dimension
     
    134139        if (!ExtValue::parseInt(strdims.c_str(), dims, true, false))
    135140        {
    136                 return GENOPER_OPFAIL;
     141                return GENOPER_OK;
    137142        }
    138143        SString line;
     
    171176                        else
    172177                        {
    173                                 return GENOPER_OPFAIL;
     178                                return GENOPER_OK;
    174179                        }
    175180                }
     
    247252        {
    248253                std::list<SString> tokenized = tokenizeSequence(line);
    249                 int rndid = rndUint(tokenized.size()); // select random letter from genotype
     254                int rndid = rndUint((int)tokenized.size()); // select random letter from genotype
    250255                // increment/decrement character - when overflow happens, this method
    251256                // uses the "reflect" approach
     
    282287                break;
    283288        }
    284         case FB_NCLASSINS:
     289        case FB_INSERTION_NEURON:
    285290        {
    286291                std::list<SString> tokenized = tokenizeSequence(line);
    287292                std::list<SString>::iterator it = tokenized.begin();
    288                 int rndid = rndUint(tokenized.size()); // select random insertion point
     293                int rndid = rndUint((int)tokenized.size()); // select random insertion point
    289294                std::advance(it, rndid);
    290295                NeuroClass *cls = getRandomNeuroClass(Model::SHAPETYPE_BALL_AND_STICK);
     
    307312                chg = 1.0 / line.length();
    308313                std::list<SString> tokenized = tokenizeSequence(line);
    309                 int rndid = rndUint(tokenized.size()); // select random insertion point
     314                int rndid = rndUint((int)tokenized.size()); // select random insertion point
    310315                std::list<SString>::iterator it = tokenized.begin();
    311316                std::advance(it, rndid);
     
    321326                std::list<SString> tokenized = tokenizeSequence(line);
    322327                std::list<SString>::iterator it = tokenized.begin();
    323                 int rndid = rndUint(tokenized.size()); // select random deletion point
     328                int rndid = rndUint((int)tokenized.size()); // select random deletion point
    324329                std::advance(it, rndid);
    325330                tokenized.erase(it);
     
    343348                for (int i = 0; i < 4; i++)
    344349                {
    345                         cuts[i] = rndUint(tokenized.size());
     350                        cuts[i] = rndUint((int)tokenized.size());
    346351                }
    347352                std::sort(cuts.begin(), cuts.end());
     
    407412        case FB_GENE_TRANSFER:
    408413        {
    409                 // get random gene from first parent
     414                // get a random gene from the first parent
    410415                int choice = rndUint(fB_GenoHelpers::geneCount(parent1));
    411416                int start, end;
     
    414419                child2 = gene + parent2;
    415420                chg2 = (float)parent2.length() / (float)child2.length();
    416                 // do the same for second parent
     421                // do the same for the second parent
    417422                choice = rndUint(fB_GenoHelpers::geneCount(parent2));
    418423                gene = fB_GenoHelpers::getGene(choice, parent2, start, end);
     
    554559                {
    555560                        pos--;
    556                         if (isdigit(geno[pos]) == 0)
    557                         {
    558                                 return GENSTYLE_CS(0, GENSTYLE_INVALID);
    559                         }
    560                 }
    561                 return GENSTYLE_RGBS(0, 0, 200, GENSTYLE_BOLD);
    562         }
    563         if (islower(ch) == 0)
    564         {
    565                 return GENSTYLE_CS(0, GENSTYLE_INVALID);
    566         }
    567         uint32_t style = GENSTYLE_CS(GENCOLOR_TEXT, GENSTYLE_NONE);
    568         if (ch == 'a' && pos > 0 && (geno[pos - 1] == 'a' || geno[pos - 1] == '\n'))
     561                        if (isdigit(geno[pos]) == 0) //going left we encountered some non-digit character
     562                        {
     563                                return GENSTYLE_CS(GENCOLOR_NUMBER, GENSTYLE_NONE); //so 'ch' is any digit in the genotype (neural property value etc.); for simplicity, digits as parts of neuroclass name or property name also get included here
     564                        }
     565                }
     566                return GENSTYLE_RGBS(0, 0, 200, GENSTYLE_BOLD); //only digits up to the beginning, so this is the dimensionality value
     567        }
     568        if (ch == '-' || ch == '.')
     569                return GENSTYLE_CS(GENCOLOR_NUMBER, GENSTYLE_NONE);
     570        if (ch == '"')
     571                return GENSTYLE_RGBS(150, 0, 150, GENSTYLE_BOLD); //quotes encompass neuron definitions. To further distinguish the text inside quotes from the text outside quotes, we would need to determine the number of '"' from the beginning, i.e. linear search through the entire genotype. We don't want to do it - it would mean the complexity of len(geno)^2 if performed for each symbol in the genotype independently, like this function does. Below we perform an approximate partial scan.
     572        if (isupper(ch) || strchr("@|*", ch))
     573                return GENSTYLE_RGBS(150, 0, 150, GENSTYLE_BOLD); //neuroclass
     574        if (strchr(":,=", ch))
     575                return GENSTYLE_RGBS(150, 0, 150, GENSTYLE_NONE); //these symbols occur exclusively inside "...neuron...", so let's make the entire neuron section "...neuron..." more visually uniform by using the same violet color as the neuroclass name and quotes have
     576        if (islower(ch)) //how to color the current lower-case letter?
     577        {
     578                static const int SCAN_RANGE = 8; //how many characters before the current one to scan to discover some context and find out if we are likely in the neuroclass name or the property name. Reduces computational complexity. Example genotype fragments: abcabc"T:r=0.9, ry=4.088, rz=1.213"abcabc or abc"N:in=0.0, fo=0.17, si=999.0"abc
     579                int i = pos;
     580                while (i > 0 && pos - i < SCAN_RANGE)
     581                {
     582                        i--; //go back one char
     583                        if (isupper(geno[i]))
     584                                return GENSTYLE_RGBS(150, 0, 150, GENSTYLE_BOLD); //neuroclass
     585                        if (geno[i] == ',' || geno[i] == ':') //this is what must occur before property name starts
     586                                return GENSTYLE_RGBS(255, 140, 0, GENSTYLE_BOLD); //property
     587                        if (!(isalpha(geno[i]) || isspace(geno[i]))) //going left we encountered any char that is not a letter or space
     588                                break;
     589                }
     590        }
     591
     592        uint32_t style = GENSTYLE_CS(GENCOLOR_TEXT, GENSTYLE_NONE); //if the current character did not fall into any of the above cases, assume default black style
     593        if (ch == 'a' && (geno[pos + 1] == 'a' || (pos > 0 && geno[pos - 1] == 'a'))) //start codon, "aa"
    569594        {
    570595                style = GENSTYLE_RGBS(0, 200, 0, GENSTYLE_BOLD);
    571596        }
    572         else if (ch == 'z' && pos > 0 && geno[pos - 1] == 'z')
     597        else if (ch == 'z' && (geno[pos + 1] == 'z' || (pos > 0 && geno[pos - 1] == 'z'))) //stop codon, "zz"
    573598        {
    574599                style = GENSTYLE_RGBS(200, 0, 0, GENSTYLE_BOLD);
  • cpp/frams/genetics/fB/fB_oper.h

    r821 r1273  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2023  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    1111/** @name Codes for general fB mutation types */
    1212//@{
    13 #define FB_SUBSTITUTION  0 ///<Relative probability of mutation by changing single random letter in genotype (substitution)
    14 #define FB_INSERTION     1 ///<Relative probability of mutation by inserting characters in random place of genotype
    15 #define FB_NCLASSINS     2 ///<Relative probability of mutation by inserting neuron class definition in random place of genotype
    16 #define FB_DELETION      3 ///<Relative probability of mutation by deleting random characters in genotype
    17 #define FB_DUPLICATION   4 ///<Relative probability of mutation by copying single *gene* of genotype and appending it to the beginning of this genotype
    18 #define FB_TRANSLOCATION 5 ///<Relative probability of mutation by replacing two substrings in genotype
    19 #define FB_MUT_COUNT     6 ///<Count of mutation types
     13#define FB_SUBSTITUTION     0 ///<Relative probability of changing a single random character (or a neuron) in the genotype
     14#define FB_INSERTION        1 ///<Relative probability of inserting a random character in a random place of the genotype
     15#define FB_INSERTION_NEURON 2 ///<Relative probability of inserting a neuron in a random place of genotype
     16#define FB_DELETION         3 ///<Relative probability of deleting a random character (or a neuron) in the genotype
     17#define FB_DUPLICATION      4 ///<Relative probability of copying a single *gene* of the genotype and appending it to the beginning of this genotype
     18#define FB_TRANSLOCATION    5 ///<Relative probability of swapping two substrings in the genotype
     19#define FB_MUT_COUNT        6 ///<Count of mutation types
    2020//@}
    2121
    2222/** @name Codes for fB cross over types */
    2323//@{
    24 #define FB_GENE_TRANSFER 0 ///<Relative probability of crossing over by transferring single genes from both parents to beginning of each other
    25 #define FB_CROSSING_OVER 1 ///<Relative probability of crossing over by random distribution of genes from both parents to both children
     24#define FB_GENE_TRANSFER 0 ///<Relative probability of crossing over by copying a single random gene from each parent to the beginning of the other parent
     25#define FB_CROSSING_OVER 1 ///<Relative probability of crossing over by a random distribution of genes from both parents to both children
    2626#define FB_XOVER_COUNT   2 ///<Count of crossing over types
    2727//@}
     
    4848        int crossOver(char *&g1, char *&g2, float& chg1, float& chg2);
    4949
    50         virtual const char* getSimplest() { return "5\naaazz"; }
     50        virtual const char* getSimplest() { return "3\naaazz"; }
    5151
    5252        uint32_t style(const char *geno, int pos);
  • cpp/frams/genetics/fH/fH_oper.cpp

    r1257 r1273  
    1414{
    1515        { "Genetics: fH", 1, FH_OPCOUNT + FH_ADD_OPCOUNT, },
    16         { "fH_mut_addition", 0, 0, "Add element", "f 0 100 30", FIELD(operations[FH_ADD]), "Probability of adding new element to genotype", },
    17         { "fH_mut_add_joint", 0, 0, " - add joint", "f 0 100 33", FIELD(addoperations[FH_ADD_STICK]), "Probability of adding new stick handle", },
    18         { "fH_mut_add_neuron", 0, 0, " - add neuron", "f 0 100 33", FIELD(addoperations[FH_ADD_NEURO]), "Probability of adding new neuron handle", },
    19         { "fH_mut_add_connection", 0, 0, " - add neural connection", "f 0 100 33", FIELD(addoperations[FH_ADD_CONN]), "Probability of adding new neuron connection handle", },
    20         { "fH_mut_deletion", 0, 0, "Delete element", "f 0 100 10", FIELD(operations[FH_DEL]), "Probability of removing element from genotype", },
    21         { "fH_mut_handle", 0, 0, "Modify vectors of handles", "f 0 100 30", FIELD(operations[FH_HANDLE]), "Probability of changing values in vectors of handle", },
    22         { "fH_mut_property", 0, 0, "Modify properties of handles", "f 0 100 30", FIELD(operations[FH_PROP]), "Probability of changing properties of handles", },
     16        { "fH_mut_addition", 0, 0, "Add element", "f 0 100 4", FIELD(operations[FH_ADD]), "Probability of adding a new element", },
     17        { "fH_mut_add_joint", 0, 0, " - add joint", "f 0 100 4", FIELD(addoperations[FH_ADD_STICK]), "Probability of adding a new stick handle", },
     18        { "fH_mut_add_neuron", 0, 0, " - add neuron", "f 0 100 3", FIELD(addoperations[FH_ADD_NEURO]), "Probability of adding a new neuron handle", },
     19        { "fH_mut_add_connection", 0, 0, " - add neural connection", "f 0 100 1", FIELD(addoperations[FH_ADD_CONN]), "Probability of adding a new neuron connection handle", },
     20        { "fH_mut_deletion", 0, 0, "Delete element", "f 0 100 4", FIELD(operations[FH_DEL]), "Probability of removing an element", },
     21        { "fH_mut_handle", 0, 0, "Modify vectors of handles", "f 0 100 1", FIELD(operations[FH_HANDLE]), "Probability of changing values in vectors of a handle", },
     22        { "fH_mut_property", 0, 0, "Modify properties of handles", "f 0 100 4", FIELD(operations[FH_PROP]), "Probability of changing properties of handles", },
    2323        { 0, },
    2424};
     
    5353                return 1;
    5454        }
    55         return 0;
     55        return GENOPER_OK;
    5656}
    5757
     
    6363        fH_Builder builder;
    6464        int err = builder.parseGenotype(geno);
    65         // if parsing failed, then it is impossible to repair genotype
     65        // if parsing failed, then it is impossible to repair the genotype
    6666        if (err != 0)
    6767        {
    68                 return GENOPER_OPFAIL;
    69         }
    70         // method removes definitions of neurons that have invalid genotype
     68                return GENOPER_OK;
     69        }
     70        // method removes definitions of neurons that have an invalid genotype
    7171        int amount = builder.removeNeuronsWithInvalidClasses();
    72         // if there were any warnings, then rewrite genotype
     72        // if there were any warnings, then rewrite the genotype
    7373        if (eh.getErrorWarningCount() > 0 || amount > 0)
    7474        {
  • cpp/frams/genetics/fL/fL_general.cpp

    r973 r1273  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2023  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    99#include <iterator>
    1010
    11 const char *fL_part_names[FL_PART_PROPS_COUNT] = { "dn", "fr", "ing", "as" };
    12 const char *fL_part_fullnames[FL_PART_PROPS_COUNT] = { "details", "friction", "ingestion", "assimilation" };
    13 
    14 const char *fL_joint_names[FL_JOINT_PROPS_COUNT] = { "stif", "rotstif", "stam" };
    15 const char *fL_joint_fullnames[FL_JOINT_PROPS_COUNT] = { "stiffness", "rotation stiffness", "stamina" };
     11const char *fL_part_names[FL_PART_PROPS_COUNT] = { "fr" }; // "dn", "ing", "as" };
     12const char *fL_part_fullnames[FL_PART_PROPS_COUNT] = { "friction" }; // "density", "ingestion", "assimilation" };
     13
     14const char *fL_joint_names[FL_JOINT_PROPS_COUNT] = { "rotstif" }; //"stif", , "stam" }; //see the comment to fH_joint_names in fH_general.cpp
     15const char *fL_joint_fullnames[FL_JOINT_PROPS_COUNT] = { "rotation stiffness" }; //"stiffness", "stamina" };
    1616
    1717#define FIELDSTRUCT fL_Word
     
    502502        fL_Word *stick = new fL_Word(true);
    503503        stick->name = "S";
    504         stick->npar = 8;
     504        stick->npar = FL_PART_PROPS_COUNT + FL_JOINT_PROPS_COUNT + 1; //MacKo 2023-07: was hardcoded "8" but crashed when the number of props in Part and Joint was decreased; I think it should be like it is now (4+3+1 - or another value depending on prop counts)
    505505        for (int i = 0; i < FL_PART_PROPS_COUNT; i++)
    506506        {
    507507                stick->mut.addProperty(NULL, fL_part_names[i], "s", fL_part_fullnames[i], fL_part_fullnames[i], PARAM_CANOMITNAME, 0, -1);
    508508        }
    509 
    510509        for (int i = 0; i < FL_JOINT_PROPS_COUNT; i++)
    511510        {
     
    10961095                                        {
    10971096                                                delete newpart;
    1098                                                 logMessage("fL_Builder", "developModel", LOG_ERROR,
    1099                                                         "Error parsing word parameter");
     1097                                                logMessage("fL_Builder", "developModel", LOG_ERROR, "Error parsing word parameter");
    11001098                                                return 1;
    11011099                                        }
     
    11231121                                                if (word->parevals[FL_PART_PROPS_COUNT + i]->evaluateRPN(jointprop) != 0)
    11241122                                                {
    1125                                                         logMessage("fL_Builder", "developModel", LOG_ERROR,
    1126                                                                 "Error parsing word parameter");
     1123                                                        logMessage("fL_Builder", "developModel", LOG_ERROR, "Error parsing word parameter");
    11271124                                                        delete newjoint;
    11281125                                                        return 1;
     
    11531150                                }
    11541151                                model->addNeuro(neu);
     1152
     1153
     1154                                // MacKo 2023-07: embody (i.e., attach to body) sensors and effectors.
     1155                                // Ad hoc modification; should be reconsidered as it was added without reminding and understanding of the entire logic of the phenotype development and assumptions, and may not be "the best performing" or "the most reasonable" approach. Without this embodiment, genotypes with sensors and effectors not attached to body had warnings (such neurons "could not be initialized") so such genotypes were not accepted when creatwarnfail==1; even with creatwarnfail==0, non-embodied sensor and effector neurons were useless.
     1156                                //printf("Neuron: -------------- %s\n", details.c_str());
     1157                                switch (neu->getClass()->getPreferredLocation())
     1158                                {
     1159                                case NeuroClass::PrefLocation::PREFER_PART: //attach to currstate.currpart
     1160                                        if (currstate.currpart != NULL)
     1161                                                neu->attachToPart(currstate.currpart);
     1162                                        break;
     1163                                case NeuroClass::PrefLocation::PREFER_JOINT: //attach to the last joint incident with currstate.currpart
     1164                                        if (currstate.currpart != NULL)
     1165                                        {
     1166                                                Joint *j = NULL;
     1167                                                for (int i = 0; i < model->getJointCount(); i++)
     1168                                                {
     1169                                                        Joint *jj = model->getJoint(i);
     1170                                                        if (jj->part1 == currstate.currpart || jj->part2 == currstate.currpart)
     1171                                                                j = jj;
     1172                                                }
     1173                                                if (j != NULL)
     1174                                                        neu->attachToJoint(j);
     1175                                        }
     1176                                        break;
     1177                                default:
     1178                                        break;
     1179                                }
     1180
     1181
    11551182                                if (using_mapping) neu->addMapping(IRange(word->begin, word->end));
    11561183                                if (neu->getClass()->getPreferredInputs() != 0)
     
    12511278                        {
    12521279                                connsbuffer[i].second->addInput(connsbuffer[i].second, weight);
    1253                                 if (using_mapping) neu->addMapping(
     1280                                if (using_mapping) connsbuffer[i].second->addMapping( //MacKo 2023-07: changed 'neu' (which is NULL here so crashed) to connsbuffer[i].second (no guarantee this is a proper fix, only inspired by the analogy to the difference in both branches of "if" in the line above)
    12541281                                        IRange((*connsbuffer[i].first)->begin,
    12551282                                                (*connsbuffer[i].first)->end));
  • cpp/frams/genetics/fL/fL_general.h

    r821 r1273  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2023  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    2525/** @name Constants used in fL methods */
    2626//@{
    27 #define FL_PART_PROPS_COUNT   4 ///<Count of part properties
    28 #define FL_JOINT_PROPS_COUNT  3 ///<Count of joint properties
     27#define FL_PART_PROPS_COUNT   1 ///<Count of part properties
     28#define FL_JOINT_PROPS_COUNT  1 ///<Count of joint properties
    2929#define FL_PE_NEURO_DET       "d" ///<Id of details type definition in f0_neuro_paramtab
    3030#define FL_PE_CONN_WEIGHT     "w" ///<Id of weight type definition in f0_neuroconn_paramtab
    3131#define FL_PE_CONN_ATTR       "attr" ///<Id of attractor of neural connection
    3232#define FL_DEFAULT_LENGTH     1.0 ///<Default length of a stick in fL encoding
    33 #define FL_MINIMAL_LENGTH     0.0 ///<Minimal length of a stick in fL encoding
     33#define FL_MINIMAL_LENGTH     0.1 ///<Minimal length of a stick in fL encoding
    3434#define FL_MAXIMAL_LENGTH     2.0 ///<Maximal length of a stick in fL encoding
    3535#define FL_MAXITER           "100.0" ///<Maximal iteration available in fL
     
    404404
    405405        /**
    406          * Developes L-System from given genotype and builds Framsticks Model from it.
    407          * When using_checkpoints is enabled, method generates checkpoint for each
    408          * step defined in timestamp.
    409          * @param neededtime reference to a time value after stopping development (usually it will be equal to time specified in the time field, unless the number of allowed words will be exceeded earlier)
     406         * Develops an L-System from a given genotype and builds a Framsticks Model from it.
     407         * When using_checkpoints is enabled, this method generates a checkpoint for each
     408         * step defined in the timestamp.
     409         * @param neededtime reference to a time value after stopping development (usually it will be equal to the time specified in the time field, unless the number of allowed words will be exceeded earlier)
    410410         * @return final model from a fL genotype
    411411         */
     
    413413
    414414        /**
    415          * Creates new checkpoint for a given model based on current state of genotype.
    416          * @param model reference to model
    417          * @return 0 if developing went successfully, 1 otherwise
     415         * Creates a new checkpoint for a given model based on the current state of the genotype.
     416         * @param model reference to the model
     417         * @return 0 if the development was successfull, 1 otherwise
    418418         */
    419419        int buildModelFromSequence(Model *model);
  • cpp/frams/genetics/fL/fL_oper.cpp

    r1075 r1273  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2023  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    88#include <algorithm>
    99
     10
     11
     12//TODO fix: occasionally happens (note that fL extensively uses Param parsing, see fL_word_paramtab): Param.loadSingleLine: Unknown property 'Word.w0(n1' (ignored)
     13//TODO reconsider and maybe improve sensor and effector embodiment; see "MacKo 2023-07: embody" in fL_general.cpp.
     14
     15
     16
    1017#define FIELDSTRUCT Geno_fL
    1118static ParamEntry geno_fL_paramtab[] =
     
    1421        {"Genetics: fL: Probabilities of mutating axiom and rules", },
    1522        {"Genetics: fL: Probabilities of mutation types", },
    16         {"fL_maxdefinedwords", 0, 0, "Maximum number of defined words", "d 0 100 10", FIELD(maxdefinedwords), "Maximum number of words that can be defined in L-System", },
    17 
    18         {"fL_axm_mut_prob", 1, 0, "Axiom mutation", "f 0 1 0.2", FIELD(groupprobabilities[FL_AXM_WORD_MUT_PROB]), "Probability of performing mutation operations on axiom", },
    19         {"fL_rul_mut_prob", 1, 0, "Rule's successor mutation", "f 0 1 0.8", FIELD(groupprobabilities[FL_RUL_WORD_MUT_PROB]), "Probability of performing mutation operations on the successor of random rule", },
    20 
    21         {"fL_mut_addition", 2, 0, "Addition of word to sequence", "f 0 1 0.2", FIELD(operations[FL_ADD_WORD]), "Probability of adding random existing word to the axiom or one of successors", },
    22 
    23         {"fL_mut_add_stick", 2, 0, " - addition of stick", "f 0 1 0.2", FIELD(addtypes[FL_ADD_STICK]), "Probability of adding stick", },
    24         {"fL_mut_add_neuro", 2, 0, " - addition of neuron", "f 0 1 0.2", FIELD(addtypes[FL_ADD_NEURO]), "Probability of adding neuron", },
    25         {"fL_mut_add_conn", 2, 0, " - addition of neuron connection", "f 0 1 0.2", FIELD(addtypes[FL_ADD_CONN]), "Probability of adding connection", },
    26         {"fL_mut_add_rot", 2, 0, " - addition of rotation words", "f 0 1 0.2", FIELD(addtypes[FL_ADD_ROT]), "Probability of adding one of rotation words", },
    27         {"fL_mut_add_branch", 2, 0, " - addition of branched stick", "f 0 1 0.2", FIELD(addtypes[FL_ADD_BRANCH]), "Probability of adding branch with rotation and stick", },
    28         {"fL_mut_add_other", 2, 0, " - addition of defined words", "f 0 1 0.4", FIELD(addtypes[FL_ADD_OTHER]), "Probability of adding other word, defined in genotype", },
    29 
    30         {"fL_mut_worddefaddition", 2, 0, "Addition of new word definition", "f 0 1 0.05", FIELD(operations[FL_ADD_WDEF]), "Probability of adding new word definition to the genotype", },
    31         {"fL_mut_ruleaddition", 2, 0, "Addition of new rule definition", "f 0 1 0.1", FIELD(operations[FL_ADD_RULE]), "Probability of adding new rule definition for existing word", },
    32         {"fL_mut_rulecond", 2, 0, "Modification of rule condition", "f 0 1 0.1", FIELD(operations[FL_CHG_COND]), "Probability of modifying random rule condition", },
    33 
    34         {"fL_mut_changeword", 2, 0, "Change of random word", "f 0 1 0.3", FIELD(operations[FL_CHG_WORD]), "Probability of changing word name or formula of a random word from axiom or one of successors", },
    35         {"fL_mut_changeword_formula", 2, 0, " - change of formula", "f 0 1 0.7", FIELD(chgoperations[FL_CHG_WORD_FORMULA]), "Probability of changing formula in word", },
    36         {"fL_mut_changeword_name", 2, 0, " - change of name", "f 0 1 0.3", FIELD(chgoperations[FL_CHG_WORD_NAME]), "Probability of changing name in word", },
    37 
    38         {"fL_mut_changeiter", 2, 0, "Change of L-System iteration", "f 0 1 0.3", FIELD(operations[FL_CHG_ITER]), "Probability of changing number of iterations of L-Systems", },
    39         {"fL_mut_changeiter_step", 2, 0, "Step of iteration changing", "f 0 1 1.0", FIELD(iterchangestep), "Minimal step that should be used for changing iterations in L-Systems", },
    40         {"fL_mut_deletion", 2, 0, "Deletion of random word", "f 0 1 0.2", FIELD(operations[FL_DEL_WORD]), "Probability of deleting random word from axiom or random successor (also deletes rule if there is only one word in successor)", },
     23        {"fL_maxdefinedwords", 0, 0, "Maximum number of defined words", "d 0 100 10", FIELD(maxdefinedwords), "Maximum number of words that can be defined in the L-System", },
     24
     25        {"fL_axm_mut_prob", 1, 0, "Axiom mutation", "f 0 100 4", FIELD(groupprobabilities[FL_AXM_WORD_MUT_PROB]), "Probability of performing mutation operations on axiom", },
     26        {"fL_rul_mut_prob", 1, 0, "Rule's successor mutation", "f 0 100 1", FIELD(groupprobabilities[FL_RUL_WORD_MUT_PROB]), "Probability of performing mutation operations on the successor of a random rule", },
     27
     28        {"fL_mut_addition", 2, 0, "Addition of a word to a sequence", "f 0 100 4", FIELD(operations[FL_ADD_WORD]), "Probability of adding a random existing word to the axiom or to one of successors", },
     29
     30        {"fL_mut_add_stick", 2, 0, " - addition of a stick", "f 0 100 1", FIELD(addtypes[FL_ADD_STICK]), "Probability of adding a stick", },
     31        {"fL_mut_add_neuro", 2, 0, " - addition of a neuron", "f 0 100 4", FIELD(addtypes[FL_ADD_NEURO]), "Probability of adding a neuron", },
     32        {"fL_mut_add_conn", 2, 0, " - addition of a neuron connection", "f 0 100 4", FIELD(addtypes[FL_ADD_CONN]), "Probability of adding a neuron connection", },
     33        {"fL_mut_add_rot", 2, 0, " - addition of rotation words", "f 0 100 2", FIELD(addtypes[FL_ADD_ROT]), "Probability of adding one of rotation words", },
     34        {"fL_mut_add_branch", 2, 0, " - addition of a branched stick", "f 0 100 4", FIELD(addtypes[FL_ADD_BRANCH]), "Probability of adding a branch with a rotation and a stick", },
     35        {"fL_mut_add_other", 2, 0, " - addition of defined words", "f 0 100 1", FIELD(addtypes[FL_ADD_OTHER]), "Probability of adding another word defined in the genotype", },
     36
     37        {"fL_mut_worddefaddition", 2, 0, "Addition of a new word definition", "f 0 100 1", FIELD(operations[FL_ADD_WDEF]), "Probability of adding a new word definition to the genotype", },
     38        {"fL_mut_ruleaddition", 2, 0, "Addition of a new rule definition", "f 0 100 1", FIELD(operations[FL_ADD_RULE]), "Probability of adding a new rule definition for an existing word", },
     39        {"fL_mut_rulecond", 2, 0, "Modification of a rule condition", "f 0 100 1", FIELD(operations[FL_CHG_COND]), "Probability of modifying a random rule condition", },
     40
     41        {"fL_mut_changeword", 2, 0, "Change a random word", "f 0 100 4", FIELD(operations[FL_CHG_WORD]), "Probability of changing a word name or a formula of a random word from an axiom or one of successors", },
     42        {"fL_mut_changeword_formula", 2, 0, " - change of a formula", "f 0 100 4", FIELD(chgoperations[FL_CHG_WORD_FORMULA]), "Probability of changing a formula in a word", },
     43        {"fL_mut_changeword_name", 2, 0, " - change of a name", "f 0 100 2", FIELD(chgoperations[FL_CHG_WORD_NAME]), "Probability of changing a name in a word", },
     44
     45        {"fL_mut_changeiter", 2, 0, "Change the number of iterations", "f 0 100 1", FIELD(operations[FL_CHG_ITER]), "Probability of changing the number of iterations of the L-System", },
     46        {"fL_mut_changeiter_step", 2, 0, "Step of the iteration change", "f 0 1 1.0", FIELD(iterchangestep), "The minimal step that should be used for changing iterations in the L-System", },
     47        {"fL_mut_deletion", 2, 0, "Deletion of a random word", "f 0 100 4", FIELD(operations[FL_DEL_WORD]), "Probability of deleting a random word from an axiom or a random successor (also deletes the rule if there is only one word in the successor)", },
    4148        { 0, },
    4249};
     
    6673        if (builder.countSticksInSequence(&builder.genotype) == 0)
    6774        {
    68                 return GENOPER_OPFAIL;
     75                return 1;
    6976        }
    7077        double neededtime = 0;
    7178        Model *m = builder.developModel(neededtime);
    72         if (!m)
    73         {
    74                 return GENOPER_OPFAIL;
     79        if (m == NULL)
     80        {
     81                return 1;
    7582        }
    7683        if (!m->isValid())
    7784        {
    7885                delete m;
    79                 return GENOPER_OPFAIL;
     86                return 1;
    8087        }
    8188        delete m;
    82 
    8389
    8490        return GENOPER_OK;
     
    9399        if (err != 0)
    94100        {
    95                 return err;
     101                return GENOPER_OK;
    96102        }
    97103        double neededtime = 0;
    98104        Model *m = builder.developModel(neededtime);
     105        if (m == NULL)
     106        {
     107                return GENOPER_OK;
     108        }
    99109        if (!m->isValid())
    100110        {
    101111                delete m;
    102                 return GENOPER_OPFAIL;
     112                return GENOPER_OK;
    103113        }
    104114        if (neededtime != builder.time)
     
    171181        else
    172182        {
    173                 int rid = rndUint(creature->rules.size());
     183                int rid = rndUint((unsigned int)creature->rules.size());
    174184                list = &creature->rules[rid]->objsucc;
    175185                numparams = creature->rules[rid]->objpred->npar;
     
    303313                if (creature->rules.size() > 0)
    304314                {
    305                         int ruleid = rndUint(creature->rules.size());
     315                        int ruleid = rndUint((unsigned int)creature->rules.size());
    306316                        if (!creature->rules[ruleid]->condeval)
    307317                        {
     
    340350                if (wordswithnorules.size() > 0)
    341351                {
    342                         int predid = rndUint(wordswithnorules.size());
     352                        int predid = rndUint((unsigned int)wordswithnorules.size());
    343353                        fL_Rule *newrule = new fL_Rule(0, 0);
    344354                        fL_Word *pred = new fL_Word();
     
    352362                else if (creature->rules.size() > 0)
    353363                {
    354                         int ruleid = rndUint(creature->rules.size());
     364                        int ruleid = rndUint((unsigned int)creature->rules.size());
    355365                        fL_Rule *newrule = new fL_Rule(0, 0);
    356366                        fL_Word *pred = new fL_Word();
     
    455465                else
    456466                {
    457                         int rndid = rndUint(list->size());
     467                        int rndid = rndUint((unsigned int)list->size());
    458468                        std::list<fL_Word *>::iterator it = list->begin();
    459469                        std::advance(it, rndid);
     
    482492                int tmp = 0;
    483493                std::list<fL_Word *> *list = selectRandomSequence(creature, numpars, tmp);
    484                 int rndid = rndUint(list->size());
     494                int rndid = rndUint((unsigned int)list->size());
    485495                std::list<fL_Word *>::iterator it = list->begin();
    486496                std::advance(it, rndid);
     
    531541                int tmp = 0;
    532542                std::list<fL_Word *> *list = selectRandomSequence(creature, numpars, tmp);
    533                 int rndid = rndUint(list->size());
     543                int rndid = rndUint((unsigned int)list->size());
    534544                std::list<fL_Word *>::iterator selectedword = list->begin();
    535545                std::advance(selectedword, rndid);
     
    545555                        int numpars = 0;
    546556                        std::list<fL_Word *> *list = selectRandomSequence(creature, numpars, tmp);
    547                         int rndid = rndUint(list->size());
     557                        int rndid = rndUint((unsigned int)list->size());
    548558                        std::list<fL_Word *>::iterator it = list->begin();
    549559                        std::advance(it, rndid);
     
    577587                                if (available.size() > 0)
    578588                                {
    579                                         int newnameid = rndUint(available.size());
     589                                        int newnameid = rndUint((unsigned int)available.size());
    580590                                        (*selectedword)->name = available[newnameid]->name;
    581591                                }
     
    752762                for (int i = 0; i < numselrules; i++)
    753763                {
    754                         int rulid = rndUint(from->rules.size());
     764                        int rulid = rndUint((unsigned int)from->rules.size());
    755765                        fL_Rule *rul = from->rules[rulid];
    756766                        fL_Rule *newrule = new fL_Rule(0, 0);
     
    894904        else if (strchr("<>$[]&\\ @|*", ch) != NULL) // other allowed symbols and special neuron symbols
    895905        {
    896                 style = GENSTYLE_CS(GENCOLOR_TEXT, ch=='[' || ch==']' ? GENSTYLE_BOLD : GENSTYLE_NONE);
     906                style = GENSTYLE_CS(GENCOLOR_TEXT, ch == '[' || ch == ']' ? GENSTYLE_BOLD : GENSTYLE_NONE);
    897907        }
    898908        return style;
  • cpp/frams/genetics/genman.cpp

    r1238 r1273  
    1212
    1313
    14 #define GENMAN_REPEAT_FAILED 100 //how many times GenMan tries to repeat a mutation or crossover when the operator does not return acceptable genotype
     14#define GENMAN_REPEAT_FAILED 100 //how many times GenMan tries to repeat a mutation or crossover when the operator does not return an acceptable genotype
    1515#define STRINGIFY_1(x) #x
    1616#define STRINGIFY(x) STRINGIFY_1(x) //this second-level macro allows the parameter to be a macro itself and to stringify its value, not its name
     
    575575                if (g[i] == '<') latex += "$<$"; else if (g[i] == '>') latex += "$>$"; else
    576576                        if (g[i] == '-') latex += "$-$"; else if (g[i] == '|') latex += "$|$"; else
    577                                 if (g[i] == '$') latex += "\\$"; else if (g[i] == '%') latex += "\\%"; else latex += g[i];
     577                                if (g[i] == '$') latex += "\\$"; else if (g[i] == '%') latex += "\\%"; else
     578                                        if (g[i] == '#') latex += "\\#"; else latex += g[i];
    578579                if ((i % 3) == 0 && g[i] == ' ') latex += "\n"; //for readability, insert some newlines into latex...
    579580                if (i % 10 == 0) latex += "{\\hskip 0pt}"; // https://tex.stackexchange.com/questions/33526/automatic-line-breaking-of-long-lines-of-text
  • cpp/frams/genetics/genooperators.h

    r1254 r1273  
    164164        virtual const char* getSimplest() { return NULL; }
    165165
    166         /**You may want to have your genotype colored. This method provides desired character styles for genes.
     166        /**Provides color styles for individual characters of the genotype. For efficiency,
     167        this function may be approximate and do not perform the full, proper analysis of the syntax.
    167168        \param geno genotype
    168169        \param pos 0-based char offset
    169         \retval number-encoded visual style (and validity) of the genotype char at \a geno[pos].
    170         Assume white background.
     170        \retval number-encoded visual style (and validity) of the genotype char at \a geno[pos]. Assume white background.
    171171        \sa GENSTYLE_* macros, like GENSTYLE_BOLD*/
    172172        virtual uint32_t style(const char *geno, int pos) { return GENSTYLE_RGBS(0, 0, 0, GENSTYLE_NONE); }
Note: See TracChangeset for help on using the changeset viewer.