QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.38
Loading...
Searching...
No Matches
hybridsimulatedannealing.hpp
Go to the documentation of this file.
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4Copyright (C) 2015 Andres Hernandez
5
6This file is part of QuantLib, a free-software/open-source library
7for financial quantitative analysts and developers - http://quantlib.org/
8
9QuantLib is free software: you can redistribute it and/or modify it
10under the terms of the QuantLib license. You should have received a
11copy of the license along with this program; if not, please email
12<quantlib-dev@lists.sf.net>. The license is also available online at
13<http://quantlib.org/license.shtml>.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the license for more details.
18*/
19
20/*! \file hybridsimulatedannealing.hpp
21\brief Implementation based on:
22Very Fast Simulated Re-Annealing, Lester Ingber,
23Mathl. Comput. Modelling, 967-973, 1989
24*/
25
26#ifndef quantlib_optimization_hybridsimulatedannealing_hpp
27#define quantlib_optimization_hybridsimulatedannealing_hpp
28
33#include <ql/shared_ptr.hpp>
34#include <utility>
35
36namespace QuantLib {
37
38 /*! Method is fairly straightforward:
39 1) Sampler provides a probability density (based on current value) for the parameters. Each
40 iteration a new draw is made from it to find a new point
41 2) Probability determines whether the new point, obtained from Sampler, is accepted or not
42 3) Temperature is a schedule T(k) for the iteration k, which affects the Sampler and Probability
43 4) Reannealing is a departure from the traditional Boltzmann Annealing method: it rescales
44 the iteration k independently for each dimension so as to improve convergence
45
46 The hybrid in the name is because one can provide it a local optimizer for use whenever any new
47 best point is found or at every accepted point, in which case is used is chose by the user.
48
49 Class Sampler must implement the following interface:
50 \code
51 void operator()(Array &newPoint, const Array &currentPoint, const Array &temp) const;
52 \endcode
53 Class Probability must implement the following interface:
54 \code
55 bool operator()(Real currentValue, Real newValue, const Array &temp) const;
56 \endcode
57 Class Temperature must implement the following interface:
58 \code
59 void operator()(Array &newTemp, const Array &currTemp, const Array &steps) const;
60 \endcode
61 Class Reannealing must implement the following interface:
62 \code
63 void operator()(Array & steps, const Array &currentPoint,
64 Real aCurrentValue, const Array & currTemp) const;
65 \endcode
66 */
67 template <class Sampler, class Probability, class Temperature, class Reannealing = ReannealingTrivial>
69 public:
74 };
79 };
80
81 HybridSimulatedAnnealing(const Sampler& sampler,
82 const Probability& probability,
83 Temperature temperature,
84 const Reannealing& reannealing = ReannealingTrivial(),
85 Real startTemperature = 200.0,
86 Real endTemperature = 0.01,
87 Size reAnnealSteps = 50,
88 ResetScheme resetScheme = ResetToBestPoint,
89 Size resetSteps = 150,
90 const ext::shared_ptr<OptimizationMethod>& localOptimizer =
91 ext::make_shared<LevenbergMarquardt>(),
92 LocalOptimizeScheme optimizeScheme = EveryBestPoint)
93 : sampler_(sampler), probability_(probability), temperature_(std::move(temperature)),
94 reannealing_(reannealing), startTemperature_(startTemperature),
95 endTemperature_(endTemperature),
96 reAnnealSteps_(reAnnealSteps == 0 ? QL_MAX_INTEGER : reAnnealSteps),
97 resetScheme_(resetScheme), resetSteps_(resetSteps == 0 ? QL_MAX_INTEGER : resetSteps),
98 localOptimizer_(localOptimizer),
99 optimizeScheme_(localOptimizer != nullptr ? optimizeScheme : NoLocalOptimize) {}
100
101 EndCriteria::Type minimize(Problem& P, const EndCriteria& endCriteria) override;
102
103 private:
104 Sampler sampler_;
106 Temperature temperature_;
107 Reannealing reannealing_;
113 ext::shared_ptr<OptimizationMethod> localOptimizer_;
115 };
116
117 template <class Sampler, class Probability, class Temperature, class Reannealing>
120 P.reset();
121 reannealing_.setProblem(P);
122 Array x = P.currentValue();
123 Size n = x.size();
124 Size k = 1;
125 Size kStationary = 1;
126 Size kReAnneal = 1;
127 Size kReset = 1;
128 Size maxK = endCriteria.maxIterations();
129 Size maxKStationary = endCriteria.maxStationaryStateIterations();
130 bool temperatureBreached = false;
131 Array currentTemperature(n, startTemperature_);
132 Array annealStep(n, 1.0);
133 Array bestPoint(x);
134 Array currentPoint(x);
135 const Array& startingPoint(x);
136 Array newPoint(x);
137 Real bestValue = P.value(bestPoint);
138 Real currentValue = bestValue;
139 Real startingValue = bestValue; //to reset to starting point if desired
140 while (k <= maxK && kStationary <= maxKStationary && !temperatureBreached)
141 {
142 //Draw a new sample point
143 sampler_(newPoint, currentPoint, currentTemperature);
144 try{
145 //Evaluate new point
146 Real newValue = P.value(newPoint);
147
148 //Determine if new point is accepted
149 if (probability_(currentValue, newValue, currentTemperature)) {
150 if (optimizeScheme_ == EveryNewPoint) {
151 P.setCurrentValue(newPoint);
152 P.setFunctionValue(newValue);
153 localOptimizer_->minimize(P, endCriteria);
154 newPoint = P.currentValue();
155 newValue = P.functionValue();
156 }
157 currentPoint = newPoint;
158 currentValue = newValue;
159 }
160
161 //Check if we have a new best point
162 if (newValue < bestValue) {
163 if (optimizeScheme_ == EveryBestPoint) {
164 P.setCurrentValue(newPoint);
165 P.setFunctionValue(newValue);
166 localOptimizer_->minimize(P, endCriteria);
167 newPoint = P.currentValue();
168 newValue = P.functionValue();
169 }
170 kStationary = 0;
171 bestValue = newValue;
172 bestPoint = newPoint;
173 }
174 } catch(...){
175 //Do nothing, move on to new draw
176 }
177 //Increase steps
178 k++;
179 kStationary++;
180 for (Real& i : annealStep)
181 i++;
182
183 //Reanneal if necessary
184 if (kReAnneal == reAnnealSteps_) {
185 kReAnneal = 0;
186 reannealing_(annealStep, currentPoint, currentValue, currentTemperature);
187 }
188 kReAnneal++;
189
190 //Reset if necessary
191 if (kReset == resetSteps_) {
192 kReset = 0;
193 switch (resetScheme_) {
194 case NoResetScheme:
195 break;
196 case ResetToOrigin:
197 currentPoint = startingPoint;
198 currentValue = startingValue;
199 break;
200 case ResetToBestPoint:
201 currentPoint = bestPoint;
202 currentValue = bestValue;
203 break;
204 }
205 }
206 kReset++;
207
208 //Update the current temperature according to current step
209 temperature_(currentTemperature, currentTemperature, annealStep);
210
211 //Check if temperature condition is breached
212 for (Size i = 0; i < n; i++)
213 temperatureBreached = temperatureBreached && currentTemperature[i] < endTemperature_;
214 }
215
216 //Change end criteria type if appropriate
217 if (k > maxK)
219 else if (kStationary > maxKStationary)
221
222 //Set result to best point
223 P.setCurrentValue(bestPoint);
224 P.setFunctionValue(bestValue);
225 return ecType;
226 }
227
234}
235
236#endif
1-D array used in linear algebra.
Definition: array.hpp:52
Size size() const
dimension of the array
Definition: array.hpp:483
Criteria to end optimization process:
Definition: endcriteria.hpp:40
Size maxIterations() const
Size maxStationaryStateIterations() const
HybridSimulatedAnnealing(const Sampler &sampler, const Probability &probability, Temperature temperature, const Reannealing &reannealing=ReannealingTrivial(), Real startTemperature=200.0, Real endTemperature=0.01, Size reAnnealSteps=50, ResetScheme resetScheme=ResetToBestPoint, Size resetSteps=150, const ext::shared_ptr< OptimizationMethod > &localOptimizer=ext::make_shared< LevenbergMarquardt >(), LocalOptimizeScheme optimizeScheme=EveryBestPoint)
ext::shared_ptr< OptimizationMethod > localOptimizer_
EndCriteria::Type minimize(Problem &P, const EndCriteria &endCriteria) override
minimize the optimization problem P
Abstract class for constrained optimization method.
Definition: method.hpp:36
Constrained optimization problem.
Definition: problem.hpp:42
const Array & currentValue() const
current value of the local minimum
Definition: problem.hpp:81
void setCurrentValue(Array currentValue)
Definition: problem.hpp:76
Real functionValue() const
value of cost function
Definition: problem.hpp:88
Real value(const Array &x)
call cost function computation and increment evaluation counter
Definition: problem.hpp:116
void setFunctionValue(Real functionValue)
Definition: problem.hpp:83
Abstract constraint class.
#define QL_MAX_INTEGER
Definition: qldefines.hpp:174
QL_REAL Real
real number
Definition: types.hpp:50
Real Probability
probability
Definition: types.hpp:82
std::size_t Size
size of a container
Definition: types.hpp:58
Functors for use on HybridSimulatedAnnealing.
Levenberg-Marquardt optimization method.
Definition: any.hpp:37
HybridSimulatedAnnealing< SamplerLogNormal, ProbabilityBoltzmannDownhill, TemperatureExponential, ReannealingTrivial > LogNormalSimulatedAnnealing
HybridSimulatedAnnealing< SamplerVeryFastAnnealing, ProbabilityBoltzmannDownhill, TemperatureVeryFastAnnealing, ReannealingFiniteDifferences > VeryFastSimulatedReAnnealing
HybridSimulatedAnnealing< SamplerVeryFastAnnealing, ProbabilityBoltzmannDownhill, TemperatureVeryFastAnnealing, ReannealingTrivial > VeryFastSimulatedAnnealing
HybridSimulatedAnnealing< SamplerGaussian, ProbabilityBoltzmannDownhill, TemperatureExponential, ReannealingFiniteDifferences > GaussianSimulatedReAnnealing
HybridSimulatedAnnealing< SamplerGaussian, ProbabilityBoltzmannDownhill, TemperatureExponential, ReannealingTrivial > GaussianSimulatedAnnealing
HybridSimulatedAnnealing< SamplerMirrorGaussian, ProbabilityBoltzmannDownhill, TemperatureExponential, ReannealingTrivial > MirrorGaussianSimulatedAnnealing
STL namespace.
Abstract optimization problem class.
Maps shared_ptr to either the boost or std implementation.