/* After each generation, this routine is called. What is done here, * is to print the best string in our own format, then check if the * best string is close to the correct value. If it is, duplicate * checking is tunred off. This is critical, as the mutation operator * will not degrade a string, so when the strings get near the correct * solution, they all become duplicates, but none can be changed! * * Other applications have done such things as send the best string * to another process to be visualized. For here, we just call our * print string function to print the best string. */ void N_EndOfGen(PGAContext *ctx) { int best; best = PGAGetBestIndex(ctx, PGA_NEWPOP); N_PrintString(ctx, stdout, best, PGA_NEWPOP); if (PGAGetEvaluation(ctx, best, PGA_NEWPOP) >= PGAGetStringLength(ctx)-10) PGASetNoDuplicatesFlag(ctx, PGA_FALSE); }
/*U**************************************************************************** PGAPrintReport - prints genetic algorithm statistics. The statistics that are printed are determined by PGASetPrintOptions(). Category: Reporting Inputs: ctx - context variable fp - file pointer to print the output to pop - symbolic constant of the population whose statistics are printed Outputs: genetic algorithm statistics are printed to fp Example: PGAContext *ctx; int p; : PGAPrintReport(ctx, stdout, PGA_NEWPOP); ****************************************************************************U*/ void PGAPrintReport(PGAContext *ctx, FILE *fp, int pop) { int p, best_p; double e, best_e; PGADebugEntered("PGAPrintReport"); /* * edd 07 Feb 2007 this prints unconditionally, so let's change it * WAS: if (ctx->ga.iter == 1) */ if ((ctx->rep.PrintFreq >=0) && !(ctx->ga.iter % ctx->rep.PrintFreq)) /* fprintf (fp, "Iter # Field Value Time\n"); */ fprintf (fp, "Iter # Field Value\n"); best_p = PGAGetBestIndex(ctx, pop); best_e = PGAGetEvaluation(ctx, best_p, pop); /* * edd 07 Feb 2007 this prints unconditionally, so let's change it * WAS: (!(ctx->ga.iter % ctx->rep.PrintFreq) || ctx->ga.iter == 1) */ if ((ctx->rep.PrintFreq >=0) && !(ctx->ga.iter % ctx->rep.PrintFreq)) { fprintf(fp, "%-11dBest %e\n", PGAGetGAIterValue(ctx), best_e); /* fprintf(fp, " %ld\n", time(NULL) - ctx->rep.starttime); */ if ((ctx->rep.PrintOptions & PGA_REPORT_WORST) == PGA_REPORT_WORST) { p = PGAGetWorstIndex(ctx, pop); e = PGAGetEvaluation(ctx, p, pop); fprintf(fp, " Worst %e\n", e); } if ((ctx->rep.PrintOptions & PGA_REPORT_AVERAGE) == PGA_REPORT_AVERAGE) fprintf(fp, " Average %e\n", ctx->rep.Average); if ((ctx->rep.PrintOptions & PGA_REPORT_OFFLINE) == PGA_REPORT_OFFLINE) fprintf(fp, " Offline %e\n", ctx->rep.Offline); if ((ctx->rep.PrintOptions & PGA_REPORT_ONLINE) == PGA_REPORT_ONLINE) fprintf(fp, " Online %e\n", ctx->rep.Online); if((ctx->rep.PrintOptions & PGA_REPORT_HAMMING) == PGA_REPORT_HAMMING) fprintf(fp, " Hamming %e\n", PGAHammingDistance(ctx, pop)); if ((ctx->rep.PrintOptions & PGA_REPORT_STRING) == PGA_REPORT_STRING) PGAPrintString(ctx, fp, best_p, pop); } fflush(fp); PGADebugExited("PGAPrintReport"); }
/*U**************************************************************************** PGAUpdateGeneration - updates internal data structures for the next genetic algorithm iteration, and checks if the termination conditions, both user and PGAPack, have been met. This routine must be called by both master and slave processes at the end of each GA generation. Category: Generation Inputs: ctx - context variable comm - an MPI communicator Outputs: PGA_TRUE if the genetic algorithm has terminated, otherwise PGA_FALSE. Example: PGAContext *ctx; : PGAUpdateGeneration(ctx, MPI_COMM_WORLD); ****************************************************************************U*/ void PGAUpdateGeneration(PGAContext *ctx, MPI_Comm comm) { PGAIndividual *temp; int i, rank; PGADebugEntered("PGAUpdateGeneration"); PGADebugPrint( ctx, PGA_DEBUG_PRINTVAR,"PGAUpdateGeneration", "ga.iter = ", PGA_INT, (void *) &(ctx->ga.iter) ); rank = PGAGetRank(ctx, comm); ctx->ga.iter++; if (rank == 0) { if (ctx->rep.PrintOptions & PGA_REPORT_AVERAGE) PGAUpdateAverage(ctx, PGA_NEWPOP); if (ctx->rep.PrintOptions & PGA_REPORT_ONLINE) PGAUpdateOnline(ctx, PGA_NEWPOP); if (ctx->rep.PrintOptions & PGA_REPORT_OFFLINE) PGAUpdateOffline(ctx, PGA_NEWPOP); if ((ctx->ga.StoppingRule & PGA_STOP_NOCHANGE) || ctx->ga.restart) { i = PGAGetBestIndex(ctx, PGA_NEWPOP); if (ctx->rep.Best == PGAGetEvaluation(ctx, i, PGA_NEWPOP)) ctx->ga.ItersOfSame++; else { ctx->rep.Best = PGAGetEvaluation(ctx, i, PGA_NEWPOP); ctx->ga.ItersOfSame = 1; } } if (ctx->ga.StoppingRule & PGA_STOP_TOOSIMILAR) ctx->ga.PercentSame = PGAComputeSimilarity(ctx, ctx->ga.newpop); /* Clear this twice in case the user EOG calls PGASelect. */ ctx->ga.SelectIndex = 0; if (ctx->fops.EndOfGen) (*ctx->fops.EndOfGen)(&ctx); if (ctx->cops.EndOfGen) (*ctx->cops.EndOfGen)(ctx); ctx->ga.SelectIndex = 0; temp = ctx->ga.oldpop; ctx->ga.oldpop = ctx->ga.newpop; ctx->ga.newpop = temp; } PGADebugExited("PGAUpdateGeneration"); }
/* Function to check "doneness" of the GA. We check the iteration * count (by calling PGACheckStoppingConditions), then check if we have found * the string yet. */ int N_StopCond(PGAContext *ctx) { int done, best; done = PGACheckStoppingConditions(ctx); best = PGAGetBestIndex(ctx, PGA_OLDPOP); if ((done == PGA_FALSE) && (PGAGetEvaluation(ctx, best, PGA_OLDPOP) == PGAGetStringLength(ctx))) done = PGA_TRUE; return(done); }