-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathgurobi_model.hpp
328 lines (279 loc) · 11.8 KB
/
gurobi_model.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
#pragma once
#include <memory>
#include "solvers/gurobi/gurobi_c.h"
#include "pyoptinterface/core.hpp"
#include "pyoptinterface/container.hpp"
#include "pyoptinterface/solver_common.hpp"
#include "pyoptinterface/dylib.hpp"
// define Gurobi C APIs
#define APILIST \
B(GRBnewmodel); \
B(GRBfreemodel); \
B(GRBgetenv); \
B(GRBwrite); \
B(GRBaddvar); \
B(GRBdelvars); \
B(GRBaddconstr); \
B(GRBaddqconstr); \
B(GRBaddsos); \
B(GRBdelconstrs); \
B(GRBdelqconstrs); \
B(GRBdelsos); \
B(GRBdelq); \
B(GRBsetdblattrarray); \
B(GRBaddqpterms); \
B(GRBoptimize); \
B(GRBupdatemodel); \
B(GRBgetparamtype); \
B(GRBsetintparam); \
B(GRBsetdblparam); \
B(GRBsetstrparam); \
B(GRBgetintparam); \
B(GRBgetdblparam); \
B(GRBgetstrparam); \
B(GRBgetattrinfo); \
B(GRBsetintattr); \
B(GRBsetdblattr); \
B(GRBsetstrattr); \
B(GRBgetintattr); \
B(GRBgetdblattr); \
B(GRBgetstrattr); \
B(GRBgetdblattrarray); \
B(GRBgetdblattrlist); \
B(GRBsetintattrelement); \
B(GRBsetcharattrelement); \
B(GRBsetdblattrelement); \
B(GRBsetstrattrelement); \
B(GRBgetintattrelement); \
B(GRBgetcharattrelement); \
B(GRBgetdblattrelement); \
B(GRBgetstrattrelement); \
B(GRBgetcoeff); \
B(GRBchgcoeffs); \
B(GRBgeterrormsg); \
B(GRBversion); \
B(GRBsetcallbackfunc); \
B(GRBcbget); \
B(GRBcbproceed); \
B(GRBterminate); \
B(GRBcbsolution); \
B(GRBcblazy); \
B(GRBcbcut); \
B(GRBemptyenv); \
B(GRBloadenv); \
B(GRBfreeenv); \
B(GRBstartenv); \
B(GRBconverttofixed); \
B(GRBcomputeIIS);
namespace gurobi
{
#define B DYLIB_EXTERN_DECLARE
APILIST
#undef B
bool is_library_loaded();
bool load_library(const std::string &path);
} // namespace gurobi
class GurobiEnv
{
public:
GurobiEnv(bool empty = false);
~GurobiEnv();
// parameter
int raw_parameter_type(const char *param_name);
void set_raw_parameter_int(const char *param_name, int value);
void set_raw_parameter_double(const char *param_name, double value);
void set_raw_parameter_string(const char *param_name, const char *value);
void start();
void close();
void check_error(int error);
private:
GRBenv *m_env = nullptr;
friend class GurobiModel;
};
struct GRBfreemodelT
{
void operator()(GRBmodel *model) const
{
gurobi::GRBfreemodel(model);
};
};
class GurobiModel;
using GurobiCallback = std::function<void(GurobiModel *, int)>;
struct GurobiCallbackUserdata
{
void *model = nullptr;
GurobiCallback callback;
int n_variables = 0;
int where = 0;
// store result of cbget
bool cb_get_mipsol_called = false;
std::vector<double> mipsol;
bool cb_get_mipnoderel_called = false;
std::vector<double> mipnoderel;
// Cache for cbsolution
bool cb_set_solution_called = false;
std::vector<double> heuristic_solution;
bool cb_requires_submit_solution = false;
};
class GurobiModel
{
public:
GurobiModel() = default;
GurobiModel(const GurobiEnv &env);
void init(const GurobiEnv &env);
void close();
void write(const std::string &filename);
VariableIndex add_variable(VariableDomain domain = VariableDomain::Continuous,
double lb = -GRB_INFINITY, double ub = GRB_INFINITY,
const char *name = nullptr);
void delete_variable(const VariableIndex &variable);
void delete_variables(const Vector<VariableIndex> &variables);
bool is_variable_active(const VariableIndex &variable);
double get_variable_value(const VariableIndex &variable);
std::string pprint_variable(const VariableIndex &variable);
void set_variable_bounds(const VariableIndex &variable, double lb, double ub);
void set_variable_name(const VariableIndex &variable, const char *name);
void set_constraint_name(const ConstraintIndex &constraint, const char *name);
ConstraintIndex add_linear_constraint(const ScalarAffineFunction &function,
ConstraintSense sense, CoeffT rhs,
const char *name = nullptr);
ConstraintIndex add_quadratic_constraint(const ScalarQuadraticFunction &function,
ConstraintSense sense, CoeffT rhs,
const char *name = nullptr);
ConstraintIndex add_sos_constraint(const Vector<VariableIndex> &variables, SOSType sos_type);
ConstraintIndex add_sos_constraint(const Vector<VariableIndex> &variables, SOSType sos_type,
const Vector<CoeffT> &weights);
void delete_constraint(const ConstraintIndex &constraint);
bool is_constraint_active(const ConstraintIndex &constraint);
void _set_affine_objective(const ScalarAffineFunction &function, ObjectiveSense sense,
bool clear_quadratic);
void set_objective(const ScalarAffineFunction &function, ObjectiveSense sense);
void set_objective(const ScalarQuadraticFunction &function, ObjectiveSense sense);
void set_objective(const ExprBuilder &function, ObjectiveSense sense);
void optimize();
void update();
void *get_raw_model();
std::string version_string();
// parameter
int raw_parameter_type(const char *param_name);
void set_raw_parameter_int(const char *param_name, int value);
void set_raw_parameter_double(const char *param_name, double value);
void set_raw_parameter_string(const char *param_name, const char *value);
int get_raw_parameter_int(const char *param_name);
double get_raw_parameter_double(const char *param_name);
std::string get_raw_parameter_string(const char *param_name);
// attribute
int raw_attribute_type(const char *attr_name);
// model attribute
void set_model_raw_attribute_int(const char *attr_name, int value);
void set_model_raw_attribute_double(const char *attr_name, double value);
void set_model_raw_attribute_string(const char *attr_name, const char *value);
int get_model_raw_attribute_int(const char *attr_name);
double get_model_raw_attribute_double(const char *attr_name);
std::string get_model_raw_attribute_string(const char *attr_name);
std::vector<double> get_model_raw_attribute_vector_double(const char *attr_name, int start,
int len);
std::vector<double> get_model_raw_attribute_list_double(const char *attr_name,
const std::vector<int> &ind);
// variable attribute
void set_variable_raw_attribute_int(const VariableIndex &variable, const char *attr_name,
int value);
void set_variable_raw_attribute_char(const VariableIndex &variable, const char *attr_name,
char value);
void set_variable_raw_attribute_double(const VariableIndex &variable, const char *attr_name,
double value);
void set_variable_raw_attribute_string(const VariableIndex &variable, const char *attr_name,
const char *value);
int get_variable_raw_attribute_int(const VariableIndex &variable, const char *attr_name);
char get_variable_raw_attribute_char(const VariableIndex &variable, const char *attr_name);
double get_variable_raw_attribute_double(const VariableIndex &variable, const char *attr_name);
std::string get_variable_raw_attribute_string(const VariableIndex &variable,
const char *attr_name);
int _variable_index(const VariableIndex &variable);
int _checked_variable_index(const VariableIndex &variable);
// constraint attribute
void set_constraint_raw_attribute_int(const ConstraintIndex &constraint, const char *attr_name,
int value);
void set_constraint_raw_attribute_char(const ConstraintIndex &constraint, const char *attr_name,
char value);
void set_constraint_raw_attribute_double(const ConstraintIndex &constraint,
const char *attr_name, double value);
void set_constraint_raw_attribute_string(const ConstraintIndex &constraint,
const char *attr_name, const char *value);
int get_constraint_raw_attribute_int(const ConstraintIndex &constraint, const char *attr_name);
char get_constraint_raw_attribute_char(const ConstraintIndex &constraint,
const char *attr_name);
double get_constraint_raw_attribute_double(const ConstraintIndex &constraint,
const char *attr_name);
std::string get_constraint_raw_attribute_string(const ConstraintIndex &constraint,
const char *attr_name);
int _constraint_index(const ConstraintIndex &constraint);
int _checked_constraint_index(const ConstraintIndex &constraint);
// Modifications of model
// 1. set/get RHS of a constraint
double get_normalized_rhs(const ConstraintIndex &constraint);
void set_normalized_rhs(const ConstraintIndex &constraint, double value);
// 2. set/get coefficient of variable in constraint
double get_normalized_coefficient(const ConstraintIndex &constraint,
const VariableIndex &variable);
void set_normalized_coefficient(const ConstraintIndex &constraint,
const VariableIndex &variable, double value);
// 3. set/get linear coefficient of variable in objective
double get_objective_coefficient(const VariableIndex &variable);
void set_objective_coefficient(const VariableIndex &variable, double value);
// Gurobi-specific convertofixed
void _converttofixed();
// IIS related
void computeIIS();
// Non-exported functions
void check_error(int error);
// Callback
void set_callback(const GurobiCallback &callback);
// For callback
bool has_callback = false;
void *m_cbdata = nullptr;
GurobiCallbackUserdata m_callback_userdata;
int cb_get_info_int(int what);
double cb_get_info_double(int what);
void cb_get_info_doublearray(int what);
double cb_get_solution(const VariableIndex &variable);
double cb_get_relaxation(const VariableIndex &variable);
void cb_set_solution(const VariableIndex &variable, double value);
double cb_submit_solution();
void cb_exit();
void cb_add_lazy_constraint(const ScalarAffineFunction &function, ConstraintSense sense,
CoeffT rhs);
void cb_add_lazy_constraint(const ExprBuilder &function, ConstraintSense sense, CoeffT rhs);
void cb_add_user_cut(const ScalarAffineFunction &function, ConstraintSense sense, CoeffT rhs);
void cb_add_user_cut(const ExprBuilder &function, ConstraintSense sense, CoeffT rhs);
private:
MonotoneIndexer<int> m_variable_index;
MonotoneIndexer<int> m_linear_constraint_index;
MonotoneIndexer<int> m_quadratic_constraint_index;
MonotoneIndexer<int> m_sos_constraint_index;
/* flag to indicate whether the model needs update */
enum : std::uint64_t
{
m_variable_creation = 1,
m_variable_deletion = 1 << 1,
m_linear_constraint_creation = 1 << 2,
m_linear_constraint_deletion = 1 << 3,
m_quadratic_constraint_creation = 1 << 4,
m_quadratic_constraint_deletion = 1 << 5,
m_sos_constraint_creation = 1 << 6,
m_sos_constraint_deletion = 1 << 7,
m_general_constraint_creation = 1 << 8,
m_general_constraint_deletion = 1 << 9,
m_objective_update = 1 << 10,
m_attribute_update = 1 << 11,
m_constraint_coefficient_update = 1 << 12,
};
std::uint64_t m_update_flag = 0;
void _update_for_information();
void _update_for_variable_index();
void _update_for_constraint_index(ConstraintType type);
/* Gurobi part */
GRBenv *m_env = nullptr;
std::unique_ptr<GRBmodel, GRBfreemodelT> m_model;
};
using GurobiModelMixin = CommercialSolverMixin<GurobiModel>;