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/fL/fL_matheval.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/extvalue.h>
    26#include <frams/util/sstring.h>
    37#include <stack>
    48#include "fL_matheval.h"
     9#include <frams/genetics/genooperators.h>
    510
    611// Used available operators in MathEvaluation
     
    9499}
    95100
     101void MathEvaluation::registerOperator(double(*operation)(double left, double right), int precedence, MathEvaluation::Associativity assoc, std::string opsymbol)
     102{
     103        operators[opsymbol] = new Operator(operation, precedence, assoc, opsymbol);
     104        operatorstrings.push_back(opsymbol);
     105}
     106
    96107void MathEvaluation::registerOperators()
    97108{
    98109        // list of available operators in MathEvaluation
    99         operators["+"] = new Operator(madd, 2, Associativity::LEFT, "+");
    100         operators["-"] = new Operator(msub, 2, Associativity::LEFT, "-");
    101         operators["*"] = new Operator(mmul, 3, Associativity::LEFT, "*");
    102         operators["&"] = new Operator(mand, 0, Associativity::LEFT, "&");
    103         operators["|"] = new Operator(mor, 0, Associativity::LEFT, "|");
    104         operators[">"] = new Operator(mgreater, 1, Associativity::LEFT, ">");
    105         operators["<"] = new Operator(mless, 1, Associativity::LEFT, "<");
    106         operators[">="] = new Operator(meqgreater, 1, Associativity::LEFT, ">=");
    107         operators["<="] = new Operator(meqless, 1, Associativity::LEFT, "<=");
    108         operators["="] = new Operator(mequal, 1, Associativity::RIGHT, "=");
    109         operators["~"] = new Operator(mnotequal, 1, Associativity::RIGHT, "~");
     110        registerOperator(madd, 2, Associativity::LEFT, "+");
     111        registerOperator(msub, 2, Associativity::LEFT, "-");
     112        registerOperator(mmul, 3, Associativity::LEFT, "*");
     113        registerOperator(mgreater, 1, Associativity::LEFT, ">");
     114        registerOperator(mless, 1, Associativity::LEFT, "<");
     115        registerOperator(meqgreater, 1, Associativity::LEFT, ">=");
     116        registerOperator(meqless, 1, Associativity::LEFT, "<=");
     117        registerOperator(mequal, 1, Associativity::RIGHT, "=");
     118        registerOperator(mnotequal, 1, Associativity::RIGHT, "~");
     119        registerOperator(mand, 0, Associativity::LEFT, "&");
     120        registerOperator(mor, 0, Associativity::LEFT, "|");
     121        arithmeticoperatorscount = 3;
     122        comparisonoperatorscount = 6;
    110123}
    111124
     
    159172int MathEvaluation::convertString(std::string expression)
    160173{
     174        originalexpression = expression;
    161175        clearPostfix(); //clear previous objects
    162176        ExtValue val;
     
    193207                                        {
    194208                                                delete operatorstack.back();
    195                                                 operatorstack.pop_back();
    196                                         }
     209                                        }
     210                                        operatorstack.pop_back();
    197211                                }
    198212                                return -1;
     
    247261                                        {
    248262                                                delete operatorstack.back();
    249                                                 operatorstack.pop_back();
    250                                         }
     263                                        }
     264                                        operatorstack.pop_back();
    251265                                }
    252266                                return -1;
     
    407421                                        {
    408422                                                delete operatorstack.back();
    409                                                 operatorstack.pop_back();
    410                                         }
     423                                        }
     424                                        operatorstack.pop_back();
    411425                                }
    412426                                return -1;
     
    434448                                {
    435449                                        delete operatorstack.back();
    436                                         operatorstack.pop_back();
    437                                 }
     450                                }
     451                                operatorstack.pop_back();
    438452                        }
    439453                        return -1;
     
    448462        // stack holds number used during operator execution
    449463        std::stack<Number *> numberstack;
    450 
    451464        for (std::list<Token *>::iterator it = postfixlist.begin(); it != postfixlist.end(); it++)
    452465        {
     
    532545int MathEvaluation::RPNToInfix(std::string &result)
    533546{
     547        if (postfixlist.size() == 0)
     548        {
     549                result = "";
     550                return 0;
     551        }
    534552        // stack holds stringified chunk and its precedence
    535553        std::stack<std::pair<std::string, int>> chunks;
     
    585603        {
    586604                logMessage("MathEvaluation", "RPNToInfix", LOG_ERROR,
    587                         "Could not convert RPN notation to infix notation");
     605                        "Could not convert RPN notation to infix notation - formula is not complete");
    588606                return -1;
    589607        }
     
    592610        return 0;
    593611}
     612
     613void MathEvaluation::mutateValueOrVariable(MathEvaluation::Number *&currval, bool usetime)
     614{
     615        if (randomN(2) == 0 && varcount > 0) // use variable
     616        {
     617                if (currval && currval->type == TokenType::NUMBER)
     618                {
     619                        delete currval;
     620                }
     621                int var = randomN(varcount + (usetime ? 1 : 0));
     622                if (varcount == var) // time is used
     623                {
     624                        currval = t;
     625                }
     626                else
     627                {
     628                        currval = vars[var];
     629                }
     630        }
     631        else
     632        {
     633                if (!currval || currval->type == TokenType::VARIABLE)
     634                {
     635                        currval = new Number(rnd01);
     636                }
     637                else
     638                {
     639                        currval->value = rnd01;
     640                }
     641        }
     642}
     643
     644MathEvaluation::Operator* MathEvaluation::getRandomOperator(int type)
     645{ // 0 for all, 1 for arithmetic only, 2 for logical only
     646        int randop = type == 2 ? arithmeticoperatorscount : 0;
     647        int count = arithmeticoperatorscount;
     648        if (type == 0)
     649        {
     650                count = operatorstrings.size();
     651        }
     652        else if (type == 2)
     653        {
     654                count = operatorstrings.size() - arithmeticoperatorscount;
     655        }
     656        randop += randomN(count);
     657        return operators[operatorstrings[randop]];
     658}
     659
     660void MathEvaluation::mutateConditional()
     661{
     662        if (varcount > 0)
     663        {
     664                int currsize = postfixlist.size();
     665                int varid = randomN(varcount);
     666                postfixlist.push_back(vars[varid]);
     667                if (randomN(2) == 0 && varcount > 1)
     668                {
     669                        int varid2 = randomN(varcount - 1);
     670                        if (varid2 >= varid) varid2++;
     671                        postfixlist.push_back(vars[varid2]);
     672                }
     673                else
     674                {
     675                        Number *num = new Number(rnd01);
     676                        postfixlist.push_back(num);
     677                }
     678                int opid = arithmeticoperatorscount + randomN(comparisonoperatorscount);
     679                postfixlist.push_back(operators[operatorstrings[opid]]);
     680                if (currsize > 0)
     681                {
     682                        postfixlist.push_back(operators["&"]);
     683                }
     684        }
     685}
     686
     687int MathEvaluation::mutate(bool logical, bool usetime)
     688{
     689        if (postfixlist.size() == 0)
     690        {
     691                Number *val = new Number(rnd01);
     692                postfixlist.push_back(val);
     693                return -1;
     694        }
     695        int method = randomN(postfixlist.size() < MAX_MUT_FORMULA_SIZE ? MATH_MUT_COUNT : MATH_MUT_COUNT - 1);
     696        switch (method)
     697        {
     698        case MATH_MUT_INSERTION:
     699        {
     700                std::list<Token *> insertpair;
     701                Number *val = NULL;
     702                mutateValueOrVariable(val, usetime);
     703                insertpair.push_back(val);
     704                std::list<Token *>::iterator it = postfixlist.begin();
     705                // insertion can be applied from 1st occurrence
     706                int insertlocation = 1 + randomN(postfixlist.size() - 1);
     707                std::advance(it, insertlocation);
     708                Operator *rndop;
     709                if (insertlocation == (int)postfixlist.size() - 1)
     710                {
     711                        rndop = getRandomOperator(logical ? 2 : 1);
     712                }
     713                else
     714                {
     715                        rndop = getRandomOperator(logical ? 0 : 1);
     716
     717                }
     718                insertpair.push_back(rndop);
     719                postfixlist.insert(it, insertpair.begin(), insertpair.end());
     720                break;
     721        }
     722        case MATH_MUT_CHANGEVAL:
     723        {
     724                std::vector<std::list<Token *>::iterator> numbersineval;
     725                int id = 0;
     726                for (std::list<Token *>::iterator it = postfixlist.begin(); it != postfixlist.end(); it++)
     727                {
     728                        if ((*it)->type == TokenType::NUMBER || (*it)->type == TokenType::VARIABLE)
     729                        {
     730                                numbersineval.push_back(it);
     731                        }
     732                        id++;
     733                }
     734                int randid = randomN(numbersineval.size());
     735                Number *numptr = (Number *)(*numbersineval[randid]);
     736                mutateValueOrVariable(numptr, usetime);
     737                (*numbersineval[randid]) = numptr;
     738                break;
     739        }
     740        case MATH_MUT_CHANGEOPER:
     741        {
     742                std::vector<std::list<Token *>::iterator> ops;
     743                for (std::list<Token *>::iterator it = postfixlist.begin(); it != postfixlist.end(); it++)
     744                {
     745                        if ((*it)->type == TokenType::OPERATOR)
     746                        {
     747                                ops.push_back(it);
     748                        }
     749                }
     750                if (ops.size() > 0)
     751                {
     752                        int randid = randomN(ops.size());
     753                        Operator *rndop;
     754                        if (randid == (int)ops.size() - 1)
     755                        {
     756                                rndop = getRandomOperator(logical ? 2 : 1);
     757                        }
     758                        else
     759                        {
     760                                rndop = getRandomOperator(logical ? 0 : 1);
     761                        }
     762                        (*ops[randid]) = rndop;
     763                }
     764                break;
     765        }
     766        case MATH_MUT_DELETION:
     767        {
     768                std::list<Token *>::iterator it = postfixlist.begin();
     769                std::vector<std::list<Token *>::iterator> firstofpairs;
     770                while (it != postfixlist.end())
     771                {
     772                        if ((*it)->type == TokenType::NUMBER || (*it)->type == TokenType::VARIABLE)
     773                        {
     774                                std::list<Token *>::iterator next = it;
     775                                next++;
     776                                if (next != postfixlist.end() && (*next)->type == TokenType::OPERATOR)
     777                                {
     778                                        firstofpairs.push_back(it);
     779                                }
     780                        }
     781                        it++;
     782                }
     783                if (firstofpairs.size() > 0)
     784                {
     785                        int rndid = randomN(firstofpairs.size());
     786                        if ((*firstofpairs[rndid])->type == TokenType::NUMBER)
     787                        {
     788                                delete (*firstofpairs[rndid]);
     789                        }
     790                        firstofpairs[rndid] = postfixlist.erase(firstofpairs[rndid]);
     791                        postfixlist.erase(firstofpairs[rndid]);
     792                }
     793                break;
     794        }
     795        }
     796        return method;
     797}
     798
     799std::string MathEvaluation::getStringifiedRPN()
     800{
     801        std::string res = "";
     802        for (Token *el: postfixlist)
     803        {
     804                res += el->toString();
     805                res += " ";
     806        }
     807        return res;
     808}
Note: See TracChangeset for help on using the changeset viewer.