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

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

very simple syntax coloring

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