source: cpp/_old/f8-to-f1/geno_f8.cpp @ 166

Last change on this file since 166 was 40, checked in by Maciej Komosinski, 15 years ago

fixed memory leak and commented out an extra condition

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