55 #include "absl/base/attributes.h" 56 #include "absl/status/status.h" 57 #include "absl/strings/match.h" 58 #include "absl/strings/str_format.h" 71 "Number of threads available for Gurobi.");
88 const MPModelRequest& request, std::atomic<bool>* interrupt)
override;
90 void Write(
const std::string& filename)
override;
94 void Reset()
override;
108 const MPVariable*
const variable,
double new_value,
109 double old_value)
override;
125 int64_t
nodes()
const override;
135 bool IsLP()
const override {
return !mip_; }
136 bool IsMIP()
const override {
return mip_; }
143 int major, minor, technical;
145 return absl::StrFormat(
"Gurobi library version %d.%d.%d\n", major, minor,
150 const absl::MutexLock lock(&hold_interruptions_mutex_);
159 LOG(DFATAL) <<
"ComputeExactConditionNumber not implemented for" 160 <<
" GUROBI_MIXED_INTEGER_PROGRAMMING";
165 LOG(DFATAL) <<
"ComputeExactConditionNumber not implemented for" 166 <<
" GUROBI_LINEAR_PROGRAMMING";
200 bool SetSolverSpecificParametersAsString(
203 void SetRelativeMipGap(
double value)
override;
204 void SetPrimalTolerance(
double value)
override;
205 void SetDualTolerance(
double value)
override;
206 void SetPresolveMode(
int value)
override;
207 void SetScalingMode(
int value)
override;
208 void SetLpAlgorithm(
int value)
override;
211 int gurobi_basis_status)
const;
213 int gurobi_basis_status,
int constraint_index)
const;
216 bool ModelIsNonincremental()
const;
218 void SetIntAttr(
const char*
name,
int value);
219 int GetIntAttr(
const char*
name)
const;
220 void SetDoubleAttr(
const char*
name,
double value);
221 double GetDoubleAttr(
const char*
name)
const;
223 int GetIntAttrElement(
const char*
name,
int index)
const;
224 void SetDoubleAttrElement(
const char*
name,
int index,
double value);
225 double GetDoubleAttrElement(
const char*
name,
int index)
const;
226 std::vector<double> GetDoubleAttrArray(
const char*
name,
int elements);
228 char GetCharAttrElement(
const char*
name,
int index)
const;
230 void CheckedGurobiCall(
int err)
const;
232 int SolutionCount()
const;
237 int current_solution_index_;
239 bool update_branching_priorities_ =
false;
245 std::vector<int> mp_var_to_gurobi_var_;
250 std::vector<int> mp_cons_to_gurobi_linear_cons_;
252 int num_gurobi_vars_ = 0;
255 int num_gurobi_linear_cons_ = 0;
257 bool had_nonincremental_change_ =
false;
262 mutable absl::Mutex hold_interruptions_mutex_;
267 void CheckedGurobiCall(
int err,
GRBenv*
const env) {
268 CHECK_EQ(0, err) <<
"Fatal error with code " << err <<
", due to " 273 struct GurobiInternalCallbackContext {
279 class GurobiMPCallbackContext :
public MPCallbackContext {
281 GurobiMPCallbackContext(
GRBenv* env,
282 const std::vector<int>* mp_var_to_gurobi_var,
283 int num_gurobi_vars,
bool might_add_cuts,
284 bool might_add_lazy_constraints);
288 bool CanQueryVariableValues()
override;
289 double VariableValue(
const MPVariable* variable)
override;
290 void AddCut(
const LinearRange& cutting_plane)
override;
291 void AddLazyConstraint(
const LinearRange& lazy_constraint)
override;
292 double SuggestSolution(
293 const absl::flat_hash_map<const MPVariable*, double>& solution)
override;
294 int64_t NumExploredNodes()
override;
298 void UpdateFromGurobiState(
299 const GurobiInternalCallbackContext& gurobi_internal_context);
305 template <
typename T>
307 const GurobiInternalCallbackContext& gurobi_internal_context,
309 void CheckedGurobiCall(
int gurobi_error_code)
const;
311 template <
typename GRBConstra
intFunction>
312 void AddGeneratedConstraint(
const LinearRange& linear_range,
313 GRBConstraintFunction grb_constraint_function);
316 const std::vector<int>*
const mp_var_to_gurobi_var_;
317 const int num_gurobi_vars_;
319 const bool might_add_cuts_;
320 const bool might_add_lazy_constraints_;
323 GurobiInternalCallbackContext current_gurobi_internal_callback_context_;
324 bool variable_values_extracted_ =
false;
325 std::vector<double> gurobi_variable_values_;
328 void GurobiMPCallbackContext::CheckedGurobiCall(
int gurobi_error_code)
const {
329 ::operations_research::CheckedGurobiCall(gurobi_error_code, env_);
332 GurobiMPCallbackContext::GurobiMPCallbackContext(
333 GRBenv* env,
const std::vector<int>* mp_var_to_gurobi_var,
334 int num_gurobi_vars,
bool might_add_cuts,
bool might_add_lazy_constraints)
337 num_gurobi_vars_(num_gurobi_vars),
338 might_add_cuts_(might_add_cuts),
339 might_add_lazy_constraints_(might_add_lazy_constraints) {}
341 void GurobiMPCallbackContext::UpdateFromGurobiState(
342 const GurobiInternalCallbackContext& gurobi_internal_context) {
343 current_gurobi_internal_callback_context_ = gurobi_internal_context;
344 variable_values_extracted_ =
false;
347 int64_t GurobiMPCallbackContext::NumExploredNodes() {
349 case MPCallbackEvent::kMipNode:
350 return static_cast<int64_t>(GurobiCallbackGet<double>(
352 case MPCallbackEvent::kMipSolution:
353 return static_cast<int64_t>(GurobiCallbackGet<double>(
356 LOG(
FATAL) <<
"Node count is supported only for callback events MIP_NODE " 357 "and MIP_SOL, but was requested at: " 362 template <
typename T>
363 T GurobiMPCallbackContext::GurobiCallbackGet(
364 const GurobiInternalCallbackContext& gurobi_internal_context,
365 const int callback_code) {
368 GRBcbget(gurobi_internal_context.gurobi_internal_callback_data,
369 gurobi_internal_context.where, callback_code,
370 static_cast<void*>(&result)));
375 switch (current_gurobi_internal_callback_context_.where) {
377 return MPCallbackEvent::kPolling;
379 return MPCallbackEvent::kPresolve;
381 return MPCallbackEvent::kSimplex;
383 return MPCallbackEvent::kMip;
385 return MPCallbackEvent::kMipSolution;
387 return MPCallbackEvent::kMipNode;
389 return MPCallbackEvent::kMessage;
391 return MPCallbackEvent::kBarrier;
397 << current_gurobi_internal_callback_context_.where;
398 return MPCallbackEvent::kUnknown;
402 bool GurobiMPCallbackContext::CanQueryVariableValues() {
404 if (
where == MPCallbackEvent::kMipSolution) {
407 if (
where == MPCallbackEvent::kMipNode) {
408 const int gurobi_node_status = GurobiCallbackGet<int>(
415 double GurobiMPCallbackContext::VariableValue(
const MPVariable* variable) {
416 CHECK(variable !=
nullptr);
417 if (!variable_values_extracted_) {
419 CHECK(
where == MPCallbackEvent::kMipSolution ||
420 where == MPCallbackEvent::kMipNode)
421 <<
"You can only call VariableValue at " 422 <<
ToString(MPCallbackEvent::kMipSolution) <<
" or " 423 <<
ToString(MPCallbackEvent::kMipNode)
425 const int gurobi_get_var_param =
where == MPCallbackEvent::kMipNode
429 gurobi_variable_values_.resize(num_gurobi_vars_);
431 current_gurobi_internal_callback_context_.gurobi_internal_callback_data,
432 current_gurobi_internal_callback_context_.where, gurobi_get_var_param,
433 static_cast<void*>(gurobi_variable_values_.data())));
434 variable_values_extracted_ =
true;
436 return gurobi_variable_values_[mp_var_to_gurobi_var_->at(variable->index())];
439 template <
typename GRBConstra
intFunction>
440 void GurobiMPCallbackContext::AddGeneratedConstraint(
441 const LinearRange& linear_range,
442 GRBConstraintFunction grb_constraint_function) {
443 std::vector<int> variable_indices;
444 std::vector<double> variable_coefficients;
445 const int num_terms = linear_range.linear_expr().terms().size();
446 variable_indices.reserve(num_terms);
447 variable_coefficients.reserve(num_terms);
448 for (
const auto& var_coef_pair : linear_range.linear_expr().terms()) {
449 variable_indices.push_back(
450 mp_var_to_gurobi_var_->at(var_coef_pair.first->index()));
451 variable_coefficients.push_back(var_coef_pair.second);
453 if (std::isfinite(linear_range.upper_bound())) {
454 CheckedGurobiCall(grb_constraint_function(
455 current_gurobi_internal_callback_context_.gurobi_internal_callback_data,
456 variable_indices.size(), variable_indices.data(),
458 linear_range.upper_bound()));
460 if (std::isfinite(linear_range.lower_bound())) {
461 CheckedGurobiCall(grb_constraint_function(
462 current_gurobi_internal_callback_context_.gurobi_internal_callback_data,
463 variable_indices.size(), variable_indices.data(),
465 linear_range.lower_bound()));
469 void GurobiMPCallbackContext::AddCut(
const LinearRange& cutting_plane) {
470 CHECK(might_add_cuts_);
473 <<
"Cuts can only be added at MIP_NODE, tried to add cut at: " 475 AddGeneratedConstraint(cutting_plane,
GRBcbcut);
478 void GurobiMPCallbackContext::AddLazyConstraint(
479 const LinearRange& lazy_constraint) {
480 CHECK(might_add_lazy_constraints_);
483 where == MPCallbackEvent::kMipSolution)
484 <<
"Lazy constraints can only be added at MIP_NODE or MIP_SOL, tried to " 485 "add lazy constraint at: " 487 AddGeneratedConstraint(lazy_constraint,
GRBcblazy);
490 double GurobiMPCallbackContext::SuggestSolution(
491 const absl::flat_hash_map<const MPVariable*, double>& solution) {
494 <<
"Feasible solutions can only be added at MIP_NODE, tried to add " 498 std::vector<double> full_solution(num_gurobi_vars_,
GRB_UNDEFINED);
499 for (
const auto& variable_value : solution) {
500 const MPVariable*
var = variable_value.first;
501 full_solution[mp_var_to_gurobi_var_->at(
var->index())] =
502 variable_value.second;
507 current_gurobi_internal_callback_context_.gurobi_internal_callback_data,
508 full_solution.data(), &objval));
513 struct MPCallbackWithGurobiContext {
522 void* raw_model_and_callback) {
523 MPCallbackWithGurobiContext*
const callback_with_context =
524 static_cast<MPCallbackWithGurobiContext*>(raw_model_and_callback);
525 CHECK(callback_with_context !=
nullptr);
526 CHECK(callback_with_context->context !=
nullptr);
527 CHECK(callback_with_context->callback !=
nullptr);
528 GurobiInternalCallbackContext gurobi_internal_context{
530 callback_with_context->context->UpdateFromGurobiState(
531 gurobi_internal_context);
532 callback_with_context->callback->RunCallback(callback_with_context->context);
538 void GurobiInterface::CheckedGurobiCall(
int err)
const {
539 ::operations_research::CheckedGurobiCall(err, env_);
542 void GurobiInterface::SetIntAttr(
const char*
name,
int value) {
546 int GurobiInterface::GetIntAttr(
const char*
name)
const {
552 void GurobiInterface::SetDoubleAttr(
const char*
name,
double value) {
556 double GurobiInterface::GetDoubleAttr(
const char*
name)
const {
562 void GurobiInterface::SetIntAttrElement(
const char*
name,
int index,
567 int GurobiInterface::GetIntAttrElement(
const char*
name,
int index)
const {
573 void GurobiInterface::SetDoubleAttrElement(
const char*
name,
int index,
577 double GurobiInterface::GetDoubleAttrElement(
const char*
name,
584 std::vector<double> GurobiInterface::GetDoubleAttrArray(
const char*
name,
586 std::vector<double> results(elements);
592 void GurobiInterface::SetCharAttrElement(
const char*
name,
int index,
596 char GurobiInterface::GetCharAttrElement(
const char*
name,
int index)
const {
603 GurobiInterface::GurobiInterface(
MPSolver*
const solver,
bool mip)
608 current_solution_index_(0) {
619 absl::GetFlag(FLAGS_num_gurobi_threads)));
631 const absl::MutexLock lock(&hold_interruptions_mutex_);
656 mp_var_to_gurobi_var_.clear();
657 mp_cons_to_gurobi_linear_cons_.clear();
658 num_gurobi_vars_ = 0;
659 num_gurobi_linear_cons_ = 0;
660 had_nonincremental_change_ =
false;
671 SetDoubleAttrElement(
GRB_DBL_ATTR_LB, mp_var_to_gurobi_var_.at(var_index),
673 SetDoubleAttrElement(
GRB_DBL_ATTR_UB, mp_var_to_gurobi_var_.at(var_index),
699 had_nonincremental_change_ =
true;
716 had_nonincremental_change_ =
true;
727 double new_value,
double old_value) {
732 int grb_var = mp_var_to_gurobi_var_.at(variable->
index());
733 int grb_cons = mp_cons_to_gurobi_linear_cons_.at(constraint->
index());
735 had_nonincremental_change_ =
true;
740 GRBchgcoeffs(model_, 1, &grb_cons, &grb_var, &new_value));
748 had_nonincremental_change_ =
true;
760 mp_var_to_gurobi_var_.at(variable->
index()),
769 if (!had_nonincremental_change_) {
778 if (!had_nonincremental_change_) {
780 for (
const auto& entry :
solver_->objective_->coefficients_) {
789 update_branching_priorities_ =
true;
798 return static_cast<int64_t>(iter);
806 LOG(DFATAL) <<
"Number of nodes only available for discrete problems.";
812 int gurobi_basis_status)
const {
813 switch (gurobi_basis_status) {
823 LOG(DFATAL) <<
"Unknown GRB basis status.";
829 int gurobi_basis_status,
int constraint_index)
const {
830 const int grb_index = mp_cons_to_gurobi_linear_cons_.at(constraint_index);
832 LOG(DFATAL) <<
"Basis status not available for nonlinear constraints.";
835 switch (gurobi_basis_status) {
840 double tolerance = 0.0;
845 VLOG(4) <<
"constraint " << constraint_index <<
" , slack = " << slack
846 <<
" , sense = " << sense;
847 if (fabs(slack) <= tolerance) {
868 LOG(DFATAL) <<
"Basis status only available after a solution has " 873 LOG(DFATAL) <<
"Basis status only available for continuous problems.";
876 const int grb_index = mp_cons_to_gurobi_linear_cons_.at(constraint_index);
878 LOG(DFATAL) <<
"Basis status not available for nonlinear constraints.";
881 const int gurobi_basis_status =
883 return TransformGRBConstraintBasisStatus(gurobi_basis_status,
891 LOG(DFATAL) <<
"Basis status only available after a solution has " 896 LOG(DFATAL) <<
"Basis status only available for continuous problems.";
899 const int grb_index = mp_var_to_gurobi_var_.at(variable_index);
900 const int gurobi_basis_status =
902 return TransformGRBVarBasisStatus(gurobi_basis_status);
907 const int total_num_vars =
solver_->variables_.size();
919 var->name().empty() ? nullptr :
var->name().c_str()));
920 mp_var_to_gurobi_var_.push_back(num_gurobi_vars_++);
924 std::vector<int> grb_cons_ind;
925 std::vector<int> grb_var_ind;
926 std::vector<double>
coef;
933 const int grb_ct_idx = mp_cons_to_gurobi_linear_cons_.at(
ct->index());
935 DCHECK(
ct->indicator_variable() ==
nullptr);
936 for (
const auto& entry :
ct->coefficients_) {
937 const int var_index = entry.first->index();
941 grb_cons_ind.push_back(grb_ct_idx);
942 grb_var_ind.push_back(mp_var_to_gurobi_var_.at(var_index));
943 coef.push_back(entry.second);
947 if (!grb_cons_ind.empty()) {
948 CheckedGurobiCall(
GRBchgcoeffs(model_, grb_cons_ind.size(),
949 grb_cons_ind.data(), grb_var_ind.data(),
958 int total_num_rows =
solver_->constraints_.size();
964 const int size =
ct->coefficients_.size();
965 std::vector<int> grb_vars;
966 std::vector<double> coefs;
967 grb_vars.reserve(size);
969 for (
const auto& entry :
ct->coefficients_) {
970 const int var_index = entry.first->index();
972 grb_vars.push_back(mp_var_to_gurobi_var_.at(var_index));
973 coefs.push_back(entry.second);
976 ct->name().empty() ? nullptr : const_cast<char*>(
ct->name().c_str());
977 if (
ct->indicator_variable() !=
nullptr) {
978 const int grb_ind_var =
979 mp_var_to_gurobi_var_.at(
ct->indicator_variable()->index());
980 if (
ct->lb() > -std::numeric_limits<double>::infinity()) {
982 model_,
name, grb_ind_var,
ct->indicator_value(), size,
983 grb_vars.data(), coefs.data(),
986 if (
ct->ub() < std::numeric_limits<double>::infinity() &&
987 ct->lb() !=
ct->ub()) {
989 model_,
name, grb_ind_var,
ct->indicator_value(), size,
992 mp_cons_to_gurobi_linear_cons_.push_back(-1);
996 if (
ct->lb() ==
ct->ub()) {
997 CheckedGurobiCall(
GRBaddconstr(model_, size, grb_vars.data(),
1000 }
else if (
ct->lb() == -std::numeric_limits<double>::infinity()) {
1001 CheckedGurobiCall(
GRBaddconstr(model_, size, grb_vars.data(),
1004 }
else if (
ct->ub() == std::numeric_limits<double>::infinity()) {
1005 CheckedGurobiCall(
GRBaddconstr(model_, size, grb_vars.data(),
1010 coefs.data(),
ct->lb(),
ct->ub(),
1016 mp_cons_to_gurobi_linear_cons_.push_back(num_gurobi_linear_cons_++);
1038 bool GurobiInterface::SetSolverSpecificParametersAsString(
1043 void GurobiInterface::SetRelativeMipGap(
double value) {
1048 LOG(
WARNING) <<
"The relative MIP gap is only available " 1049 <<
"for discrete problems.";
1059 void GurobiInterface::SetPrimalTolerance(
double value) {
1070 void GurobiInterface::SetDualTolerance(
double value) {
1075 void GurobiInterface::SetPresolveMode(
int value) {
1094 void GurobiInterface::SetScalingMode(
int value) {
1114 void GurobiInterface::SetLpAlgorithm(
int value) {
1134 int GurobiInterface::SolutionCount()
const {
1138 bool GurobiInterface::ModelIsNonincremental()
const {
1140 if (c->indicator_variable() !=
nullptr) {
1153 ModelIsNonincremental() || had_nonincremental_change_) {
1164 VLOG(1) << absl::StrFormat(
"Model built in %s.",
1168 for (
const std::pair<const MPVariable*, double>& p :
1171 mp_var_to_gurobi_var_.at(p.first->index()), p.second);
1175 if (update_branching_priorities_) {
1178 mp_var_to_gurobi_var_.at(
var->index()),
1179 var->branching_priority());
1181 update_branching_priorities_ =
false;
1196 SetParameters(param);
1198 solver_->solver_specific_parameter_string_);
1200 std::unique_ptr<GurobiMPCallbackContext> gurobi_context;
1201 MPCallbackWithGurobiContext mp_callback_with_context;
1202 int gurobi_precrush = 0;
1203 int gurobi_lazy_constraint = 0;
1204 if (callback_ ==
nullptr) {
1207 gurobi_context = absl::make_unique<GurobiMPCallbackContext>(
1208 env_, &mp_var_to_gurobi_var_, num_gurobi_vars_,
1210 mp_callback_with_context.context = gurobi_context.get();
1211 mp_callback_with_context.callback = callback_;
1213 model_, CallbackImpl, static_cast<void*>(&mp_callback_with_context)));
1229 VLOG(1) << absl::StrFormat(
"Solved in %s.",
1235 VLOG(1) << absl::StrFormat(
"Solution status %d.\n", optimization_status);
1236 const int solution_count = SolutionCount();
1238 switch (optimization_status) {
1254 if (solution_count > 0) {
1268 <<
"Best objective bound is not available, error=" << error
1275 current_solution_index_ = 0;
1281 const std::vector<double> grb_variable_values =
1283 for (
int i = 0; i <
solver_->variables_.size(); ++i) {
1285 const double val = grb_variable_values.at(mp_var_to_gurobi_var_.at(i));
1286 var->set_solution_value(val);
1287 VLOG(3) <<
var->name() <<
", value = " << val;
1292 const std::vector<double> grb_reduced_costs =
1294 for (
int i = 0; i <
solver_->variables_.size(); ++i) {
1296 const double rc = grb_reduced_costs.at(mp_var_to_gurobi_var_.at(i));
1297 var->set_reduced_cost(rc);
1298 VLOG(4) <<
var->name() <<
", reduced cost = " << rc;
1303 std::vector<double> grb_dual_values =
1305 for (
int i = 0; i <
solver_->constraints_.size(); ++i) {
1307 const double dual_value =
1308 grb_dual_values.at(mp_cons_to_gurobi_linear_cons_.at(i));
1309 ct->set_dual_value(dual_value);
1310 VLOG(4) <<
"row " <<
ct->index() <<
", dual value = " << dual_value;
1324 if (interrupt !=
nullptr)
return absl::nullopt;
1329 if (status_or.ok())
return status_or.value();
1332 if (absl::IsUnimplemented(status_or.status()))
return absl::nullopt;
1335 LOG(
INFO) <<
"Invalid Gurobi status: " << status_or.status();
1339 response.set_status_str(status_or.status().ToString());
1345 if (!mip_)
return false;
1352 if (current_solution_index_ + 1 >= SolutionCount()) {
1355 current_solution_index_++;
1361 const std::vector<double> grb_variable_values =
1364 for (
int i = 0; i <
solver_->variables_.size(); ++i) {
1366 var->set_solution_value(
1367 grb_variable_values.at(mp_var_to_gurobi_var_.at(i)));
1381 VLOG(1) <<
"Writing Gurobi model file \"" << filename <<
"\".";
1382 const int status =
GRBwrite(model_, filename.c_str());
1393 callback_ = mp_callback;
MPSolverInterface * BuildGurobiInterface(bool mip, MPSolver *const solver)
std::function< const char *(GRBenv *env)> GRBgeterrormsg
#define GRB_INT_PAR_PRECRUSH
ResultStatus
The status of solving the problem.
std::function< int(GRBmodel *model, const char *attrname, int element, double *valueP)> GRBgetdblattrelement
#define GRB_METHOD_PRIMAL
void set_variable_as_extracted(int var_index, bool extracted)
Advanced usage: incrementality from one solve to the next.
void AddVariable(MPVariable *const var) override
#define GRB_INT_PAR_OUTPUTFLAG
#define GRB_INT_ATTR_NUMVARS
#define GRB_GREATER_EQUAL
bool SupportsCallbacks() const override
double best_objective_bound_
const std::vector< MPConstraint * > & constraints() const
Returns the array of constraints handled by the MPSolver.
std::string SolverVersion() const override
#define GRB_CHAR_ATTR_VTYPE
void set_constraint_as_extracted(int ct_index, bool extracted)
void BranchingPriorityChangedForVariable(int var_index) override
std::function< int(GRBmodel *model, const char *attrname, int *valueP)> GRBgetintattr
#define GRB_DBL_ATTR_NODECOUNT
int64_t nodes() const override
std::function< int(GRBmodel *model, const char *filename)> GRBwrite
SynchronizationStatus sync_status_
#define GRB_DBL_PAR_INTFEASTOL
#define GRB_INT_ATTR_CBASIS
std::function< int(GRBenv *env, const char *paramname, double value)> GRBsetdblparam
#define VLOG(verboselevel)
const MPObjective & Objective() const
Returns the objective object.
void ExtractNewConstraints() override
#define GRB_INT_ATTR_VBASIS
A C++ wrapper that provides a simple and unified interface to several linear programming and mixed in...
void SetVariableBounds(int var_index, double lb, double ub) override
std::function< GRBenv *(GRBmodel *model)> GRBgetenv
absl::StatusOr< GRBenv * > GetGurobiEnv()
struct _GRBmodel GRBmodel
std::function< int(void *cbdata, int lazylen, const int *lazyind, const double *lazyval, char lazysense, double lazyrhs)> GRBcblazy
const absl::string_view ToString(MPSolver::OptimizationProblemType optimization_problem_type)
#define GRB_DBL_PAR_OBJSCALE
std::function< int(GRBmodel *model, const char *attrname, int element, char newvalue)> GRBsetcharattrelement
void SetObjectiveCoefficient(const MPVariable *const variable, double coefficient) override
std::function< int(GRBenv *env, GRBmodel **modelP, const char *Pname, int numvars, double *obj, double *lb, double *ub, char *vtype, char **varnames)> GRBnewmodel
void AddRowConstraint(MPConstraint *const ct) override
Advanced usage: presolve mode.
BasisStatus
Advanced usage: possible basis status values for a variable and the slack variable of a linear constr...
void ExtractNewVariables() override
std::function< int(GRBenv *env, const char *paramname, int value)> GRBsetintparam
bool InterruptSolve() override
MPSolver::ResultStatus result_status_
#define GRB_CHAR_ATTR_SENSE
#define GRB_DBL_PAR_MIPGAP
void * gurobi_internal_callback_data
int64_t iterations() const override
GurobiInterface(MPSolver *const solver, bool mip)
~GurobiInterface() override
int GetIntegerParam(MPSolverParameters::IntegerParam param) const
Returns the value of an integer parameter.
std::function< int(GRBmodel *model)> GRBfreemodel
std::function< int(GRBmodel *model, int numnz, int *vind, double *vval, double obj, double lb, double ub, char vtype, const char *varname)> GRBaddvar
#define GRB_CB_MIPNODE_NODCNT
#define GRB_CB_MIPSOL_NODCNT
void * underlying_solver() override
The class for variables of a Mathematical Programming (MP) model.
std::function< int(GRBenv *env)> GRBresetparams
#define GRB_INT_ATTR_STATUS
void ExtractObjective() override
#define GRB_DBL_ATTR_SLACK
std::function< int(GRBmodel *model, const char *attrname, double *valueP)> GRBgetdblattr
bool SetSolverSpecificParametersAsString(const std::string ¶meters)
Advanced usage: pass solver specific parameters in text format.
ABSL_FLAG(int, num_gurobi_threads, 4, "Number of threads available for Gurobi.")
bool NextSolution() override
#define GRB_DBL_PAR_OPTIMALITYTOL
std::function< int(void *cbdata, const double *solution, double *objvalP)> GRBcbsolution
friend class MPConstraint
#define GRB_INT_PAR_SOLUTIONNUMBER
std::function< int(void *cbdata, int cutlen, const int *cutind, const double *cutval, char cutsense, double cutrhs)> GRBcbcut
void SetConstraintBounds(int row_index, double lb, double ub) override
std::function< int(GRBmodel *model, int cnt, int *cind, int *vind, double *val)> GRBchgcoeffs
#define GRB_DBL_ATTR_OBJVAL
std::function< int(GRBmodel *model, const char *attrname, int element, int newvalue)> GRBsetintattrelement
#define GRB_INT_PAR_SCALEFLAG
void SetCallback(MPCallback *mp_callback) override
std::function< int(void *cbdata, int where, int what, void *resultP)> GRBcbget
void ClearConstraint(MPConstraint *const constraint) override
std::function< void(GRBmodel *model)> GRBterminate
#define GRB_DBL_PAR_TIMELIMIT
std::function< int(GRBmodel *lp, const char *name, int binvar, int binval, int nvars, const int *vars, const double *vals, char sense, double rhs)> GRBaddgenconstrIndicator
virtual void SetIntegerParamToUnsupportedValue(MPSolverParameters::IntegerParam param, int value)
std::function< int(GRBmodel *model, int(GUROBI_STDCALL *cb)(CB_ARGS), void *usrdata)> GRBsetcallbackfunc
#define GRB_DBL_PAR_FEASIBILITYTOL
#define GRB_DBL_ATTR_START
std::function< int(GRBmodel *model, const char *attrname, int element, double newvalue)> GRBsetdblattrelement
std::function< int(GRBmodel *model)> GRBupdatemodel
bool IsMIP() const override
void SetCommonParameters(const MPSolverParameters ¶m)
int64_t time_limit() const
static constexpr int64_t kUnknownNumberOfIterations
std::function< int(GRBenv *dest, GRBenv *src)> GRBcopyparams
The class for constraints of a Mathematical Programming (MP) model.
feasible, or stopped by limit.
std::function< int(GRBmodel *model, const char *attrname, double newvalue)> GRBsetdblattr
#define DCHECK_GE(val1, val2)
void SetMIPParameters(const MPSolverParameters ¶m)
SharedResponseManager * response
#define GRB_NONBASIC_UPPER
#define GRB_DBL_ATTR_OBJCON
bool IsContinuous() const override
#define GRB_INT_PAR_PRESOLVE
#define CHECK_EQ(val1, val2)
bool constraint_is_extracted(int ct_index) const
std::function< int(GRBmodel *model, const char *attrname, int element, char *valueP)> GRBgetcharattrelement
void InvalidateSolutionSynchronization()
#define GRB_INT_PAR_METHOD
#define GRB_INT_ATTR_SOLCOUNT
int index() const
Returns the index of the constraint in the MPSolver::constraints_.
#define GRB_INT_ATTR_MODELSENSE
#define GRB_CB_MIPNODE_STATUS
absl::Status SetSolverSpecificParameters(const std::string ¶meters, GRBenv *gurobi)
#define LOG_IF(severity, condition)
#define GRB_DBL_ATTR_OBJBOUND
#define DCHECK(condition)
int last_constraint_index_
int index() const
Returns the index of the variable in the MPSolver::variables_.
double ComputeExactConditionNumber() const override
absl::Duration GetDuration() const
void SetObjectiveOffset(double value) override
#define GRB_INT_ATTR_BRANCHPRIORITY
std::function< int(GRBmodel *model)> GRBoptimize
#define GRB_CB_MIPSOL_SOL
bool CheckSolutionIsSynchronized() const
void SetOptimizationDirection(bool maximize) override
static constexpr int64_t kUnknownNumberOfNodes
#define DCHECK_EQ(val1, val2)
#define GRB_DBL_ATTR_POOLOBJVAL
bool CheckSolutionIsSynchronizedAndExists() const
void Write(const std::string &filename) override
void ClearObjective() override
#define GRB_INT_PAR_LAZYCONSTRAINTS
#define LOG_FIRST_N(severity, n)
void SetVariableInteger(int var_index, bool integer) override
std::function< int(GRBmodel *model, const char *attrname, int element, int *valueP)> GRBgetintattrelement
std::function< int(GRBmodel *model, const char *attrname, int newvalue)> GRBsetintattr
std::function< void(GRBenv *env)> GRBfreeenv
std::function< int(GRBmodel *model, int numnz, int *cind, double *cval, char sense, double rhs, const char *constrname)> GRBaddconstr
void SetCoefficient(MPConstraint *const constraint, const MPVariable *const variable, double new_value, double old_value) override
This mathematical programming (MP) solver class is the main class though which users build and solve ...
Collection of objects used to extend the Constraint Solver library.
bool IsLP() const override
Start solve from scratch.
#define GRB_METHOD_BARRIER
bool might_add_cuts() const
MPSolver::BasisStatus row_status(int constraint_index) const override
#define GRB_INT_PAR_THREADS
This class stores parameter settings for LP and MIP solvers.
#define GRB_DBL_ATTR_ITERCOUNT
Algorithm to solve linear programs.
MPSolver::BasisStatus column_status(int variable_index) const override
#define GRB_CB_MIPNODE_REL
void ResetExtractionInformation()
bool might_add_lazy_constraints() const
GurobiMPCallbackContext * context
bool enable_internal_solver_output() const
absl::optional< MPSolutionResponse > DirectlySolveProto(const MPModelRequest &request, std::atomic< bool > *interrupt) override
std::function< void(int *majorP, int *minorP, int *technicalP)> GRBversion
MPSolver::ResultStatus Solve(const MPSolverParameters ¶m) override
bool AddIndicatorConstraint(MPConstraint *const ct) override
std::function< int(GRBenv *env, const char *paramname, double *valueP)> GRBgetdblparam
absl::StatusOr< MPSolutionResponse > GurobiSolveProto(const MPModelRequest &request, GRBenv *gurobi_env)
double offset() const
Gets the constant term in the objective.
#define GRB_INT_ATTR_NUMCONSTRS
double time_limit_in_secs() const
bool variable_is_extracted(int var_index) const
#define GRB_NONBASIC_LOWER
std::function< int(GRBmodel *model, const char *attrname, int first, int len, double *values)> GRBgetdblattrarray
std::function< int(GRBmodel *model, int numnz, int *cind, double *cval, double lower, double upper, const char *constrname)> GRBaddrangeconstr