Changeset 797 for cpp/frams/genetics/fB


Ignore:
Timestamp:
06/06/18 01:45:18 (6 years ago)
Author:
Maciej Komosinski
Message:

A more complete implementation of fB, fH, fL

Location:
cpp/frams/genetics/fB
Files:
5 edited

Legend:

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

    r780 r797  
     1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
     3// See LICENSE.txt for details.
     4
    15#include "fB_conv.h"
    26
     
    8993                        continue;
    9094                }
    91                 fH_Handle *handle = convertCharacterToHandle(gene[2], dims, start, end, ranges);
     95                int hclasspos = 2;
     96                if (gene[2] == '"')
     97                {
     98                        hclasspos--;
     99                        if (!getNextCharId(gene, hclasspos))
     100                        {
     101                                return "";
     102                        }
     103                }
     104                fH_Handle *handle = convertCharacterToHandle(gene[hclasspos], dims, start, end, ranges);
    92105                ParamEntry *tab = creature.getParamTab(handle->type);
    93106                void *obj = ParamObject::makeObject(tab);
     
    97110
    98111                int propindex = 0;
    99                 int z = 3;
     112                int z = hclasspos;
     113                if (gene[z] == '"')
     114                {
     115                        z--;
     116                        if (!getNextCharId(gene, z))
     117                        {
     118                                delete handle;
     119                                ParamObject::freeObject(obj);
     120                                return "";
     121                        }
     122                }
    100123                endoffset = 0;
    101124                if (gene.indexOf("zz", 0) != -1) endoffset = 2;
     125                int nclassdefcount = 1;
    102126                while (z < gene.len() - endoffset)
    103127                {
    104                         if (processNextLetter(creature, handle, par, gene, propindex, z, ranges) == -1)
    105                         {
    106                                 logMessage("GenoConv_fBH", "convert", LOG_WARN, "Property of fH could not be parsed");
    107                         }
     128                        if (processNextLetter(creature, handle, par, gene, propindex, z, ranges, nclassdefcount) == -1)
     129                        {
     130                                logMessage("GenoConv_fBH", "convert", LOG_ERROR, "Property of fH could not be parsed");
     131                                delete handle;
     132                                ParamObject::freeObject(obj);
     133                                return "";
     134                        }
     135                }
     136                if (handle->type == fHBodyType::NEURON && propindex < par.getPropCount())
     137                {
     138                        SString nclass;
     139                        if (!getNeuroClass(gene, nclass, nclassdefcount))
     140                        {
     141                                delete handle;
     142                                ParamObject::freeObject(obj);
     143                                return "";
     144                        }
     145                        par.setStringById(FH_PE_NEURO_DET, nclass);
    108146                }
    109147                handle->loadProperties(par);
     
    132170}
    133171
    134 int GenoConv_fBH::processNextLetter(fH_Builder &creature, fH_Handle *&currhandle, Param &par, SString gene, int &propindex, int &i, std::vector<IRange> ranges[3])
     172bool GenoConv_fBH::getNextCharId(SString genotype, int &i)
     173{
     174        i++;
     175        if (genotype[i] == '"')
     176        {
     177                int nextid = i + 1;
     178                do
     179                {
     180                        nextid = genotype.indexOf('"', nextid);
     181                        if (nextid == -1)
     182                        {
     183                                return false;
     184                        }
     185                        nextid++;
     186                }
     187                while (genotype[nextid] == '"');
     188                i = nextid;
     189        }
     190        return true;
     191}
     192
     193bool GenoConv_fBH::getNeuroClass(SString gene, SString &def, int nclassdefcount)
     194{
     195        SString lastdef = "N";
     196        int nclass = 0;
     197        int pos = 0;
     198        while (nclass < nclassdefcount)
     199        {
     200                pos = gene.indexOf('\"', pos);
     201                if (pos == -1)
     202                {
     203                        def = lastdef;
     204                        return true;
     205                }
     206                pos++;
     207                SString currdef;
     208                if (gene.indexOf('\"', pos) == -1 || !gene.getNextToken(pos, currdef, '\"'))
     209                {
     210                        def = lastdef;
     211                        return false;
     212                }
     213                lastdef = currdef;
     214                nclass++;
     215        }
     216        def = lastdef;
     217        return true;
     218}
     219
     220int GenoConv_fBH::processNextLetter(fH_Builder &creature, fH_Handle *&currhandle, Param &par, SString gene, int &propindex, int &i, std::vector<IRange> ranges[3], int &nclassdefcount)
    135221{
    136222        if (propindex >= par.getPropCount())
     
    147233                par.setDefault();
    148234                propindex = 0;
    149                 i++;
     235                if (!getNextCharId(gene, i))
     236                        return -1;
    150237                return 0;
    151238        }
     
    166253                        }
    167254                        propindex++;
    168                         i++;
     255                        if (!getNextCharId(gene, i))
     256                                return -1;
    169257                        return 0;
    170258                }
    171259                else if (currhandle->type == fHBodyType::NEURON && *par.id(propindex) == 'd')
    172260                {
    173                         //TODO: handle neuron classes and properties
     261                        //When 'd' property appears for i-th element in gene, the method
     262                        //looks for i-th neuron definition
     263                        SString nclass;
     264                        if (!getNeuroClass(gene, nclass, nclassdefcount)) return -1;
     265                        par.setString(propindex, nclass);
    174266                        propindex++;
    175                         i++;
     267                        nclassdefcount++;
     268                        if (!getNextCharId(gene, i))
     269                                return -1;
    176270                        return 0;
    177271                }
  • cpp/frams/genetics/fB/fB_conv.h

    r780 r797  
     1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
     3// See LICENSE.txt for details.
     4
    15#ifndef _FB_CONV_H_
    26#define _FB_CONV_H_
     
    812{
    913private:
     14        bool getNextCharId(SString genotype, int &i);
    1015        double convertCharacterTo01(char c);
    1116        double convertCharacterToWeight(char c);
    1217        static fH_Handle* convertCharacterToHandle(char c, int dims, int start, int end, std::vector<IRange> ranges[3]);
    13         int processNextLetter(fH_Builder &creature, fH_Handle *&currhandle, Param &par, SString gene, int &propindex, int &i, std::vector<IRange> ranges[3]);
     18        int processNextLetter(fH_Builder &creature, fH_Handle *&currhandle, Param &par, SString gene, int &propindex, int &i, std::vector<IRange> ranges[3], int &nclassdefcount);
     19        bool getNeuroClass(SString gene, SString &def, int nclassdefcount);
    1420
    1521public:
  • cpp/frams/genetics/fB/fB_general.h

    r780 r797  
     1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
     3// See LICENSE.txt for details.
     4
    15#ifndef _FB_GENERAL_H_
    26#define _FB_GENERAL_H_
     
    1014        {
    1115                int start = 0;
     16                int prev = 0;
    1217                int count = -1;
    1318                do {
    1419                        count++;
    1520                        start = geno.indexOf("aa", start) + 1; // +1 is for progress, starting codons can overlap
     21                        int quotecount = 0;
     22                        for (int q = prev; q < start; q++) if (geno[q] == '\"') quotecount++;
     23                        prev = start;
     24                        if (quotecount % 2 != 0) count--; // 'aa' sequence is within quotes
    1625                } while (start - 1 != -1);
    1726                return count;
     
    2534                        count++;
    2635                        start = genotype.indexOf("aa", start) + 1;
     36                        int quotecount = 0;
     37                        for (int q = 0; q < start; q++) if (genotype[q] == '\"') quotecount++;
     38                        if (quotecount % 2 != 0) count--; // 'aa' sequence is within quotes
    2739                } while (start - 1 != -1 && count != i);
    2840                if (start - 1 == -1) // there is no gene with a given "i"
     
    3345                }
    3446                end = start;
    35                 end = genotype.indexOf("zz", end);
     47                int quotecount = 0;
     48                do {
     49                        quotecount = 0;
     50                        end = genotype.indexOf("zz", end);
     51                        if (end != -1)
     52                        {
     53                                for (int q = start; q < end; q++) if (genotype[q] == '\"') quotecount++;
     54                                if (quotecount % 2 != 0) end++;
     55                        }
     56                } while (quotecount % 2 != 0 && end != -1);
     57
    3658                if (end == -1) end = genotype.len();
    3759                else end += 2;
  • cpp/frams/genetics/fB/fB_oper.cpp

    r780 r797  
     1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
     3// See LICENSE.txt for details.
     4
    15#include <frams/util/sstring.h>
    26#include <vector>
     
    59#include "fB_general.h"
    610#include "fB_oper.h"
     11#include "../fH/fH_oper.h"
    712
    813#define FIELDSTRUCT Geno_fB
     
    1015static ParamEntry GENOfBparam_tab[] =
    1116{
    12         { "Genetics: fB", 3, FB_MUT_COUNT + FB_XOVER_COUNT, }, // ask about it
     17        { "Genetics: fB", 3, FB_MUT_COUNT + FB_XOVER_COUNT, },
    1318        { "Genetics: fB: Mutation", },
    1419        { "Genetics: fB: Crossover", },
    1520        { "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", },
    16         { "fB_mut_insertion", 1, 0, "Insertion", "f 0 1 0.1", FIELD(mutationprobs[FB_INSERTION]), "Probability of mutation by inserting characters in random place of genotype", },
     21        { "fB_mut_insertion", 1, 0, "Insertion", "f 0 1 0.95", FIELD(mutationprobs[FB_INSERTION]), "Probability of mutation by inserting characters in random place of genotype", },
     22        { "fB_mut_nclassins", 1, 0, "Insertion of neuron class definition", "f 0 1 0.05", FIELD(mutationprobs[FB_NCLASSINS]), "Probability of mutation by inserting neuron class definition in random place of genotype", },
    1723        { "fB_mut_deletion", 1, 0, "Deletion", "f 0 1 0.1", FIELD(mutationprobs[FB_DELETION]), "Probability of mutation by deleting random characters in genotype", },
    1824        { "fB_mut_duplication", 1, 0, "Duplication", "f 0 1 0.05", FIELD(mutationprobs[FB_DUPLICATION]), "Probability of mutation by copying single *gene* of genotype and appending it to the beginning of this genotype", },
     
    8187                if (!islower(genotype[i]))
    8288                {
    83                         return i + 1;
     89                        if (genotype[i] == '"')
     90                        {
     91                                SString neuclassdef;
     92                                int nextid = i + 1;
     93                                if (!genotype.getNextToken(nextid, neuclassdef, '"'))
     94                                {
     95                                        return i + 1;
     96                                }
     97                                Neuro *neu = new Neuro();
     98                                neu->setDetails(neuclassdef);
     99
     100                                bool isclass = neu->getClass() ? true : false;
     101                                delete neu;
     102                                if (!isclass)
     103                                {
     104                                        return i + 1;
     105                                }
     106                                i = nextid;
     107                        }
     108                        else
     109                        {
     110                                return i + 1;
     111                        }
    84112                }
    85113        }
     
    121149                if (!isalpha(genotype[i]))
    122150                {
    123                         return GENOPER_OPFAIL;
     151                        if (genotype[i] == '"')
     152                        {
     153                                SString neuclassdef;
     154                                int nextid = i + 1;
     155                                if (!genotype.getNextToken(nextid, neuclassdef, '"'))
     156                                {
     157                                        return i + 1;
     158                                }
     159                                Neuro *neu = new Neuro();
     160                                neu->setDetails(neuclassdef);
     161
     162                                bool isclass = neu->getClass() ? true : false;
     163                                delete neu;
     164                                if (!isclass)
     165                                {
     166                                        return i + 1;
     167                                }
     168                                i = nextid;
     169                        }
     170                        else
     171                        {
     172                                return GENOPER_OPFAIL;
     173                        }
    124174                }
    125175                // if character is uppercase, then convert it to lowercase
    126                 if (isupper(genotype[i]))
     176                else if (isupper(genotype[i]))
    127177                {
    128178                        genotype.directWrite()[i] = tolower(genotype[i]);
     
    142192        }
    143193        return GENOPER_OK;
     194}
     195
     196SString Geno_fB::detokenizeSequence(std::list<SString> tokenlist)
     197{
     198        SString res = "";
     199        for (std::list<SString>::iterator it = tokenlist.begin(); it != tokenlist.end(); it++)
     200        {
     201                res += (*it);
     202        }
     203        return res;
     204}
     205
     206std::list<SString> Geno_fB::tokenizeSequence(SString genotype)
     207{
     208        std::list<SString> res;
     209        int i = 0;
     210        while (i < genotype.len())
     211        {
     212                // if character is not alphabetic - error
     213                if (isalpha(genotype[i]))
     214                {
     215                        SString el = "";
     216                        el += genotype[i];
     217                        res.push_back(el);
     218                        i++;
     219                }
     220                else
     221                {
     222                        SString neuclassdef;
     223                        i++;
     224                        genotype.getNextToken(i, neuclassdef, '"');
     225                        SString ndef = "\"";
     226                        ndef += neuclassdef;
     227                        ndef += "\"";
     228                        res.push_back(ndef);
     229                }
     230        }
     231        return res;
    144232}
    145233
     
    157245        case FB_SUBSTITUTION:
    158246        {
    159                 int rndid = randomN(line.len()); // select random letter from genotype
     247                std::list<SString> tokenized = tokenizeSequence(line);
     248                int rndid = randomN(tokenized.size()); // select random letter from genotype
    160249                // increment/decrement character - when overflow happens, this method
    161250                // uses reflect method
    162                 if (randomN(2) == 0)
    163                 {
    164                         if (line[rndid] == 'a') line.directWrite()[rndid] = 'b';
    165                         else line.directWrite()[rndid] = line[rndid] - 1;
     251                std::list<SString>::iterator it = tokenized.begin();
     252                std::advance(it, rndid);
     253                SString t = (*it);
     254                if ((*it).len() == 1)
     255                {
     256                        if (randomN(2) == 0)
     257                        {
     258                                if ((*it)[0] == 'a') (*it).directWrite()[0] = 'b';
     259                                else (*it).directWrite()[0] = (*it)[0] - 1;
     260                        }
     261                        else
     262                        {
     263                                if ((*it)[0] == 'z') (*it).directWrite()[0] = 'y';
     264                                else (*it).directWrite()[0] = (*it)[0] + 1;
     265                        }
     266                        chg = 1.0 / line.len();
    166267                }
    167268                else
    168269                {
    169                         if (line[rndid] == 'z') line.directWrite()[rndid] = 'y';
    170                         else line.directWrite()[rndid] = line[rndid] + 1;
    171                 }
     270                        // first method needs to extract quotes
     271                        SString def = (*it);
     272                        def = def.substr(1, def.len() - 2);
     273                        Geno_fH::mutateNeuronProperties(def);
     274                        SString res = "\"";
     275                        res += def;
     276                        res += "\"";
     277                        (*it) = res;
     278                        chg = (double)def.len() / line.len();
     279                }
     280                line = detokenizeSequence(tokenized);
     281                break;
     282        }
     283        case FB_INSERTION:
     284        {
    172285                chg = 1.0 / line.len();
    173                 break;
    174         }
    175         case FB_INSERTION:
     286                std::list<SString> tokenized = tokenizeSequence(line);
     287                int rndid = randomN(tokenized.size()); // select random insertion point
     288                std::list<SString>::iterator it = tokenized.begin();
     289                std::advance(it, rndid);
     290                SString letter = "a";
     291                letter.directWrite()[0] = 'a' + randomN(26);
     292                tokenized.insert(it, letter);
     293                line = detokenizeSequence(tokenized);
     294                break;
     295        }
     296        case FB_NCLASSINS:
     297        {
     298                std::list<SString> tokenized = tokenizeSequence(line);
     299                std::list<SString>::iterator it = tokenized.begin();
     300                int rndid = randomN(tokenized.size()); // select random insertion point
     301                std::advance(it, rndid);
     302                NeuroClass *cls = getRandomNeuroClass();
     303                SString classdef = cls->getName();
     304                Geno_fH::mutateNeuronProperties(classdef);
     305                SString res = "\"";
     306                res += classdef;
     307                res += "\"";
     308                tokenized.insert(it, res);
     309                chg = (double)classdef.len() / line.len();
     310                line = detokenizeSequence(tokenized);
     311                break;
     312        }
     313        case FB_DELETION:
    176314        {
    177315                chg = 1.0 / line.len();
    178                 int rndid = randomN(genotype.len()); // select random insertion point
    179                 char letter = 'a' + randomN(26);
    180                 SString result = line.substr(0, rndid);
    181                 result += letter;
    182                 result += line.substr(rndid);
    183                 line = result;
    184                 break;
    185         }
    186         case FB_DELETION:
    187         {
    188                 chg = 1.0 / line.len();
    189                 int rndid = randomN(line.len()); // select random insertion point
    190                 if (rndid == line.len() - 1)
    191                 {
    192                         line = line.substr(0, line.len() - 1);
    193                 }
    194                 else
    195                 {
    196                         line = line.substr(0, rndid) + line.substr(rndid + 1);
    197                 }
     316                std::list<SString> tokenized = tokenizeSequence(line);
     317                std::list<SString>::iterator it = tokenized.begin();
     318                int rndid = randomN(tokenized.size()); // select random deletion point
     319                std::advance(it, rndid);
     320                tokenized.erase(it);
     321                line = detokenizeSequence(tokenized);
    198322                break;
    199323        }
     
    210334        case FB_TRANSLOCATION:
    211335        {
    212                 std::vector<int> cuts(4);
     336                std::list<SString> tokenized = tokenizeSequence(line);
     337                std::vector<unsigned int> cuts(4);
    213338                for (int i = 0; i < 4; i++)
    214339                {
    215                         cuts[i] = randomN(line.len());
     340                        cuts[i] = randomN(tokenized.size());
    216341                }
    217342                std::sort(cuts.begin(), cuts.end());
    218                 SString first = line.substr(cuts[0], cuts[1] - cuts[0]);
    219                 SString second = line.substr(cuts[2], cuts[3] - cuts[2]);
    220                 SString result = line.substr(0, cuts[0]) + second +
    221                         line.substr(cuts[1], cuts[2] - cuts[1]) + first + line.substr(cuts[3]);
    222                 line = result;
     343                std::vector<std::list<SString>::iterator> iters(4);
     344                for (int i = 0; i < 4; i++)
     345                {
     346                        iters[i] = tokenized.begin();
     347                        std::advance(iters[i], cuts[i]);
     348                }
     349
     350                std::list<SString> res;
     351                res.insert(res.end(), tokenized.begin(), iters[0]);
     352                res.insert(res.end(), iters[2], iters[3]);
     353                res.insert(res.end(), iters[1], iters[2]);
     354                res.insert(res.end(), iters[0], iters[1]);
     355                res.insert(res.end(), iters[3], tokenized.end());
     356
     357//              SString first = line.substr(cuts[0], cuts[1] - cuts[0]);
     358//              SString second = line.substr(cuts[2], cuts[3] - cuts[2]);
     359//              SString result = line.substr(0, cuts[0]) + second +
     360//                      line.substr(cuts[1], cuts[2] - cuts[1]) + first + line.substr(cuts[3]);
     361                line = detokenizeSequence(res);
    223362                chg = (float)(cuts[3] - cuts[2] + cuts[1] - cuts[0]) / line.len();
    224363                break;
  • cpp/frams/genetics/fB/fB_oper.h

    r780 r797  
     1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
     3// See LICENSE.txt for details.
     4
    15#ifndef _FB_OPER_H_
    26#define _FB_OPER_H_
    37
    48#include "../genooperators.h"
     9#include <list>
    510
    611/** @name Codes for general fB mutation types */
     
    813#define FB_SUBSTITUTION  0 ///<Relative probability of mutation by changing single random letter in genotype (substitution)
    914#define FB_INSERTION     1 ///<Relative probability of mutation by inserting characters in random place of genotype
    10 #define FB_DELETION      2 ///<Relative probability of mutation by deleting random characters in genotype
    11 #define FB_DUPLICATION   3 ///<Relative probability of mutation by copying single *gene* of genotype and appending it to the beginning of this genotype
    12 #define FB_TRANSLOCATION 4 ///<Relative probability of mutation by replacing two substrings in genotype
    13 #define FB_MUT_COUNT     5 ///<Count of mutation types
     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
    1420//@}
    1521
     
    2531private:
    2632        bool hasStick(SString genotype);
     33        SString detokenizeSequence(std::list<SString> tokenlist);
     34        std::list<SString> tokenizeSequence(SString genotype);
    2735
    2836public:
Note: See TracChangeset for help on using the changeset viewer.