/*U**************************************************************************** PGARunMutationAndCrossover - Performs crossover and mutation from one population to create the next. Assumes PGASelect has been called. Category: Generation Inputs: ctx - context variable oldpop - symbolic constant of old population newpop - symbolic constant of new population Outputs: newpop is modified by side-effect. Example: PGAContext *ctx, : PGARunMutationAndCrossover(ctx, PGA_OLDPOP, PGA_NEWPOP); ****************************************************************************U*/ void PGARunMutationAndCrossover (PGAContext *ctx, int oldpop, int newpop) { int i, j, n, m1, m2; int popsize, numreplace; double pc; PGADebugEntered("PGARunMutationAndCrossover"); popsize = PGAGetPopSize(ctx); numreplace = PGAGetNumReplaceValue(ctx); /*** first, copy n best strings (sorted by fitness) to new pop ***/ PGASortPop( ctx, oldpop ); n = popsize - numreplace; for ( i=0; i < n; i++ ) { j = PGAGetSortedPopIndex( ctx, i ); PGACopyIndividual ( ctx, j, oldpop, i, newpop ); } pc = PGAGetCrossoverProb(ctx); /*** reproduce to create the rest of the new population ***/ while ( n < popsize) { m1 = PGASelectNextIndex( ctx ); m2 = PGASelectNextIndex( ctx ); if ( PGARandomFlip(ctx, pc) ) { PGACrossover ( ctx, m1, m2, oldpop, PGA_TEMP1, PGA_TEMP2, newpop); /*** mutate and copy first string to new population ***/ PGAMutate ( ctx, PGA_TEMP1, newpop); while (PGADuplicate( ctx, PGA_TEMP1, newpop, newpop, n)) PGAChange ( ctx, PGA_TEMP1, newpop ); PGACopyIndividual ( ctx, PGA_TEMP1, newpop, n, newpop); n++; if ( n < popsize ) { /*** mutate and copy second string to new population ***/ PGAMutate ( ctx, PGA_TEMP2, newpop); while ( PGADuplicate( ctx, PGA_TEMP2, newpop, newpop, n)) PGAChange ( ctx, PGA_TEMP2, newpop ); PGACopyIndividual ( ctx, PGA_TEMP2, newpop, n, newpop); n++; } } else { PGACopyIndividual ( ctx, m1, oldpop, n, newpop ); n++; if ( n < ctx->ga.PopSize ) { PGACopyIndividual ( ctx, m2, oldpop, n, newpop ); n++; } } } PGADebugExited("PGARunMutationAndCrossover"); }
/* Function to muatate a PGA_DATATYPE_CHARACTER string. This is done * by simply picking allele locations and replacing whatever was there. * Again, legal values are all printable ASCII characters. */ int N_Mutation(PGAContext *ctx, int p, int pop, double mr) { int i, count; count = 0; for(i=PGAGetStringLength(ctx)-1; i>=0; i--) if (PGAGetCharacterAllele(ctx, p, pop, i) != Name[i]) { if (PGARandomFlip(ctx, mr) == PGA_TRUE) { PGASetCharacterAllele(ctx, p, pop, i, PGARandomInterval(ctx, 32, 126)); count++; } } return(count); }
/* Function to crossover two name strings. Quite an interesting * crossover, too. Works like a normal uniform crossover, except * that, if one of the strings matches the correct value, we set * BOTH children to the correct value 50% of the time. */ void N_Crossover(PGAContext *ctx, int p1, int p2, int pop1, int c1, int c2, int pop2) { int i, length; char a, b; length = PGAGetStringLength(ctx); for (i=0; i<length; i++) { a = PGAGetCharacterAllele(ctx, p1, pop1, i); b = PGAGetCharacterAllele(ctx, p2, pop1, i); if ((a == Name[i]) || (b == Name[i])) a = b = Name[i]; if (PGARandomFlip(ctx, 0.5) == PGA_TRUE) { PGASetCharacterAllele(ctx, c1, pop2, i, a); PGASetCharacterAllele(ctx, c2, pop2, i, b); } else { PGASetCharacterAllele(ctx, c1, pop2, i, b); PGASetCharacterAllele(ctx, c2, pop2, i, a); } } }
/*U**************************************************************************** PGARunMutationOrCrossover - Performs crossover or mutation (but not both) from one populationto create the next. Assumes PGASelect has been called. Category: Generation Inputs: ctx - context variable oldpop - symbolic constant of old population newpop - symbolic constant of new population Outputs: newpop is modified by side-effect. Example: PGAContext *ctx, : PGARunMutationOrCrossover(ctx, PGA_OLDPOP, PGA_NEWPOP); ****************************************************************************U*/ void PGARunMutationOrCrossover ( PGAContext *ctx, int oldpop, int newpop ) { int i, j, n, m1, m2; int popsize, numreplace; double pc; PGADebugEntered("PGARunMutationOrCrossover"); popsize = PGAGetPopSize(ctx); numreplace = PGAGetNumReplaceValue(ctx); /*** first, copy n best strings (sorted by fitness) to new pop ***/ PGASortPop( ctx, oldpop ); n = popsize - numreplace; for ( i=0; i < n; i++ ) { j = PGAGetSortedPopIndex( ctx, i ); PGACopyIndividual ( ctx, j, oldpop, i, newpop ); } pc = PGAGetCrossoverProb(ctx); /*** reproduce to create the rest of the new population ***/ while ( n < popsize ) { m1 = PGASelectNextIndex( ctx ); m2 = PGASelectNextIndex( ctx ); if ( PGARandomFlip(ctx, pc) ) { PGACrossover ( ctx, m1, m2, oldpop, PGA_TEMP1, PGA_TEMP2, newpop); /*** copy first string to new population ***/ while (PGADuplicate(ctx, PGA_TEMP1, newpop, newpop, n)) PGAChange ( ctx, PGA_TEMP1, newpop ); PGACopyIndividual ( ctx, PGA_TEMP1, newpop, n, newpop); n++; if ( n < popsize ) { /*** copy second string to new population ***/ while (PGADuplicate(ctx, PGA_TEMP2, newpop, newpop, n)) PGAChange ( ctx, PGA_TEMP2, newpop ); PGACopyIndividual ( ctx, PGA_TEMP2, newpop, n, newpop); n++; } } else { PGACopyIndividual(ctx, m1, oldpop, PGA_TEMP1, newpop); PGAMutate ( ctx, PGA_TEMP1, newpop ); while (PGADuplicate(ctx, PGA_TEMP1, newpop, newpop, n )) PGAChange ( ctx, PGA_TEMP1, newpop ); PGACopyIndividual ( ctx, PGA_TEMP1, newpop, n, newpop); /* A bug of PGA ??? -- PGAChange doesn't set the UpToDateFlag, so it won't be evaluated and gives wrong evaluation result */ PGASetEvaluationUpToDateFlag (ctx, n, newpop, PGA_FALSE); n++; if ( n < popsize ) { PGACopyIndividual(ctx, m2, oldpop, PGA_TEMP2, newpop); PGAMutate ( ctx, PGA_TEMP2, newpop ); while (PGADuplicate(ctx, PGA_TEMP2, newpop, newpop, n )) PGAChange ( ctx, PGA_TEMP2, newpop ); PGACopyIndividual ( ctx, PGA_TEMP2, newpop, n, newpop); PGASetEvaluationUpToDateFlag (ctx, n, newpop, PGA_FALSE); n++; } } } PGADebugExited("PGARunMutationOrCrossover"); }