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_;
267void CheckedGurobiCall(
int err,
GRBenv*
const env) {
268 CHECK_EQ(0, err) <<
"Fatal error with code " << err <<
", due to "
273struct GurobiInternalCallbackContext {
279class 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_;
328void GurobiMPCallbackContext::CheckedGurobiCall(
int gurobi_error_code)
const {
329 ::operations_research::CheckedGurobiCall(gurobi_error_code, env_);
332GurobiMPCallbackContext::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) {}
341void GurobiMPCallbackContext::UpdateFromGurobiState(
342 const GurobiInternalCallbackContext& gurobi_internal_context) {
343 current_gurobi_internal_callback_context_ = gurobi_internal_context;
344 variable_values_extracted_ =
false;
347int64_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: "
363T 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;
402bool GurobiMPCallbackContext::CanQueryVariableValues() {
404 if (
where == MPCallbackEvent::kMipSolution) {
407 if (
where == MPCallbackEvent::kMipNode) {
408 const int gurobi_node_status = GurobiCallbackGet<int>(
415double 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())];
439template <
typename GRBConstra
intFunction>
440void 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()));
469void 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);
478void 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);
490double 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));
513struct 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);
538void GurobiInterface::CheckedGurobiCall(
int err)
const {
539 ::operations_research::CheckedGurobiCall(err, env_);
542void GurobiInterface::SetIntAttr(
const char*
name,
int value) {
546int GurobiInterface::GetIntAttr(
const char*
name)
const {
552void GurobiInterface::SetDoubleAttr(
const char*
name,
double value) {
556double GurobiInterface::GetDoubleAttr(
const char*
name)
const {
562void GurobiInterface::SetIntAttrElement(
const char*
name,
int index,
567int GurobiInterface::GetIntAttrElement(
const char*
name,
int index)
const {
573void GurobiInterface::SetDoubleAttrElement(
const char*
name,
int index,
577double GurobiInterface::GetDoubleAttrElement(
const char*
name,
584std::vector<double> GurobiInterface::GetDoubleAttrArray(
const char*
name,
586 std::vector<double> results(elements);
592void GurobiInterface::SetCharAttrElement(
const char*
name,
int index,
596char GurobiInterface::GetCharAttrElement(
const char*
name,
int index)
const {
603GurobiInterface::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_++);
1038bool GurobiInterface::SetSolverSpecificParametersAsString(
1043void GurobiInterface::SetRelativeMipGap(
double value) {
1048 LOG(
WARNING) <<
"The relative MIP gap is only available "
1049 <<
"for discrete problems.";
1059void GurobiInterface::SetPrimalTolerance(
double value) {
1070void GurobiInterface::SetDualTolerance(
double value) {
1075void GurobiInterface::SetPresolveMode(
int value) {
1094void GurobiInterface::SetScalingMode(
int value) {
1114void GurobiInterface::SetLpAlgorithm(
int value) {
1134int GurobiInterface::SolutionCount()
const {
1138bool 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;
#define LOG_IF(severity, condition)
#define LOG_FIRST_N(severity, n)
#define CHECK_EQ(val1, val2)
#define DCHECK_GE(val1, val2)
#define DCHECK(condition)
#define DCHECK_EQ(val1, val2)
#define VLOG(verboselevel)
absl::Duration GetDuration() const
void BranchingPriorityChangedForVariable(int var_index) override
void AddRowConstraint(MPConstraint *const ct) override
GurobiInterface(MPSolver *const solver, bool mip)
void Write(const std::string &filename) override
void ExtractObjective() override
void * underlying_solver() override
bool IsContinuous() const override
void SetConstraintBounds(int row_index, double lb, double ub) override
bool InterruptSolve() override
MPSolver::ResultStatus Solve(const MPSolverParameters ¶m) override
void ClearConstraint(MPConstraint *const constraint) override
void SetObjectiveCoefficient(const MPVariable *const variable, double coefficient) override
~GurobiInterface() override
void SetCoefficient(MPConstraint *const constraint, const MPVariable *const variable, double new_value, double old_value) override
MPSolver::BasisStatus row_status(int constraint_index) const override
bool SupportsCallbacks() const override
double ComputeExactConditionNumber() const override
void SetVariableInteger(int var_index, bool integer) override
void SetCallback(MPCallback *mp_callback) override
void SetObjectiveOffset(double value) override
void ExtractNewConstraints() override
absl::optional< MPSolutionResponse > DirectlySolveProto(const MPModelRequest &request, std::atomic< bool > *interrupt) override
std::string SolverVersion() const override
void AddVariable(MPVariable *const var) override
void ExtractNewVariables() override
int64_t nodes() const override
void SetVariableBounds(int var_index, double lb, double ub) override
bool IsLP() const override
bool IsMIP() const override
int64_t iterations() const override
bool AddIndicatorConstraint(MPConstraint *const ct) override
bool NextSolution() override
void SetOptimizationDirection(bool maximize) override
MPSolver::BasisStatus column_status(int variable_index) const override
void ClearObjective() override
bool might_add_cuts() const
bool might_add_lazy_constraints() const
The class for constraints of a Mathematical Programming (MP) model.
int index() const
Returns the index of the constraint in the MPSolver::constraints_.
bool enable_internal_solver_output() const
double offset() const
Gets the constant term in the objective.
This mathematical programming (MP) solver class is the main class though which users build and solve ...
const std::vector< MPConstraint * > & constraints() const
Returns the array of constraints handled by the MPSolver.
ResultStatus
The status of solving the problem.
@ FEASIBLE
feasible, or stopped by limit.
@ NOT_SOLVED
not been solved yet.
@ INFEASIBLE
proven infeasible.
@ UNBOUNDED
proven unbounded.
bool SetSolverSpecificParametersAsString(const std::string ¶meters)
Advanced usage: pass solver specific parameters in text format.
int64_t time_limit() const
const MPObjective & Objective() const
Returns the objective object.
double time_limit_in_secs() const
BasisStatus
Advanced usage: possible basis status values for a variable and the slack variable of a linear constr...
virtual void SetIntegerParamToUnsupportedValue(MPSolverParameters::IntegerParam param, int value)
friend class MPConstraint
void set_constraint_as_extracted(int ct_index, bool extracted)
MPSolver::ResultStatus result_status_
void InvalidateSolutionSynchronization()
void SetMIPParameters(const MPSolverParameters ¶m)
int last_constraint_index_
bool constraint_is_extracted(int ct_index) const
static constexpr int64_t kUnknownNumberOfNodes
double best_objective_bound_
bool CheckSolutionIsSynchronizedAndExists() const
bool CheckSolutionIsSynchronized() const
void ResetExtractionInformation()
bool variable_is_extracted(int var_index) const
static constexpr int64_t kUnknownNumberOfIterations
void set_variable_as_extracted(int var_index, bool extracted)
void SetCommonParameters(const MPSolverParameters ¶m)
SynchronizationStatus sync_status_
This class stores parameter settings for LP and MIP solvers.
@ INCREMENTALITY_OFF
Start solve from scratch.
@ SCALING_ON
Scaling is on.
@ SCALING_OFF
Scaling is off.
@ LP_ALGORITHM
Algorithm to solve linear programs.
@ PRESOLVE
Advanced usage: presolve mode.
@ INCREMENTALITY
Advanced usage: incrementality from one solve to the next.
@ BARRIER
Barrier algorithm.
@ PRESOLVE_ON
Presolve is on.
@ PRESOLVE_OFF
Presolve is off.
int GetIntegerParam(MPSolverParameters::IntegerParam param) const
Returns the value of an integer parameter.
The class for variables of a Mathematical Programming (MP) model.
int index() const
Returns the index of the variable in the MPSolver::variables_.
SharedResponseManager * response
#define GRB_INT_ATTR_BRANCHPRIORITY
#define GRB_DBL_ATTR_START
#define GRB_DBL_PAR_MIPGAP
#define GRB_DBL_PAR_FEASIBILITYTOL
#define GRB_NONBASIC_LOWER
#define GRB_INT_ATTR_MODELSENSE
#define GRB_INT_ATTR_VBASIS
#define GRB_GREATER_EQUAL
#define GRB_DBL_ATTR_NODECOUNT
#define GRB_INT_PAR_PRESOLVE
#define GRB_DBL_ATTR_ITERCOUNT
#define GRB_INT_PAR_THREADS
#define GRB_CB_MIPNODE_REL
#define GRB_INT_PAR_METHOD
#define GRB_DBL_ATTR_OBJVAL
#define GRB_DBL_ATTR_SLACK
#define GRB_INT_PAR_LAZYCONSTRAINTS
#define GRB_DBL_PAR_OPTIMALITYTOL
#define GRB_CB_MIPSOL_NODCNT
#define GRB_CB_MIPNODE_STATUS
#define GRB_INT_PAR_SCALEFLAG
#define GRB_METHOD_BARRIER
struct _GRBmodel GRBmodel
#define GRB_CHAR_ATTR_VTYPE
#define GRB_NONBASIC_UPPER
#define GRB_DBL_ATTR_OBJCON
#define GRB_DBL_PAR_INTFEASTOL
#define GRB_CHAR_ATTR_SENSE
#define GRB_INT_ATTR_NUMVARS
#define GRB_INT_ATTR_NUMCONSTRS
#define GRB_INT_ATTR_CBASIS
#define GRB_INT_ATTR_STATUS
#define GRB_DBL_ATTR_POOLOBJVAL
#define GRB_INT_PAR_SOLUTIONNUMBER
#define GRB_INT_ATTR_SOLCOUNT
#define GRB_METHOD_PRIMAL
#define GRB_INT_PAR_OUTPUTFLAG
#define GRB_DBL_PAR_TIMELIMIT
#define GRB_CB_MIPSOL_SOL
#define GRB_DBL_ATTR_OBJBOUND
#define GRB_INT_PAR_PRECRUSH
#define GRB_DBL_PAR_OBJSCALE
#define GRB_CB_MIPNODE_NODCNT
void * gurobi_internal_callback_data
GurobiMPCallbackContext * context
ABSL_FLAG(int, num_gurobi_threads, 4, "Number of threads available for Gurobi.")
A C++ wrapper that provides a simple and unified interface to several linear programming and mixed in...
Collection of objects used to extend the Constraint Solver library.
std::function< int(GRBmodel *model, const char *attrname, int element, char *valueP)> GRBgetcharattrelement
std::function< int(GRBmodel *model, int numnz, int *cind, double *cval, char sense, double rhs, const char *constrname)> GRBaddconstr
std::function< int(GRBmodel *model, const char *attrname, double *valueP)> GRBgetdblattr
MPSolverInterface * BuildGurobiInterface(bool mip, MPSolver *const solver)
std::function< int(GRBmodel *model, int numnz, int *vind, double *vval, double obj, double lb, double ub, char vtype, const char *varname)> GRBaddvar
const absl::string_view ToString(MPSolver::OptimizationProblemType optimization_problem_type)
std::function< void(int *majorP, int *minorP, int *technicalP)> GRBversion
std::function< int(GRBmodel *model, const char *attrname, int newvalue)> GRBsetintattr
std::function< int(void *cbdata, int lazylen, const int *lazyind, const double *lazyval, char lazysense, double lazyrhs)> GRBcblazy
std::function< int(GRBenv *env, const char *paramname, int value)> GRBsetintparam
std::function< int(void *cbdata, int where, int what, void *resultP)> GRBcbget
std::function< int(GRBmodel *model, const char *attrname, int element, int *valueP)> GRBgetintattrelement
std::function< int(GRBenv *dest, GRBenv *src)> GRBcopyparams
std::function< int(GRBmodel *model)> GRBfreemodel
std::function< void(GRBmodel *model)> GRBterminate
std::function< int(GRBenv *env, const char *paramname, double *valueP)> GRBgetdblparam
std::function< const char *(GRBenv *env)> GRBgeterrormsg
std::function< int(GRBmodel *model, int cnt, int *cind, int *vind, double *val)> GRBchgcoeffs
absl::StatusOr< GRBenv * > GetGurobiEnv()
std::function< GRBenv *(GRBmodel *model)> GRBgetenv
std::function< int(GRBmodel *model, const char *attrname, int element, double newvalue)> GRBsetdblattrelement
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
std::function< int(GRBenv *env)> GRBresetparams
std::function< int(GRBmodel *model, const char *attrname, int first, int len, double *values)> GRBgetdblattrarray
std::function< int(GRBmodel *model)> GRBupdatemodel
absl::Status SetSolverSpecificParameters(const std::string ¶meters, GRBenv *gurobi)
std::function< int(GRBmodel *model, int numnz, int *cind, double *cval, double lower, double upper, const char *constrname)> GRBaddrangeconstr
absl::StatusOr< MPSolutionResponse > GurobiSolveProto(const MPModelRequest &request, GRBenv *gurobi_env)
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(GRBmodel *model, const char *attrname, int element, double *valueP)> GRBgetdblattrelement
std::function< int(void *cbdata, const double *solution, double *objvalP)> GRBcbsolution
std::function< int(GRBmodel *model)> GRBoptimize
std::function< int(GRBmodel *model, const char *filename)> GRBwrite
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< void(GRBenv *env)> GRBfreeenv
std::function< int(void *cbdata, int cutlen, const int *cutind, const double *cutval, char cutsense, double cutrhs)> GRBcbcut
std::function< int(GRBmodel *model, const char *attrname, double newvalue)> GRBsetdblattr
std::function< int(GRBmodel *model, int(GUROBI_STDCALL *cb)(CB_ARGS), void *usrdata)> GRBsetcallbackfunc
std::function< int(GRBmodel *model, const char *attrname, int *valueP)> GRBgetintattr
std::function< int(GRBenv *env, const char *paramname, double value)> GRBsetdblparam