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

Last change on this file since 32 was 30, checked in by mwajcht, 15 years ago

Added mutation which deletes a production.

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