Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
g_gurobi.cc
Go to the documentation of this file.
1// Copyright 2010-2024 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
15
16#include <memory>
17#include <optional>
18#include <string>
19#include <utility>
20#include <vector>
21
22#include "absl/log/check.h"
23#include "absl/log/die_if_null.h"
24#include "absl/memory/memory.h"
25#include "absl/status/status.h"
26#include "absl/status/statusor.h"
27#include "absl/strings/str_format.h"
28#include "absl/types/span.h"
35#include "ortools/math_opt/solvers/gurobi.pb.h"
36
38
39namespace {
40constexpr int kGrbOk = 0;
41
42struct UserCallbackData {
44 absl::Status status = absl::OkStatus();
45 Gurobi* gurobi = nullptr;
46};
47
48int GUROBI_STDCALL GurobiCallback(GRBmodel* const model, void* const cbdata,
49 const int where, void* const usrdata) {
50 CHECK(usrdata != nullptr);
51 CHECK(model != nullptr);
52 auto user_cb_data = static_cast<UserCallbackData*>(usrdata);
53 CHECK_EQ(model, user_cb_data->gurobi->model());
54 // NOTE: if a previous callback failed, we never run the callback again.
55 if (!user_cb_data->status.ok()) {
56 return GRB_ERROR_CALLBACK;
57 }
58 const Gurobi::CallbackContext context(user_cb_data->gurobi, cbdata, where);
59 user_cb_data->status = user_cb_data->user_cb(context);
60 if (!user_cb_data->status.ok()) {
61 user_cb_data->gurobi->Terminate();
62 return GRB_ERROR_CALLBACK;
63 }
64 return kGrbOk;
65}
66
67// A class for handling callback management (setting/unsetting) and their
68// associated errors. Users create this handler to register their callback, do
69// something, then call `Flush()` to flush errors returned from the callback,
70// and then finally call `Release()` to clear the registered callback. This
71// class uses RAII to attempt to automatically clear the callback if your code
72// returns prior to calling `Release()` manually, but note that this does not
73// propagate any errors if it fails.
74
75// A typical use case would be:
76//
77// ASSIGN_OR_RETURN(const auto scope, ScopedCallback::New(this, std::move(cb)));
78// const int error = GRBxxx(gurobi_model_);
79// RETURN_IF_ERROR(scope->Flush());
80// RETURN_IF_ERROR(ToStatus(error));
81// return scope->Release();
82class ScopedCallback {
83 public:
84 ScopedCallback(const ScopedCallback&) = delete;
85 ScopedCallback& operator=(const ScopedCallback&) = delete;
86 ScopedCallback(ScopedCallback&&) = delete;
87 ScopedCallback& operator=(ScopedCallback&&) = delete;
88
89 // Returned object retains a pointer to `gurobi`, which must not be null.
90 static absl::StatusOr<std::unique_ptr<ScopedCallback>> New(
91 Gurobi* const gurobi, Gurobi::Callback cb) {
92 CHECK(gurobi != nullptr);
93 auto scope = absl::WrapUnique(new ScopedCallback(gurobi));
94 if (cb != nullptr) {
95 scope->user_cb_data_.user_cb = std::move(cb);
96 scope->user_cb_data_.gurobi = gurobi;
98 gurobi->model(), GurobiCallback, &scope->user_cb_data_)));
99 scope->needs_cleanup_ = true;
100 }
101 return scope;
102 }
103
104 // Propagates any errors returned from the callback.
105 absl::Status Flush() {
106 const absl::Status status = std::move(user_cb_data_.status);
107 user_cb_data_.status = absl::OkStatus();
108 return status;
109 }
110
111 // Clears the registered callback.
112 absl::Status Release() {
113 if (needs_cleanup_) {
114 needs_cleanup_ = false;
115 return gurobi_->ToStatus(
116 GRBsetcallbackfunc(gurobi_->model(), nullptr, nullptr));
117 }
118 return absl::OkStatus();
119 }
120
121 ~ScopedCallback() {
122 if (const absl::Status s = Flush(); !s.ok()) {
123 LOG(ERROR) << "Error returned from callback: " << s;
124 }
125 if (const absl::Status s = Release(); !s.ok()) {
126 LOG(ERROR) << "Error cleaning up callback: " << s;
127 }
128 }
129
130 private:
131 explicit ScopedCallback(Gurobi* const gurobi) : gurobi_(gurobi) {}
132
133 bool needs_cleanup_ = false;
134 Gurobi* gurobi_;
135 UserCallbackData user_cb_data_;
136};
137
138// Returns true if both keys are equal.
139bool AreISVKeyEqual(const GurobiIsvKey& key,
140 const GurobiInitializerProto::ISVKey& proto_key) {
141 return key.name == proto_key.name() &&
142 key.application_name == proto_key.application_name() &&
143 key.expiration == proto_key.expiration() && key.key == proto_key.key();
144}
145
146} // namespace
147
148void GurobiFreeEnv::operator()(GRBenv* const env) const {
149 if (env != nullptr) {
150 GRBfreeenv(env);
151 }
152}
153
154absl::StatusOr<GRBenvUniquePtr> GurobiNewPrimaryEnv(
155 const std::optional<GurobiIsvKey>& isv_key) {
156 if (isv_key.has_value()) {
157 ASSIGN_OR_RETURN(GRBenv* const naked_primary_env,
158 NewPrimaryEnvFromISVKey(*isv_key));
159 return GRBenvUniquePtr(naked_primary_env);
160 }
161 GRBenv* naked_primary_env = nullptr;
162 const int err = GRBloadenv(&naked_primary_env, /*logfilename=*/nullptr);
163 // Surprisingly, Gurobi will still create an environment if initialization
164 // fails, so we want this wrapper even in the error case to free it properly.
165 GRBenvUniquePtr primary_env(naked_primary_env);
166 if (err == kGrbOk) {
167 return primary_env;
168 }
170 << "failed to create Gurobi primary environment, GRBloadenv() "
171 "returned the error ("
172 << err << "): " << GRBgeterrormsg(primary_env.get());
173}
174
175absl::StatusOr<std::unique_ptr<Gurobi>> Gurobi::NewWithSharedPrimaryEnv(
176 GRBenv* const primary_env) {
177 CHECK(primary_env != nullptr);
178 return New(nullptr, primary_env);
179}
180
181absl::StatusOr<std::unique_ptr<Gurobi>> Gurobi::New(
182 GRBenvUniquePtr primary_env) {
183 if (primary_env == nullptr) {
185 }
186 GRBenv* const raw_primary_env = primary_env.get();
187 return New(std::move(primary_env), raw_primary_env);
188}
189
190Gurobi::Gurobi(GRBenvUniquePtr optional_owned_primary_env,
191 GRBmodel* const model, GRBenv* const model_env)
192 : owned_primary_env_(std::move(optional_owned_primary_env)),
193 gurobi_model_(ABSL_DIE_IF_NULL(model)),
194 model_env_(ABSL_DIE_IF_NULL(model_env)) {}
195
196absl::StatusOr<std::unique_ptr<Gurobi>> Gurobi::New(
197 GRBenvUniquePtr optional_owned_primary_env, GRBenv* const primary_env) {
198 CHECK(primary_env != nullptr);
199 GRBmodel* model = nullptr;
200 const int err = GRBnewmodel(primary_env, &model,
201 /*Pname=*/nullptr,
202 /*numvars=*/0,
203 /*obj=*/nullptr, /*lb=*/nullptr,
204 /*ub=*/nullptr, /*vtype=*/nullptr,
205 /*varnames=*/nullptr);
206 if (err != kGrbOk) {
208 << "Error creating gurobi model on GRBnewmodel(), error code: "
209 << err << " message: " << GRBgeterrormsg(primary_env);
210 }
211 CHECK(model != nullptr);
212 GRBenv* const model_env = GRBgetenv(model);
213
214 if (VLOG_IS_ON(3)) {
215 int gurobi_major, gurobi_minor, gurobi_technical;
216 GRBversion(&gurobi_major, &gurobi_minor, &gurobi_technical);
217 VLOG(3) << absl::StrFormat(
218 "Successfully created model for Gurobi v%d.%d.%d (%s)", gurobi_major,
219 gurobi_minor, gurobi_technical, GRBplatform());
220 }
221 return absl::WrapUnique(
222 new Gurobi(std::move(optional_owned_primary_env), model, model_env));
223}
224
226 const int err = GRBfreemodel(gurobi_model_);
227 if (err != kGrbOk) {
228 LOG(ERROR) << "Error freeing gurobi model, code: " << err
229 << ", message: " << GRBgeterrormsg(model_env_);
230 }
231}
232
233absl::Status Gurobi::ToStatus(const int grb_err, const absl::StatusCode code,
234 const absl::SourceLocation loc) const {
235 if (grb_err == kGrbOk) {
236 return absl::OkStatus();
237 }
238
239 return util::StatusBuilder(code)
240 << "Gurobi error code: " << grb_err
241 << ", message: " << GRBgeterrormsg(model_env_);
242}
243
244absl::Status Gurobi::AddVar(const double obj, const double lb, const double ub,
245 const char vtype, const std::string& name) {
246 return AddVar({}, {}, obj, lb, ub, vtype, name);
247}
248
249absl::Status Gurobi::AddVar(const absl::Span<const int> vind,
250 const absl::Span<const double> vval,
251 const double obj, const double lb, const double ub,
252 const char vtype, const std::string& name) {
253 CHECK_EQ(vind.size(), vval.size());
254 const int numnz = static_cast<int>(vind.size());
255 return ToStatus(GRBaddvar(/*model=*/gurobi_model_, /*numnz=*/numnz,
256 /*vind=*/const_cast<int*>(vind.data()),
257 /*vval=*/const_cast<double*>(vval.data()),
258 /*obj=*/obj,
259 /*lb=*/lb,
260 /*ub=*/ub,
261 /*vtype=*/vtype,
262 /*varname=*/name.empty() ? nullptr : name.data()));
263}
264
265absl::Status Gurobi::AddVars(const absl::Span<const double> obj,
266 const absl::Span<const double> lb,
267 const absl::Span<const double> ub,
268 const absl::Span<const char> vtype,
269 const absl::Span<const std::string> names) {
270 return AddVars({}, {}, {}, obj, lb, ub, vtype, names);
271}
272
273absl::Status Gurobi::AddVars(const absl::Span<const int> vbegin,
274 const absl::Span<const int> vind,
275 const absl::Span<const double> vval,
276 const absl::Span<const double> obj,
277 const absl::Span<const double> lb,
278 const absl::Span<const double> ub,
279 const absl::Span<const char> vtype,
280 const absl::Span<const std::string> names) {
281 CHECK_EQ(vind.size(), vval.size());
282 const int num_vars = static_cast<int>(lb.size());
283 CHECK_EQ(ub.size(), num_vars);
284 CHECK_EQ(vtype.size(), num_vars);
285 double* c_obj = nullptr;
286 if (!obj.empty()) {
287 CHECK_EQ(obj.size(), num_vars);
288 c_obj = const_cast<double*>(obj.data());
289 }
290 if (!vbegin.empty()) {
291 CHECK_EQ(vbegin.size(), num_vars);
292 }
293 char** c_names = nullptr;
294 std::vector<char*> c_names_data;
295 if (!names.empty()) {
296 CHECK_EQ(num_vars, names.size());
297 for (const std::string& name : names) {
298 c_names_data.push_back(const_cast<char*>(name.c_str()));
299 }
300 c_names = c_names_data.data();
301 }
302 return ToStatus(GRBaddvars(/*model=*/gurobi_model_, /*numvars=*/num_vars,
303 /*numnz=*/vind.size(),
304 /*vbeg=*/const_cast<int*>(vbegin.data()),
305 /*vind=*/const_cast<int*>(vind.data()),
306 /*vval=*/const_cast<double*>(vval.data()),
307 /*obj=*/c_obj,
308 /*lb=*/const_cast<double*>(lb.data()),
309 /*ub=*/const_cast<double*>(ub.data()),
310 /*vtype=*/const_cast<char*>(vtype.data()),
311 /*varnames=*/c_names));
312}
313
314absl::Status Gurobi::DelVars(const absl::Span<const int> ind) {
315 return ToStatus(
316 GRBdelvars(gurobi_model_, ind.size(), const_cast<int*>(ind.data())));
317}
318
319absl::Status Gurobi::AddConstr(const char sense, const double rhs,
320 const std::string& name) {
321 return AddConstr({}, {}, sense, rhs, name);
322}
323
324absl::Status Gurobi::AddConstr(const absl::Span<const int> cind,
325 const absl::Span<const double> cval,
326 const char sense, const double rhs,
327 const std::string& name) {
328 CHECK_EQ(cind.size(), cval.size());
329 const int numnz = static_cast<int>(cind.size());
330 return ToStatus(
331 GRBaddconstr(/*model=*/gurobi_model_, /*numnz=*/numnz,
332 /*cind=*/const_cast<int*>(cind.data()),
333 /*cval=*/const_cast<double*>(cval.data()),
334 /*sense=*/sense,
335 /*rhs=*/rhs,
336 /*constrname=*/name.empty() ? nullptr : name.data()));
337}
338
339absl::Status Gurobi::AddConstrs(const absl::Span<const char> sense,
340 const absl::Span<const double> rhs,
341 const absl::Span<const std::string> names) {
342 const int num_cons = static_cast<int>(sense.size());
343 CHECK_EQ(rhs.size(), num_cons);
344 char** c_names = nullptr;
345 std::vector<char*> c_names_data;
346 if (!names.empty()) {
347 CHECK_EQ(num_cons, names.size());
348 for (const std::string& name : names) {
349 c_names_data.push_back(const_cast<char*>(name.c_str()));
350 }
351 c_names = c_names_data.data();
352 }
353 return ToStatus(GRBaddconstrs(
354 /*model=*/gurobi_model_,
355 /*numconstrs=*/num_cons,
356 /*numnz=*/0, /*cbeg=*/nullptr, /*cind=*/nullptr,
357 /*cval=*/nullptr, /*sense=*/const_cast<char*>(sense.data()),
358 /*rhs=*/const_cast<double*>(rhs.data()), /*constrnames=*/c_names));
359}
360
361absl::Status Gurobi::DelConstrs(const absl::Span<const int> ind) {
362 return ToStatus(
363 GRBdelconstrs(gurobi_model_, ind.size(), const_cast<int*>(ind.data())));
364}
365
366absl::Status Gurobi::AddQpTerms(const absl::Span<const int> qrow,
367 const absl::Span<const int> qcol,
368 const absl::Span<const double> qval) {
369 const int numqnz = static_cast<int>(qrow.size());
370 CHECK_EQ(qcol.size(), numqnz);
371 CHECK_EQ(qval.size(), numqnz);
372 return ToStatus(GRBaddqpterms(
373 gurobi_model_, numqnz, const_cast<int*>(qcol.data()),
374 const_cast<int*>(qrow.data()), const_cast<double*>(qval.data())));
375}
376
377absl::Status Gurobi::DelQ() { return ToStatus(GRBdelq(gurobi_model_)); }
378
379absl::Status Gurobi::SetNthObjective(const int index, const int priority,
380 const double weight, const double abs_tol,
381 const double rel_tol,
382 const std::string& name,
383 const double constant,
384 const absl::Span<const int> lind,
385 const absl::Span<const double> lval) {
386 const int numlnz = static_cast<int>(lind.size());
387 CHECK_EQ(lval.size(), numlnz);
389 /*model=*/gurobi_model_,
390 /*index=*/index,
391 /*priority=*/priority,
392 /*weight=*/weight,
393 /*abstol=*/abs_tol,
394 /*reltol=*/rel_tol,
395 /*name=*/const_cast<char*>(name.c_str()),
396 /*constant=*/constant,
397 /*lnz=*/numlnz,
398 /*lind=*/const_cast<int*>(lind.data()),
399 /*lval=*/const_cast<double*>(lval.data())));
400}
401
402absl::Status Gurobi::AddQConstr(const absl::Span<const int> lind,
403 const absl::Span<const double> lval,
404 const absl::Span<const int> qrow,
405 const absl::Span<const int> qcol,
406 const absl::Span<const double> qval,
407 const char sense, const double rhs,
408 const std::string& name) {
409 const int numlnz = static_cast<int>(lind.size());
410 CHECK_EQ(lval.size(), numlnz);
411
412 const int numqlnz = static_cast<int>(qrow.size());
413 CHECK_EQ(qcol.size(), numqlnz);
414 CHECK_EQ(qval.size(), numqlnz);
415
416 return ToStatus(GRBaddqconstr(
417 /*model=*/gurobi_model_,
418 /*numlnz=*/numlnz,
419 /*lind=*/const_cast<int*>(lind.data()),
420 /*lval=*/const_cast<double*>(lval.data()),
421 /*numqlnz=*/numqlnz,
422 /*qrow=*/const_cast<int*>(qrow.data()),
423 /*qcol=*/const_cast<int*>(qcol.data()),
424 /*qval=*/const_cast<double*>(qval.data()),
425 /*sense=*/sense,
426 /*rhs=*/rhs,
427 /*constrname=*/const_cast<char*>(name.c_str())));
428}
429
430absl::Status Gurobi::DelQConstrs(const absl::Span<const int> ind) {
431 return ToStatus(GRBdelqconstrs(gurobi_model_, static_cast<int>(ind.size()),
432 const_cast<int*>(ind.data())));
433}
434
435absl::Status Gurobi::AddSos(const absl::Span<const int> types,
436 const absl::Span<const int> beg,
437 const absl::Span<const int> ind,
438 const absl::Span<const double> weight) {
439 const int num_sos = static_cast<int>(types.size());
440 CHECK_EQ(beg.size(), num_sos);
441
442 const int num_members = static_cast<int>(ind.size());
443 CHECK_EQ(weight.size(), num_members);
444
445 return ToStatus(GRBaddsos(/*model=*/gurobi_model_, /*numsos=*/num_sos,
446 /*nummembers=*/num_members,
447 /*types=*/const_cast<int*>(types.data()),
448 /*beg=*/const_cast<int*>(beg.data()),
449 /*ind=*/const_cast<int*>(ind.data()),
450 /*weight=*/const_cast<double*>(weight.data())));
451}
452
453absl::Status Gurobi::DelSos(const absl::Span<const int> ind) {
454 return ToStatus(GRBdelsos(gurobi_model_, static_cast<int>(ind.size()),
455 const_cast<int*>(ind.data())));
456}
457
458absl::Status Gurobi::AddIndicator(const std::string& name, const int binvar,
459 const int binval,
460 const absl::Span<const int> ind,
461 const absl::Span<const double> val,
462 const char sense, const double rhs) {
463 const int nvars = static_cast<int>(ind.size());
464 CHECK_EQ(val.size(), nvars);
466 /*model=*/gurobi_model_, /*name=*/const_cast<char*>(name.c_str()),
467 /*binvar=*/binvar, /*binval=*/binval, /*nvars=*/nvars,
468 /*ind=*/const_cast<int*>(ind.data()),
469 /*val=*/const_cast<double*>(val.data()), /*sense=*/sense, /*rhs=*/rhs));
470}
471
472absl::Status Gurobi::DelGenConstrs(const absl::Span<const int> ind) {
473 return ToStatus(GRBdelgenconstrs(gurobi_model_, static_cast<int>(ind.size()),
474 const_cast<int*>(ind.data())));
475}
476
477absl::Status Gurobi::ChgCoeffs(const absl::Span<const int> cind,
478 const absl::Span<const int> vind,
479 const absl::Span<const double> val) {
480 const int num_changes = static_cast<int>(cind.size());
481 CHECK_EQ(vind.size(), num_changes);
482 CHECK_EQ(val.size(), num_changes);
483 return ToStatus(GRBchgcoeffs(
484 gurobi_model_, num_changes, const_cast<int*>(cind.data()),
485 const_cast<int*>(vind.data()), const_cast<double*>(val.data())));
486}
487
488absl::StatusOr<int> Gurobi::GetNnz(const int first_var, const int num_vars) {
489 int nnz = 0;
490 RETURN_IF_ERROR(ToStatus(GRBgetvars(gurobi_model_, &nnz, nullptr, nullptr,
491 nullptr, first_var, num_vars)));
492 return nnz;
493}
494
495absl::Status Gurobi::GetVars(const absl::Span<int> vbegin,
496 const absl::Span<int> vind,
497 const absl::Span<double> vval, const int first_var,
498 const int num_vars) {
499 CHECK_EQ(vbegin.size(), num_vars);
500 CHECK_EQ(vind.size(), vval.size());
501 int nnz = 0;
503 ToStatus(GRBgetvars(gurobi_model_, &nnz, vbegin.data(), vind.data(),
504 vval.data(), first_var, num_vars)));
505 CHECK_EQ(nnz, vind.size());
506 return absl::OkStatus();
507}
508
509absl::StatusOr<Gurobi::SparseMat> Gurobi::GetVars(const int first_var,
510 const int num_vars) {
511 SparseMat result;
512 ASSIGN_OR_RETURN(const int nnz, GetNnz(first_var, num_vars));
513 result.begins.resize(num_vars);
514 result.inds.resize(nnz);
515 result.vals.resize(nnz);
516 int read_nnz = 0;
518 GRBgetvars(gurobi_model_, &read_nnz, result.begins.data(),
519 result.inds.data(), result.vals.data(), first_var, num_vars)));
520 CHECK_EQ(read_nnz, nnz);
521 return result;
522}
523
524absl::Status Gurobi::UpdateModel() {
525 return ToStatus(GRBupdatemodel(gurobi_model_));
526}
527
528absl::Status Gurobi::Optimize(Callback cb) {
529 ASSIGN_OR_RETURN(const auto scope, ScopedCallback::New(this, std::move(cb)));
530 const int error = GRBoptimize(gurobi_model_);
531 RETURN_IF_ERROR(scope->Flush());
533 return scope->Release();
534}
535
536absl::StatusOr<bool> Gurobi::ComputeIIS(Callback cb) {
537 ASSIGN_OR_RETURN(const auto scope, ScopedCallback::New(this, std::move(cb)));
538 const int error = GRBcomputeIIS(gurobi_model_);
539 RETURN_IF_ERROR(scope->Flush());
540 if (error == GRB_ERROR_IIS_NOT_INFEASIBLE) {
541 RETURN_IF_ERROR(scope->Release());
542 return false;
543 } else if (error == kGrbOk) {
544 // If Gurobi v11 terminates at a limit before determining if the model is
545 // feasible or not, it will return an OK error code but then will fail to
546 // return anything about the IIS it does not have. To detect this case, we
547 // query the minimality attribute: we know that our env is valid at this
548 // point, and this should fail iff an IIS is present, i.e., Gurobi proved
549 // that the model was infeasible.
550 const bool has_iis = GetIntAttr(GRB_INT_ATTR_IIS_MINIMAL).ok();
551 RETURN_IF_ERROR(scope->Release());
552 return has_iis;
553 }
555 return scope->Release();
556}
557
558bool Gurobi::IsAttrAvailable(const char* name) const {
559 return GRBisattravailable(gurobi_model_, name) > 0;
560}
561
562absl::StatusOr<int> Gurobi::GetIntAttr(const char* const name) const {
563 int result;
564 RETURN_IF_ERROR(ToStatus(GRBgetintattr(gurobi_model_, name, &result)))
565 << "Error getting Gurobi int attribute: " << name;
566 return result;
567}
568
569absl::StatusOr<double> Gurobi::GetDoubleAttr(const char* const name) const {
570 double result;
571 RETURN_IF_ERROR(ToStatus(GRBgetdblattr(gurobi_model_, name, &result)))
572 << "Error getting Gurobi double attribute: " << name;
573 return result;
574}
575
576absl::StatusOr<std::string> Gurobi::GetStringAttr(
577 const char* const name) const {
578 // WARNING: if a string attribute is the empty string, we need to be careful,
579 // std::string(char*) cannot take a nullptr.
580 char* result = nullptr;
581 RETURN_IF_ERROR(ToStatus(GRBgetstrattr(gurobi_model_, name, &result)))
582 << "Error getting Gurobi string attribute: " << name;
583 if (result == nullptr) {
584 return std::string();
585 }
586 return std::string(result);
587}
588
589absl::Status Gurobi::SetStringAttr(const char* const attr_name,
590 const std::string& value) {
591 return ToStatus(GRBsetstrattr(gurobi_model_, attr_name, value.c_str()));
592}
593
594absl::Status Gurobi::SetIntAttr(const char* const attr_name, const int value) {
595 return ToStatus(GRBsetintattr(gurobi_model_, attr_name, value));
596}
597
598absl::Status Gurobi::SetDoubleAttr(const char* const attr_name,
599 const double value) {
600 return ToStatus(GRBsetdblattr(gurobi_model_, attr_name, value));
601}
602
603absl::Status Gurobi::SetIntAttrArray(const char* const name,
604 const absl::Span<const int> new_values) {
605 return ToStatus(GRBsetintattrarray(gurobi_model_, name, 0, new_values.size(),
606 const_cast<int*>(new_values.data())));
607}
608
610 const char* const name, const absl::Span<const double> new_values) {
611 return ToStatus(GRBsetdblattrarray(gurobi_model_, name, 0, new_values.size(),
612 const_cast<double*>(new_values.data())));
613}
614
615absl::Status Gurobi::SetCharAttrArray(const char* const name,
616 const absl::Span<const char> new_values) {
617 return ToStatus(GRBsetcharattrarray(gurobi_model_, name, 0, new_values.size(),
618 const_cast<char*>(new_values.data())));
619}
620
621absl::Status Gurobi::GetIntAttrArray(const char* const name,
622 const absl::Span<int> attr_out) const {
624 gurobi_model_, name, 0, attr_out.size(), attr_out.data())))
625 << "Error getting Gurobi int array attribute: " << name;
626 return absl::OkStatus();
627}
628
629absl::StatusOr<std::vector<int>> Gurobi::GetIntAttrArray(const char* const name,
630 const int len) const {
631 std::vector<int> result(len);
632 RETURN_IF_ERROR(GetIntAttrArray(name, absl::MakeSpan(result)));
633 return result;
634}
635
637 const char* const name, const absl::Span<double> attr_out) const {
639 gurobi_model_, name, 0, attr_out.size(), attr_out.data())))
640 << "Error getting Gurobi double array attribute: " << name;
641 return absl::OkStatus();
642}
643
644absl::StatusOr<std::vector<double>> Gurobi::GetDoubleAttrArray(
645 const char* const name, const int len) const {
646 std::vector<double> result(len);
647 RETURN_IF_ERROR(GetDoubleAttrArray(name, absl::MakeSpan(result)));
648 return result;
649}
650
651absl::Status Gurobi::GetCharAttrArray(const char* const name,
652 const absl::Span<char> attr_out) const {
654 gurobi_model_, name, 0, attr_out.size(), attr_out.data())))
655 << "Error getting Gurobi char array attribute: " << name;
656 return absl::OkStatus();
657}
658
659absl::StatusOr<std::vector<char>> Gurobi::GetCharAttrArray(
660 const char* const name, const int len) const {
661 std::vector<char> result(len);
662 RETURN_IF_ERROR(GetCharAttrArray(name, absl::MakeSpan(result)));
663 return result;
664}
665
666absl::Status Gurobi::SetIntAttrList(const char* const name,
667 const absl::Span<const int> ind,
668 const absl::Span<const int> new_values) {
669 const int len = static_cast<int>(ind.size());
670 CHECK_EQ(new_values.size(), len);
671 return ToStatus(GRBsetintattrlist(gurobi_model_, name, len,
672 const_cast<int*>(ind.data()),
673 const_cast<int*>(new_values.data())));
674}
675
677 const char* const name, const absl::Span<const int> ind,
678 const absl::Span<const double> new_values) {
679 const int len = static_cast<int>(ind.size());
680 CHECK_EQ(new_values.size(), len);
681 return ToStatus(GRBsetdblattrlist(gurobi_model_, name, len,
682 const_cast<int*>(ind.data()),
683 const_cast<double*>(new_values.data())));
684}
685
686absl::Status Gurobi::SetCharAttrList(const char* const name,
687 const absl::Span<const int> ind,
688 const absl::Span<const char> new_values) {
689 const int len = static_cast<int>(ind.size());
690 CHECK_EQ(new_values.size(), len);
691 return ToStatus(GRBsetcharattrlist(gurobi_model_, name, len,
692 const_cast<int*>(ind.data()),
693 const_cast<char*>(new_values.data())));
694}
695
696absl::StatusOr<int> Gurobi::GetIntAttrElement(const char* const name,
697 const int element) const {
698 int value;
700 ToStatus(GRBgetintattrelement(gurobi_model_, name, element, &value)));
701 return value;
702}
703
704absl::Status Gurobi::SetIntAttrElement(const char* const name,
705 const int element, const int new_value) {
706 return ToStatus(
707 GRBsetintattrelement(gurobi_model_, name, element, new_value));
708}
709
710absl::StatusOr<double> Gurobi::GetDoubleAttrElement(const char* const name,
711 const int element) const {
712 double value;
714 ToStatus(GRBgetdblattrelement(gurobi_model_, name, element, &value)));
715 return value;
716}
717
718absl::Status Gurobi::SetDoubleAttrElement(const char* const name, int element,
719 double new_value) {
720 return ToStatus(
721 GRBsetdblattrelement(gurobi_model_, name, element, new_value));
722}
723
724absl::StatusOr<char> Gurobi::GetCharAttrElement(const char* const name,
725 const int element) const {
726 char value;
728 ToStatus(GRBgetcharattrelement(gurobi_model_, name, element, &value)));
729 return value;
730}
731
732absl::Status Gurobi::SetCharAttrElement(const char* const name,
733 const int element,
734 const char new_value) {
735 return ToStatus(
736 GRBsetcharattrelement(gurobi_model_, name, element, new_value));
737}
738
739absl::Status Gurobi::SetParam(const char* const name,
740 const std::string& value) {
741 return ToStatus(GRBsetparam(model_env_, name, value.c_str()));
742}
743
744absl::Status Gurobi::SetIntParam(const char* const name, const int value) {
745 return ToStatus(GRBsetintparam(model_env_, name, value));
746}
747
748absl::Status Gurobi::SetDoubleParam(const char* const name,
749 const double value) {
750 return ToStatus(GRBsetdblparam(model_env_, name, value));
751}
752
753absl::Status Gurobi::SetStringParam(const char* const name,
754 const std::string& value) {
755 return ToStatus(GRBsetstrparam(model_env_, name, value.c_str()));
756}
757
758absl::StatusOr<int> Gurobi::GetIntParam(const char* const name) {
759 int result;
760 RETURN_IF_ERROR(ToStatus(GRBgetintparam(model_env_, name, &result)));
761 return result;
762}
763
764absl::StatusOr<double> Gurobi::GetDoubleParam(const char* const name) {
765 double result;
766 RETURN_IF_ERROR(ToStatus(GRBgetdblparam(model_env_, name, &result)));
767 return result;
768}
769
770absl::StatusOr<std::string> Gurobi::GetStringParam(const char* const name) {
771 std::vector<char> result(GRB_MAX_STRLEN);
772 RETURN_IF_ERROR(ToStatus(GRBgetstrparam(model_env_, name, result.data())));
773 return std::string(result.data());
774}
775
777 return ToStatus(GRBresetparams(model_env_));
778}
779
780void Gurobi::Terminate() { GRBterminate(gurobi_model_); }
781
783 void* const cb_data, const int where)
784 : gurobi_(ABSL_DIE_IF_NULL(gurobi)), cb_data_(cb_data), where_(where) {}
785
786absl::StatusOr<int> Gurobi::CallbackContext::CbGetInt(const int what) const {
787 int result;
788 RETURN_IF_ERROR(gurobi_->ToStatus(
789 GRBcbget(cb_data_, where_, what, static_cast<void*>(&result))));
790 return result;
791}
792
794 const int what) const {
795 double result;
796 RETURN_IF_ERROR(gurobi_->ToStatus(
797 GRBcbget(cb_data_, where_, what, static_cast<void*>(&result))));
798 return result;
799}
800
802 const int what, const absl::Span<double> result) const {
803 return gurobi_->ToStatus(
804 GRBcbget(cb_data_, where_, what, static_cast<void*>(result.data())));
805}
806
807absl::StatusOr<std::string> Gurobi::CallbackContext::CbGetMessage() const {
808 char* result = nullptr;
809 RETURN_IF_ERROR(gurobi_->ToStatus(GRBcbget(
810 cb_data_, where_, GRB_CB_MSG_STRING, static_cast<void*>(&result))));
811 if (result == nullptr) {
812 return std::string();
813 }
814 return std::string(result);
815}
816
818 const absl::Span<const int> cutind, const absl::Span<const double> cutval,
819 const char cutsense, const double cutrhs) const {
820 const int cut_len = static_cast<int>(cutind.size());
821 CHECK_EQ(cutval.size(), cut_len);
822 return gurobi_->ToStatus(
823 GRBcbcut(cb_data_, cut_len, const_cast<int*>(cutind.data()),
824 const_cast<double*>(cutval.data()), cutsense, cutrhs));
825}
826
828 const absl::Span<const int> lazyind, const absl::Span<const double> lazyval,
829 const char lazysense, const double lazyrhs) const {
830 const int lazy_len = static_cast<int>(lazyind.size());
831 CHECK_EQ(lazyval.size(), lazy_len);
832 return gurobi_->ToStatus(
833 GRBcblazy(cb_data_, lazy_len, const_cast<int*>(lazyind.data()),
834 const_cast<double*>(lazyval.data()), lazysense, lazyrhs));
835}
836
838 const absl::Span<const double> solution) const {
839 double result;
840 RETURN_IF_ERROR(gurobi_->ToStatus(
841 GRBcbsolution(cb_data_, const_cast<double*>(solution.data()), &result)));
842 return result;
843}
844
845} // namespace operations_research::math_opt
#define ASSIGN_OR_RETURN(lhs, rexpr)
#define RETURN_IF_ERROR(expr)
absl::StatusOr< std::string > CbGetMessage() const
Calls GRBcbget() where what=MSG_STRING (call only at where=MESSAGE).
Definition g_gurobi.cc:807
absl::Status CbLazy(absl::Span< const int > lazyind, absl::Span< const double > lazyval, char lazysense, double lazyrhs) const
Calls GRBcblazy().
Definition g_gurobi.cc:827
CallbackContext(Gurobi *gurobi, void *cb_data, int where)
For internal use only.
Definition g_gurobi.cc:782
absl::StatusOr< double > CbGetDouble(int what) const
Definition g_gurobi.cc:793
absl::Status CbCut(absl::Span< const int > cutind, absl::Span< const double > cutval, char cutsense, double cutrhs) const
Calls GRBcbcut().
Definition g_gurobi.cc:817
absl::StatusOr< double > CbSolution(absl::Span< const double > solution) const
Calls GRBcbsolution().
Definition g_gurobi.cc:837
absl::Status CbGetDoubleArray(int what, absl::Span< double > result) const
Definition g_gurobi.cc:801
absl::StatusOr< int > CbGetInt(int what) const
Definition g_gurobi.cc:786
absl::Status AddIndicator(const std::string &name, int binvar, int binval, absl::Span< const int > ind, absl::Span< const double > val, char sense, double rhs)
Definition g_gurobi.cc:458
absl::Status GetIntAttrArray(const char *name, absl::Span< int > attr_out) const
Definition g_gurobi.cc:621
absl::Status ToStatus(int grb_err, absl::StatusCode code=absl::StatusCode::kInvalidArgument, absl::SourceLocation loc=absl::SourceLocation::current()) const
Definition g_gurobi.cc:233
absl::Status DelGenConstrs(absl::Span< const int > ind)
Definition g_gurobi.cc:472
absl::Status SetDoubleAttrElement(const char *name, int element, double new_value)
Definition g_gurobi.cc:718
static absl::StatusOr< std::unique_ptr< Gurobi > > NewWithSharedPrimaryEnv(GRBenv *primary_env)
Definition g_gurobi.cc:175
absl::StatusOr< bool > ComputeIIS(Callback cb=nullptr)
Definition g_gurobi.cc:536
absl::Status AddVar(double obj, double lb, double ub, char vtype, const std::string &name)
Calls GRBaddvar() to add a variable to the model.
Definition g_gurobi.cc:244
bool IsAttrAvailable(const char *name) const
Definition g_gurobi.cc:558
absl::StatusOr< char > GetCharAttrElement(const char *name, int element) const
Definition g_gurobi.cc:724
absl::Status SetIntAttrElement(const char *name, int element, int new_value)
Definition g_gurobi.cc:704
absl::Status SetCharAttrArray(const char *name, absl::Span< const char > new_values)
Definition g_gurobi.cc:615
absl::Status SetDoubleAttrArray(const char *name, absl::Span< const double > new_values)
Definition g_gurobi.cc:609
absl::StatusOr< int > GetIntAttr(const char *name) const
Definition g_gurobi.cc:562
absl::Status SetStringParam(const char *name, const std::string &value)
Calls GRBsetstrparam().
Definition g_gurobi.cc:753
absl::Status DelSos(absl::Span< const int > ind)
Definition g_gurobi.cc:453
absl::StatusOr< int > GetNnz(int first_var, int num_vars)
Definition g_gurobi.cc:488
absl::Status SetDoubleAttrList(const char *name, absl::Span< const int > ind, absl::Span< const double > new_values)
Definition g_gurobi.cc:676
absl::Status AddSos(absl::Span< const int > types, absl::Span< const int > beg, absl::Span< const int > ind, absl::Span< const double > weight)
Definition g_gurobi.cc:435
absl::Status SetIntAttr(const char *attr_name, int value)
Definition g_gurobi.cc:594
absl::Status AddConstr(char sense, double rhs, const std::string &name)
Definition g_gurobi.cc:319
absl::Status SetParam(const char *name, const std::string &value)
Definition g_gurobi.cc:739
absl::Status SetStringAttr(const char *attr_name, const std::string &value)
Definition g_gurobi.cc:589
std::function< absl::Status(const CallbackContext &)> Callback
Definition g_gurobi.h:222
absl::Status GetVars(absl::Span< int > vbegin, absl::Span< int > vind, absl::Span< double > vval, int first_var, int num_vars)
Definition g_gurobi.cc:495
absl::Status ChgCoeffs(absl::Span< const int > cind, absl::Span< const int > vind, absl::Span< const double > val)
Definition g_gurobi.cc:477
void Terminate()
Calls GRBterminate().
Definition g_gurobi.cc:780
static absl::StatusOr< std::unique_ptr< Gurobi > > New(GRBenvUniquePtr primary_env=nullptr)
Definition g_gurobi.cc:181
GRBmodel * model() const
Typically not needed.
Definition g_gurobi.h:574
absl::Status Optimize(Callback cb=nullptr)
Definition g_gurobi.cc:528
absl::Status GetCharAttrArray(const char *name, absl::Span< char > attr_out) const
Definition g_gurobi.cc:651
absl::StatusOr< double > GetDoubleAttrElement(const char *name, int element) const
Definition g_gurobi.cc:710
absl::StatusOr< double > GetDoubleAttr(const char *name) const
Definition g_gurobi.cc:569
absl::Status SetCharAttrElement(const char *name, int element, char new_value)
Definition g_gurobi.cc:732
absl::Status SetIntParam(const char *name, int value)
Calls GRBsetintparam().
Definition g_gurobi.cc:744
absl::StatusOr< std::string > GetStringAttr(const char *name) const
Definition g_gurobi.cc:576
absl::Status SetIntAttrArray(const char *name, absl::Span< const int > new_values)
Definition g_gurobi.cc:603
absl::StatusOr< int > GetIntParam(const char *name)
Calls GRBgetintparam().
Definition g_gurobi.cc:758
absl::StatusOr< int > GetIntAttrElement(const char *name, int element) const
Definition g_gurobi.cc:696
absl::Status AddQpTerms(absl::Span< const int > qrow, absl::Span< const int > qcol, absl::Span< const double > qval)
Definition g_gurobi.cc:366
absl::Status SetDoubleParam(const char *name, double value)
Calls GRBsetdblparam().
Definition g_gurobi.cc:748
absl::StatusOr< double > GetDoubleParam(const char *name)
Calls GRBgetdblparam().
Definition g_gurobi.cc:764
absl::Status SetNthObjective(int index, int priority, double weight, double abs_tol, double rel_tol, const std::string &name, double constant, absl::Span< const int > lind, absl::Span< const double > lval)
Definition g_gurobi.cc:379
absl::Status GetDoubleAttrArray(const char *name, absl::Span< double > attr_out) const
Definition g_gurobi.cc:636
absl::Status ResetParameters()
Calls GRBresetparams().
Definition g_gurobi.cc:776
absl::Status UpdateModel()
Calls GRBupdatemodel().
Definition g_gurobi.cc:524
absl::Status SetDoubleAttr(const char *attr_name, double value)
Definition g_gurobi.cc:598
absl::StatusOr< std::string > GetStringParam(const char *name)
Calls GRBgetstrparam().
Definition g_gurobi.cc:770
absl::Status DelQConstrs(absl::Span< const int > ind)
Definition g_gurobi.cc:430
absl::Status AddQConstr(absl::Span< const int > lind, absl::Span< const double > lval, absl::Span< const int > qrow, absl::Span< const int > qcol, absl::Span< const double > qval, char sense, double rhs, const std::string &name)
Definition g_gurobi.cc:402
have size equal to the number of new be empty(all new constraints have name ""). absl absl::Status DelConstrs(absl::Span< const int > ind)
Calls GRBdelconstrs().
Definition g_gurobi.cc:361
absl::Status SetIntAttrList(const char *name, absl::Span< const int > ind, absl::Span< const int > new_values)
Definition g_gurobi.cc:666
absl::Status SetCharAttrList(const char *name, absl::Span< const int > ind, absl::Span< const char > new_values)
Definition g_gurobi.cc:686
have size equal to the number of new be be empty(all new variables have name ""). absl have size equal to the number of new be be empty(all new variables have name ""). absl absl::Status DelVars(absl::Span< const int > ind)
Calls GRBdelvars().
Definition g_gurobi.cc:314
const std::string name
A name for logging purposes.
int64_t value
absl::Status status
Definition g_gurobi.cc:44
Gurobi::Callback user_cb
Definition g_gurobi.cc:43
Gurobi * gurobi
Definition g_gurobi.cc:45
#define GRB_ERROR_CALLBACK
Definition environment.h:79
#define GUROBI_STDCALL
Definition environment.h:27
struct _GRBenv GRBenv
Definition environment.h:32
#define GRB_CB_MSG_STRING
#define GRB_MAX_STRLEN
struct _GRBmodel GRBmodel
Definition environment.h:31
#define GRB_ERROR_IIS_NOT_INFEASIBLE
Definition environment.h:83
#define GRB_INT_ATTR_IIS_MINIMAL
GRBmodel * model
GurobiMPCallbackContext * context
int where
int index
double solution
An object oriented wrapper for quadratic constraints in ModelStorage.
Definition gurobi_isv.cc:28
absl::StatusOr< GRBenvUniquePtr > GurobiNewPrimaryEnv(const std::optional< GurobiIsvKey > &isv_key)
Definition g_gurobi.cc:154
std::unique_ptr< GRBenv, GurobiFreeEnv > GRBenvUniquePtr
Definition g_gurobi.h:59
absl::StatusOr< GRBenv * > NewPrimaryEnvFromISVKey(const GurobiIsvKey &isv_key)
Definition gurobi_isv.cc:30
std::function< int(GRBmodel *model, int numnz, int *cind, double *cval, char sense, double rhs, const char *constrname)> GRBaddconstr
std::function< void(GRBenv *env)> GRBfreeenv
std::function< int(GRBmodel *model, const char *attrname, double *valueP)> GRBgetdblattr
std::function< int(GRBmodel *model, const char *attrname, int first, int len, double *values)> GRBgetdblattrarray
std::function< int(GRBmodel *model, const char *attrname, int first, int len, int *values)> GRBgetintattrarray
std::function< int(GRBmodel *model, const char *attrname, double newvalue)> GRBsetdblattr
std::function< int(GRBmodel *model, int len, int *ind)> GRBdelsos
std::function< int(GRBmodel *model, int numvars, int numnz, int *vbeg, int *vind, double *vval, double *obj, double *lb, double *ub, char *vtype, char **varnames)> GRBaddvars
std::function< int(GRBmodel *model, int(GUROBI_STDCALL *cb)(CB_ARGS), void *usrdata)> GRBsetcallbackfunc
std::function< int(GRBmodel *model, int *numnzP, int *vbeg, int *vind, double *vval, int start, int len)> GRBgetvars
std::function< int(GRBmodel *model, const char *attrname, int len, int *ind, int *newvalues)> GRBsetintattrlist
std::function< int(GRBmodel *model, int cnt, int *cind, int *vind, double *val)> GRBchgcoeffs
std::function< int(GRBmodel *model, const char *attrname, int first, int len, char *values)> GRBgetcharattrarray
std::function< int(void *cbdata, int cutlen, const int *cutind, const double *cutval, char cutsense, double cutrhs)> GRBcbcut
std::function< int(GRBenv *env, const char *paramname, double *valueP)> GRBgetdblparam
std::function< int(GRBmodel *model, int numlnz, int *lind, double *lval, int numqnz, int *qrow, int *qcol, double *qval, char sense, double rhs, const char *QCname)> GRBaddqconstr
std::function< int(GRBmodel *model, int len, int *ind)> GRBdelvars
std::function< int(GRBmodel *model, const char *attrname, int newvalue)> GRBsetintattr
std::function< int(GRBenv *env, const char *paramname, const char *value)> GRBsetparam
std::function< int(GRBmodel *model, const char *attrname, int element, int *valueP)> GRBgetintattrelement
std::function< int(GRBenv *env, GRBmodel **modelP, const char *Pname, int numvars, double *obj, double *lb, double *ub, char *vtype, char **varnames)> GRBnewmodel
std::function< int(GRBmodel *model, int numnz, int *vind, double *vval, double obj, double lb, double ub, char vtype, const char *varname)> GRBaddvar
std::function< int(GRBmodel *model, const char *attrname, int first, int len, int *newvalues)> GRBsetintattrarray
std::function< int(GRBmodel *model)> GRBupdatemodel
std::function< void(int *majorP, int *minorP, int *technicalP)> GRBversion
std::function< GRBenv *(GRBmodel *model)> GRBgetenv
std::function< int(GRBmodel *model, const char *attrname, int len, int *ind, char *newvalues)> GRBsetcharattrlist
std::function< int(GRBenv *env, const char *paramname, char *valueP)> GRBgetstrparam
std::function< int(GRBmodel *model, const char *attrname, int element, double *valueP)> GRBgetdblattrelement
std::function< int(GRBmodel *model, const char *attrname, int first, int len, char *newvalues)> GRBsetcharattrarray
std::function< int(GRBmodel *model)> GRBfreemodel
std::function< int(GRBmodel *model, int len, int *ind)> GRBdelqconstrs
std::function< int(void *cbdata, int lazylen, const int *lazyind, const double *lazyval, char lazysense, double lazyrhs)> GRBcblazy
std::function< int(GRBmodel *model)> GRBcomputeIIS
std::function< int(void *cbdata, int where, int what, void *resultP)> GRBcbget
std::function< int(GRBenv *env, const char *paramname, int value)> GRBsetintparam
std::function< int(GRBmodel *model, const char *attrname)> GRBisattravailable
std::function< int(GRBenv *env, const char *paramname, const char *value)> GRBsetstrparam
std::function< int(GRBmodel *model, const char *attrname, int first, int len, double *newvalues)> GRBsetdblattrarray
std::function< int(GRBmodel *model, const char *name, int binvar, int binval, int nvars, const int *vars, const double *vals, char sense, double rhs)> GRBaddgenconstrIndicator
std::function< int(GRBmodel *model, const char *attrname, int element, char newvalue)> GRBsetcharattrelement
std::function< int(GRBmodel *model, const char *attrname, int element, int newvalue)> GRBsetintattrelement
std::function< int(GRBenv *env)> GRBresetparams
std::function< int(GRBmodel *model, const char *attrname, const char *newvalue)> GRBsetstrattr
std::function< int(GRBmodel *model)> GRBoptimize
std::function< int(GRBenv **envP, const char *logfilename)> GRBloadenv
std::function< int(GRBmodel *model, int numqnz, int *qrow, int *qcol, double *qval)> GRBaddqpterms
std::function< int(GRBmodel *model, int len, int *ind)> GRBdelconstrs
std::function< int(GRBmodel *model, const char *attrname, int *valueP)> GRBgetintattr
std::function< int(GRBmodel *model, int len, int *ind)> GRBdelgenconstrs
std::function< int(GRBmodel *model, int index, int priority, double weight, double abstol, double reltol, const char *name, double constant, int lnz, int *lind, double *lval)> GRBsetobjectiven
std::function< const char *(GRBenv *env)> GRBgeterrormsg
std::function< int(GRBenv *env, const char *paramname, int *valueP)> GRBgetintparam
std::function< int(GRBmodel *model, int numconstrs, int numnz, int *cbeg, int *cind, double *cval, char *sense, double *rhs, char **constrnames)> GRBaddconstrs
std::function< int(GRBmodel *model, const char *attrname, int len, int *ind, double *newvalues)> GRBsetdblattrlist
std::function< char *(void)> GRBplatform
std::function< int(GRBmodel *model, int numsos, int nummembers, int *types, int *beg, int *ind, double *weight)> GRBaddsos
std::function< int(GRBmodel *model, const char *attrname, int element, char *valueP)> GRBgetcharattrelement
std::function< int(GRBmodel *model, const char *attrname, char **valueP)> GRBgetstrattr
std::function< int(GRBmodel *model)> GRBdelq
std::function< int(void *cbdata, const double *solution, double *objvalP)> GRBcbsolution
std::function< void(GRBmodel *model)> GRBterminate
std::function< int(GRBenv *env, const char *paramname, double value)> GRBsetdblparam
std::function< int(GRBmodel *model, const char *attrname, int element, double newvalue)> GRBsetdblattrelement
STL namespace.
StatusBuilder InvalidArgumentErrorBuilder()
int64_t weight
Definition pack.cc:510