Ignore:
Timestamp:
03/15/18 22:55:05 (3 years ago)
Author:
Maciej Komosinski
Message:
  • added support for new API for neuron types and their properties
  • added support for checkpoints
File:
1 edited

Legend:

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

    r676 r760  
    55// Copyright (C) 1999,2000  Adam Rotaru-Varga (adam_rotaru@yahoo.com), GNU LGPL
    66// Copyright (C) since 2001 Maciej Komosinski
     7// 2018, Grzegorz Latosinski, added support for new API for neuron types and their properties
    78
    89#include "oper_f4.h"
     
    138139#define REP_MAXCOUNT 19
    139140
    140         f4_node * n1, *n2, *n3, *n4, *n5;
    141 
    142141        // do the mutation
    143142        // pick a random node
    144         n1 = g->child->randomNode();
     143        f4_node *n1 = g->child->randomNode();
     144        vector<NeuroClass*> neulist;
    145145        //DB( printf("%c\n", n1->name); )
     146        int neuronid = -1;
    146147
    147148        switch (roulette(prob, F4_COUNT))
     
    155156                {
    156157                        // add division ('<')
    157                         n3 = n1->parent;
     158                        f4_node *n3 = n1->parent;
    158159                        n3->removeChild(n1);
    159                         n2 = new f4_node('<', n3, n3->pos);
     160                        f4_node *n2 = new f4_node('<', n3, n3->pos);
    160161                        n2->addChild(n1);
    161162                        // new cell is stick or neuron
    162163                        // "X>" or "N>"
     164                        f4_node *n5 = NULL;
    163165                        double pr = rnd01;
    164166                        pr -= 0.5;
    165                         if (pr < 0) n3 = new f4_node('X', n2, n2->pos);
     167                        if (pr < 0) n5 = new f4_node('X', n2, n2->pos);
    166168                        else
    167169                        {
    168                                 pr -= 0.5;
    169                                 if (pr < 0)
    170                                 {
    171                                         // if neuron, make muscle and add a link
    172                                         n3 = new f4_node('N', n2, n2->pos);
    173                                         if (randomN(2) == 0)
    174                                                 n4 = new f4_node('|', n3, n2->pos);
    175                                         else
    176                                                 n4 = new f4_node('@', n3, n2->pos);
    177                                         n5 = new f4_node('[', n4, n2->pos);
    178                                         linkNodeMakeRandom(n5);
    179                                 }
    180                         }
    181                         new f4_node('>', n3, n3->pos);
     170                                // make neuron
     171                                NeuroClass * rndclass = GenoOperators::getRandomNeuroClass();
     172                                if (rndclass == NULL)
     173                                {
     174                                        n5 = new f4_node('X', n2, n2->pos);
     175                                }
     176                                else
     177                                {
     178                                        f4_node *n4 = new f4_node(rndclass->getName().c_str(), n2, n2->pos); //TODO move this above
     179                                        if (rndclass->getPreferredInputs() != 0)
     180                                        {
     181                                                neuronid = -1;
     182                                                for (int i = 0; i < g->count(); i++)
     183                                                {
     184                                                        f4_node * gcur = g->ordNode(i);
     185                                                        char * temp = (char*)gcur->name.c_str();
     186                                                        NeuroClass * neuclass = GenoOperators::parseNeuroClass(temp);
     187                                                        if (neuclass != NULL)
     188                                                        {
     189                                                                neulist.push_back(neuclass);
     190                                                        }
     191                                                        if (g->ordNode(i) == n3)
     192                                                        {
     193                                                                neuronid = neulist.size()-1;
     194                                                        }
     195                                                }
     196                                                if (neuronid == -1)
     197                                                {
     198                                                        return GENOPER_OPFAIL;
     199                                                }
     200                                                n5 = new f4_node('[', n4, n2->pos);
     201                                                linkNodeMakeRandom(n5, neuronid, neulist);
     202                                        }
     203                                        else {
     204                                                n5 = n4;
     205                                        }
     206                                }
     207                        }
     208                        new f4_node('>', n5, n5->pos);
    182209                        n1->parent = n2;
    183210                        // now with 50% chance swap children
     
    193220                {
    194221                        // add link
    195                         n1->parent->removeChild(n1);
    196                         n2 = new f4_node('[', n1->parent, n1->parent->pos);
    197                         linkNodeMakeRandom(n2);
    198                         n2->addChild(n1);
    199                         n1->parent = n2;
     222                        f4_node * par = n1->parent;
     223                        char * temp = (char*)par->name.c_str();
     224                        NeuroClass * neuclass = GenoOperators::parseNeuroClass(temp);
     225                        if (neuclass != NULL)
     226                        {
     227                                n1->parent->removeChild(n1);
     228                                f4_node *n2 = new f4_node('[', n1->parent, n1->parent->pos);
     229                                n2->addChild(n1);
     230                                n1->parent = n2;
     231                                neuronid = -1;
     232                                for (int i = 0; i < g->count(); i++)
     233                                {
     234                                        f4_node *gcur = g->ordNode(i);
     235                                        temp = (char*)gcur->name.c_str();
     236                                        NeuroClass *neuclass = GenoOperators::parseNeuroClass(temp);
     237                                        if (neuclass != NULL)
     238                                        {
     239                                                neulist.push_back(neuclass);
     240                                        }
     241                                        if (gcur == par)
     242                                        {
     243                                                neuronid = neulist.size()-1;
     244                                        }
     245                                }
     246                                if (neuronid == -1)
     247                                {
     248                                        return GENOPER_OPFAIL;
     249                                }
     250                                linkNodeMakeRandom(n2, neuronid, neulist);
     251                        }
    200252                }
    201253                        break;
     
    204256                        // add neuron modifier
    205257                        n1->parent->removeChild(n1);
    206                         n2 = new f4_node(':', n1->parent, n1->parent->pos);
     258                        f4_node *n2 = new f4_node(':', n1->parent, n1->parent->pos);
    207259                        nparNodeMakeRandom(n2);
    208260                        n2->addChild(n1);
     
    214266                        // add repetition ('#')
    215267                        // repeated code (left child) is the original, right child is empty, count is 2
    216                         n3 = n1->parent;
     268                        f4_node *n3 = n1->parent;
    217269                        n3->removeChild(n1);
    218                         n2 = new f4_node('#', n3, n3->pos);
     270                        f4_node *n2 = new f4_node('#', n3, n3->pos);
    219271                        n2->i1 = 2;
    220272                        n2->addChild(n1);
     
    228280                        // choose a simple node from ADD_SIMPLE_CODES
    229281                        n1->parent->removeChild(n1);
    230                         n2 = new f4_node(ADD_SIMPLE_CODES[randomN(strlen(ADD_SIMPLE_CODES))], n1->parent, n1->parent->pos);
     282                        f4_node *n2 = new f4_node(ADD_SIMPLE_CODES[randomN(strlen(ADD_SIMPLE_CODES))], n1->parent, n1->parent->pos);
    231283                        n2->addChild(n1);
    232284                        n1->parent = n2;
     
    258310                        case 1:  // one child
    259311                        {
    260                                 n2 = n1->parent;
     312                                f4_node *n2 = n1->parent;
    261313                                n2->removeChild(n1);
    262314                                if (NULL != n1->child)
     
    281333                        {
    282334                                // two children
    283                                 n2 = n1->parent;
     335                                f4_node *n2 = n1->parent;
    284336                                n2->removeChild(n1);
    285337                                // n1 has two children. pick one randomly 50-50, destroy other
     
    318370                while (1)
    319371                {
    320                         if (strchr(MUT_CHAN_CODES, n1->name)) break;
     372                        if (strchr(MUT_CHAN_CODES, n1->name[0])) break;
    321373                        // try a new one
    322374                        n1 = g->child->randomNode();
     
    324376                        if (i >= 20) return GENOPER_OPFAIL;
    325377                }
    326                 switch (n1->name)
     378                switch (n1->name[0])
    327379                {
    328380                case '<':
     381                {
    329382                        // swap children
    330                         n2 = n1->child; n1->child = n1->child2; n1->child2 = n2;
     383                        f4_node *n2 = n1->child; n1->child = n1->child2; n1->child2 = n2;
     384                }
    331385                        break;
    332386                case '[':
    333                         linkNodeChangeRandom(n1);
     387                {
     388                        neuronid = -1;
     389                        for (int i = 0; i < g->count(); i++)
     390                        {
     391                                f4_node *gcur = g->ordNode(i);
     392                                char *temp = (char*)gcur->name.c_str();
     393                                NeuroClass *neuclass = GenoOperators::parseNeuroClass(temp);
     394                                if (neuclass != NULL)
     395                                {
     396                                        neulist.push_back(neuclass);
     397                                }
     398                                if (gcur == n1)
     399                                {
     400                                        neuronid = neulist.size()-1;
     401                                }
     402                        }
     403                        if (neuronid == -1)
     404                        {
     405                                return GENOPER_OPFAIL;
     406                        }
     407                        linkNodeChangeRandom(n1, neuronid, neulist);
     408                }
    334409                        break;
     410
    335411                case '#':
     412                {
    336413                        repeatNodeChangeRandom(n1);
     414                }
    337415                        break;
    338416                }
     
    348426
    349427// make a random [ node
    350 void Geno_f4::linkNodeMakeRandom(f4_node * nn) const
    351 {
    352         int i;
     428void Geno_f4::linkNodeMakeRandom(f4_node *nn, int neuid, vector<NeuroClass*> neulist) const
     429{
    353430        float prob1;
    354 
    355         i = 0;
     431        NeuroClass *nc = NULL;
     432
    356433        // 35% chance one of *GTS
    357434        prob1 = rnd01;
     
    360437        {
    361438                // '*', 'G', 'T', or 'S', 1/4 chance each
    362                 i = 1 + (int)(3.999f * rnd01);
    363         }
    364         nn->i1 = i;
    365         nn->l1 = 0;
    366         if (0 == i)
     439                nc =  GenoOperators::getRandomNeuroClassWithOutputAndNoInputs();
     440        }
     441        if (nc != NULL)
     442        {
     443                nn->i1 = 1;
     444                nn->s1 = nc->getName().c_str();
     445                nn->l1 = 0;
     446        }
     447        else
    367448        {
    368449                // relative input link
    369                 nn->l1 = (int)(4.0f * (rnd01 - 0.5f));
     450                int id = GenoOperators::getRandomNeuroClassWithOutput(neulist);
     451                int relid = neuid - id;
     452                nn->l1 = relid;
     453                //nn->l1 = (int)(4.0f * (rnd01 - 0.5f));
    370454        }
    371455        // weight
    372         nn->f1 = 10.0f * (rnd01 - 0.5f);
     456        nn->f1 = GenoOperators::mutateNeuProperty(nn->f1,NULL,-1);
     457        //nn->f1 = 10.0f * (rnd01 - 0.5f);
    373458}
    374459
    375460// change a [ node
    376 void Geno_f4::linkNodeChangeRandom(f4_node * nn) const      //rewritten by M.K. - should work as before (not tested)
    377 {
    378         int i;
    379         float prob2;
    380 
     461void Geno_f4::linkNodeChangeRandom(f4_node * nn, int neuid, std::vector<NeuroClass*> neulist) const      //rewritten by M.K. - should work as before (not tested)
     462{
    381463        double probs[3] = { 0.1, 0.3, 0.6 };
     464        NeuroClass *cl;
    382465        // 10% change type
    383466        // 30% change link
     
    387470        {
    388471        case 0: // change type
    389                 i = 0;
    390                 // * G, 10% chance each
    391                 prob2 = rnd01 - 0.10f;
    392                 if (prob2 < 0) i = 1; else { prob2 -= 0.10f; if (prob2 < 0) i = 2; }
    393                 nn->i1 = i;
     472                // 80% for link, 20% for random sensor
     473                if (rnd01 < 0.2f)
     474                {
     475                        cl = GenoOperators::getRandomNeuroClassWithOutputAndNoInputs();
     476                        if (cl != NULL)
     477                        {
     478                                nn->i1 = 1;
     479                                nn->s1 = cl->name.c_str();
     480                                nn->l1 = 0;
     481                        }
     482                }
    394483                break;
    395484        case 1: // change link
    396485                if (0 == nn->i1) // relative input link
    397                         nn->l1 += (int)(2.0f * (rnd01 - 0.5f));
     486                {
     487                        int id = GenoOperators::getRandomNeuroClassWithOutput(neulist);
     488                        nn->l1 = neuid - id;
     489                }
     490                        //nn->l1 += (int)(2.0f * (rnd01 - 0.5f));
    398491                break;
    399492        case 2: // change weight
    400                 nn->f1 += 1.0f * (rnd01 - 0.5f);
     493                nn->f1 = GenoOperators::mutateNeuProperty(nn->f1,NULL,-1);
     494                //nn->f1 += 1.0f * (rnd01 - 0.5f);
    401495                break;
    402496        }
Note: See TracChangeset for help on using the changeset viewer.