Changeset 797 for cpp/frams/genetics/fL/fL_matheval.cpp
- Timestamp:
- 06/06/18 01:45:18 (7 years ago)
- 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 1 5 #include <frams/util/extvalue.h> 2 6 #include <frams/util/sstring.h> 3 7 #include <stack> 4 8 #include "fL_matheval.h" 9 #include <frams/genetics/genooperators.h> 5 10 6 11 // Used available operators in MathEvaluation … … 94 99 } 95 100 101 void 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 96 107 void MathEvaluation::registerOperators() 97 108 { 98 109 // 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; 110 123 } 111 124 … … 159 172 int MathEvaluation::convertString(std::string expression) 160 173 { 174 originalexpression = expression; 161 175 clearPostfix(); //clear previous objects 162 176 ExtValue val; … … 193 207 { 194 208 delete operatorstack.back(); 195 operatorstack.pop_back();196 }209 } 210 operatorstack.pop_back(); 197 211 } 198 212 return -1; … … 247 261 { 248 262 delete operatorstack.back(); 249 operatorstack.pop_back();250 }263 } 264 operatorstack.pop_back(); 251 265 } 252 266 return -1; … … 407 421 { 408 422 delete operatorstack.back(); 409 operatorstack.pop_back();410 }423 } 424 operatorstack.pop_back(); 411 425 } 412 426 return -1; … … 434 448 { 435 449 delete operatorstack.back(); 436 operatorstack.pop_back();437 }450 } 451 operatorstack.pop_back(); 438 452 } 439 453 return -1; … … 448 462 // stack holds number used during operator execution 449 463 std::stack<Number *> numberstack; 450 451 464 for (std::list<Token *>::iterator it = postfixlist.begin(); it != postfixlist.end(); it++) 452 465 { … … 532 545 int MathEvaluation::RPNToInfix(std::string &result) 533 546 { 547 if (postfixlist.size() == 0) 548 { 549 result = ""; 550 return 0; 551 } 534 552 // stack holds stringified chunk and its precedence 535 553 std::stack<std::pair<std::string, int>> chunks; … … 585 603 { 586 604 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"); 588 606 return -1; 589 607 } … … 592 610 return 0; 593 611 } 612 613 void 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 644 MathEvaluation::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 660 void 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 687 int 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 799 std::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.