in masses/garescorer.c [688:917]
int myMutation(PGAContext *ctx, int p, int pop, double mr) {
int count=0;
int i;
# ifdef USE_VARIABLE_MUTATIONS
double *myscores;
double old_evaluation,new_evaluation,min_score,max_score;
myscores = PGAGetIndividual(ctx, p, pop)->chrom;
if (PGAGetEvaluationUpToDateFlag(ctx, p, pop))
old_evaluation = PGAGetEvaluation(ctx, p, pop);
else {
old_evaluation = evaluate(ctx, p, pop);
PGASetEvaluation(ctx, p, pop, old_evaluation);
PGASetEvaluationUpToDateFlag(ctx, p, pop, PGA_TRUE);
}
for (i=0; i<num_mutable; i++) {
tmp_scores[i][0] = 0;
if (PGARandomFlip(ctx, mr)) {
#ifdef USE_SCORE_RANGES
min_score = range_lo[i];
max_score = range_hi[i];
#else
min_score = SCORE_CAP;
max_score = NEG_SCORE_CAP;
#endif
if (myscores[i] > max_score)
myscores[i] = max_score;
else if (myscores[i] < min_score)
myscores[i] = min_score;
tmp_scores[i][1] = (max_score - min_score)/4;
myscores[i+num_scores] *=
pow(2,(PGARandomGaussian(ctx,0,mutation_noise*2)));
if (myscores[i+num_scores] < min_mutation_noise)
myscores[i+num_scores] = min_mutation_noise;
else if (myscores[i+num_scores] > tmp_scores[i][1])
myscores[i+num_scores] = tmp_scores[i][1];
while (! tmp_scores[i][0]) {
tmp_scores[i][0] = PGARandomGaussian(ctx,0,
myscores[i+num_scores]);
#ifdef USE_SCORE_RANGES
if (((double)(myscores[i] + tmp_scores[i][0]) >= max_score) ||
((double)(myscores[i] + tmp_scores[i][0]) <= min_score)) {
if (myscores[i+num_scores] > mutation_noise) {
myscores[i+num_scores] =
(myscores[i+num_scores] + mutation_noise)/2;
tmp_scores[i][0] = 0;
} else if ((double)(myscores[i] + tmp_scores[i][0]) >= max_score) {
tmp_scores[i][0] = max_score - myscores[i] - (double)0.001;
break;
} else {
tmp_scores[i][0] = min_score - myscores[i] + (double)0.001;
break;
}
}
#endif
}
myscores[i] += tmp_scores[i][0];
count++;
}
}
if (count > 0) {
var_mutated++;
new_evaluation = evaluate(ctx, p, pop);
if (new_evaluation > old_evaluation) {
/* Did previous try go too far away? */
if (iters_same_passed) { /* in 2nd phase */
count = 0;
for (i=0; i<num_mutable; i++) {
if (tmp_scores[i][0]) {
if (myscores[i+num_scores] > mutation_noise) {
tmp_scores[i][1] = PGARandomGaussian(ctx,0,mutation_noise);
count++;
} else
tmp_scores[i][1] =
PGARandomGaussian(ctx,0,myscores[i+num_scores]);
tmp_scores[i][1] = copysign(tmp_scores[i][1],tmp_scores[i][0]);
#ifdef USE_SCORE_RANGES
if ((double)(myscores[i] + tmp_scores[i][1]
- tmp_scores[i][0]) >= range_hi[i]) {
tmp_scores[i][1] = range_hi[i] - myscores[i] +
tmp_scores[i][0] - (double)0.001;
} else if ((double)(myscores[i] + tmp_scores[i][1]
- tmp_scores[i][0]) <= range_lo[i]) {
tmp_scores[i][1] = range_lo[i] - myscores[i] +
tmp_scores[i][0] + (double)0.001;
}
#endif
myscores[i] += tmp_scores[i][1] - tmp_scores[i][0];
}
}
if (count > 0) {
num_mutated++;
new_evaluation = evaluate(ctx, p, pop);
if (PGAGetNoDuplicatesFlag(ctx) == PGA_FALSE) {
/* Hack to avoid redoing evaluation without need - Allen */
count = 0;
PGASetEvaluation(ctx, p, pop, new_evaluation);
PGASetEvaluationUpToDateFlag(ctx, p, pop, PGA_TRUE);
}
if (new_evaluation <= old_evaluation) {
/* Previous try went too far away */
if (mr < base_mutation_rate)
num_better_same++;
for (i=0; i<num_mutable; i++) {
if (tmp_scores[i][0] &&
(myscores[i+num_scores] > mutation_noise)
&& (fabs(tmp_scores[i][1]) < fabs(tmp_scores[i][0])))
myscores[i+num_scores] =
(myscores[i+num_scores] + mutation_noise)/2;
}
} else {
#ifdef LAMARCK
if (mr < base_mutation_rate) {
count = adapt(ctx,p,pop,1,1,0);
if (count) {
count = adapt(ctx,p,pop,0,2,1);
if (count)
new_evaluation = PGAGetEvaluation(ctx, p, pop);
else
new_evaluation = evaluate(ctx, p, pop);
if (new_evaluation > old_evaluation)
num_worse++;
else
num_better_same++; /* only had to adapt once */
if (PGAGetNoDuplicatesFlag(ctx) == PGA_FALSE) {
/* Hack to avoid redoing evaluation without need - Allen */
count = 0;
PGASetEvaluation(ctx, p, pop, new_evaluation);
PGASetEvaluationUpToDateFlag(ctx, p, pop, PGA_TRUE);
}
} else
num_worse++;
} else
#endif
num_worse++;
}
} else { /* didn't decrease mutation SD */
#ifdef LAMARCK
if (mr < base_mutation_rate) {
count = adapt(ctx,p,pop,0,1,0);
new_evaluation = evaluate(ctx, p, pop);
}
#endif
if (new_evaluation > old_evaluation) {
#ifdef LAMARCK
if ((mr < base_mutation_rate) && count) {
count = adapt(ctx,p,pop,1,2,1);
if (count) {
new_evaluation = PGAGetEvaluation(ctx, p, pop);
if (new_evaluation > old_evaluation)
num_worse++;
else
num_better_same++;
} else
num_worse++;
} else
#endif
num_worse++;
} else
num_better_same++;
if (PGAGetNoDuplicatesFlag(ctx) == PGA_FALSE) {
/* Hack to avoid redoing evaluation without need - Allen */
count = 0;
PGASetEvaluation(ctx, p, pop, new_evaluation);
PGASetEvaluationUpToDateFlag(ctx, p, pop, PGA_TRUE);
}
}
if ((! count) &&
(PGAGetNoDuplicatesFlag(ctx) == PGA_TRUE))
count++;
} else
num_worse++;
} else {
if (PGAGetNoDuplicatesFlag(ctx) == PGA_FALSE) {
/* Hack to avoid redoing evaluation without need - Allen */
count = 0;
PGASetEvaluation(ctx, p, pop, new_evaluation);
PGASetEvaluationUpToDateFlag(ctx, p, pop, PGA_TRUE);
}
num_better_same++;
}
}
#ifdef LAMARCK
else if (mr < base_mutation_rate) {
count = adapt(ctx,p,pop,1,2,0);
if (! count)
num_better_same++; /* adapt not working, use mutation */
}
#endif
# else /* USE_VARIABLE_MUTATIONS */
int j;
for (i=0; i<num_mutable; i++)
{
if(PGARandomFlip(ctx, mr))
{
double gene_sum=0.0;
/* Find the mean */
for(j=0; j<pop_size; j++) {
if(p!=j)
gene_sum += PGAGetRealAllele(ctx, j, pop, i);
}
gene_sum /= (double)(pop_size-1);
/* Regress towards it... */
gene_sum = (1.0-regression_coefficient)*gene_sum+regression_coefficient*PGAGetRealAllele(ctx, p, pop, i);
/* Set this gene in this allele to be the average, plus some gaussian noise */
if(gene_sum > SCORE_CAP)
gene_sum = SCORE_CAP;
else if(gene_sum < NEG_SCORE_CAP)
gene_sum = NEG_SCORE_CAP;
PGASetRealAllele(ctx, p, pop, i,
PGARandomGaussian(ctx, gene_sum, mutation_noise));
count++;
}
}
# endif /* !USE_VARIABLE_MUTATIONS */
return count;
}