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