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

A more complete implementation of fB, fH, fL

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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;
Note: See TracChangeset for help on using the changeset viewer.