in masses/garescorer.c [474:670]
int adapt(PGAContext *ctx, int p, int pop, int done_eval, int threshold,
int repeat) {
double *myscores;
int i;
int changed = 0;
double tmp,old_evaluation,new_evaluation;
if (justCount) {
return 0;
}
adapt_times++;
if (done_eval && 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);
}
if ((double)ga_yn > ((double)ga_ny*nybias))
weight_balance--;
else if ((double)ga_yn < ((double)ga_ny*nybias))
weight_balance++;
if ((weight_balance < (threshold-1)) &&
(weight_balance > -threshold))
return 0;
myscores = PGAGetIndividual(ctx, p, pop)->chrom;
if (repeat) {
for (i = 0; i < num_mutable; i++) {
if ((yn_hit[i] && (weight_balance < 0)) ||
(ny_hit[i] && (weight_balance > 0))) {
if (((weight_balance < 0) &&
#ifdef USE_SCORE_RANGES
(myscores[i] < range_hi[i]) &&
#endif
(myscores[i] < -(double)0.01)) ||
((weight_balance > 0) &&
#ifdef USE_SCORE_RANGES
(myscores[i] > range_lo[i]) &&
#endif
(myscores[i] > (double)0.01))) {
tmp_scores[i][0] = (double)0.001*rint(myscores[i]); /* reducing */
#ifdef USE_SCORE_RANGES
if (((myscores[i] < -(double)0.01) && ((myscores[i] - tmp_scores[i][0]) > range_hi[i])) ||
((myscores[i] > (double)0.01) && ((myscores[i] - tmp_scores[i][0]) < range_lo[i]))) {
tmp_scores[i][0] = 0;
}
#endif
if (tmp_scores[i][0]) {
changed = 1;
lookup[i] = 0;
}
} else
tmp_scores[i][0] = 0;
} else
tmp_scores[i][0] = 0;
}
if (! changed) /* if can't reduce, don't do anything - safe */
return 0;
/* For every message */
for (i=num_nondup-1; i>=0; i--) {
tmp_total[i] = scores[i];
scores[i] =
score_msg(ctx,p,pop,i)/tests_count[i]; /* score sans ones modifying */
}
for (i = 0; i < num_mutable; i++) {
if (tmp_scores[i][0]) {
lookup[i] = myscores[i];
tmp_scores[i][1] = 1;
if (weight_balance < 0) {
yn_hit[i] = 1;
ny_hit[i] = 0;
} else {
ny_hit[i] = 1;
yn_hit[i] = 0;
}
} else {
lookup[i] = 0;
tmp_scores[i][1] = 0;
yn_hit[i] = ny_hit[i] = 0;
}
}
new_evaluation = old_evaluation; /* avoid a warning */
while (1) {
changed = 0;
for (i = 0; i < num_mutable; i++) {
if (((tmp_scores[i][0] < 0) && yn_hit[i] && /* going up */
#ifdef USE_SCORE_RANGES
((lookup[i] - tmp_scores[i][0]) < range_hi[i]) &&
#endif
(weight_balance < 0) && (lookup[i] < -(double)0.01)) ||
((tmp_scores[i][0] > 0) && ny_hit[i] && /* going down */
#ifdef USE_SCORE_RANGES
((lookup[i] - tmp_scores[i][0]) > range_lo[i]) &&
#endif
(weight_balance > 0) &&
(lookup[i] > (double)0.01))) {
lookup[i] -= tmp_scores[i][0];
changed = 1;
} else
tmp_scores[i][0] = 0;
yn_hit[i] = ny_hit[i] = 0;
}
if (changed) {
if (weight_balance > 0)
adapt_ny++;
else
adapt_yn++;
adapt_repeat++;
} else
break;
yyscore = ynscore = nyscore = nnscore = 0.0;
ga_yy=ga_yn=ga_ny=ga_nn=0;
for (i=num_nondup-1; i>=0; i--)
(void)score_msg(ctx,p,pop,i);
new_evaluation = evaluate_inner();
if (new_evaluation > old_evaluation) {
for (i = 0; i < num_mutable; i++) {
if (tmp_scores[i][0])
lookup[i] += tmp_scores[i][0];
}
new_evaluation = old_evaluation;
adapt_overshot++;
break;
} else
old_evaluation = new_evaluation;
if ((double)ga_yn > ((double)ga_ny*nybias))
weight_balance--;
else if ((double)ga_yn < ((double)ga_ny*nybias))
weight_balance++;
if ((weight_balance < (threshold-1)) &&
(weight_balance > -threshold))
break;
}
for (i=num_nondup-1; i>=0; i--)
scores[i] = tmp_total[i];
for (i=0; i < num_mutable; i++) {
if (tmp_scores[i][1])
myscores[i] = lookup[i];
}
PGASetEvaluation(ctx, p, pop, new_evaluation);
PGASetEvaluationUpToDateFlag(ctx, p, pop, PGA_TRUE);
return 1;
} else {
for (i = 0; i < num_mutable; i++) {
if ((yn_hit[i] && (weight_balance < 0)) ||
(ny_hit[i] && (weight_balance > 0))) {
tmp = (double)0.001*rint(myscores[i]);
if (! tmp) {
if (myscores[i] > (double)0.01)
tmp = (double)0.001;
else if (myscores[i] < -(double)0.01)
tmp = -(double)0.001;
}
#ifdef USE_SCORE_RANGES
if (tmp && (((myscores[i] > 0) &&
((myscores[i] - tmp) < range_lo[i])) ||
((myscores[i] < 0) &&
((myscores[i] - tmp) > range_hi[i]))))
tmp = 0;
#endif
if (tmp) {
myscores[i] -= tmp;
changed = 1;
}
}
}
if (changed) {
if (weight_balance > 0)
adapt_ny++;
else
adapt_yn++;
return 1;
} else
return 0;
}
}