1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2012 Ralph Schreyer
5 Copyright (C) 2012 Mateusz Kapturski
6
7 This file is part of QuantLib, a free-software/open-source library
8 for financial quantitative analysts and developers - http://quantlib.org/
9
10 QuantLib is free software: you can redistribute it and/or modify it
11 under the terms of the QuantLib license. You should have received a
12 copy of the license along with this program; if not, please email
13 <quantlib-dev@lists.sf.net>. The license is also available online at
14 <http://quantlib.org/license.shtml>.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the license for more details.
19*/
20
21/*! \file differentialevolution.hpp
22 \brief Differential Evolution optimization method
23*/
24
25#ifndef quantlib_optimization_differential_evolution_hpp
26#define quantlib_optimization_differential_evolution_hpp
27
28#include <ql/math/optimization/constraint.hpp>
29#include <ql/math/optimization/problem.hpp>
30#include <ql/math/randomnumbers/mt19937uniformrng.hpp>
31
32namespace QuantLib {
33
34 //! Differential Evolution configuration object
35 /*! The algorithm and strategy names are taken from here:
36
37 Price, K., Storn, R., 1997. Differential Evolution -
38 A Simple and Efficient Heuristic for Global Optimization
39 over Continuous Spaces.
40 Journal of Global Optimization, Kluwer Academic Publishers,
41 1997, Vol. 11, pp. 341 - 359.
42
43 There are seven basic strategies for creating mutant population
44 currently implemented. Three basic crossover types are also
45 available.
46
47 Future development:
48 1) base element type to be extracted
49 2) L differences to be used instead of fixed number
50 3) various weights distributions for the differences (dither etc.)
51 4) printFullInfo parameter usage to track the algorithm
52
53 \warning This was reported to fail tests on Mac OS X 10.8.4.
54 */
55
56
57 //! %OptimizationMethod using Differential Evolution algorithm
58 /*! \ingroup optimizers */
59 class DifferentialEvolution: public OptimizationMethod {
60 public:
61 enum Strategy {
62 Rand1Standard,
63 BestMemberWithJitter,
64 CurrentToBest2Diffs,
65 Rand1DiffWithPerVectorDither,
66 Rand1DiffWithDither,
67 EitherOrWithOptimalRecombination,
68 Rand1SelfadaptiveWithRotation
69 };
70 enum CrossoverType {
71 Normal,
72 Binomial,
73 Exponential
74 };
75
76 struct Candidate {
77 Array values;
78 Real cost = 0.0;
79 Candidate(Size size = 0) : values(size, 0.0) {}
80 };
81
82 class Configuration {
83 public:
84 Strategy strategy = BestMemberWithJitter;
85 CrossoverType crossoverType = Normal;
86 Size populationMembers = 100;
87 Real stepsizeWeight = 0.2, crossoverProbability = 0.9;
88 unsigned long seed = 0;
89 bool applyBounds = true, crossoverIsAdaptive = false;
90 std::vector<Array> initialPopulation;
91 Array upperBound, lowerBound;
92
93 // Clang seems to have problems if we use '= default' here.
94 // NOLINTNEXTLINE(modernize-use-equals-default)
95 Configuration() {}
96
97 Configuration& withBounds(bool b = true) {
98 applyBounds = b;
99 return *this;
100 }
101
102 Configuration& withCrossoverProbability(Real p) {
103 QL_REQUIRE(p>=0.0 && p<=1.0,
104 "Crossover probability (" << p
105 << ") must be in [0,1] range");
106 crossoverProbability = p;
107 return *this;
108 }
109
110 Configuration& withPopulationMembers(Size n) {
111 QL_REQUIRE(n>0, "Positive number of population members required");
112 populationMembers = n;
113 initialPopulation.clear();
114 return *this;
115 }
116
117 Configuration& withInitialPopulation(const std::vector<Array>& c) {
118 initialPopulation = c;
119 populationMembers = c.size();
120 return *this;
121 }
122
123 Configuration& withUpperBound(const Array& u) {
124 upperBound = u;
125 return *this;
126 }
127
128 Configuration& withLowerBound(const Array& l) {
129 lowerBound = l;
130 return *this;
131 }
132
133 Configuration& withSeed(unsigned long s) {
134 seed = s;
135 return *this;
136 }
137
138 Configuration& withAdaptiveCrossover(bool b = true) {
139 crossoverIsAdaptive = b;
140 return *this;
141 }
142
143 Configuration& withStepsizeWeight(Real w) {
144 QL_ENSURE(w>=0 && w<=2.0,
145 "Step size weight ("<< w
146 << ") must be in [0,2] range");
147 stepsizeWeight = w;
148 return *this;
149 }
150
151 Configuration& withCrossoverType(CrossoverType t) {
152 crossoverType = t;
153 return *this;
154 }
155
156 Configuration& withStrategy(Strategy s) {
157 strategy = s;
158 return *this;
159 }
160 };
161
162
163 DifferentialEvolution(const Configuration& configuration = Configuration())
164 : configuration_(configuration), rng_(configuration.seed) {}
165
166 EndCriteria::Type minimize(Problem& p, const EndCriteria& endCriteria) override;
167
168 const Configuration& configuration() const {
169 return configuration_;
170 }
171
172 private:
173 Configuration configuration_;
174 Array upperBound_, lowerBound_;
175 mutable Array currGenSizeWeights_, currGenCrossover_;
176 Candidate bestMemberEver_;
177 MersenneTwisterUniformRng rng_;
178
179 void fillInitialPopulation(std::vector<Candidate>& population,
180 const Problem& p) const;
181
182 void getCrossoverMask(std::vector<Array>& crossoverMask,
183 std::vector<Array>& invCrossoverMask,
184 const Array& mutationProbabilities) const;
185
186 Array getMutationProbabilities(
187 const std::vector<Candidate>& population) const;
188
189 void adaptSizeWeights() const;
190
191 void adaptCrossover() const;
192
193 void calculateNextGeneration(std::vector<Candidate>& population,
194 Problem& costFunction) const;
195
196 Array rotateArray(Array inputArray) const;
197
198 void crossover(const std::vector<Candidate>& oldPopulation,
199 std::vector<Candidate> & population,
200 const std::vector<Candidate>& mutantPopulation,
201 const std::vector<Candidate>& mirrorPopulation,
202 Problem& costFunction) const;
203 };
204
205}
206
207#endif
208

source code of quantlib/ql/math/optimization/differentialevolution.hpp

Morty Proxy This is a proxified and sanitized view of the page, visit original site.