Loading...
Searching...
No Matches
Optimizer.h
1//
2// Created by henri on 31/01/23.
3//
4
5#ifndef IDOL_OPTIMIZER_H
6#define IDOL_OPTIMIZER_H
7
8#include <cassert>
9#include <string>
10#include <optional>
11
12#include "Timer.h"
13#include "idol/general/numericals.h"
14#include "idol/general/utils/types.h"
15
16namespace idol {
17 class Model;
18 class Var;
19 class Ctr;
20 class QCtr;
21 class SOSCtr;
22
23 namespace impl {
24 class Optimizer;
25 }
26
27 class Optimizer;
28}
29
30class idol::impl::Optimizer {
31 const ::idol::Model& m_parent;
32
33 bool m_is_terminated = false;
34
35 unsigned int m_param_threads = 1;
36 unsigned int m_param_iteration_limit = std::numeric_limits<unsigned int>::max();
37
38 bool m_param_logs = false;
39 double m_param_time_limit = std::numeric_limits<double>::max();
40 std::optional<double> m_param_best_obj_stop;
41 std::optional<double> m_param_best_bound_stop;
42 bool m_param_presolve = true;
43 bool m_param_infeasible_or_unbounded_info = false;
44
45 std::optional<double> m_tol_mip_relative_gap;
46 std::optional<double> m_tol_mip_absolute_gap;
47 std::optional<double> m_tol_integer;
48 std::optional<double> m_tol_feasibility;
49 std::optional<double> m_tol_optimality;
50
51 Timer m_timer;
52protected:
53 virtual void build() = 0;
54
55 virtual void add(const Var& t_var) = 0;
56 virtual void add(const Ctr& t_ctr) = 0;
57 virtual void add(const QCtr& t_ctr) = 0;
58 virtual void add(const SOSCtr& t_ctr) {
59 throw Exception("SOS constraints are not supported by this optimizer.");
60 }
61
62 virtual void remove(const Var& t_var) = 0;
63 virtual void remove(const Ctr& t_ctr) = 0;
64 virtual void remove(const QCtr& t_ctr) = 0;
65 virtual void remove(const SOSCtr& t_ctr) {
66 throw Exception("SOS constraints are not supported by this optimizer.");
67 }
68
69 virtual void update() = 0;
70
71 virtual void write(const std::string& t_name) = 0;
72
73 void optimize();
74
75 virtual void hook_before_optimize() {}
76
77 virtual void hook_optimize() = 0;
78
79 virtual void hook_after_optimize() {}
80
81 virtual void set_solution_index(unsigned int t_index) = 0;
82
83 virtual void update_obj_sense() = 0;
84
85 virtual void update_obj() = 0;
86
87 virtual void update_rhs() = 0;
88
89 virtual void update_obj_constant() = 0;
90
91 virtual void update_mat_coeff(const Ctr& t_ctr, const Var& t_var) = 0;
92
93 virtual void update_ctr_type(const Ctr& t_ctr) = 0;
94
95 virtual void update_ctr_rhs(const Ctr& t_ctr) = 0;
96
97 virtual void update_var_type(const Var& t_var) = 0;
98
99 virtual void update_var_lb(const Var& t_var) = 0;
100
101 virtual void update_var_ub(const Var& t_var) = 0;
102
103 virtual void update_var_obj(const Var& t_var) = 0;
104public:
105 explicit Optimizer(const ::idol::Model& t_parent);
106
107 virtual ~Optimizer() = default;
108
109 [[nodiscard]] virtual std::string name() const = 0;
110
111 [[nodiscard]] virtual const ::idol::Model& parent() const { return m_parent; }
112
113 [[nodiscard]] virtual SolutionStatus get_status() const = 0;
114
115 [[nodiscard]] virtual SolutionReason get_reason() const = 0;
116
117 [[nodiscard]] virtual double get_best_obj() const = 0;
118
119 [[nodiscard]] virtual double get_best_bound() const = 0;
120
121 [[nodiscard]] virtual double get_var_primal(const Var& t_var) const = 0;
122
123 [[nodiscard]] virtual double get_var_reduced_cost(const Var& t_var) const = 0;
124
125 [[nodiscard]] virtual double get_var_ray(const Var& t_var) const = 0;
126
127 [[nodiscard]] virtual double get_ctr_dual(const Ctr& t_ctr) const = 0;
128
129 [[nodiscard]] virtual double get_ctr_farkas(const Ctr& t_ctr) const = 0;
130
131 [[nodiscard]] virtual double get_relative_gap() const = 0;
132
133 [[nodiscard]] virtual double get_absolute_gap() const = 0;
134
135 [[nodiscard]] virtual unsigned int get_n_solutions() const = 0;
136
137 [[nodiscard]] virtual unsigned int get_solution_index() const = 0;
138
139 [[nodiscard]] bool get_param_logs() const { return m_param_logs; }
140
141 virtual void set_param_logs(bool t_value) { m_param_logs = t_value; }
142
143 [[nodiscard]] double get_param_time_limit() const { return m_param_time_limit; }
144
145 virtual void set_param_time_limit(double t_time_limit) { m_param_time_limit = t_time_limit; }
146
147 [[nodiscard]] unsigned int get_param_thread_limit() const { return m_param_threads; }
148
149 virtual void set_param_threads(unsigned int t_threads) { m_param_threads = t_threads; }
150
151 [[nodiscard]] double get_param_best_obj_stop() const;
152
153 virtual void set_param_best_obj_stop(double t_best_obj_stop) { m_param_best_obj_stop = t_best_obj_stop; }
154
155 [[nodiscard]] double get_param_best_bound_stop() const;
156
157 virtual void set_param_best_bound_stop(double t_best_bound_stop) { m_param_best_bound_stop = t_best_bound_stop; }
158
159 [[nodiscard]] double get_tol_mip_relative_gap() const { assert(m_tol_mip_relative_gap); return *m_tol_mip_relative_gap; }
160
161 virtual void set_tol_mip_relative_gap(double t_tol_mip_relative_gap) { m_tol_mip_relative_gap = t_tol_mip_relative_gap; }
162
163 [[nodiscard]] double get_tol_mip_absolute_gap() const { assert(m_tol_mip_absolute_gap); return *m_tol_mip_absolute_gap; }
164
165 virtual void set_tol_mip_absolute_gap(double t_mip_tol_absolute_gap) { m_tol_mip_absolute_gap = t_mip_tol_absolute_gap; }
166
167 [[nodiscard]] double get_tol_feasibility() const { assert(m_tol_feasibility); return *m_tol_feasibility; }
168
169 virtual void set_tol_feasibility(double t_tol_feasibility) { m_tol_feasibility = t_tol_feasibility; }
170
171 [[nodiscard]] double get_tol_optimality() const { assert(m_tol_optimality); return *m_tol_optimality; }
172
173 virtual void set_tol_optimality(double t_tol_optimality) { m_tol_optimality = t_tol_optimality; }
174
175 [[nodiscard]] double get_tol_integer() const { assert(m_tol_integer); return *m_tol_integer; }
176
177 virtual void set_tol_integer(double t_tol_integer) { m_tol_integer = t_tol_integer; }
178
179 [[nodiscard]] unsigned int get_param_iteration_limit() const { return m_param_iteration_limit; }
180
181 void set_param_iteration_limit(unsigned int t_iteration_limit) { m_param_iteration_limit = t_iteration_limit; }
182
183 [[nodiscard]] bool get_param_presolve() const { return m_param_presolve; }
184
185 virtual void set_param_presolve(bool t_value) { m_param_presolve = t_value; }
186
187 [[nodiscard]] bool get_param_infeasible_or_unbounded_info() const { return m_param_infeasible_or_unbounded_info; }
188
189 virtual void set_param_infeasible_or_unbounded_info(bool t_value) { m_param_infeasible_or_unbounded_info = t_value; }
190
191 [[nodiscard]] const Timer& time() const { return m_timer; }
192
193 [[nodiscard]] double get_remaining_time() const;
194
195 [[nodiscard]] bool is_terminated() const { return m_is_terminated; }
196
197 virtual void terminate();
198
199 template<class T> T& as() {
200 auto* result = dynamic_cast<T*>(this);
201 if (!result) {
202 throw Exception("Optimizer could not be cast to desired type.");
203 }
204 return *result;
205 }
206
207 template<class T> const T& as() const {
208 auto* result = dynamic_cast<const T*>(this);
209 if (!result) {
210 throw Exception("Optimizer could not be cast to desired type.");
211 }
212 return *result;
213 }
214
215 template<class T> [[nodiscard]] bool is() const {
216 return dynamic_cast<const T*>(this);
217 }
218};
219
220class idol::Optimizer : public impl::Optimizer {
221 friend class Model;
222public:
223 explicit Optimizer(const ::idol::Model& t_parent);
224};
225
226#endif //IDOL_OPTIMIZER_H