numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
heuristic_global_optimizer.h
Go to the documentation of this file.
1/*
2 * Copyright 2021 MusicScience37 (Kenta Kabashima)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
20#pragma once
21
22#include <type_traits> // IWYU pragma: keep
23
35
36namespace num_collect::opt {
37
40 logging::log_tag_view("num_collect::opt::heuristic_global_optimizer");
41
47template <concepts::objective_function ObjectiveFunction>
49
55template <concepts::single_variate_objective_function ObjectiveFunction>
56class heuristic_global_optimizer<ObjectiveFunction>
57 : public optimizer_base<heuristic_global_optimizer<ObjectiveFunction>> {
58public:
61
63 using objective_function_type = ObjectiveFunction;
64
66 using variable_type = typename objective_function_type::variable_type;
67
69 using value_type = typename objective_function_type::value_type;
70
71 static_assert(std::is_same_v<variable_type, value_type>);
72
80 : optimizer_base<heuristic_global_optimizer<ObjectiveFunction>>(
82 opt1_(obj_fun),
83 opt2_(obj_fun) {}
84
91 opt1_.change_objective_function(obj_fun);
92 opt2_.change_objective_function(obj_fun);
93 }
94
101 void init(const variable_type& lower, const variable_type& upper) {
102 opt1_.init(lower, upper);
103 opt2_.init(opt1_.lower(), opt1_.upper());
104 }
105
109 void iterate() { opt2_.iterate(); }
110
114 [[nodiscard]] auto is_stop_criteria_satisfied() const -> bool {
115 return opt2_.is_stop_criteria_satisfied();
116 }
117
123 const {
124 iteration_logger.template append<index_type>(
125 "Iter.", &this_type::iterations);
126 iteration_logger.template append<index_type>(
127 "Eval.", &this_type::evaluations);
128 iteration_logger.template append<value_type>(
129 "Value", &this_type::opt_value);
130 }
131
135 [[nodiscard]] auto opt_variable() const -> const variable_type& {
136 return opt2_.opt_variable();
137 }
138
142 [[nodiscard]] auto opt_value() const -> const value_type& {
143 return opt2_.opt_value();
144 }
145
149 [[nodiscard]] auto iterations() const noexcept -> index_type {
150 return opt1_.iterations() + opt2_.iterations();
151 }
152
156 [[nodiscard]] auto evaluations() const noexcept -> index_type {
157 return opt1_.evaluations() + opt2_.evaluations();
158 }
159
160private:
163
166};
167
174template <concepts::multi_variate_objective_function ObjectiveFunction>
175class heuristic_global_optimizer<ObjectiveFunction>
176 : public optimizer_base<heuristic_global_optimizer<ObjectiveFunction>> {
177public:
180
182 using objective_function_type = ObjectiveFunction;
183
185 using variable_type = typename objective_function_type::variable_type;
186
188 using variable_scalar_type = typename variable_type::Scalar;
189
191 using value_type = typename objective_function_type::value_type;
192
200 : optimizer_base<heuristic_global_optimizer<ObjectiveFunction>>(
202 opt1_(obj_fun),
203 opt2_(obj_fun) {
204 opt1_.max_evaluations(default_opt1_max_evaluations);
205 }
206
213 opt1_.change_objective_function(obj_fun);
214 opt2_.change_objective_function(obj_fun);
215 }
216
223 void init(const variable_type& lower, const variable_type& upper) {
224 opt1_.init(lower, upper);
225 current_optimizer_index_ = 1;
226 }
227
231 void iterate() {
232 if (current_optimizer_index_ == 1) {
233 if (!opt1_.is_stop_criteria_satisfied()) {
234 opt1_.iterate();
235 return;
236 }
237 opt2_.init(opt1_.opt_variable());
238 current_optimizer_index_ = 2;
239 }
240 opt2_.iterate();
241 }
242
246 [[nodiscard]] auto is_stop_criteria_satisfied() const -> bool {
247 if (current_optimizer_index_ == 1) {
248 return false;
249 }
250 return opt2_.is_stop_criteria_satisfied();
251 }
252
258 const {
259 iteration_logger.template append<index_type>(
260 "Iter.", &this_type::iterations);
261 iteration_logger.template append<index_type>(
262 "Eval.", &this_type::evaluations);
263 iteration_logger.template append<value_type>(
264 "Value", &this_type::opt_value);
265 iteration_logger.template append<index_type>(
266 "Stage", &this_type::current_optimizer_index);
267 }
268
272 [[nodiscard]] auto opt_variable() const -> const variable_type& {
273 if (current_optimizer_index_ == 1) {
274 return opt1_.opt_variable();
275 }
276 return opt2_.opt_variable();
277 }
278
282 [[nodiscard]] auto opt_value() const -> const value_type& {
283 if (current_optimizer_index_ == 1) {
284 return opt1_.opt_value();
285 }
286 return opt2_.opt_value();
287 }
288
292 [[nodiscard]] auto iterations() const noexcept -> index_type {
293 if (current_optimizer_index_ == 1) {
294 return opt1_.iterations();
295 }
296 return opt1_.iterations() + opt2_.iterations();
297 }
298
302 [[nodiscard]] auto evaluations() const noexcept -> index_type {
303 if (current_optimizer_index_ == 1) {
304 return opt1_.evaluations();
305 }
306 return opt1_.evaluations() + opt2_.evaluations();
307 }
308
317 opt1_.max_evaluations(value);
318 return *this;
319 }
320
329 opt2_.tol_simplex_size(value);
330 return *this;
331 }
332
339 constexpr index_type max_evaluations = 20;
340 opt1_max_evaluations(max_evaluations);
341 return *this;
342 }
343
350 constexpr index_type max_evaluations = default_opt1_max_evaluations;
351 opt1_max_evaluations(max_evaluations);
352 return *this;
353 }
354
361 constexpr index_type max_evaluations = 10000;
362 opt1_max_evaluations(max_evaluations);
363 return *this;
364 }
365
366private:
372 [[nodiscard]] auto current_optimizer_index() const noexcept -> index_type {
373 return current_optimizer_index_;
374 }
375
378
381
383 index_type current_optimizer_index_{1};
384
386 static constexpr index_type default_opt1_max_evaluations = 1000;
387};
388
389} // namespace num_collect::opt
Class of tags of logs without memory management.
Class of dividing rectangles (DIRECT) method jones1993 for optimization.
Class of downhill simplex method.
Class of golden section search method.
Class to perform global optimization in 1 dimension using heuristics.
auto light_mode() -> heuristic_global_optimizer &
Configure this optimizer for easy problems.
typename objective_function_type::value_type value_type
Type of function values.
auto opt1_max_evaluations(index_type value) -> heuristic_global_optimizer &
Set the maximum number of function evaluations in the first optimizer.
auto is_stop_criteria_satisfied() const -> bool
Determine if stopping criteria of the algorithm are satisfied.
auto middle_mode() -> heuristic_global_optimizer &
Configure this optimizer for middle problems.
auto heavy_mode() -> heuristic_global_optimizer &
Configure this optimizer for difficult problems.
dividing_rectangles< ObjectiveFunction > opt1_
First optimizer.
typename objective_function_type::variable_type variable_type
Type of variables.
auto opt_value() const -> const value_type &
Get current optimal value.
ObjectiveFunction objective_function_type
Type of the objective function.
heuristic_global_optimizer(const objective_function_type &obj_fun=objective_function_type())
Constructor.
auto evaluations() const noexcept -> index_type
Get the number of function evaluations.
void configure_iteration_logger(logging::iterations::iteration_logger< this_type > &iteration_logger) const
Configure an iteration logger.
auto current_optimizer_index() const noexcept -> index_type
Get the current optimizer index.
typename variable_type::Scalar variable_scalar_type
Type of scalars in variables.
downhill_simplex< ObjectiveFunction > opt2_
Second optimizer.
sampling_optimizer< objective_function_type > opt1_
First optimizer.
void init(const variable_type &lower, const variable_type &upper)
Initialize the algorithm.
golden_section_search< objective_function_type > opt2_
Second optimizer.
auto opt_variable() const -> const variable_type &
Get current optimal variable.
auto iterations() const noexcept -> index_type
Get the number of iterations.
auto opt2_tol_simplex_size(const variable_scalar_type &value) -> heuristic_global_optimizer &
Set tolerance of size of simplex in the second optimizer.
void change_objective_function(const objective_function_type &obj_fun)
Change the objective function.
Class to perform global optimization using heuristics.
Base class of implementations of optimization algorithms.
Class to perform optimization using samples of objective functions.
Definition of dividing_rectangles class.
Definition of downhill_simplex class.
Definition of golden_section_search class.
Definition of index_type type.
Definition of iteration_logger class.
Definition of log_tag_view class.
Definition of multi_variate_objective_function concept.
std::ptrdiff_t index_type
Type of indices in this library.
Definition index_type.h:33
Namespace of optimization algorithms.
constexpr auto heuristic_global_optimizer_tag
Tag of heuristic_global_optimizer.
Definition of objective_function concept.
Definition of optimizer_base class.
Definition of sampling_optimizer class.
Definition of single_variate_objective_function concept.