INMOST
A toolkit for distributed mathematical modeling
inmost_optimizer.h
1 #ifndef INMOST_INMOST_OPTIMIZER_H
2 #define INMOST_INMOST_OPTIMIZER_H
3 
4 #include "inmost.h"
5 
6 #if defined(USE_OPTIMIZER)
7 
8 #include <vector>
9 #include <algorithm>
10 #include <string>
11 #include <deque>
12 #include <unordered_map>
13 #include <functional>
14 
15 namespace INMOST {
16 
20  enum class OptimizationParameterType {
21  PARAMETER_TYPE_DEFAULT,
22  PARAMETER_TYPE_EXPONENT
23  };
24 
28  class OptimizationParameterPoint {
29  private:
30  std::string name;
31  double value;
32 
33  OptimizationParameterPoint(const std::string &name, double value, OptimizationParameterType type);
34 
35  static void swap(OptimizationParameterPoint &left, OptimizationParameterPoint &right);
36 
37  public:
38  OptimizationParameterPoint(const OptimizationParameterPoint &other);
39 
40  OptimizationParameterPoint(OptimizationParameterPoint &&other) noexcept;
41 
42  OptimizationParameterPoint &operator=(const OptimizationParameterPoint &other);
43 
44  const std::string &GetName() const noexcept;
45 
46  double GetValue() const noexcept;
47 
48  ~OptimizationParameterPoint();
49 
50  static double convert(double value, OptimizationParameterType type);
51 
52  friend class OptimizationParameters;
53  };
54 
59  typedef std::vector<OptimizationParameterPoint> OptimizationParameterPoints;
60 
63  typedef std::pair<double, double> OptimizationParameterRange;
64 
69  class OptimizationParameter {
70  private:
71  std::string name;
72  std::vector<double> values;
73  double default_value;
74  OptimizationParameterType type;
75 
76  static void swap(OptimizationParameter &left, OptimizationParameter &right);
77 
78  public:
85  OptimizationParameter(const std::string &name, const OptimizationParameterRange &range, double step,
86  double default_value, OptimizationParameterType type = OptimizationParameterType::PARAMETER_TYPE_DEFAULT);
87 
93  OptimizationParameter(const std::string &name, const std::vector<double> &values,
94  double default_value, OptimizationParameterType type = OptimizationParameterType::PARAMETER_TYPE_DEFAULT);
95 
98  OptimizationParameter(const OptimizationParameter &other);
99 
102  OptimizationParameter(OptimizationParameter &&other) noexcept;
103 
106  OptimizationParameter &operator=(const OptimizationParameter &other);
107 
109  const std::string &GetName() const noexcept;
110 
112  const std::vector<double> &GetValues() const noexcept;
113 
115  double GetMinimalValue() const noexcept;
116 
118  double GetMaximumValue() const noexcept;
119 
120  double GetMinStrictBound(double v, double modifier = 1.0) const noexcept;
121 
122  double GetMaxStrictBound(double v, double modifier = 1.0) const noexcept;
123 
125  double GetClosestTo(double to) const noexcept;
126 
128  std::size_t GetClosestIndexTo(double to) const noexcept;
129 
131  std::size_t GetValuesCount() const noexcept;
132 
134  double GetDefaultValue() const noexcept;
135 
137  OptimizationParameterType GetType() const noexcept;
138 
139  double ExtractValueFromPoint(const OptimizationParameterPoint &point) const noexcept;
140  };
141 
144  typedef std::pair<OptimizationParameter, double> OptimizationParametersEntry;
145 
149  typedef std::vector<OptimizationParametersEntry> OptimizationParameterEntries;
150 
151  class SuggestionChangedParameter {
152  private:
153  std::size_t index;
154  double value;
155 
156  static void swap(SuggestionChangedParameter &left, SuggestionChangedParameter &right);
157 
158  public:
159  SuggestionChangedParameter(std::size_t index, double value);
160 
161  SuggestionChangedParameter(const SuggestionChangedParameter &other);
162 
163  SuggestionChangedParameter(SuggestionChangedParameter &&other);
164 
165  SuggestionChangedParameter &operator=(const SuggestionChangedParameter &other);
166 
167  std::size_t GetIndex() const noexcept;
168 
169  double GetValue() const noexcept;
170 
171  ~SuggestionChangedParameter();
172  };
173 
174  typedef std::vector<SuggestionChangedParameter> SuggestionChangedParameters;
175 
181  class OptimizationParametersSuggestion {
182  private:
183  SuggestionChangedParameters changed;
184  OptimizationParameterPoints before;
185  double metrics_before;
186  OptimizationParameterPoints after;
187  public:
188  OptimizationParametersSuggestion(const SuggestionChangedParameters &changed,
189  const OptimizationParameterPoints &before, double metrics_before,
190  const OptimizationParameterPoints &after);
191 
192  const SuggestionChangedParameters &GetChangedParameters() const noexcept;
193 
194  const OptimizationParameterPoints &GetPointsBefore() const noexcept;
195 
196  double GetMetricsBefore() const noexcept;
197 
198  const OptimizationParameterPoints &GetPointsAfter() const noexcept;
199  };
200 
203  class OptimizationParameters {
204  private:
205  OptimizationParameterEntries entries;
206  double metrics;
207 
208  static void swap(OptimizationParameters &left, OptimizationParameters &right);
209 
210  public:
214  OptimizationParameters(const OptimizationParameterEntries &entries, double metrics);
215 
218  OptimizationParameters(const OptimizationParameters &other);
219 
222  OptimizationParameters(OptimizationParameters &&other) noexcept;
223 
226  OptimizationParameters &operator=(const OptimizationParameters &other);
227 
229  const OptimizationParameterEntries &GetParameterEntries() const noexcept;
230 
232  const OptimizationParametersEntry &GetParameterEntry(std::size_t index) const;
233 
235  const OptimizationParameter &GetParameter(std::size_t index) const;
236 
238  std::size_t Size() const;
239 
241  const OptimizationParameterPoints GetPoints() const noexcept;
242 
244  double GetMetrics() const noexcept;
245 
247  const OptimizationParameterPoints GetPointsWithChangedParameter(const OptimizationParameter &parameter, double value) const noexcept;
248 
250  const OptimizationParameterPoints GetPointsWithChangedParameters(const SuggestionChangedParameters &changed) const noexcept;
251 
252  void Update(const SuggestionChangedParameters &changed, double metrics);
253 
254  void Update(std::size_t index, double value, double metrics);
255  };
256 
258  class OptimizationParameterResult {
259  private:
260  SuggestionChangedParameters changed;
261  OptimizationParameterPoints before;
262  double metrics_before;
263  OptimizationParameterPoints after;
264  double metrics_after;
265  bool is_good;
266 
267  static void swap(OptimizationParameterResult &left, OptimizationParameterResult &right);
268 
269  public:
271  OptimizationParameterResult(const SuggestionChangedParameters &changed,
272  const OptimizationParameterPoints &before, const OptimizationParameterPoints &after,
273  double metrics_before, double metrics_after, bool is_good);
274 
277  OptimizationParameterResult(const OptimizationParameterResult &other);
278 
281  OptimizationParameterResult(OptimizationParameterResult &&other) noexcept;
282 
285  OptimizationParameterResult &operator=(const OptimizationParameterResult &other);
286 
288  const OptimizationParameterPoints &GetPointsBefore() const noexcept;
289 
291  const OptimizationParameterPoints &GetPointsAfter() const noexcept;
292 
294  double GetMetricsBefore() const noexcept;
295 
297  double GetMetricsAfter() const noexcept;
298 
300  bool IsGood() const noexcept;
301 
303  const SuggestionChangedParameters& GetChangedParameters() const noexcept;
304  };
305 
308  class OptimizationParameterResultsBuffer {
309  private:
310  std::size_t capacity;
311  std::deque<OptimizationParameterResult> buffer;
312 
313  static void swap(OptimizationParameterResultsBuffer &left, OptimizationParameterResultsBuffer &right);
314 
315  public:
318  OptimizationParameterResultsBuffer(std::size_t capacity);
319 
322  OptimizationParameterResultsBuffer(const OptimizationParameterResultsBuffer &other);
323 
326  OptimizationParameterResultsBuffer(OptimizationParameterResultsBuffer &&other) noexcept;
327 
330  OptimizationParameterResultsBuffer &operator=(const OptimizationParameterResultsBuffer &other);
331 
333  std::deque<OptimizationParameterResult>::const_reverse_iterator cbegin() const noexcept;
334 
335  const OptimizationParameterResult &at(std::size_t index) const;
336 
338  std::deque<OptimizationParameterResult>::const_reverse_iterator cend() const noexcept;
339 
343  void push(const OptimizationParameterResult &result);
344 
346  std::size_t size() const noexcept;
347 
349  bool IsEmpty() const noexcept;
350 
352  bool IsLastResultSuccessful() const noexcept;
353 
354  bool IsSuccessfulResultExist() const noexcept;
355 
357  const OptimizationParameterResult &GetLastSuccessfulResult() const;
358 
360  const std::vector<OptimizationParameterResult> GetLastUniqueEntries(std::size_t max) const;
361  };
362 
363  typedef std::map<std::string, std::string> OptimizerProperties;
364 
365  enum class OptimizerVerbosityLevel {
366  Level0,
367  Level1,
368  Level2,
369  Level3
370  };
371 
372  enum class OptimizerRestartStrategy {
373  RESTART_STRATEGY_NO_RESTART,
374  RESTART_STRATEGY_WITH_BEST
375  };
376 
377  typedef std::pair<bool, double> OptimizationFunctionInvokeResult;
378 
379  class OptimizerInterface {
380  private:
381  int mpi_rank;
382 
383  std::string name;
384  OptimizerVerbosityLevel verbosity = OptimizerVerbosityLevel::Level0;
385 
386  OptimizerRestartStrategy restart_strategy = OptimizerRestartStrategy::RESTART_STRATEGY_NO_RESTART;
387  std::size_t max_fails = std::numeric_limits<std::size_t>::max();
388  std::size_t fails_count = 0;
389 
390  std::deque<OptimizationParametersSuggestion> suggestions;
391 
392  void RestartWithBestStrategy();
393 
394  protected:
395  OptimizationParameterResultsBuffer results;
396  OptimizationParameters parameters;
397  const OptimizerProperties properties;
398 
399  virtual bool UpdateSpaceWithLatestResults();
400 
401  virtual SuggestionChangedParameters AlgorithmMakeSuggestion() const = 0;
402 
403  public:
404  OptimizerInterface(const std::string &name, const OptimizationParameters &parameters, const OptimizerProperties &properties, std::size_t buffer_capacity) :
405  name(name), parameters(parameters), properties(properties), results(buffer_capacity), mpi_rank(0) {
406 #ifdef USE_MPI
407  MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
408 #endif
409  };
410 
411  OptimizationParametersSuggestion Suggest();
412 
413  void SaveResult(const SuggestionChangedParameters &changed,
414  const OptimizationParameterPoints &before, double metrics_before,
415  const OptimizationParameterPoints &after, double metrics_after, bool is_good);
416 
417  void SaveResult(const SuggestionChangedParameters &changed, const OptimizationParameterPoints &after, double metrics_after, bool is_good);
418 
419  void SaveResult(const OptimizationParametersSuggestion &suggestion, double metrics, bool is_good);
420 
421  const OptimizationParameterResultsBuffer &GetResults() const noexcept;
422 
423  const OptimizationParameterPoints GetPoints() const noexcept;
424 
425  void SetVerbosityLevel(OptimizerVerbosityLevel level) noexcept;
426 
427  OptimizerVerbosityLevel GetVerbosityLevel() const noexcept;
428 
429  bool HasProperty(const std::string &name) const noexcept;
430 
431  const std::string &GetProperty(const std::string &name) const;
432 
433  const OptimizationParametersSuggestion &GetLastSuggestion() const;
434 
435  void SetRestartStrategy(OptimizerRestartStrategy strategy, std::size_t max_fails) noexcept;
436 
437  const std::string &GetName() const noexcept;
438 
439  virtual ~OptimizerInterface() {};
440  };
441 
442  typedef std::unordered_map<std::string, OptimizerInterface *> SavedOptimizersMap;
443 
444  class Optimizers {
445  private:
446  static SavedOptimizersMap optimizers;
447 
448  Optimizers() = delete;
449  public:
450  static bool IsOptimizerAvailable(const std::string &type);
451 
452  static std::vector<std::string> GetAvailableOptimizers();
453 
454  static OptimizerInterface *GetOptimizer(const std::string &name, const std::string &type,
455  const OptimizationParameters &parameters, const OptimizerProperties &properties, std::size_t buffer_capacity);
456 
457  static void SaveOptimizerOrReplace(const std::string &name, const std::string &type,
458  const OptimizationParameters &parameters, const OptimizerProperties &properties, std::size_t buffer_capacity);
459 
460  static void SaveOptimizerOrReplace(const std::string &name, const std::string &type, const OptimizerProperties &properties, std::size_t buffer_capacity);
461 
462  static OptimizerInterface *GetSavedOptimizer(const std::string &name);
463  };
464 
465  class OptimizersConfiguration {
466  private:
467  enum class OptimizerConfigurationReaderState {
468  READ_GLOBAL_PARAMETER
469  };
470 
471  static std::vector<OptimizationParameter> global_parameters;
472 
473  OptimizersConfiguration() = delete;
474 
475  static OptimizationParameter ParseOptimizationParameter(const std::string &line);
476  public:
477  static void FromFile(const std::string &path);
478 
479  static void FromStream(std::istream &stream);
480 
481  static OptimizationParameters GetGlobalOptimizationParameters();
482  };
483 
484 };
485 
486 #endif
487 
488 #endif //INMOST_INMOST_OPTIMIZER_H