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);
}
Esempio n. 2
0
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;
}