00001 #include "SIGEL_GP/SIG_GPOperations.h"
00002 #include "SIGEL_Program/SIG_Program.h"
00003 #include "SIGEL_GP/SIG_GPPopulation.h"
00004 #include "SIGEL_Tools/SIG_IO.h"
00005 #include <qarray.h>
00006 #include <qstringlist.h>
00007
00008
00009
00010 QVector<SIGEL_GP::SIG_GPIndividual> SIGEL_GP::SIG_GPOperations::crossOver( SIGEL_GP::SIG_GPIndividual& winner1,
00011 int poolPos1,
00012 SIG_GPIndividual& winner2,
00013 int poolPos2,
00014 QString newName1,
00015 QString newName2,
00016 SIGEL_Tools::SIG_Randomizer& randomizer,
00017 SIGEL_GP::SIG_GPParameter& gpParameter,
00018 SIGEL_Robot::SIG_LanguageParameters &languageP)
00019 {
00020 SIGEL_GP::SIG_GPIndividual *crossoverInd1 = new SIGEL_GP::SIG_GPIndividual( SIGEL_Program::SIG_Program(),
00021 newName1,
00022 "",
00023 "",
00024 QDateTime(),
00025 poolPos1,
00026 winner1.getHistory() );
00027
00028 SIGEL_GP::SIG_GPIndividual *crossoverInd2 = new SIGEL_GP::SIG_GPIndividual( SIGEL_Program::SIG_Program(),
00029 newName2,
00030 "",
00031 "",
00032 QDateTime(),
00033 poolPos2,
00034 winner2.getHistory() );
00035
00036 double fitness1 = winner1.getFitness();
00037 double fitness2 = winner2.getFitness();
00038
00039 long const minLength = gpParameter.getMinIndLength();
00040 long const maxLength = gpParameter.getMaxIndLength();
00041 int historyInfo;
00042
00043 SIGEL_Program::SIG_Program &newProgram1 = crossoverInd1->getProgramVar();
00044 SIGEL_Program::SIG_Program &newProgram2 = crossoverInd2->getProgramVar();
00045
00046 SIGEL_Program::SIG_Program &winnerProgram1 = winner1.getProgramVar();
00047 SIGEL_Program::SIG_Program &winnerProgram2 = winner2.getProgramVar();
00048
00049 long int crossPoint1 = randomizer.getRandomLong( winnerProgram1.getProgramLength() - 1 ) + 1;
00050 long int crossPoint2 = randomizer.getRandomLong( winnerProgram2.getProgramLength() - 1 ) + 1;
00051
00052 #ifdef SIG_DEBUG
00053
00054 SIGEL_Tools::SIG_IO::cerr << "\n<CrossOver> Info: ProgramLength = " << minLength;
00055
00056 if( maxLength==0 )
00057 SIGEL_Tools::SIG_IO::cerr << " - no limit\n";
00058 else
00059 SIGEL_Tools::SIG_IO::cerr << " - " << maxLength << "\n";
00060
00061 #endif
00062
00063
00064 if( minLength > 0 )
00065 {
00066 if( ( crossPoint1 + winnerProgram2.getProgramLength() - crossPoint2 < minLength ) ||
00067 ( crossPoint2 + winnerProgram1.getProgramLength() - crossPoint1 < minLength ) )
00068 {
00069 crossPoint1 = winnerProgram1.getProgramLength() / 2;
00070 crossPoint2 = winnerProgram2.getProgramLength() / 2;
00071
00072 #ifdef SIG_DEBUG
00073
00074 SIGEL_Tools::SIG_IO::cerr << "\n-> CrossOver points have been set to "
00075 << crossPoint1
00076 << " and "
00077 << crossPoint2
00078 << "\nThe resulting legths are: "
00079 << crossPoint1 + winnerProgram2.getProgramLength() - crossPoint2
00080 << " and "
00081 << crossPoint2 + winnerProgram1.getProgramLength() - crossPoint1;
00082 #endif
00083 }
00084 }
00085
00086 long const generalRecombinationType = randomizer.getRandomInt( 2 );
00087
00088 SIGEL_Program::SIG_ProgramLine *newProgLine = 0;
00089 SIGEL_Program::SIG_ProgramLine *sourceProgLine = 0;
00090
00091 if( generalRecombinationType == 0 )
00092 {
00093
00094 for (long int i = 0; i < crossPoint1; i++)
00095 {
00096 newProgLine = new SIGEL_Program::SIG_ProgramLine();
00097 sourceProgLine = winnerProgram1.getLine( i );
00098 *newProgLine = *sourceProgLine;
00099 newProgram1.appendLine( newProgLine );
00100 };
00101
00102 for (long int i = crossPoint2; i < winnerProgram2.getProgramLength(); i++)
00103 {
00104 newProgLine = new SIGEL_Program::SIG_ProgramLine();
00105 sourceProgLine = winnerProgram2.getLine( i );
00106 *newProgLine = *sourceProgLine;
00107 newProgram1.appendLine( newProgLine );
00108 };
00109
00110 for (long int i = 0; i < crossPoint2; i++)
00111 {
00112 newProgLine = new SIGEL_Program::SIG_ProgramLine();
00113 sourceProgLine = winnerProgram2.getLine( i );
00114 *newProgLine = *sourceProgLine;
00115 newProgram2.appendLine( newProgLine );
00116 };
00117
00118 for (long int i = crossPoint1; i < winnerProgram1.getProgramLength(); i++)
00119 {
00120 newProgLine = new SIGEL_Program::SIG_ProgramLine();
00121 sourceProgLine = winnerProgram1.getLine( i );
00122 *newProgLine = *sourceProgLine;
00123 newProgram2.appendLine( newProgLine );
00124 };
00125 }
00126
00127 if( generalRecombinationType == 1 )
00128 {
00129 for( long int i = 0; i < crossPoint2; i++ )
00130 {
00131 newProgLine = new SIGEL_Program::SIG_ProgramLine();
00132 sourceProgLine = winnerProgram2.getLine( i );
00133 *newProgLine = *sourceProgLine;
00134
00135 newProgram2.appendLine( newProgLine );
00136 }
00137
00138 for( long int i = crossPoint1; i < winnerProgram1.getProgramLength(); i++ )
00139 {
00140 newProgLine = new SIGEL_Program::SIG_ProgramLine();
00141 sourceProgLine = winnerProgram1.getLine( i );
00142 *newProgLine = *sourceProgLine;
00143
00144 newProgram2.appendLine( newProgLine );
00145 }
00146
00147 for( long int i = 0; i < crossPoint1; i++ )
00148 {
00149 newProgLine = new SIGEL_Program::SIG_ProgramLine();
00150 sourceProgLine = winnerProgram1.getLine( i );
00151 *newProgLine = *sourceProgLine;
00152
00153 newProgram1.appendLine( newProgLine );
00154 }
00155
00156 for( long int i = crossPoint2; i < winnerProgram2.getProgramLength(); i++ )
00157 {
00158 newProgLine = new SIGEL_Program::SIG_ProgramLine();
00159 sourceProgLine = winnerProgram2.getLine( i );
00160 *newProgLine = *sourceProgLine;
00161
00162 newProgram1.appendLine( newProgLine );
00163 }
00164
00165
00166 long int prgLength1 = newProgram1.getProgramLength();
00167 long int prgLength2 = newProgram2.getProgramLength();
00168
00169 if( maxLength > 0 )
00170 if( prgLength1 > maxLength )
00171 {
00172
00173 #ifdef SIG_DEBUG
00174
00175 SIGEL_Tools::SIG_IO::cerr << "\n-> new program (1) too long (length="
00176 << newProgram1.getProgramLength() << ") -> length decreased\n";
00177 #endif
00178 for( long int i = maxLength - 1; i < prgLength1; i++ )
00179 newProgram1.deleteLine( i );
00180
00181 #ifdef SIG_DEBUG
00182
00183 SIGEL_Tools::SIG_IO::cerr << "\n-> new length = " << newProgram1.getProgramLength();
00184
00185 #endif
00186 }
00187
00188 if( maxLength > 0 )
00189 if( prgLength2 > maxLength )
00190 {
00191 #ifdef SIG_DEBUG
00192
00193 SIGEL_Tools::SIG_IO::cerr << "\n-> new program (2) too long (length="
00194 << newProgram2.getProgramLength() << ") -> length decreased\n";
00195
00196 #endif
00197 for( long int i = maxLength - 1; i < prgLength2; i++ )
00198 newProgram2.deleteLine( i );
00199
00200 #ifdef SIG_DEBUG
00201
00202 SIGEL_Tools::SIG_IO::cerr << "\n-> new length = " << newProgram2.getProgramLength();
00203
00204 #endif
00205
00206 }
00207
00208 #ifdef SIG_DEBUG
00209
00210 SIGEL_Tools::SIG_IO::cerr << "\n-> new program (1) length = " << newProgram1.getProgramLength();
00211 SIGEL_Tools::SIG_IO::cerr << "\n-> new program (2) length = " << newProgram2.getProgramLength();
00212
00213 #endif
00214
00215 }
00216
00217 QDateTime actTime = QDateTime::currentDateTime();
00218
00219 newProgram1.checkLength( minLength,
00220 maxLength,
00221 randomizer,
00222 languageP,
00223 gpParameter.getInstructionProbabilities(),
00224 historyInfo );
00225
00226 if( historyInfo > 0 ) crossoverInd1->addLengthIncreasedInfo( actTime, historyInfo );
00227 if( historyInfo < 0 ) crossoverInd1->addLengthDecreasedInfo( actTime, (-1) * historyInfo );
00228
00229 newProgram2.checkLength( minLength,
00230 maxLength,
00231 randomizer,
00232 languageP,
00233 gpParameter.getInstructionProbabilities(),
00234 historyInfo );
00235
00236 if( historyInfo > 0 ) crossoverInd2->addLengthIncreasedInfo( actTime, historyInfo );
00237 if( historyInfo < 0 ) crossoverInd2->addLengthDecreasedInfo( actTime, (-1) * historyInfo );
00238
00239 crossoverInd1->addCrossOverInfo( winner1.getName(),
00240 winner2.getName(),
00241 actTime,
00242 crossPoint1,
00243 crossPoint2,
00244 fitness1,
00245 fitness2 );
00246
00247 crossoverInd2->addCrossOverInfo( winner1.getName(),
00248 winner2.getName(),
00249 actTime,
00250 crossPoint1,
00251 crossPoint2,
00252 fitness1,
00253 fitness2 );
00254
00255 QVector< SIG_GPIndividual > crossedInds( 2 );
00256 crossedInds.insert( 0, crossoverInd1 );
00257 crossedInds.insert( 1, crossoverInd2 );
00258
00259 return crossedInds;
00260 };
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 SIGEL_GP::SIG_GPIndividual& SIGEL_GP::SIG_GPOperations::mutation( SIGEL_GP::SIG_GPIndividual& winner,
00271 int poolPos,
00272 QString newName,
00273 SIGEL_Tools::SIG_Randomizer& randomizer,
00274 SIGEL_GP::SIG_GPParameter& gpParameter,
00275 SIGEL_Robot::SIG_LanguageParameters &languageP)
00276 {
00277 double winnerFitness = winner.getFitness();
00278 int generalMutationType = randomizer.getRandomInt( 3 );
00279
00280
00281 int specializedMutation = 0;
00282 long const minLength = gpParameter.getMinIndLength();
00283 long const maxLength = gpParameter.getMaxIndLength();
00284 int op1 = 0;
00285 int op2 = 0;
00286 SIGEL_Program::Robotinstruction instructionType;
00287 SIGEL_Program::SIG_ProgramLine *newProgLine ;
00288 long int mutPoint = 0;
00289 long int numberOfOperands = 0;
00290 int historyInfo;
00291
00292 #ifdef SIG_DEBUG
00293
00294 SIGEL_Tools::SIG_IO::cerr << "\n<MUTATION> ";
00295
00296 #endif
00297
00298
00299 SIG_GPIndividual *mutatedInd = new SIG_GPIndividual( SIG_GPParameter(),
00300 winner.getHistory(),
00301 newName,
00302 QDateTime(),
00303 poolPos );
00304
00305 SIGEL_Program::SIG_Program &newProgram = mutatedInd->getProgramVar();
00306 newProgram = winner.getProgramVar();
00307
00308
00309
00310
00311 newProgram.checkLength( minLength,
00312 maxLength,
00313 randomizer,
00314 languageP,
00315 gpParameter.getInstructionProbabilities(),
00316 historyInfo );
00317
00318
00319
00320 mutPoint = randomizer.getRandomLong( newProgram.getProgramLength() );
00321
00322
00323
00324 instructionType = newProgram.getLine( mutPoint )->getRobotinstructionType();
00325
00326
00327
00328 numberOfOperands = newProgram.getLine( mutPoint )->getNumberOfElements();
00329
00330
00331
00332 if( instructionType == SIGEL_Program::NOP )
00333 {
00334 op1 = 0;
00335 op2 = 0;
00336 }
00337 else
00338 {
00339 op1 = newProgram.getLine( mutPoint )->getInstructionElement( 0 );
00340
00341 if( numberOfOperands == 2 )
00342
00343 op2 = newProgram.getLine( mutPoint )->getInstructionElement( 1 );
00344
00345 else
00346
00347 op2 = 0;
00348 }
00349
00350
00351
00352
00353
00354 if( generalMutationType == 0 )
00355 {
00356
00357 #ifdef SIG_DEBUG
00358
00359 SIGEL_Tools::SIG_IO::cerr << "\n<TYPE 0>";
00360 SIGEL_Tools::SIG_IO::cerr << "\nline to mutate: [";
00361 newProgram.getLine( mutPoint )->print();
00362 SIGEL_Tools::SIG_IO::cerr << "]";
00363
00364 #endif
00365
00366 specializedMutation = randomizer.getRandomInt( 3 );
00367
00368
00369 #ifdef SIG_DEBUG
00370
00371 SIGEL_Tools::SIG_IO::cerr << "\n<SUBTYPE " << specializedMutation << ">";
00372
00373 #endif
00374
00375
00376 switch( specializedMutation )
00377 {
00378 case 0:
00379
00380
00381
00382
00383 newProgram.getLine( mutPoint )->randomRobotinstruction( languageP,
00384 randomizer,
00385 gpParameter.getInstructionProbabilities() );
00386 break;
00387
00388 case 1:
00389
00390
00391
00392
00393
00394
00395 if( numberOfOperands == 2 )
00396 {
00397
00398
00399
00400 if( randomizer.getRandomInt( 2 ) == 0 )
00401 {
00402
00403
00404 op1 = randomizer.getRandomInt( 32000 );
00405 if( randomizer.getRandomInt( 2 ) == 1 ) op1 = (-1) * op1;
00406 op2 = newProgram.getLine( mutPoint )->getInstructionElement( 1 );
00407 }
00408 else
00409 {
00410
00411
00412 op1 = newProgram.getLine( mutPoint )->getInstructionElement( 0 );
00413 op2 = randomizer.getRandomInt( 32000 );
00414 if( randomizer.getRandomInt( 2 ) == 1 ) op2 = (-1) * op2;
00415 }
00416 }
00417 else
00418 {
00419 if( instructionType != SIGEL_Program::NOP )
00420 {
00421
00422
00423 op1 = randomizer.getRandomInt( 32000 );
00424 if( randomizer.getRandomInt( 2 ) == 1 ) op1 = (-1) * op1;
00425 }
00426 else
00427 {
00428
00429
00430 op1 = 0;
00431 op2 = 0;
00432 }
00433 }
00434
00435
00436
00437 newProgram.getLine( mutPoint )->setRobotinstruction( instructionType,
00438 op1,
00439 op2 );
00440 break;
00441
00442 case 2:
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454 newProgLine = new SIGEL_Program::SIG_ProgramLine( randomizer,
00455 languageP,
00456 gpParameter.getInstructionProbabilities() );
00457
00458 if( newProgLine->getRobotinstructionType() != SIGEL_Program::NOP )
00459 {
00460
00461
00462
00463
00464 if( ( newProgLine->getNumberOfElements() >= 1 ) && ( op1 == 0 ) )
00465
00466 op1 = newProgLine->getInstructionElement( 0 );
00467
00468 if( ( newProgLine->getNumberOfElements() == 2 ) && ( op2 == 0 ) )
00469
00470 op2 = newProgLine->getInstructionElement( 1 );
00471 }
00472 else
00473 {
00474
00475
00476 op1 = 0;
00477 op2 = 0;
00478 }
00479
00480 newProgram.getLine( mutPoint )->setRobotinstruction( newProgLine->getRobotinstructionType(),
00481 op1,
00482 op2 );
00483 delete newProgLine;
00484
00485 break;
00486 }
00487
00488 #ifdef SIG_DEBUG
00489
00490 SIGEL_Tools::SIG_IO::cerr << "\nresult: [";
00491 newProgram.getLine( mutPoint )->print();
00492 SIGEL_Tools::SIG_IO::cerr << "]";
00493
00494 #endif
00495
00496 }
00497
00498 if( generalMutationType == 1 )
00499 if( newProgram.getProgramLength() + 1 <= maxLength )
00500 {
00501
00502 #ifdef SIG_DEBUG
00503
00504 SIGEL_Tools::SIG_IO::cerr << "\n<TYPE 1>";
00505
00506 #endif
00507
00508 newProgLine = new SIGEL_Program::SIG_ProgramLine( randomizer,
00509 languageP,
00510 gpParameter.getInstructionProbabilities() );
00511
00512 newProgram.insertLine( mutPoint, newProgLine );
00513
00514 }
00515 else
00516 generalMutationType = 2;
00517
00518
00519 if( generalMutationType == 2 )
00520 if( newProgram.getProgramLength() - 1 >= minLength )
00521 {
00522
00523 #ifdef SIG_DEBUG
00524
00525 SIGEL_Tools::SIG_IO::cerr << "\n<TYPE 2>";
00526
00527 #endif
00528
00529 newProgram.deleteLine( mutPoint );
00530 }
00531 else
00532 {
00533 if( newProgram.getProgramLength() + 1 <= maxLength )
00534 {
00535
00536 #ifdef SIG_DEBUG
00537
00538 SIGEL_Tools::SIG_IO::cerr << "\n<TYPE 1>";
00539
00540 #endif
00541
00542 newProgLine = new SIGEL_Program::SIG_ProgramLine( randomizer,
00543 languageP,
00544 gpParameter.getInstructionProbabilities() );
00545
00546 newProgram.insertLine( mutPoint, newProgLine );
00547 }
00548 }
00549
00550 #ifdef SIG_DEBUG
00551
00552 SIGEL_Tools::SIG_IO::cerr << "\n\n";
00553
00554 #endif
00555
00556
00557 QDateTime actTime = QDateTime::currentDateTime();
00558
00559 if( historyInfo > 0 ) mutatedInd->addLengthIncreasedInfo( actTime, historyInfo );
00560 if( historyInfo < 0 ) mutatedInd->addLengthDecreasedInfo( actTime, (-1) * historyInfo );
00561
00562 mutatedInd->addMutationInfo( winner.getName(), actTime, mutPoint, winnerFitness );
00563
00564 return *mutatedInd;
00565 };
00566
00567
00568
00569
00570
00571 SIGEL_GP::SIG_GPIndividual& SIGEL_GP::SIG_GPOperations::reproduction( SIGEL_GP::SIG_GPIndividual& winner,
00572 QString newName,
00573 int poolPos,
00574 SIGEL_Tools::SIG_Randomizer& randomizer,
00575 SIGEL_GP::SIG_GPParameter& gpParameter,
00576 SIGEL_Robot::SIG_LanguageParameters &languageP )
00577 {
00578 SIGEL_GP::SIG_GPIndividual *reproducedInd = new SIGEL_GP::SIG_GPIndividual( SIG_GPParameter(),
00579 winner.getHistory(),
00580 newName,
00581 QDateTime(),
00582 poolPos );
00583
00584 reproducedInd->setFitness( winner.getFitness() );
00585
00586 long const minLength = gpParameter.getMinIndLength();
00587 long const maxLength = gpParameter.getMaxIndLength();
00588 int historyInfo;
00589
00590 #ifdef SIG_DEBUG
00591
00592 SIGEL_Tools::SIG_IO::cerr << "\n<REPRODUCTION>";
00593
00594 if (!reproducedInd)
00595 {
00596 SIGEL_Tools::SIG_IO::cerr << "reproduction: Konnte kein neues Individuum erzeugen.\n";
00597 exit(1);
00598 };
00599
00600 #endif
00601
00602 reproducedInd->getProgramVar() = winner.getProgramVar();
00603
00604 reproducedInd->getProgramVar().checkLength( minLength,
00605 maxLength,
00606 randomizer,
00607 languageP,
00608 gpParameter.getInstructionProbabilities(),
00609 historyInfo );
00610
00611 QDateTime actTime = QDateTime::currentDateTime();
00612
00613 if( historyInfo > 0 ) reproducedInd->addLengthIncreasedInfo( actTime, historyInfo );
00614 if( historyInfo < 0 ) reproducedInd->addLengthDecreasedInfo( actTime, (-1) * historyInfo );
00615
00616 reproducedInd->addReproductionInfo( winner.getName(), actTime );
00617
00618
00619
00620 #ifdef SIG_DEBUG
00621
00622
00623
00624
00625
00626
00627 #endif
00628
00629 return *reproducedInd;
00630 };