EndCriteria::Type DifferentialEvolution::minimize(Problem& p, const EndCriteria& endCriteria) { EndCriteria::Type ecType; upperBound_ = p.constraint().upperBound(p.currentValue()); lowerBound_ = p.constraint().lowerBound(p.currentValue()); currGenSizeWeights_ = Array(configuration().populationMembers, configuration().stepsizeWeight); currGenCrossover_ = Array(configuration().populationMembers, configuration().crossoverProbability); std::vector<Candidate> population(configuration().populationMembers, Candidate(p.currentValue().size())); fillInitialPopulation(population, p); std::partial_sort(population.begin(), population.begin() + 1, population.end(), sort_by_cost()); bestMemberEver_ = population.front(); Real fxOld = population.front().cost; Size iteration = 0, stationaryPointIteration = 0; // main loop - calculate consecutive emerging populations while (!endCriteria.checkMaxIterations(iteration++, ecType)) { calculateNextGeneration(population, p.costFunction()); std::partial_sort(population.begin(), population.begin() + 1, population.end(), sort_by_cost()); if (population.front().cost < bestMemberEver_.cost) bestMemberEver_ = population.front(); Real fxNew = population.front().cost; if (endCriteria.checkStationaryFunctionValue(fxOld, fxNew, stationaryPointIteration, ecType)) break; fxOld = fxNew; }; p.setCurrentValue(bestMemberEver_.values); p.setFunctionValue(bestMemberEver_.cost); return ecType; }
EndCriteria::Type LineSearchBasedMethod::minimize(Problem& P, const EndCriteria& endCriteria) { // Initializations Real ftol = endCriteria.functionEpsilon(); Size maxStationaryStateIterations_ = endCriteria.maxStationaryStateIterations(); EndCriteria::Type ecType = EndCriteria::None; // reset end criteria P.reset(); // reset problem Array x_ = P.currentValue(); // store the starting point Size iterationNumber_ = 0; // dimension line search lineSearch_->searchDirection() = Array(x_.size()); bool done = false; // function and squared norm of gradient values; Real fnew, fold, gold2; Real fdiff; // classical initial value for line-search step Real t = 1.0; // Set gradient g at the size of the optimization problem // search direction Size sz = lineSearch_->searchDirection().size(); Array prevGradient(sz), d(sz), sddiff(sz), direction(sz); // Initialize cost function, gradient prevGradient and search direction P.setFunctionValue(P.valueAndGradient(prevGradient, x_)); P.setGradientNormValue(DotProduct(prevGradient, prevGradient)); lineSearch_->searchDirection() = -prevGradient; bool first_time = true; // Loop over iterations do { // Linesearch if (!first_time) prevGradient = lineSearch_->lastGradient(); t = (*lineSearch_)(P, ecType, endCriteria, t); // don't throw: it can fail just because maxIterations exceeded //QL_REQUIRE(lineSearch_->succeed(), "line-search failed!"); if (lineSearch_->succeed()) { // Updates // New point x_ = lineSearch_->lastX(); // New function value fold = P.functionValue(); P.setFunctionValue(lineSearch_->lastFunctionValue()); // New gradient and search direction vectors // orthogonalization coef gold2 = P.gradientNormValue(); P.setGradientNormValue(lineSearch_->lastGradientNorm2()); // conjugate gradient search direction direction = getUpdatedDirection(P, gold2, prevGradient); sddiff = direction - lineSearch_->searchDirection(); lineSearch_->searchDirection() = direction; // Now compute accuracy and check end criteria // Numerical Recipes exit strategy on fx (see NR in C++, p.423) fnew = P.functionValue(); fdiff = 2.0*std::fabs(fnew-fold) / (std::fabs(fnew) + std::fabs(fold) + QL_EPSILON); if (fdiff < ftol || endCriteria.checkMaxIterations(iterationNumber_, ecType)) { endCriteria.checkStationaryFunctionValue(0.0, 0.0, maxStationaryStateIterations_, ecType); endCriteria.checkMaxIterations(iterationNumber_, ecType); return ecType; } P.setCurrentValue(x_); // update problem current value ++iterationNumber_; // Increase iteration number first_time = false; } else { done = true; } } while (!done); P.setCurrentValue(x_); return ecType; }