bool DESolver::Solve(int maxGenerations) { int generation; int candidate; bool bAtSolution; bestEnergy = 1.0E20; bAtSolution = false; for (generation=0;(generation < maxGenerations) && !bAtSolution;generation++) for (candidate=0; candidate < nPop; candidate++) { (this->*calcTrialSolution)(candidate); trialEnergy = EnergyFunction(trialSolution,bAtSolution); if (trialEnergy < popEnergy[candidate]) { // New low for this candidate popEnergy[candidate] = trialEnergy; CopyVector(RowVector(population,candidate),trialSolution); // Check if all-time low if (trialEnergy < bestEnergy) { bestEnergy = trialEnergy; CopyVector(bestSolution,trialSolution); } } } generations = generation; return(bAtSolution); }
int DESolver::Solve( int maxGenerations, int verbose ) { int generation; int candidate; bool bAtSolution; double relativeDeltas[3] = {100.0, 100.0, 100.0}; double lastBestEnergy; bestEnergy = 1.0E20; lastBestEnergy = bestEnergy; bAtSolution = false; for (generation = 0; (generation < maxGenerations) && !bAtSolution; generation++) { for (candidate = 0; candidate < nPop; candidate++) { // modified by PE //(this->*calcTrialSolution)(candidate); CalcTrialSolution(candidate); // trialSolution now contains a newly generated parameter vector // check for out-of-bounds values and generate random values w/in the bounds CopyVector(oldValues, RowVector(population, candidate)); // oldValues is guaranteed to lie between minBounds and maxBounds for (int j = 0; j < nDim; j++) { if (trialSolution[j] < minBounds[j]) trialSolution[j] = minBounds[j] + RandomUniform(0.0,1.0)*(oldValues[j] - minBounds[j]); if (trialSolution[j] > maxBounds[j]) trialSolution[j] = maxBounds[j] - RandomUniform(0.0,1.0)*(maxBounds[j] - oldValues[j]); } // Test our newly mutated/bred trial parameter vector trialEnergy = EnergyFunction(trialSolution, bAtSolution); if (trialEnergy < popEnergy[candidate]) { // New low for this candidate popEnergy[candidate] = trialEnergy; CopyVector(RowVector(population,candidate), trialSolution); // Check if all-time low if (trialEnergy < bestEnergy) { bestEnergy = trialEnergy; CopyVector(bestSolution, trialSolution); } } } // Debugging printout code added by PE -- print an update every 10 generations double relativeDeltaEnergy = 0.0; if ((generation % 10) == 0) { if (verbose > 0) printf("\nGeneration %4d: bestEnergy = %12.10f", generation, bestEnergy); if (generation == 20) { relativeDeltaEnergy = fabs(1.0 - lastBestEnergy/bestEnergy); relativeDeltas[0] = relativeDeltaEnergy; if (verbose > 0) printf(" (relative change = %e)", relativeDeltaEnergy); } else if (generation == 30) { relativeDeltaEnergy = fabs(1.0 - lastBestEnergy/bestEnergy); relativeDeltas[1] = relativeDeltas[0]; relativeDeltas[0] = relativeDeltaEnergy; if (verbose > 0) printf(" (relative change = %e)", relativeDeltaEnergy); } else if (generation >= 40) { relativeDeltaEnergy = fabs(1.0 - lastBestEnergy/bestEnergy); relativeDeltas[2] = relativeDeltas[1]; relativeDeltas[1] = relativeDeltas[0]; relativeDeltas[0] = relativeDeltaEnergy; if (verbose > 0) printf(" (relative change = %e)", relativeDeltaEnergy); if (TestConverged(relativeDeltas, tolerance)) { generations = generation; bAtSolution = true; return 1; } } lastBestEnergy = bestEnergy; } if (isnan(bestEnergy)) { // fprintf(stderr, "\n*** NaN-valued fit statistic detected (DE optimization)!\n"); printf("\n\tcandidate %d, bestEnergy = %f\n", candidate, bestEnergy); } } generations = generation; return 5; }