source: cpp/f8-to-f1/geno_f8.cpp @ 36

Last change on this file since 36 was 35, checked in by Maciej Komosinski, 14 years ago

simple productions are now more complete, and stored once, in a constant variable

File size: 46.5 KB
Line 
1/*
2 *  geno_f8.cpp
3 *  L-systemToF1
4 *
5 *  Created by Maciej Wajcht on 08-06-07.
6 *  Copyright 2008 __MyCompanyName__. All rights reserved.
7 *
8 */
9
10#include "geno_f8.h"
11#include <cstdlib>
12//#include <sys/time.h>
13#include "conv_f8tof1.h"
14#include "multimap.h"
15#include <iostream>
16#include <string>
17#include "sstringutils.h"
18#include "conv_f8_utils.h"
19
20#define GENO_F8_DEBUG 1 //0 - off, 1 - on
21
22#define FIELDSTRUCT Geno_f8
23
24static ParamEntry GENO8param_tab[]=
25{
26{"Genetics: f8",1,F8_OPERATION_COUNT,},
27{"f8_mut_chg_begin_arg", 0, 0, "Change beginning argument", "f 0 100 7", FIELD(operation[F8_CHANGE_BEGINNING_ARG]),"mutation: probability of changing a beginning argument", },
28{"f8_mut_chg_arg", 0, 0, "Change argument", "f 0 100 7", FIELD(operation[F8_CHANGE_ARG]),"mutation: probability of changing a production's argument", },
29{"f8_mut_del_comm", 0, 0, "Delete command", "f 0 100 8", FIELD(operation[F8_DELETE_COMMAND]),"mutation: probability of deleting a command", },
30{"f8_mut_insert_comm", 0, 0, "Insert commands", "f 0 100 8", FIELD(operation[F8_INSERT_COMMANDS]),"mutation: probability of inserting commands", },
31{"f8_mut_enc", 0, 0, "Encapsulate commands", "f 0 100 8",FIELD(operation[F8_ENCAPSULATE]),"mutation: probability of encapsulating commands", },
32{"f8_mut_chg_cond_sign", 0, 0, "Change condition sign", "f 0 100 7",FIELD(operation[F8_CHANGE_CONDITION_SIGN]),"mutation: probability of changing a condition sign", },
33{"f8_mut_add_param", 0, 0, "Add parameter", "f 0 100 8", FIELD(operation[F8_ADD_PARAMETER]),"mutation: probability of adding a parameter to the production", },
34{"f8_mut_add_cond", 0, 0, "Add condition", "f 0 100 8", FIELD(operation[F8_ADD_CONDITION]),"mutation: probability of adding a condition to the subproduction", },
35{"f8_mut_add_subprod", 0, 0, "Add subproduction", "f 0 100 8", FIELD(operation[F8_ADD_SUBPRODUCTION]),"mutation: probability of adding a subproduction", },
36{"f8_mut_chg_iter_number", 0, 0, "Change iteration number", "f 0 100 7", FIELD(operation[F8_CHANGE_ITERATIONS_NUMBER]),"mutation: probability of changing a number of iterations", },
37{"f8_mut_del_param", 0, 0, "Delete parameter", "f 0 100 8", FIELD(operation[F8_DELETE_PARAMETER]),"mutation: probability of deleting a parameter", },
38{"f8_mut_del_cond", 0, 0, "Delete condition", "f 0 100 8", FIELD(operation[F8_DELETE_CONDITION]),"mutation: probability of deleting a condition", },
39{"f8_mut_add_loop", 0, 0, "Add loop", "f 0 100 0", FIELD(operation[F8_ADD_LOOP]),"mutation: probability of adding a loop", },
40{"f8_mut_del_loop", 0, 0, "Delete loop", "f 0 100 0", FIELD(operation[F8_DELETE_LOOP]),"mutation: probability of deleting a loop", },
41{"f8_mut_del_prod", 0, 0, "Delete production", "f 0 100 8", FIELD(operation[F8_DELETE_PRODUCTION]),"mutation: probability of deleting a production", },
42{0,},
43};
44
45#undef FIELDSTRUCT
46
47ProductionInfo::ProductionInfo(SString name, int paramCount) {
48        this->name = name;
49        this->paramCount = paramCount;
50}
51
52Geno_f8::Geno_f8()
53{
54        supported_format = '8';
55
56        for(int i=0;i<strlen(GenoConv_F8ToF1::simpleprods);i++)
57                this->simpleCommandLetters.push_back(GenoConv_F8ToF1::simpleprods[i]);
58               
59        this->converter = new GenoConv_F8ToF1();
60
61        par.setParamTab(GENO8param_tab);
62        par.select(this);
63        par.setDefault();
64
65        /*mutation_method_names = new char*[F8_OPERATION_COUNT - 1]; //FIXME
66        int index = 0;
67        mutation_method_names[index++]="changed beginning argument";
68        mutation_method_names[index++]="changed argument";
69        mutation_method_names[index++]="deleted command";
70        mutation_method_names[index++]="inserted command";
71        mutation_method_names[index++]="encapsulated command";
72        mutation_method_names[index++]="changed condition sign";
73        mutation_method_names[index++]="added parameter";
74        mutation_method_names[index++]="added condition";
75        mutation_method_names[index++]="added subproduction";
76        mutation_method_names[index++]="changed iterations number";
77        mutation_method_names[index++]="deleted parameter";
78        mutation_method_names[index++]="deleted condition";
79        mutation_method_names[index++]="added loop";
80        mutation_method_names[index++]="deleted loop";
81        */
82       
83#ifdef GENO_F8_DEBUG > 0
84        for (int i = 0; i < F8_OPERATION_COUNT; i++) {
85                this->operation[i] = 1.0 / (double)F8_OPERATION_COUNT;
86        }
87#endif
88}
89
90Geno_f8::~Geno_f8() {
91        delete this->converter;
92}
93
94
95char* Geno_f8::getSimplest() {
96        const char* geno = "1\n---\nP0\nP0():X\n";
97        char* retGeno = (char*)malloc(strlen(geno) + 1);
98        strcpy(retGeno, geno);
99        return retGeno;
100}
101
102int Geno_f8::checkValidity(const char * geno) {
103        SString ssgeno = SString(geno);
104        SString f1ssgeno = this->converter->convert(ssgeno, NULL);
105        const char* f1genosrc = f1ssgeno;
106        Geno f1geno(f1genosrc);
107        if (this->converter->checkSyntax(geno) && f1geno.isValid()) {
108                return GENOPER_OK;
109        } else {
110                return 1;
111        }
112}
113
114int Geno_f8::validate(char *& geno) {
115        SString in = geno;
116        SString validated = "";
117        SString line;
118        int pos = 0;
119        bool firstLine = true;
120        bool beforeDelim = true;
121        bool justAfterDelim = false;
122        while (in.getNextToken(pos, line, '\n')) {
123                if (firstLine) {
124                        firstLine = false;
125                        const char* str = geno;
126                        std::istringstream i(str);
127                        double x;
128                        if (i >> x) {
129                                validated += line + "\n";
130                        } else {
131                                validated += "10\n";
132                        }
133                } else if (beforeDelim) {
134                        if (line[0] == 'P' && line.indexOf('(') != -1 && line.indexOf(')') != -1 && line.indexOf(':') != -1) {
135                                validated += "---\n";
136                                validated += line + "\n";
137                                beforeDelim = false;
138                        }
139                        int eqSignPos = line.indexOf('=');
140                        if (line[0] == 'n' && eqSignPos != -1) {
141                                validated += line + "\n";
142                        } else if (line == SString("---")) {
143                                validated += line + "\n";
144                                beforeDelim = false;
145                                justAfterDelim = true;
146                        }
147                } else if (justAfterDelim && line[0] == 'P') {
148                        const char* digits = "0123456789";
149                        SString s = line.substr(1);
150                        bool ok = true;
151                        for (int i = 0; i < s.len(); i++) {
152                                if (!strContainsOneOf(s(i), digits)) {
153                                        ok = false;
154                                        break;
155                                }
156                        }
157                        if (ok) {
158                                validated += line +"\n";
159                        }
160                        justAfterDelim = false;
161                } else if (line[0] == 'P' && line.indexOf('(') != -1 && line.indexOf(')') != -1 && line.indexOf(':') != -1) {
162                        validated += line + "\n";
163                }
164        }
165        free(geno); //must take care of the original allocation
166        char* validatedTmp = (char*)malloc(strlen(validated) + 1); //allocate for mutated genotype
167        strcpy(validatedTmp, validated); //the rest is originalg = mutated;
168        geno = validatedTmp;
169
170        return GENOPER_OK;
171}
172
173unsigned long Geno_f8::style(const char *g, int pos)
174{
175   char ch=g[pos];
176   unsigned long style=GENSTYLE_CS(0,GENSTYLE_NONE); //default, should be changed below
177   if (strchr("^[]X",ch))          style=GENSTYLE_RGBS(0,0,0,GENSTYLE_BOLD); else
178   if (strchr(":",ch))             style=GENSTYLE_RGBS(220,0,0,GENSTYLE_BOLD); else
179   if (strchr("|",ch))             style=GENSTYLE_RGBS(220,0,0,GENSTYLE_NONE);
180   return style;
181}
182
183
184int Geno_f8::getProductionsCount(const SString &in) {
185        int pos = 0;
186        SString line;
187        int counter = 0;
188        bool beforeDelim = true;
189        while (in.getNextToken(pos, line, '\n')) {
190                if (line.startsWith("---")) {
191                        beforeDelim = false;
192                        //also skip the start production
193                        in.getNextToken(pos, line, '\n');
194                        continue;
195                } else if (beforeDelim) {
196                        continue;
197                } else {
198                        counter++;
199                }                               
200        }
201        return counter;
202}
203
204vector<ProductionInfo> Geno_f8::getProductionsInfo(const SString &in) {
205        vector<ProductionInfo> productions;
206        SString line;
207        int pos = 0;
208        bool beforeFirstProd = true;
209        SString firstProdName;
210        while (in.getNextToken(pos, line, '\n')) {
211                if (line.startsWith("P") && line.indexOf('(', 0) == -1) {
212                        firstProdName = line;
213                        beforeFirstProd = false;
214                        continue;
215                }
216                if (beforeFirstProd) {
217                        continue;
218                }
219                int lParenIndex = line.indexOf('(', 0);
220                int rParenIndex = line.indexOf(')', 0);
221                if (line[0] == 'P' && lParenIndex != -1 && rParenIndex != -1) {
222                        ProductionInfo info;
223                        SString prodName = line.substr(0, lParenIndex);
224                        info.name = prodName;
225                        info.paramCount = 0;
226                        //if (line[lParenIndex + 1] == 'n') {
227                        SString strParams = line.substr(lParenIndex + 1, rParenIndex - lParenIndex - 1);
228                        int pos2 = 0;
229                        SString tok;
230                        while (strParams.getNextToken(pos2, tok, ',')) {
231                                info.paramCount++;
232                                info.paramNames.push_back(tok);
233                        }
234                        //}
235                        info.isFirstProduction = (prodName == firstProdName) ? true : false;
236                        productions.push_back(info);
237                }
238        }
239        return productions;
240}
241
242SString Geno_f8::mutateChangeBeginningArg(SString &in, float& chg) {
243        SString mutated, line, before, mid, after, tmp;
244        int counter = 0;
245        int pos = 0;
246        bool afterDelim = false;
247        bool firstLine = true;
248        while (in.getNextToken(pos, line, '\n')) {
249                if (firstLine) {
250                        firstLine = false;
251                        before += line + "\n";
252                        continue;
253                }
254                if (afterDelim) {
255                        after += line + "\n";
256                        continue;
257                }
258                if (line.startsWith("---")) {
259                        afterDelim = true;
260                        after += line + "\n";                                   
261                } else {
262                        mid += line + "\n";
263                        counter++;
264                }                               
265        }
266        if (counter == 0) {
267                chg = 0.0;
268                mutated = in;
269        } else {
270                int randNbr = randomN(counter);
271                pos = 0;
272                counter = 0;
273                while (mid.getNextToken(pos, line, '\n')) {
274                        if (counter++ == randNbr) {
275                                int pos2 = 0;
276                                SString tok;
277                                line.getNextToken(pos2, tok, '=');
278                                tmp += tok + "=";
279                                line.getNextToken(pos2, tok, '=');
280                                double arg = parseDouble(tok);
281                                arg += (double) (randomN(11) - 5); //-5..5
282                                tmp += SString::valueOf(arg) + "\n";
283                                chg = (float) (SString::valueOf(arg).len()) / (float) in.len();
284                        } else {
285                                tmp += line + "\n";
286                        }
287                }
288                mid = tmp;
289                mutated += before;
290                mutated += mid;
291                mutated += after;
292        }
293        return mutated;
294}
295
296SString Geno_f8::mutateChangeArg(SString &in, float& chg) {
297        SString mutated;
298
299        Lsystem *newLsystem = this->converter->createLsystem(in);
300        if (newLsystem == NULL) {
301                mutated += in;
302                chg = -1.0;
303                return mutated;
304        }
305       
306        vector<Production*> interestingProductions;
307       
308        for (map<string, Production*>::iterator prodIter = newLsystem->productions.begin();
309                 prodIter != newLsystem->productions.end(); prodIter++) {
310                if (prodIter->second->parameters.size() > 0) {
311                        interestingProductions.push_back(prodIter->second);
312                }
313        }
314       
315        if (interestingProductions.size() > 0) {
316                int rnd = randomN(interestingProductions.size());
317               
318                Production *randomProduction = interestingProductions[rnd];
319                SString prodName = randomProduction->name;
320               
321                int paramIndex = randomN(randomProduction->parameters.size());
322               
323                for (map<string, Production*>::iterator prodIter = newLsystem->productions.begin();
324                         prodIter != newLsystem->productions.end(); prodIter++) {
325                        vector<SubProduction> *subproductions = &(prodIter->second->subproductions);
326                        for (vector<SubProduction>::iterator subProdIter = subproductions->begin();
327                                 subProdIter != subproductions->end(); subProdIter++) {
328                                SubProduction *sp = &(*subProdIter);
329                                for (vector<ActionStrP>::iterator actionIter = sp->actions.begin();
330                                         actionIter != sp->actions.end(); actionIter++) {
331                                        if ((*actionIter).action != NULL && (*actionIter).action->name == prodName && (*actionIter).params.size() > paramIndex) {
332                                                SString param = (*actionIter).params[paramIndex];
333                                                int counter = 0;
334                                                int pos = 0;
335                                                SString tok;
336                                                while (in.getNextToken(pos, tok, ',')) {
337                                                        counter++;
338                                                }
339                                                int rnd = randomN(counter);
340                                                pos = 0;
341                                                counter = 0;
342                                                SString newParam = "";
343                                                if (randomN(2) == 0 || prodIter->second->parameters.size() == 0) {
344                                                        int rnd2 = randomN(5) + 1;
345                                                        newParam += param + SString::valueOf(rnd2) + ";";
346                                                } else {
347                                                        SString paramName = prodIter->second->parameters.getParameterName(randomN(prodIter->second->parameters.size())+1);
348                                                        newParam += param + paramName + ";";
349                                                }
350                                                newParam += (rnd == 0) ? SString("+;") : SString("-;");
351                                                (*actionIter).params[paramIndex] = newParam;
352                                                goto label;
353                                        }
354                                }
355                        }
356                }
357        label:
358                chg = 2.0 / (float) in.len();
359        }
360       
361        mutated = newLsystem->toString();
362       
363        delete newLsystem;
364       
365        return mutated;
366}
367
368SString Geno_f8::mutateDeleteCommand(SString &in, float& chg) {
369        SString mutated;
370       
371        Lsystem *lsystem = this->converter->createLsystem(in);
372        if (lsystem == NULL) {
373                mutated += in;
374                chg = -1.0;
375                return mutated;
376        }
377       
378        map<string, Production*>::iterator prodIter = lsystem->productions.begin();
379        for (int i = 0; i < randomN(lsystem->productions.size()); i++) {
380                if (i != 0) {
381                        prodIter++;
382                }
383        }
384       
385        Production *randomProduction = prodIter->second;
386        if (randomProduction->subproductions.size() > 0) {
387                vector<ActionStrP> *actions = &(randomProduction->subproductions.at(randomN(randomProduction->subproductions.size())).actions);
388                int rnd = randomN(actions->size());
389                if (actions->size() > 0) {
390                        Action *a = actions->at(rnd).action;
391                        if (a != NULL) {
392                                chg = (float) (a->getF8Representation().len()) / (float) in.len();
393                                actions->erase(actions->begin() + rnd);
394                        }
395                }
396        }
397       
398        mutated = lsystem->toString();
399       
400        delete lsystem;
401       
402        return mutated;
403}
404
405SString Geno_f8::mutateInsertCommands(SString &in, float& chg) {
406        SString mutated;
407       
408        //cout << "insertCommands 1" << endl;
409        Lsystem *lsystem = this->converter->createLsystem(in);
410        if (lsystem == NULL) {
411                mutated += in;
412                chg = -1.0;
413                return mutated;
414        }
415       
416        //cout << "insertCommands 2" << endl;
417        vector<Action*> actions = lsystem->getAllActions(true, true, false, false);
418        //cout << "insertCommands 3" << endl;
419       
420        int random1 = randomN(lsystem->productions.size());
421       
422        map<string, Production*>::iterator prodIter = lsystem->productions.begin();
423        for (int counter = 0; counter < random1; counter++) {
424                prodIter++;
425        }
426        //cout << "insertCommands 4" << endl;
427       
428        Production *p = prodIter->second;
429        SubProduction *sp;
430        if (p->subproductions.size() > 0) {
431                sp = &(p->subproductions.at(randomN(p->subproductions.size())));
432        } else {
433                mutated += in;
434                chg = -1.0;
435                return mutated;
436        }
437       
438        int commandsToInsert = /*randomN(3) +*/ 1;
439        int insertLen = 0;
440        for (int i = 0; i < commandsToInsert; i++) {
441                ActionStrP a;
442                if (actions.size() > 0) {
443                        a.action = actions.at(randomN(actions.size()));
444                } else {
445                        mutated += in;
446                        chg = -1.0;
447                        return mutated;
448                }
449                insertLen += a.action->getF8Representation().len();
450                if (a.action->ignoreParams == false && a.action->name[0] == 'P') {
451                        Production *p = (Production*) a.action;
452                        insertLen += 2;
453                        for (int j = 0; j < p->parameters.size(); j++) {
454                                int rnd = randomN(p->parameters.size() + 1);
455                                if (rnd == 0) {
456                                        a.params.push_back(SString("0;"));
457                                        insertLen += 1;
458                                } else {
459                                        SString s = p->parameters.getParameterName(randomN(p->parameters.size()) + 1);
460                                        a.params.push_back(s + ";");
461                                        insertLen += s.len();
462                                }
463                        }
464                }
465                sp->actions.push_back(a);
466        }
467        //cout << "insertCommands 5" << endl;
468       
469        mutated = lsystem->toString();
470        //cout << "insertCommands 6" << endl;
471        chg = (float) insertLen / (float) in.len();
472       
473        delete lsystem;
474        //cout << "insertCommands 7" << endl;
475                       
476        return mutated;
477}
478
479SString Geno_f8::mutateEncapsulate(SString &in, float& chg) {
480        SString mutated;
481       
482        Lsystem *lsystem = this->converter->createLsystem(in);
483        if (lsystem == NULL || lsystem->productions.size() == 0) {
484                mutated += in;
485                chg = -1.0;
486                return mutated;
487        }
488       
489        int counter = 0;
490        int rnd = randomN(lsystem->productions.size());
491        int len = 0;
492       
493        Production *p = new Production();
494        p->subproductions.push_back(SubProduction());
495        SubProduction *newSubProd = &(p->subproductions.back());
496       
497        for (map<string, Production*>::iterator prodIter = lsystem->productions.begin();
498                 prodIter != lsystem->productions.end(); prodIter++) {
499                if (counter++ == rnd) {
500                        ParameterCollection *params = &(prodIter->second->parameters);
501                        //copy parameters to the encapsulated production
502                        for (int i = 1; i <= params->size(); i++) {
503                                p->parameters.addParameter(params->getParameterName(i));
504                        }
505                       
506                        SubProduction *subproduction;
507                        if (prodIter->second->subproductions.size() > 0) {
508                                subproduction = &(prodIter->second->subproductions[randomN(prodIter->second->subproductions.size())]);
509                        } else {
510                                mutated += in;
511                                chg = -1.0;
512                                return mutated;
513                        }
514                        int firstActionIdx;
515                        if (subproduction->actions.size() > 0) {
516                                firstActionIdx = randomN(subproduction->actions.size());
517                        } else {
518                                mutated += in;
519                                chg = -1.0;
520                                return mutated;
521                        }
522                        int i;
523                        vector<ActionStrP> newActions;
524                        for (i = 0; i < firstActionIdx; i++) {
525                                newActions.push_back(subproduction->actions[i]);
526                        }
527                        for (i = firstActionIdx; i <= firstActionIdx + randomN(4) + 1
528                                 && i < subproduction->actions.size(); i++) { //1..4 actions
529                                newSubProd->actions.push_back(subproduction->actions[i]);
530                                if (subproduction->actions[i].action != NULL) {
531                                        len += subproduction->actions[i].action->getF8Representation().len();
532                                }
533                        }
534                        ActionStrP a;
535                        a.action = p;
536                        a.params = vector<SString>();
537                        for (int j = 0; j < params->size(); j++) {
538                                //a.params.push_back(SString("0;"));
539                                a.params.push_back(params->getParameterName(j + 1));
540                        }
541                        newActions.push_back(a);
542                        while (i < subproduction->actions.size()) {
543                                if (subproduction->actions[i].action != NULL) {
544                                        newActions.push_back(subproduction->actions[i]);
545                                }
546                                i++;
547                        }
548                        subproduction->actions = newActions;
549                        break;
550                }               
551        }
552       
553        SString newName;
554        for (int i = 0; i < 100000; i++) {
555                newName = "P";
556                newName += SString::valueOf(i);
557                if (lsystem->productions[sstringToString(newName)] == NULL) {
558                        break;
559                }
560        }       
561        p->name = newName;
562        lsystem->productions[sstringToString(newName)] = p;
563       
564        mutated = lsystem->toString();
565       
566        delete lsystem;
567
568        chg = (float) len / (float) in.len();
569        return mutated;
570}
571
572SString Geno_f8::mutateDeleteProduction(SString &in, float& chg) {
573        SString mutated;
574       
575        Lsystem *lsystem = this->converter->createLsystem(in);
576        if (lsystem == NULL || lsystem->productions.size() == 0) {
577                mutated += in;
578                chg = -1.0;
579                return mutated;
580        }
581       
582        if (lsystem->productions.size() < 2) {
583                mutated += in;
584                chg = 0.0;
585                delete lsystem;
586                return mutated;
587        }
588
589        vector<SString> productionNamesSS = this->converter->readProductionNames(in);
590        vector<string> productionNames;
591        for (int ssI = 0; ssI < productionNamesSS.size(); ssI++) {
592                productionNames.push_back(sstringToString(productionNamesSS[ssI]));
593        }
594        vector<string>::iterator prodNameIter = productionNames.begin();
595        while (prodNameIter != productionNames.end()) {
596                //delete first production from candidate list
597                if ((*prodNameIter).compare(lsystem->firstProductionName) == 0) {
598                        prodNameIter = productionNames.erase(prodNameIter);
599                } else {
600                        prodNameIter++;
601                }
602        }
603        //choose production to delete
604        string prodNameToDelete = productionNames[randomN(productionNames.size())];
605        productionNames.push_back(lsystem->firstProductionName);
606        prodNameIter = productionNames.begin();
607        while (prodNameIter != productionNames.end()) {
608                //delete prodNameToDelete from candidate list
609                if ((*prodNameIter).compare(prodNameToDelete) == 0) {
610                        prodNameIter = productionNames.erase(prodNameIter);
611                } else {
612                        prodNameIter++;
613                }
614        }
615        //choose production to which we will append the contents of deleted production
616        string prodNameToAppendTo = productionNames[randomN(productionNames.size())];
617
618        int len = 0;
619
620        Production* deletedProd = lsystem->productions[prodNameToDelete];
621        Production* appendProd = lsystem->productions[prodNameToAppendTo];
622        //add missing parameters
623        for (int i = 1; i <= deletedProd->parameters.size(); i++) {
624                SString paramName = deletedProd->parameters.getParameterName(i);
625                if (appendProd->parameters.paramExist(paramName) == false) {
626                        appendProd->parameters.addParameter(paramName);
627                }
628        }
629
630        //copy subproductions
631        for (vector<SubProduction>::iterator subprodIter = deletedProd->subproductions.begin();
632                 subprodIter != deletedProd->subproductions.end(); subprodIter++) {
633                SubProduction sp;
634                //copy conditions
635                for (vector<Condition>::iterator condIter = (*subprodIter).conditions.begin();
636                         condIter != (*subprodIter).conditions.end(); condIter++) {
637                        Condition *cFrom = &(*condIter);
638                        Condition cTo;
639                        cTo.parameter = SString(cFrom->parameter);
640                        cTo.relation = cFrom->relation;
641                        cTo.value = cFrom->value;
642                        sp.conditions.push_back(cTo);
643                }
644                for (vector<ActionStrP>::iterator actionIter = (*subprodIter).actions.begin();
645                         actionIter != (*subprodIter).actions.end(); actionIter++) {
646                        ActionStrP aFrom = *actionIter;
647                        ActionStrP aTo;
648                        aTo.action = aFrom.action;
649                        aTo.params = vector<SString>(aFrom.params);
650                        sp.actions.push_back(aTo);
651                }
652                appendProd->subproductions.push_back(sp);
653        }
654        lsystem->productions.erase(string(prodNameToDelete));
655
656        int paramCount = appendProd->parameters.size();
657        for (map<string, Production*>::iterator prodIter = lsystem->productions.begin();
658                 prodIter != lsystem->productions.end(); prodIter++) {
659                for (vector<SubProduction>::iterator subprodIter = prodIter->second->subproductions.begin();
660                         subprodIter != prodIter->second->subproductions.end(); subprodIter++) {
661                        for (vector<ActionStrP>::iterator actionIter = (*subprodIter).actions.begin();
662                                 actionIter != (*subprodIter).actions.end(); actionIter++) {
663                                if ((*actionIter).action != NULL && (*actionIter).action->name != NULL) {
664                                        if ((*actionIter).action->name == stringToSString(prodNameToDelete)) {
665                                                (*actionIter).action = appendProd;
666                                                (*actionIter).params = vector<SString>(paramCount, SString("0;"));
667                                        }
668                                        if ((*actionIter).action->name == stringToSString(prodNameToAppendTo)) {
669                                                (*actionIter).action = appendProd;
670                                                SString paramVal = "0;";
671                                                for (int i = (*actionIter).params.size(); i < paramCount; i++) {
672                                                        (*actionIter).params.push_back("0;");
673                                                }
674                                        }
675
676                                }
677                        }
678                }
679        }
680        delete deletedProd;
681
682
683        mutated = lsystem->toString();
684
685        delete lsystem;
686
687        chg = (float) len / (float) in.len();
688        return mutated;
689}
690
691SString Geno_f8::mutateChangeConditionSign(SString &in, float& chg) {
692        SString mutated;
693
694        Lsystem *newLsystem = this->converter->createLsystem(in);
695        if (newLsystem == NULL) {
696                mutated += in;
697                chg = -1.0;
698                return mutated;
699        }
700
701        map<int, SubProduction*> interestingSubproductions;
702        int counter = 0;
703
704        for (map<string, Production*>::iterator prodIter = newLsystem->productions.begin();
705                 prodIter != newLsystem->productions.end(); prodIter++) {
706                for (vector<SubProduction>::iterator subprodIter = prodIter->second->subproductions.begin();
707                         subprodIter != prodIter->second->subproductions.end(); subprodIter++) {
708                        SubProduction *sp = &(*subprodIter);
709                        if (sp->conditions.size() > 0) {
710                                interestingSubproductions[counter++] =  sp;
711                        }
712                }
713        }
714
715        if (interestingSubproductions.size() > 0) {
716                int random1 = randomN(interestingSubproductions.size());
717                SubProduction *randomSubproduction = interestingSubproductions[random1];
718                int random2 = randomN(randomSubproduction->conditions.size()); //all interesting conditions have conditions.size() > 0
719                Condition *c = &(randomSubproduction->conditions.at(random2));
720                c->relation = this->getDifferentCondition(c->relation);
721                chg = 2.0 / (float) in.len();
722        }
723
724        mutated = newLsystem->toString();
725
726        delete newLsystem;
727
728        return mutated;
729}
730
731SString Geno_f8::mutateAddParameter(SString &in, float& chg) {
732        SString mutated;
733
734        Lsystem *lsystem = this->converter->createLsystem(in);
735        if (lsystem == NULL || lsystem->productions.size() == 0) {
736                mutated += in;
737                chg = -1.0;
738                return mutated;
739        }
740
741        //cout << "addParameter 1" << endl;
742        int rnd = randomN(lsystem->productions.size());
743        int chglen = 0;
744
745        SString prodName = "";
746
747        int counter = 0;
748        for (map<string, Production*>::iterator prodIter = lsystem->productions.begin();
749                 prodIter != lsystem->productions.end(); prodIter++) {
750                if (counter++ == rnd) {
751                        prodName = prodIter->second->name;
752                        SString newParam;
753                        for (int i = 0; i < 10000; i++) {
754                                newParam = "n";
755                                newParam += SString::valueOf(i);
756                                if (!prodIter->second->parameters.paramExist(newParam)) {
757                                        prodIter->second->parameters.addParameter(newParam);
758                                        chglen += newParam.len();
759                                        break;
760                                }
761                        }
762
763                        if (prodName == stringToSString(lsystem->firstProductionName)) {
764                                lsystem->startParams[sstringToString(newParam)] = 0.0;
765                        }
766                        break;
767                }
768        }
769        //cout << "addParameter 2" << endl;
770        for (map<string, Production*>::iterator prodIter = lsystem->productions.begin();
771                 prodIter != lsystem->productions.end(); prodIter++) {
772                for (vector<SubProduction>::iterator subprodIter = prodIter->second->subproductions.begin();
773                         subprodIter != prodIter->second->subproductions.end(); subprodIter++) {
774                        for (vector<ActionStrP>::iterator actionIter = (*subprodIter).actions.begin();
775                                 actionIter != (*subprodIter).actions.end(); actionIter++) {
776                                if ((*actionIter).action != NULL && (*actionIter).action->name != NULL) {
777                                        if ((*actionIter).action->name == prodName) {
778                                                int randParamVal = randomN(prodIter->second->parameters.size() + 1);
779                                                SString paramVal = NULL;
780                                                if (randParamVal == 0) {
781                                                        paramVal = "0;";
782                                                } else {
783                                                        paramVal = prodIter->second->parameters.getParameterName(randParamVal) + ";";
784                                                }
785                                                //(*actionIter).params.push_back(paramVal);
786                                                chglen += 2;
787                                        }
788                                }
789                        }
790                }
791        }
792        //cout << "addParameter 3" << endl;
793       
794        mutated = lsystem->toString();
795        //cout << "addParameter 4" << endl;
796       
797        delete lsystem;
798       
799        chg = (float) chglen / (float) in.len();
800        return mutated;
801}
802
803SString Geno_f8::mutateAddCondition(SString &in, float& chg) {
804        SString mutated, before, mid, after, line;
805        vector<ProductionInfo> prodInfo = this->getProductionsInfo(in);
806        vector<int> interestingProductions;
807        for (int i = 0; i < prodInfo.size(); i++) {
808                if (prodInfo[i].paramNames.size() > 0) {
809                        interestingProductions.push_back(i);
810                }
811        }
812        if (interestingProductions.size() == 0) {
813                chg = -1.0;
814                mutated = in;
815                return mutated;
816        }
817        int rndProd = interestingProductions[randomN(interestingProductions.size())];
818        int pos = 0;
819        mutated = "";
820        while (in.getNextToken(pos, line, '\n')) {
821                if (line.startsWith(prodInfo[rndProd].name) && line.len() > prodInfo[rndProd].name.len()) {
822                        int subproductionsCount = -1;
823                        SString tok;
824                        int pos2 = 0;
825                        while (line.getNextToken(pos2, tok, ':')) {
826                                subproductionsCount++;
827                        }
828                        if (subproductionsCount == 0) {
829                                chg = -1.0;
830                                mutated = in;
831                                return mutated;
832                        }
833                        int rnd = randomN(subproductionsCount);
834                        int counter = 0;
835                        int colonIdx = line.indexOf(':', 0);
836                        pos2 = colonIdx;
837                        while (counter != rnd) {
838                                colonIdx = line.indexOf(':', pos2 + 1);
839                                counter++;
840                        }
841                       
842                        int nextColonIdx = line.indexOf(':', colonIdx + 1);
843                        if (nextColonIdx == -1) {
844                                nextColonIdx = 2147483646;
845                        }
846                        int pipeIdx = line.indexOf('|', colonIdx + 1);
847                        mid = "";
848                        if (pipeIdx < nextColonIdx && pipeIdx != -1) {
849                                //before += line.substr(colonIdx + 1, pipeIdx - colonIdx - 1);
850                                before = line.substr(0, pipeIdx);
851                                mid += ",";
852                                after = line.substr(pipeIdx);                           
853                        } else {
854                                before = line.substr(0, colonIdx + 1);
855                                after = SString("|") + line.substr(colonIdx + 1);
856                        }
857                        int paramIdx = (int) randomN(prodInfo[rndProd].paramNames.size());
858                        mid += prodInfo[rndProd].paramNames[paramIdx];
859                        mid += (randomN(2) == 0) ? ">" : "<";
860                        mid += SString::valueOf((int) randomN(21) - 10);
861                       
862                        mutated += before + mid + after + "\n";
863                        chg = (float) mid.len() / (float)in.len();
864                } else {
865                        mutated += line + "\n";
866                }
867        }
868        return mutated;
869}
870
871SString Geno_f8::mutateDeleteParameter(SString &in, float& chg) {
872        SString mutated;
873       
874        Lsystem *newLsystem = this->converter->createLsystem(in);
875        if (newLsystem == NULL) {
876                mutated += in;
877                chg = -1.0;
878                return mutated;
879        }
880               
881        map<int, Production*> interestingProductions;
882        int counter = 0;
883       
884        for (map<string, Production*>::iterator prodIter = newLsystem->productions.begin();
885                        prodIter != newLsystem->productions.end(); prodIter++) {
886                if (prodIter->second->parameters.size() > 0) {
887                        interestingProductions[counter++] =  prodIter->second;
888                }
889        }
890       
891        if (interestingProductions.size() > 0) {
892                int rnd = randomN(interestingProductions.size());
893               
894                Production *randomProduction = interestingProductions[rnd];
895                SString prodName = randomProduction->name;
896               
897                int paramIndex = randomN(randomProduction->parameters.size()) + 1;
898                SString paramName = randomProduction->parameters.getParameterName(paramIndex);
899                string sparamName = sstringToString(paramName);
900                int change = paramName.len();
901               
902                randomProduction->parameters.removeParameter(paramName);
903               
904                if (prodName == stringToSString(newLsystem->firstProductionName)) {
905                        newLsystem->startParams.erase(sstringToString(paramName));
906                }
907               
908                for (vector<SubProduction>::iterator subProdIter = randomProduction->subproductions.begin();
909                                subProdIter != randomProduction->subproductions.end(); subProdIter++) {
910                        for (vector<Condition>::iterator condIter = (*subProdIter).conditions.begin();
911                                 condIter != (*subProdIter).conditions.end(); /*nothing*/) {
912                                if ((*condIter).parameter == paramName) {
913                                        condIter = (*subProdIter).conditions.erase(condIter);
914                                } else {
915                                        condIter++;
916                                }
917                        }
918                        for (vector<ActionStrP>::iterator actionIter = (*subProdIter).actions.begin();
919                                        actionIter != (*subProdIter).actions.end(); actionIter++) {
920                                for (vector<SString>::iterator paramIter = (*actionIter).params.begin();
921                                                paramIter != (*actionIter).params.end(); paramIter++) {
922                                        string s = sstringToString(*paramIter);
923                                        if (s.find(sparamName, 0) != string::npos) {
924                                                *paramIter = SString("0;");
925                                        }
926                                }
927                        }
928                }
929                               
930                for (map<string, Production*>::iterator prodIter = newLsystem->productions.begin();
931                                prodIter != newLsystem->productions.end(); prodIter++) {
932                        vector<SubProduction> *subproductions = &(prodIter->second->subproductions);
933                        for (vector<SubProduction>::iterator subProdIter = subproductions->begin();
934                                subProdIter != subproductions->end(); subProdIter++) {
935                                SubProduction *sp = &(*subProdIter);
936                                for (vector<ActionStrP>::iterator actionIter = sp->actions.begin();
937                                         actionIter != sp->actions.end(); actionIter++) {
938                                        if ((*actionIter).action != NULL) {
939                                                if ((*actionIter).action->name == prodName && (*actionIter).params.size() > paramIndex - 1) {
940                                                        change += paramName.len(); //more less
941                                                        (*actionIter).params.erase((*actionIter).params.begin() + (paramIndex - 1));
942                                                }
943                                        }
944                                }
945                        }
946                }
947                chg = (float) change / (float) in.len();
948        }
949       
950        mutated = newLsystem->toString();
951       
952        delete newLsystem;
953       
954        return mutated;
955}
956
957SString Geno_f8::mutateDeleteCondition(SString &in, float& chg) {
958        SString mutated;
959       
960        Lsystem *newLsystem = this->converter->createLsystem(in);
961        if (newLsystem == NULL) {
962                mutated += in;
963                chg = -1.0;
964                return mutated;
965        }
966               
967        map<int, SubProduction*> interestingSubproductions;
968        int counter = 0;
969       
970        for (map<string, Production*>::iterator prodIter = newLsystem->productions.begin();
971                 prodIter != newLsystem->productions.end(); prodIter++) {
972                for (vector<SubProduction>::iterator subprodIter = prodIter->second->subproductions.begin();
973                         subprodIter != prodIter->second->subproductions.end(); subprodIter++) {
974                        SubProduction *sp = &(*subprodIter);
975                        if (sp->conditions.size() > 0) {
976                                interestingSubproductions[counter++] =  sp;
977                        }
978                }
979        }
980       
981        if (interestingSubproductions.size() > 0) {
982                int rnd = randomN(interestingSubproductions.size());
983                SubProduction *randomSubproduction = interestingSubproductions[rnd];
984                vector<Condition>::iterator condIter = randomSubproduction->conditions.begin();
985                condIter += randomN(randomSubproduction->conditions.size() - 1);
986                Condition c = *condIter;
987                chg = (float) (c.parameter.len() + 1 + SString::valueOf(c.value).len()) / (float) in.len();
988                randomSubproduction->conditions.erase(condIter);
989        }
990       
991        mutated = newLsystem->toString();
992       
993        delete newLsystem;
994       
995        return mutated;
996}
997
998SString Geno_f8::mutateAddLoop(SString &in, float& chg) {
999        /*
1000         * Podczas wczytania genotypu do obiektu typu Lsystem nastepuje rozwiniecie petli, wiec kolejne mutacje
1001         * zniweczyly by zysk ktory mozna uzyskac dzieki petlom. Dlatego nic nie zmieniamy.
1002         */
1003        SString mutated, line;
1004        int pos = 0;
1005        while (in.getNextToken(pos, line, '\n')) {
1006                mutated += line + "\n";
1007        }
1008        chg = 0.0;
1009        return mutated;
1010}
1011
1012SString Geno_f8::mutateDeleteLoop(SString &in, float& chg) {
1013        /*
1014         * Podczas wczytania genotypu do obiektu typu Lsystem nastepuje rozwiniecie petli, wiec kolejne mutacje
1015         * zniweczyly by zysk ktory mozna uzyskac dzieki petlom. Dlatego nic nie zmieniamy.
1016         */
1017        SString mutated, line;
1018        int pos = 0;
1019        while (in.getNextToken(pos, line, '\n')) {
1020                mutated += line + "\n";
1021        }
1022        chg = 0.0;
1023        return mutated;
1024}
1025
1026SString Geno_f8::mutateAddSubproduction(SString &in, float& chg) {
1027        SString mutated, line;
1028        vector<ProductionInfo> prodInfo = this->getProductionsInfo(in);
1029        int rndProd = randomN(prodInfo.size());
1030        int pos = 0;
1031        mutated = "";
1032        while (in.getNextToken(pos, line, '\n')) {
1033                if (line.startsWith(prodInfo[rndProd].name) && line.indexOf(':', 0) != -1) {
1034                        SString tmp = ":";
1035                        int paramCount = prodInfo[rndProd].paramNames.size();
1036                        if (paramCount > 0) {
1037                                tmp += prodInfo[rndProd].paramNames[(int) randomN(paramCount)];
1038                                tmp += (randomN(2) == 0) ? ">" : "<";
1039                                tmp += SString::valueOf((int) randomN(21) - 10);
1040                                tmp += "|";
1041                        }
1042                        tmp += "X\n";
1043                        chg = (float) tmp.len() / (float) in.len();
1044                        mutated += line + tmp;
1045                } else {
1046                        mutated += line + "\n";
1047                }
1048        }
1049        return mutated;
1050}
1051
1052SString Geno_f8::mutateChangeIterationsNumber(SString &in, float& chg) {
1053        SString mutated;       
1054        Lsystem *newLsystem = this->converter->createLsystem(in);
1055        if (newLsystem == NULL) {
1056                mutated += in;
1057                chg = -1.0;
1058                return mutated;
1059        }
1060       
1061        newLsystem->iterations += randomN(7) - 3; //-3..3
1062        if (newLsystem->iterations < 1) {
1063                newLsystem->iterations = 1;
1064        }
1065        mutated = newLsystem->toString();       
1066        delete newLsystem;     
1067        chg = 1.0 / (float) in.len();
1068        return mutated;
1069}
1070
1071int Geno_f8::mutate(char *&g,float& chg, int &method) {
1072        SString in = g;
1073       
1074        /*struct timeval tv;
1075        gettimeofday(&tv, NULL);
1076        srandom(tv.tv_sec + tv.tv_usec);
1077        */
1078        method = roulette(this->operation, F8_OPERATION_COUNT);
1079        if (method < 0) {
1080                return GENOPER_OPFAIL;
1081        }
1082       
1083#if GENO_F8_DEBUG > 0
1084        string mutationName = (method == 0) ? "F8_CHANGE_BEGINNING_ARG" : //TODO use mutation_method_names[] here
1085        (method == 1) ? "F8_CHANGE_ARG" :
1086        (method == 2) ? "F8_DELETE_COMMAND" :
1087        (method == 3) ? "F8_INSERT_COMMANDS" :
1088        (method == 4) ? "F8_ENCAPSULATE" :
1089        (method == 5) ? "F8_CHANGE_CONDITION_SIGN" :
1090        (method == 6) ? "F8_REPLACE_COMMAND" :
1091        (method == 7) ? "F8_ADD_PARAMETER" :
1092        (method == 8) ? "F8_ADD_CONDITION" :
1093        (method == 9) ? "F8_ADD_SUBPRODUCTION" :
1094        (method == 10) ? "F8_CHANGE_ITERATIONS_NUMBER" :
1095        (method == 11) ? "F8_DELETE_PARAMETER" :
1096        (method == 12) ? "F8_DELETE_CONDITION" :
1097        (method == 13) ? "F8_ADD_LOOP" :
1098        (method == 14) ? "F8_DELETE_LOOP" :
1099        (method == 15) ? "F8_OPERATION_COUNT" : "*invalid*";
1100        //cout << "-------------------- " << mutationName << " --------------------" << endl;
1101#endif
1102       
1103        const char* mutatedTmp;
1104        SString ssMutatedTmp;
1105       
1106        //cout << "mutate 1" << endl;
1107        switch (method) {
1108                case F8_CHANGE_BEGINNING_ARG:
1109                        ssMutatedTmp = this->mutateChangeBeginningArg(in, chg);
1110                        break;
1111                case F8_CHANGE_ARG:
1112                        ssMutatedTmp = this->mutateChangeArg(in, chg);
1113                        break;
1114                case F8_DELETE_COMMAND:
1115                        ssMutatedTmp = this->mutateDeleteCommand(in, chg);
1116                        break;
1117                case F8_INSERT_COMMANDS:
1118                        ssMutatedTmp = this->mutateInsertCommands(in, chg);
1119                        break;
1120                case F8_ENCAPSULATE:
1121                        ssMutatedTmp = this->mutateEncapsulate(in, chg);
1122                        break;
1123                case F8_CHANGE_CONDITION_SIGN:
1124                        ssMutatedTmp = this->mutateChangeConditionSign(in, chg);
1125                        break;
1126                /*case F8_REPLACE_COMMAND:
1127                        ssMutatedTmp = this->mutateReplaceCommand(in, chg);
1128                        break;*/
1129                case F8_ADD_PARAMETER:
1130                        ssMutatedTmp = this->mutateAddParameter(in, chg);
1131                        break;
1132                case F8_ADD_CONDITION:
1133                        ssMutatedTmp = this->mutateAddCondition(in, chg);
1134                        break;
1135                case F8_ADD_SUBPRODUCTION:
1136                        ssMutatedTmp = this->mutateAddSubproduction(in, chg);
1137                        break;
1138                case F8_CHANGE_ITERATIONS_NUMBER:
1139                        ssMutatedTmp = this->mutateChangeIterationsNumber(in, chg);
1140                        break;
1141                case F8_DELETE_PARAMETER:
1142                        ssMutatedTmp = this->mutateDeleteParameter(in, chg);
1143                        break;
1144                case F8_DELETE_CONDITION:
1145                        ssMutatedTmp = this->mutateDeleteCondition(in, chg);
1146                        break;
1147                case F8_ADD_LOOP:
1148                        ssMutatedTmp = this->mutateAddLoop(in, chg);
1149                        break;
1150                case F8_DELETE_LOOP:
1151                        ssMutatedTmp = this->mutateDeleteLoop(in, chg);
1152                        break;
1153                case F8_DELETE_PRODUCTION:
1154                        ssMutatedTmp = this->mutateDeleteProduction(in, chg);
1155                        break;
1156                default:
1157                        return GENOPER_OPFAIL;
1158        }
1159       
1160        //cout << "mutate 2" << endl;
1161        if (ssMutatedTmp.len() < 16) {
1162                return GENOPER_OPFAIL;
1163        }
1164        if (chg == -1.0) {
1165                chg = 0.0;
1166                return GENOPER_OPFAIL;
1167        }
1168       
1169        mutatedTmp = ssMutatedTmp;
1170       
1171        if (this->checkValidity(mutatedTmp) == GENOPER_OK) {
1172                free(g); //must take care of the original allocation
1173                g = (char*)malloc(strlen(mutatedTmp) + 1); //allocate for mutated genotype
1174                strcpy(g, mutatedTmp); //the rest is originalg = mutated;
1175                //cout << "mutate 3" << endl;
1176                return GENOPER_OK;
1177        } else {
1178                return GENOPER_OPFAIL;
1179        }
1180}
1181
1182int Geno_f8::crossOver(char *&g1,char *&g2,float& chg1,float& chg2) {
1183        /* wymiana niewielkiej (max. 25%) ilości odpowiadającej sobie informacji
1184         * ma to przypominać "celowaną" mutację, w której osobnik dostaje
1185         * niewiele wiedzy, która sprawdziła się u innego osobnika
1186         */
1187        SString in1 = g1;
1188        SString in2 = g2;
1189        SString mutated;
1190        //SString dst;
1191        //const char* src = in;
1192        //const char* t;
1193       
1194        Lsystem *newLsystem = this->converter->createLsystem(in1);
1195        Lsystem *lsystem2 = this->converter->createLsystem(in2);
1196        if (newLsystem == NULL || lsystem2 == NULL) {
1197                chg1 = 0.0;
1198                chg2 = 0.0;
1199                return GENOPER_OPFAIL;
1200        }
1201       
1202        //shuffle second parent's productions
1203        vector<int> indices;
1204        for (int i = 0; i < lsystem2->productions.size(); i++) {
1205                indices.push_back(i);
1206        }
1207        map<string, Production*> shuffledProductions;
1208        while (!indices.empty()) {
1209                int rnd = randomN(indices.size());
1210                int counter = 0;
1211                //Production *p;
1212                for (map<string, Production*>::iterator it = lsystem2->productions.begin();
1213                         it != lsystem2->productions.end(); it++) {
1214                        if (counter == rnd) {
1215                                //p = it->second;
1216                                shuffledProductions[it->first] = it->second;
1217                                break;
1218                        }
1219                }
1220                //delete index number
1221                indices.erase(indices.begin() + rnd);
1222        }
1223       
1224        int productionCount = randomN(min(newLsystem->productions.size() / 4, lsystem2->productions.size())) + 1;
1225       
1226        int counter = 0;
1227        for (map<string, Production*>::iterator it = shuffledProductions.begin();
1228                 it != shuffledProductions.end() && counter < productionCount; it++) {
1229                //if selected production's name exist in the first parent
1230                if (newLsystem->productions.find(it->first) != newLsystem->productions.end()) {
1231                        newLsystem->productions[it->first]->subproductions = it->second->subproductions;
1232                        counter++;
1233                } else {
1234                        /* This fragment is commented out because we are interested only in matching productions ///////
1235                        //search for first production, which name does not exist in one of the productions
1236                        //selected from second parent
1237                        //this is to avoid information loss when new subproductions will be overwritten
1238                        //just after adding to the child production
1239                        for (map<string, Production*>::iterator it2 = newLsystem->productions.begin();
1240                                 it2 != newLsystem->productions.end(); it2++) {
1241                                if (shuffledProductions.find(it2->first) == shuffledProductions.end()) { //not found
1242                                        it2->second->subproductions = it->second->subproductions;
1243                                        break;
1244                                }
1245                                //there are no "else" because there is at least twice as many productions
1246                                //in the first parent as selected productions from the second parent
1247                                //so always we will find "free" production name
1248                        }*/
1249                }               
1250        }
1251       
1252        //check validity of productions indicated in actions
1253        for (map<string, Production*>::iterator prodIter = newLsystem->productions.begin();
1254                 prodIter != newLsystem->productions.end(); prodIter++) {
1255                vector<SString> paramNames;
1256                for (int i = 1; i <= prodIter->second->parameters.size(); i++) {
1257                        paramNames.push_back(prodIter->second->parameters.getParameterName(i));
1258                }
1259                for (vector<SubProduction>::iterator subprodIter = prodIter->second->subproductions.begin();
1260                         subprodIter != prodIter->second->subproductions.end(); subprodIter++) {
1261                        //conditions
1262                        if (paramNames.size() > 0) {
1263                                for (vector<Condition>::iterator condIter = (*subprodIter).conditions.begin();
1264                                         condIter != (*subprodIter).conditions.end(); condIter++) {
1265                                        vector<SString>::iterator searchIter = find(paramNames.begin(), paramNames.end(),
1266                                                                                                                                (*condIter).parameter);
1267                                        if (searchIter == paramNames.end()) { //unknown parameter name!
1268                                                //choose random existing parameter
1269                                                (*condIter).parameter = paramNames[randomN(paramNames.size())];
1270                                        }
1271                                }
1272                        } else { //no params, so delete all conditions
1273                                (*subprodIter).conditions.clear();
1274                        }
1275                       
1276                        //actions
1277                        for (vector<ActionStrP>::iterator i = (*subprodIter).actions.begin();
1278                                 i != (*subprodIter).actions.end(); /*nothing*/) {
1279                                bool deleted = false;
1280                                if ((*i).action == NULL) {
1281                                        continue;
1282                                }
1283                                SString &actionName = (*i).action->name;
1284                                if (actionName[0] == 'n') {
1285                                        if (paramNames.size() > 0) {
1286                                                vector<SString>::iterator searchIter = find(paramNames.begin(), paramNames.end(),
1287                                                                                                                                        actionName);
1288                                                if (searchIter != paramNames.end()) { //valid name
1289                                                        //ensure it is linked to the correct production
1290                                                        (*i).action = newLsystem->getParamProduction(actionName);
1291                                                } else {
1292                                                        //link to random parameter prodution
1293                                                        SString name = paramNames[randomN(paramNames.size())];
1294                                                        (*i).action = newLsystem->getParamProduction(name);
1295                                                }
1296                                        } else { //no params, so delete this param production
1297                                                i = (*subprodIter).actions.erase(i);
1298                                                deleted = true;
1299                                        }
1300                                } else if (actionName[0] == 'P') {
1301                                        if (newLsystem->productions.find(sstringToString(actionName)) != newLsystem->productions.end()) {
1302                                                //ensure it is linked to the correct production
1303                                                (*i).action = newLsystem->productions[sstringToString(actionName)];
1304                                        } else {
1305                                                //delete this action
1306                                                i = (*subprodIter).actions.erase(i);
1307                                                deleted = true;
1308                                        }
1309                                }
1310                                if (!deleted) {
1311                                        i++;
1312                                }
1313                        }
1314                        if ((*subprodIter).actions.size() == 0) { //we erased all the actions
1315                                ActionStrP a;
1316                                a.action = newLsystem->getPrimitiveProduction(SString("X"));
1317                                (*subprodIter).actions.push_back(a);
1318                        }
1319                }
1320        }
1321       
1322        mutated = newLsystem->toString();
1323       
1324        shuffledProductions.clear();
1325       
1326        delete newLsystem;
1327        delete lsystem2;
1328       
1329        free(g1); //must take care of the original allocation
1330        //free(g2);
1331        const char* mutatedTmp = mutated;
1332        char* mutatedTmp2 = (char*)malloc(strlen(mutatedTmp) + 1); //allocate for mutated genotype
1333    strcpy(mutatedTmp2, mutatedTmp); //the rest is originalg = mutated;
1334        g1 = mutatedTmp2;
1335        chg1 = 0.5;
1336       
1337        return GENOPER_OK;     
1338}
1339
1340
1341bool Geno_f8::checkProdNameExist(vector<ProductionInfo> info, SString name) const {
1342        for (vector<ProductionInfo>::iterator it = info.begin(); it != info.end(); it++) {
1343                if ((*it).name == name) {
1344                        return true;
1345                }
1346        }
1347        return false;
1348}
1349
1350bool Geno_f8::checkParamNameExist(vector<SString> names, SString name) const {
1351        for (vector<SString>::iterator it = names.begin(); it != names.end(); it++ ) {
1352                if ((*it) == name) {
1353                        return true;
1354                }
1355        }
1356        return false;
1357}
1358
1359SString Geno_f8::getOppositeCondition(const SString &c) const {
1360        if (c.equals("=="))
1361                return "!=";
1362        if (c.equals("!="))
1363                return "==";
1364        if (c.equals(">"))
1365                return "<=";
1366        if (c.equals("<"))
1367                return ">=";
1368        if (c.equals(">="))
1369                return "<";
1370        if (c.equals("<="))
1371                return ">";
1372        return "<"; //default
1373}
1374
1375RelationType Geno_f8::getDifferentCondition(RelationType type) {
1376        RelationType types[6];
1377        types[0] = r_greater;
1378        types[1] = r_greaterEqual;
1379        types[2] = r_equal;
1380        types[3] = r_different;
1381        types[4] = r_lessEqual;
1382        types[5] = r_less;
1383       
1384        for (int i = 0; i < 6; i++) {
1385                if (types[i] == type) {
1386                        types[i] = types[5];
1387                        //types[5] = type;
1388                        break;
1389                }
1390        }
1391       
1392        int randomType = randomN(5);
1393        return types[randomType];
1394}
1395
1396SString Geno_f8::removeProductionCalls(const SString production) const {
1397        SString line = trimSString(production);
1398        SString result = "";
1399        bool skip = false;
1400        for (int i = 0; i < line.len(); i++) {
1401                if (skip) {
1402                        if (line[i] == ')') {
1403                                skip = false;
1404                        } else {
1405                                //do nothing
1406                        }
1407                } else {
1408                        if (line[i] == 'P') {
1409                                skip = true;
1410                        } else {
1411                                result += line[i];
1412                        }
1413                }
1414        }
1415        return result;
1416}
1417
1418SString Geno_f8::addParameterToCalls(const SString line, SString &prodName) {
1419        SString newStr = "";
1420        int colonIdx = line.indexOf(':', 0);
1421        if (colonIdx != -1 && line.indexOf(prodName, colonIdx) != -1) {
1422                int pos2 = colonIdx;
1423                int beginIdx = 0;
1424                int prodIdx;
1425                while ((prodIdx = line.indexOf(prodName, pos2)) != -1) {
1426                        int indexRBrace = line.indexOf(')', prodIdx);
1427                        newStr += line.substr(beginIdx, indexRBrace);
1428                        if (newStr[newStr.len() - 1] != '(') {
1429                                newStr += SString(",");
1430                        }
1431                        newStr += "0.0";
1432                        beginIdx = indexRBrace;
1433                        pos2 = indexRBrace;
1434                }
1435                newStr += line.substr(pos2);
1436        } else {
1437                newStr = line;
1438        }
1439        return newStr;
1440}
1441
1442SString Geno_f8::deleteParameterFromCalls(const SString line, SString &prodName, int paramIdx) {
1443        SString newStr = "";
1444        SString tmp, before, mid, midTmp;
1445        mid = "";
1446        int colonIdx = line.indexOf(':', 0);
1447        if (colonIdx != -1 && line.indexOf(prodName, colonIdx) != -1) {
1448                int pos2 = colonIdx;
1449                int beginIdx = 0;
1450                int prodIdx;
1451                while ((prodIdx = line.indexOf(prodName, pos2)) != -1) {
1452                        int indexRBrace = line.indexOf(')', prodIdx);
1453                        before = line.substr(beginIdx, prodIdx + prodName.len() + 1);
1454                        midTmp = line.substr(prodIdx + prodName.len() + 1, indexRBrace - (prodIdx + prodName.len() + 1));
1455                        pos2 = 0;
1456                        SString tok;
1457                        int i = 0;
1458                        while (midTmp.getNextToken(pos2, tok, ',')) {
1459                                if (i++ == paramIdx) {
1460                                        //do nothing
1461                                } else {
1462                                        mid += tok + ",";
1463                                }
1464                        }
1465                        if (mid[mid.len() - 1] == ',') {
1466                                mid = mid.substr(0, mid.len() - 1);
1467                        }
1468                       
1469                        newStr += before + mid + ")";
1470                        beginIdx = indexRBrace;
1471                        pos2 = indexRBrace;
1472                }
1473                newStr += line.substr(pos2 + 1);
1474        } else {
1475                newStr = line;
1476        }
1477        return newStr;
1478}
1479
1480SString Geno_f8::testMutate(SString &in, int method) {
1481        /*struct timeval tv;
1482        gettimeofday(&tv, NULL);
1483        srandom(tv.tv_sec + tv.tv_usec);
1484        */
1485        SString mutatedTmp;
1486        float chg = 0.0;
1487        switch (method) {
1488                case F8_CHANGE_BEGINNING_ARG:
1489                        mutatedTmp = this->mutateChangeBeginningArg(in, chg);
1490                        break;
1491                case F8_CHANGE_ARG:
1492                        mutatedTmp = this->mutateChangeArg(in, chg);
1493                        break;
1494                case F8_DELETE_COMMAND:
1495                        mutatedTmp = this->mutateDeleteCommand(in, chg);
1496                        break;
1497                case F8_INSERT_COMMANDS:
1498                        mutatedTmp = this->mutateInsertCommands(in, chg);
1499                        break;
1500                case F8_ENCAPSULATE:
1501                        mutatedTmp = this->mutateEncapsulate(in, chg);
1502                        break;
1503                case F8_CHANGE_CONDITION_SIGN:
1504                        mutatedTmp = this->mutateChangeConditionSign(in, chg);
1505                        break;
1506                /*case F8_REPLACE_COMMAND:
1507                        mutatedTmp = this->mutateReplaceCommand(in, chg);
1508                        break;*/
1509                case F8_ADD_PARAMETER:
1510                        mutatedTmp = this->mutateAddParameter(in, chg);
1511                        break;
1512                case F8_ADD_CONDITION:
1513                        mutatedTmp = this->mutateAddCondition(in, chg);
1514                        break;
1515                case F8_ADD_SUBPRODUCTION:
1516                        mutatedTmp = this->mutateAddSubproduction(in, chg);
1517                        break;
1518                case F8_CHANGE_ITERATIONS_NUMBER:
1519                        mutatedTmp = this->mutateChangeIterationsNumber(in, chg);
1520                        break;
1521                case F8_DELETE_PARAMETER:
1522                        mutatedTmp = this->mutateDeleteParameter(in, chg);
1523                        break;
1524                case F8_DELETE_CONDITION:
1525                        mutatedTmp = this->mutateDeleteCondition(in, chg);
1526                        break;
1527                case F8_ADD_LOOP:
1528                        mutatedTmp = this->mutateAddLoop(in, chg);
1529                        break;
1530                case F8_DELETE_LOOP:
1531                        mutatedTmp = this->mutateDeleteLoop(in, chg);
1532                        break;
1533                default:
1534                        mutatedTmp = "";
1535        }
1536        return mutatedTmp;
1537       
1538}
Note: See TracBrowser for help on using the repository browser.