Changeset 1259 for cpp/frams/genetics


Ignore:
Timestamp:
06/22/23 03:52:39 (18 months ago)
Author:
Maciej Komosinski
Message:

f4: three #define's -> enum, minor refactorizations, added comments

Location:
cpp/frams/genetics/f4
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/genetics/f4/f4_conv.cpp

    r1249 r1259  
    153153f4_Cell* f4_Model::getStick(f4_Cell *C)
    154154{
    155         if (C->type == CELL_STICK) return C;
     155        if (C->type == f4_Cell_type::CELL_STICK) return C;
    156156        if (NULL != C->dadlink)
    157157                return getStick(C->dadlink);
    158158        // we have no more dadlinks, find any stick
    159159        for (int i = 0; i < cells->cell_count; i++)
    160                 if (cells->C[i]->type == CELL_STICK)
     160                if (cells->C[i]->type == f4_Cell_type::CELL_STICK)
    161161                        return cells->C[i];
    162162        // none!
     
    177177        // make sure parent is a stick
    178178        if (C->dadlink != NULL)
    179                 if (C->dadlink->type != CELL_STICK)
     179                if (C->dadlink->type != f4_Cell_type::CELL_STICK)
    180180                {
    181181                        C->dadlink = getStick(C->dadlink);
     
    192192        MultiRange range = C->genoRange;
    193193
    194         if (C->type == CELL_STICK)
     194        if (C->type == f4_Cell_type::CELL_STICK)
    195195        {
    196196                int jj_p1_refno;  // save for later
     
    244244        }
    245245
    246         if (C->type == CELL_NEURON)
     246        if (C->type == f4_Cell_type::CELL_NEURON)
    247247        {
    248248                const char* nclass = C->neuclass->name.c_str();
     
    253253                        else
    254254                                sprintf(tmpLine, "d=\"%s\"", nclass);
    255 
    256                         C->neuro_refno = addFromString(NeuronType, tmpLine, &range);
    257                         if (C->neuro_refno < 0) return -22;
    258                         this->checkpoint();
    259255                }
    260256                else if (C->neuclass->getPreferredLocation() == 1) // attached to Part or have no required attachment - also part
     
    264260
    265261                        sprintf(tmpLine, "p=%d,d=\"%s\"", partno, nclass);
    266 
    267                         C->neuro_refno = addFromString(NeuronType, tmpLine, &range);
    268                         if (C->neuro_refno < 0) return -22;
    269                         this->checkpoint();
    270262                }
    271263                else // attached to Joint, assume there are only three possibilities of getPreferredLocation()
     
    277269                        else if (strcmp(nclass, "|") == 0)
    278270                        {
    279                                 sprintf(tmpLine, "j=%d,d=\"|:p=%g,r=%g\"", jointno, C->P.muscle_power, C->dadlink->P.muscle_bend_range); //Macko 2023-05 change: we take muscle_bend_range from dadlink, not from C, because we also assign this neuron to C->dadlink->joint_refno. Without this, for example in /*4*/<<X><<<<X>N:|>X>X>X>X the muscle is attached to the junction with 3 sticks, but gets range=33% as in a four-stick junction. f1 correctly sets range=0.5 for the analogous phenotype: X(X[|],X(X,X,X))
     271                                sprintf(tmpLine, "j=%d,d=\"|:p=%g,r=%g\"", jointno, C->P.muscle_power, C->dadlink->P.muscle_bend_range); //Macko 2023-05 change: we take muscle_bend_range from dadlink, not from C, because we also assign this neuron to C->dadlink->joint_refno. Without this, for example in /*4*/<<X><<<<X>N:|>X>X>X>X the muscle is attached to the junction with 3 sticks, but gets range=33% as in a four-stick junction. f1 correctly sets range=0.5 (see also conv_f1_f0_branch_muscle_range) for the analogous phenotype: X(X[|],X(X,X,X))
    280272                        }
    281273                        else
    282274                                sprintf(tmpLine, "j=%d,d=\"%s\"", jointno, nclass);
    283 
    284                         C->neuro_refno = addFromString(NeuronType, tmpLine, &range);
    285                         if (C->neuro_refno < 0) return -32;
    286                         this->checkpoint();
    287                 }
     275                }
     276
     277                C->neuro_refno = addFromString(NeuronType, tmpLine, &range);
     278                if (C->neuro_refno < 0) return -22;
     279                this->checkpoint();
     280
    288281                for (int j = 0; j < C->conns_count; j++)
    289282                {
  • cpp/frams/genetics/f4/f4_general.cpp

    r1249 r1259  
    3737{
    3838        nr = nnr;
    39         type = CELL_UNDIFF;
     39        type = f4_Cell_type::CELL_UNDIFF;
    4040        dadlink = ndad;
    4141        org = NULL;
     
    6262        {
    6363                // make sure it is a stick (and not a stick f4_Cell!)
    64                 if (ndad->type == CELL_STICK)
     64                if (ndad->type == f4_Cell_type::CELL_STICK)
    6565                {
    6666                        //firstend = ndad->lastend;
     
    6868                        ndad->stickchildcount++;
    6969                }
    70                 if (ndad->type == CELL_NEURON)
     70                if (ndad->type == f4_Cell_type::CELL_NEURON)
    7171                {
    7272                        inertia = ndad->inertia;
     
    8484{
    8585        nr = nnr;
    86         type = CELL_UNDIFF;
     86        type = f4_Cell_type::CELL_UNDIFF;
    8787        dadlink = ndad;
    8888        org = nO;
     
    112112        {
    113113                // make sure it is a stick (and not a stick f4_Cell!)
    114                 if (ndad->type == CELL_STICK)
     114                if (ndad->type == f4_Cell_type::CELL_STICK)
    115115                {
    116116                        //firstend = ndad->lastend;
     
    118118                        ndad->stickchildcount++;
    119119                }
    120                 if (ndad->type == CELL_NEURON)
     120                if (ndad->type == f4_Cell_type::CELL_NEURON)
    121121                {
    122122                        inertia = ndad->inertia;
     
    173173
    174174                                // error: sticks cannot divide
    175                                 if (type == CELL_STICK)
     175                                if (type == f4_Cell_type::CELL_STICK)
    176176                                {
    177177                                        // cannot fix
     
    181181
    182182                                // undiff divides
    183                                 if (type == CELL_UNDIFF)
     183                                if (type == f4_Cell_type::CELL_UNDIFF)
    184184                                {
    185185                                        // commacount is set only when daughter turns into X
     
    194194                                }
    195195                                // a neuron divides: create a new, duplicate connections
    196                                 if (type == CELL_NEURON)
     196                                if (type == f4_Cell_type::CELL_NEURON)
    197197                                {
    198198                                        // daughter cell
     
    203203                                        repeat.clear();
    204204                                        // it is a neuron from start
    205                                         tmp->type = CELL_NEURON;
     205                                        tmp->type = f4_Cell_type::CELL_NEURON;
    206206                                        // it has the same type as the parent neuron
    207207                                        tmp->neuclass = neuclass;
     
    257257                                {
    258258                                        // error: still undiff
    259                                         if (type == CELL_UNDIFF)
     259                                        if (type == f4_Cell_type::CELL_UNDIFF)
    260260                                        {
    261261                                                // fix it: insert an 'X'
     
    301301                        {
    302302                                // error: if neuron
    303                                 if (type == CELL_NEURON)
     303                                if (type == f4_Cell_type::CELL_NEURON)
    304304                                {
    305305                                        // fix: delete it
     
    331331                        {
    332332                                // error: if neuron
    333                                 if (type == CELL_NEURON) //some neurons have the same single-letter names as modifiers (for example G,S,D), but they are supposed to have is_neuroclass==true so they should indeed not be handled here
     333                                if (type == f4_Cell_type::CELL_NEURON) //some neurons have the same single-letter names as modifiers (for example G,S,D), but they are supposed to have is_neuroclass==true so they should indeed not be handled here
    334334                                {//however, what we see here is actually modifiers such as IdqEbWL (so not valid neuroclasses) that occurred within an already differentiated cell of type==CELL_NEURON.
    335335                                        //printf("Handled as a modifier, but type==CELL_NEURON: '%c'\n", name);
     
    346346                                // turn undiff. cell into a stick
    347347                                // error: already differentiated
    348                                 if (type != CELL_UNDIFF)
     348                                if (type != f4_Cell_type::CELL_UNDIFF)
    349349                                {
    350350                                        // fix: delete this node
     
    352352                                        return;  // error code set -> stop further cells development
    353353                                }
    354                                 type = CELL_STICK;
     354                                type = f4_Cell_type::CELL_STICK;
    355355                                // fix dad commacount and own anglepos
    356356                                if (dadlink != NULL)
     
    367367                                // connection to neuron
    368368                                // error: not a neuron
    369                                 if (type != CELL_NEURON)
     369                                if (type != f4_Cell_type::CELL_NEURON)
    370370                                {
    371371                                        // fix: delete it
     
    384384                                for (int i = 0; i < org->cell_count; i++)
    385385                                {
    386                                         if (org->C[i]->type == CELL_NEURON) neu_counter++;
     386                                        if (org->C[i]->type == f4_Cell_type::CELL_NEURON) neu_counter++;
    387387                                        if (org->C[i] == this) { this_index = neu_counter - 1; break; }
    388388                                }
     
    398398                                for (from = 0; from < org->cell_count; from++)
    399399                                {
    400                                         if (org->C[from]->type == CELL_NEURON) neu_counter++;
     400                                        if (org->C[from]->type == f4_Cell_type::CELL_NEURON) neu_counter++;
    401401                                        if (from_index == (neu_counter - 1)) break;
    402402                                }
     
    457457                                // neuron parameter
    458458                                // error: not a neuron
    459                                 if (type != CELL_NEURON)
     459                                if (type != f4_Cell_type::CELL_NEURON)
    460460                                {
    461461                                        // fix: delete it
     
    513513                {
    514514                        genoRange.add(gcur->pos, gcur->pos + int(gcur->name.length()) + 2 - 1); // +2 for N:
    515                         if (type != CELL_UNDIFF)
     515                        if (type != f4_Cell_type::CELL_UNDIFF)
    516516                        {
    517517                                // fix: delete this node
     
    527527                        }
    528528                        neuclass = gcur->neuclass;
    529                         type = CELL_NEURON;
     529                        type = f4_Cell_type::CELL_NEURON;
    530530                        // change of type also halts development, to give other
    531531                        // cells a chance for adjustment.  Namely, it is important
     
    567567        {
    568568                if (org->C[i]->dadlink == this)
    569                         if (org->C[i]->type == CELL_STICK)
     569                        if (org->C[i]->type == f4_Cell_type::CELL_STICK)
    570570                                stickchildcount++;
    571571        }
     
    575575        else
    576576                P.muscle_bend_range = 1.0 / std::max(1, dadlink->stickchildcount); //bend range in f1: 0, 1 (line XX[|]) -> 100%, 2 (Y-shape X(X[|],X)) -> 50%, 3 (cross X(X[|],X,X)) -> 33%
    577         //MacKo 2023-05: but shouldn't this formula ^^ also take commacount into consideration, like in f1?
    578 
    579         if (type == CELL_STICK)
     577        //MacKo 2023-05: but shouldn't this formula ^^ also take commacount into consideration, like in f1? Note: in f0, the range of a newly added muscle has the default value (1.0) until modified by mutation, and the range can be set to any value completely unrelated to the junction where the muscle is located. In f1, the range of a newly added muscle depends on the number of branches (commas) in the junction including empty branches (see also conv_f1_f0_branch_muscle_range), but can be overridden by the genotype due to mutation and any value can be directly set just as in f0 - e.g. X[|,r:0.8] - so the value based on the number of commas only serves as a default. Compared to f0 and f1, f4 enforces a specific range here and this cannot be changed in any way, because as of now (2023-05) there is no support to mutate neural properties except for the N neuron.
     578
     579        if (type == f4_Cell_type::CELL_STICK)
    580580        {
    581581                if (dadlink == NULL)
     
    716716        for (int i = 0; i < cell_count; i++)
    717717        {
    718                 if (C[i]->type == CELL_NEURON)
    719                 {
    720                         while (C[i]->dadlink->type == CELL_NEURON)
     718                if (C[i]->type == f4_Cell_type::CELL_NEURON)
     719                {
     720                        while (C[i]->dadlink->type == f4_Cell_type::CELL_NEURON)
    721721                        {
    722722                                C[i]->dadlink = C[i]->dadlink->dadlink;
     
    729729        for (int i = 0; i < cell_count; i++)
    730730        {
    731                 if (C[i]->type == CELL_UNDIFF)
    732                 {
    733                         C[i]->type = CELL_STICK;
     731                if (C[i]->type == f4_Cell_type::CELL_UNDIFF)
     732                {
     733                        C[i]->type = f4_Cell_type::CELL_STICK;
    734734                        //setError();
    735735                }
     
    764764                switch (c->type)
    765765                {
    766                 case CELL_UNDIFF: type = "undiff"; break;
    767                 case CELL_STICK:  type = "STICK"; break;
    768                 case CELL_NEURON: type = string("NEURON:") + c->neuclass->name.c_str(); break;
    769                 default: type = std::to_string(c->type);
     766                case f4_Cell_type::CELL_UNDIFF: type = "undiff"; break;
     767                case f4_Cell_type::CELL_STICK:  type = "STICK"; break;
     768                case f4_Cell_type::CELL_NEURON: type = string("NEURON:") + c->neuclass->name.c_str(); break;
     769                default: type = std::to_string(static_cast<int>(c->type));
    770770                }
    771771                const char *status = c->gcur == c->old_gcur ? (c->gcur != NULL ? "no progress" : "") : (c->gcur != NULL ? "progress" : "finished"); //progress or no progress means the cell is yielding = not finished but decided to halt development and wait for other cells. New cells may be created in case of "no progress" status.
     
    893893        if (curc >= cell_count) return;
    894894
    895         if (C[curc]->type != CELL_STICK) return;
     895        if (C[curc]->type != f4_Cell_type::CELL_STICK) return;
    896896
    897897        f4_Cell *thisti = C[curc];
     
    899899                *tmpcel = *(thisti->dadlink);
    900900
    901         // adjust length, curvedness, etc.
     901        // Adjust length, curvedness, etc.
    902902        tmpcel->P.propagateAlong(false);
     903
     904        // The sequence of "while" loops below is a fast and simple heuristic (decrease as long as the value is too big, then increase as long as the value is too small).
     905        // However, since every different sequence of upper- and lower-case modifiers produces a different value of a given property,
     906        // all 2^N sequences should be tested to discover the best approximation of the target value of a given property using N modifiers.
     907        // This issue is TODO if anybody needed this function (and modifier sequences it produces) for any serious use. Also, add support for Qq.
     908        // See also GenoOperators::simplifiedModifiers() and geneprops_test.cpp.
    903909        while (tmpcel->P.length > thisti->P.length)
    904910        {
     
    938944        for (int i = 0; i < cell_count; i++)
    939945        {
    940                 if (C[i]->type == CELL_NEURON)
     946                if (C[i]->type == f4_Cell_type::CELL_NEURON)
    941947                {
    942948                        if (C[i]->dadlink == thisti)
     
    971977        for (int i = 0; i < cell_count; i++)
    972978        {
    973                 if (C[i]->type == CELL_STICK)
     979                if (C[i]->type == f4_Cell_type::CELL_STICK)
    974980                {
    975981                        if (C[i]->dadlink == thisti)
  • cpp/frams/genetics/f4/f4_general.h

    r1249 r1259  
    3333class f4_Cells;  // later
    3434
    35 
    36 /** @name Types of f4_Cell's */
    37 //@{
    38 #define CELL_UNDIFF 40 ///<undifferentiated cell
    39 #define CELL_STICK  41 ///<differentiated to stick, cannot divide
    40 #define CELL_NEURON 42 ///<differentiated to neuron, can divide
    41 //@}
    42 
     35enum class f4_Cell_type {
     36        CELL_UNDIFF, ///<undifferentiated cell
     37        CELL_STICK,  ///<differentiated to stick, cannot divide
     38        CELL_NEURON  ///<differentiated to neuron, can divide
     39};
    4340
    4441class f4_CellConn;
     
    154151         * at least once. If one cell requires another one to develop, oneStep
    155152         * should be deployed again on this cell.
    156          * 
     153         *
    157154         * This method, unlike genotype tree creation, checks semantics. This means that
    158155         * this function will fail (set error code) if:
     
    184181
    185182        int        nr;                 ///<number of cell (seems to be used only in the approximate f1 converter for neuron connections)
    186         int        type;               ///<type
     183        f4_Cell_type type;             ///<type
    187184        f4_Cell *dadlink;              ///<pointer to cell parent
    188185        f4_Cells  *org;                ///<uplink to organism
     
    462459 * @return a pointer to the f4_Node object representing the f4 tree root
    463460 */
    464 //f4_Node* f4_processTree(const char *geno);
    465 
    466 /**
    467  * Scans a genotype string starting from a given position. This recursive method creates
    468  * a tree of f4_Node objects. This method extracts each potentially functional element
    469  * of a genotype string to a separate f4_Nodes. When the branching character '<' occurs,
    470  * f4_processRecur is deployed for the latest f4_Node element. This method does not
    471  * analyse the genotype semantically, it only checks if the syntax is proper. The only
    472  * semantic aspect is neuron class name extraction, where the GenoOperators
    473  * class is used to parse the potential neuron class name.
    474  * This is an internal function; for regular cases, use f4_process().
    475  * @param genot the string with the entire genotype
    476  * @param genot_len length of genot (precomputed for efficiency)
    477  * @param pos_inout the current position of processing in string (advanced by the function)
    478  * @param parent current parent of the analysed branch of the genotype
    479  * @return 0 if processing was successful, otherwise returns the position of an error in the genotype
    480  */
     461 //f4_Node* f4_processTree(const char *geno);
     462
     463 /**
     464  * Scans a genotype string starting from a given position. This recursive method creates
     465  * a tree of f4_Node objects. This method extracts each potentially functional element
     466  * of a genotype string to a separate f4_Nodes. When the branching character '<' occurs,
     467  * f4_processRecur is deployed for the latest f4_Node element. This method does not
     468  * analyse the genotype semantically, it only checks if the syntax is proper. The only
     469  * semantic aspect is neuron class name extraction, where the GenoOperators
     470  * class is used to parse the potential neuron class name.
     471  * This is an internal function; for regular cases, use f4_process().
     472  * @param genot the string with the entire genotype
     473  * @param genot_len length of genot (precomputed for efficiency)
     474  * @param pos_inout the current position of processing in string (advanced by the function)
     475  * @param parent current parent of the analysed branch of the genotype
     476  * @return 0 if processing was successful, otherwise returns the position of an error in the genotype
     477  */
    481478int f4_processRecur(const char *genot, const int genot_len, int &pos_inout, f4_Node *parent);
    482479
  • cpp/frams/genetics/f4/f4_oper.cpp

    r1247 r1259  
    1515//
    1616// TODO the behavior of neuron input indexes during mutation seems badly implemented (see also TREAT_BAD_CONNECTIONS_AS_INVALID_GENO). Are they kept properly maintained when nodes are added and removed? This could be done well because during mutation we operate on the tree structure with cross-references between nodes (so they should not be affected by local changes in the tree), and then convert the tree back to string. Yet, the f4_Node.conn_from is an integer and these fields in nodes do not seem to be maintained on tree node adding/removal... change these integer offsets to references to node objects? But actually, do the offsets that constitute relative connection references concern the f4_Node tree structure (and all these sophisticated calculations of offsets during mutation are useful) or rather they concern the f4_Cells development? verify all situations in f4_Cell::oneStep(), case '['.
    17 // TODO in mutation, adding the '#' gene does not seem to be effective. The gene is added and genotypes are valid, but hardly ever #n is effective, i.e., it hardly ever multiplicates body or brain parts... investigate! And maybe, during repair or mutations, simplify/remove ineffective #N genes, if there is no chance/hardly any chance that they will be turned effective after future mutation (or crossover)
     17// TODO in mutation, adding the '#' gene does not seem to be effective. The gene is added and genotypes are valid, but hardly ever #n is effective, i.e., it hardly ever multiplicates body or brain parts... investigate! Maybe most places it is added at are ineffective. And maybe, during repair or mutations, simplify/remove ineffective #N genes, if there is no chance/hardly any chance that they will be turned effective after future mutation (or crossover)
    1818// TODO add support for properties of (any class of) neurons - not just sigmoid/force/intertia (':' syntax) for N
    1919// TODO add mapping genotype character ranges for neural [connections]
    20 // TODO The f0 genotypes for /*4*/<<RX>X>X> and RX(X,X) are identical, but if you replace R with Q or C, there are small differences (they were present both before and after the Q,C change in f1 in 2023-05) - check why and perhaps unify?
     20// TODO The f0 genotypes for /*4*/<<RX>X>X> and RX(X,X) are identical, but if you replace R with C or Q, there are small differences (they were present both before and after the change in C,Q effects in the f1 converter in 2023-06, see conv_f1_f0_cq_influence) - check why (modifiers affecting cells=sticks are applied differently or skip some initial sticks?) and perhaps unify with f1?
    2121// TODO F4_SIMPLIFY_MODIFIERS in f4_general.cpp: currently it works while parsing (which is a bit "cheating": we get a phenotype that is a processed version of the genotype, thus some changes in modifiers in the genotype have no effect on its phenotype). Another (likely better) option, instead of simplifying while parsing, would be during mutations (like it is done in f1): when mutations add/modify/remove a modifier node, they could "clean" the tree by simplifying modifiers on the same subpath just as GenoOperators::simplifiedModifiers() does. This way, simplifying would be only performed when we actually modify a part of a genotype, not each time we interpret it, and there would be no hidden mechanism: all visible genes would have an expected effect on the phenotype.
     22// TODO improve the way modifiers are handled in the f4->f1 approximate converter (used extremely rarely just for illustration)
    2223
    2324
     
    4344{
    4445        { "Genetics: f4", 1, F4_COUNT + F4_ADD_COUNT + F4_MODNEU_COUNT + 2, },
    45         { "f4_mut_add", 0, 0, "Add node", "f 0 100 50", FIELD(prob[F4_ADD]), "Mutation: probability of adding a node", },
    46         { "f4_mut_add_div", 0, 0, "- add division", "f 0 100 20", FIELD(probadd[F4_ADD_DIV]), "Add node mutation: probability of adding a division", },
    47         { "f4_mut_add_conn", 0, 0, "- add connection", "f 0 100 15", FIELD(probadd[F4_ADD_CONN]), "Add node mutation: probability of adding a neural connection", },
    48         { "f4_mut_add_neupar", 0, 0, "- add neuron property", "f 0 100 5", FIELD(probadd[F4_ADD_NEUPAR]), "Add node mutation: probability of adding a neuron property/modifier", },
    49         { "f4_mut_add_rep", 0, 0, "- add repetition '#'", "f 0 100 10", FIELD(probadd[F4_ADD_REP]), "Add node mutation: probability of adding the '#' repetition gene", },
    50         { "f4_mut_add_simp", 0, 0, "- add simple node", "f 0 100 50", FIELD(probadd[F4_ADD_SIMP]), "Add node mutation: probability of adding a random, simple gene", },
    51 
    52         { "f4_mut_del", 0, 0, "Delete node", "f 0 100 20", FIELD(prob[F4_DEL]), "Mutation: probability of deleting a node", },
    53 
    54         { "f4_mut_mod", 0, 0, "Modify node", "f 0 100 30", FIELD(prob[F4_MOD]), "Mutation: probability of changing a node", },
    55         { "f4_mut_modneu_conn", 0, 0, "- neuron input: modify source", "f 0 100 60", FIELD(probmodneu[F4_MODNEU_CONN]), "Neuron input mutation: probability of changing its source neuron", },
    56         { "f4_mut_modneu_weight", 0, 0, "- neuron input: modify weight", "f 0 100 40", FIELD(probmodneu[F4_MODNEU_WEIGHT]), "Neuron input mutation: probability of changing its weight", },
     46        { "f4_mut_add", 0, 0, "Add node", "f 0 100 4", FIELD(prob[F4_ADD]), "Mutation: probability of adding a node", },
     47        { "f4_mut_add_div", 0, 0, "- add division", "f 0 100 4", FIELD(probadd[F4_ADD_DIV]), "Add node mutation: probability of adding a division", },
     48        { "f4_mut_add_conn", 0, 0, "- add connection", "f 0 100 1", FIELD(probadd[F4_ADD_CONN]), "Add node mutation: probability of adding a neural connection", },
     49        { "f4_mut_add_neupar", 0, 0, "- add neuron property", "f 0 100 1", FIELD(probadd[F4_ADD_NEUPAR]), "Add node mutation: probability of adding a neuron property/modifier", },
     50        { "f4_mut_add_rep", 0, 0, "- add repetition '#'", "f 0 100 1", FIELD(probadd[F4_ADD_REP]), "Add node mutation: probability of adding the '#' repetition gene", },
     51        { "f4_mut_add_simp", 0, 0, "- add simple node", "f 0 100 4", FIELD(probadd[F4_ADD_SIMP]), "Add node mutation: probability of adding a random, simple gene", },
     52
     53        { "f4_mut_del", 0, 0, "Delete node", "f 0 100 1", FIELD(prob[F4_DEL]), "Mutation: probability of deleting a node", },
     54
     55        { "f4_mut_mod", 0, 0, "Modify node", "f 0 100 1", FIELD(prob[F4_MOD]), "Mutation: probability of changing a node", },
     56        { "f4_mut_modneu_conn", 0, 0, "- neuron input: modify source", "f 0 100 3", FIELD(probmodneu[F4_MODNEU_CONN]), "Neuron input mutation: probability of changing its source neuron", },
     57        { "f4_mut_modneu_weight", 0, 0, "- neuron input: modify weight", "f 0 100 3", FIELD(probmodneu[F4_MODNEU_WEIGHT]), "Neuron input mutation: probability of changing its weight", },
    5758
    5859        { "f4_mut_max_rep", 1, 0, "Maximum number for '#' repetitions", "d 2 20 6", FIELD(mut_max_rep), "Maximum allowed number of repetitions for the '#' repetition gene", },
Note: See TracChangeset for help on using the changeset viewer.