54#include "absl/status/status.h"
55#include "absl/strings/match.h"
56#include "absl/strings/str_format.h"
68 "Number of threads available for Gurobi.");
85 const MPModelRequest& request)
override;
88 void Write(
const std::string& filename)
override;
92 void Reset()
override;
106 const MPVariable*
const variable,
double new_value,
107 double old_value)
override;
133 bool IsLP()
const override {
return !mip_; }
134 bool IsMIP()
const override {
return mip_; }
141 int major, minor, technical;
143 return absl::StrFormat(
"Gurobi library version %d.%d.%d\n", major, minor,
148 const absl::MutexLock lock(&hold_interruptions_mutex_);
157 LOG(DFATAL) <<
"ComputeExactConditionNumber not implemented for"
158 <<
" GUROBI_MIXED_INTEGER_PROGRAMMING";
163 LOG(DFATAL) <<
"ComputeExactConditionNumber not implemented for"
164 <<
" GUROBI_LINEAR_PROGRAMMING";
198 bool SetSolverSpecificParametersAsString(
201 void SetRelativeMipGap(
double value)
override;
202 void SetPrimalTolerance(
double value)
override;
203 void SetDualTolerance(
double value)
override;
204 void SetPresolveMode(
int value)
override;
205 void SetScalingMode(
int value)
override;
206 void SetLpAlgorithm(
int value)
override;
209 int gurobi_basis_status)
const;
211 int gurobi_basis_status,
int constraint_index)
const;
214 bool ModelIsNonincremental()
const;
216 void SetIntAttr(
const char*
name,
int value);
217 int GetIntAttr(
const char*
name)
const;
218 void SetDoubleAttr(
const char*
name,
double value);
219 double GetDoubleAttr(
const char*
name)
const;
221 int GetIntAttrElement(
const char*
name,
int index)
const;
222 void SetDoubleAttrElement(
const char*
name,
int index,
double value);
223 double GetDoubleAttrElement(
const char*
name,
int index)
const;
224 std::vector<double> GetDoubleAttrArray(
const char*
name,
int elements);
226 char GetCharAttrElement(
const char*
name,
int index)
const;
228 void CheckedGurobiCall(
int err)
const;
230 int SolutionCount()
const;
235 int current_solution_index_;
237 bool update_branching_priorities_ =
false;
243 std::vector<int> mp_var_to_gurobi_var_;
248 std::vector<int> mp_cons_to_gurobi_linear_cons_;
250 int num_gurobi_vars_ = 0;
253 int num_gurobi_linear_cons_ = 0;
255 bool had_nonincremental_change_ =
false;
260 mutable absl::Mutex hold_interruptions_mutex_;
265void CheckedGurobiCall(
int err,
GRBenv*
const env) {
266 CHECK_EQ(0, err) <<
"Fatal error with code " << err <<
", due to "
271struct GurobiInternalCallbackContext {
277class GurobiMPCallbackContext :
public MPCallbackContext {
279 GurobiMPCallbackContext(
GRBenv* env,
280 const std::vector<int>* mp_var_to_gurobi_var,
281 int num_gurobi_vars,
bool might_add_cuts,
282 bool might_add_lazy_constraints);
286 bool CanQueryVariableValues()
override;
287 double VariableValue(
const MPVariable* variable)
override;
288 void AddCut(
const LinearRange& cutting_plane)
override;
289 void AddLazyConstraint(
const LinearRange& lazy_constraint)
override;
290 double SuggestSolution(
291 const absl::flat_hash_map<const MPVariable*, double>& solution)
override;
292 int64 NumExploredNodes()
override;
296 void UpdateFromGurobiState(
297 const GurobiInternalCallbackContext& gurobi_internal_context);
303 template <
typename T>
305 const GurobiInternalCallbackContext& gurobi_internal_context,
307 void CheckedGurobiCall(
int gurobi_error_code)
const;
309 template <
typename GRBConstra
intFunction>
310 void AddGeneratedConstraint(
const LinearRange& linear_range,
311 GRBConstraintFunction grb_constraint_function);
314 const std::vector<int>*
const mp_var_to_gurobi_var_;
315 const int num_gurobi_vars_;
317 const bool might_add_cuts_;
318 const bool might_add_lazy_constraints_;
321 GurobiInternalCallbackContext current_gurobi_internal_callback_context_;
322 bool variable_values_extracted_ =
false;
323 std::vector<double> gurobi_variable_values_;
326void GurobiMPCallbackContext::CheckedGurobiCall(
int gurobi_error_code)
const {
327 ::operations_research::CheckedGurobiCall(gurobi_error_code, env_);
330GurobiMPCallbackContext::GurobiMPCallbackContext(
331 GRBenv* env,
const std::vector<int>* mp_var_to_gurobi_var,
332 int num_gurobi_vars,
bool might_add_cuts,
bool might_add_lazy_constraints)
335 num_gurobi_vars_(num_gurobi_vars),
336 might_add_cuts_(might_add_cuts),
337 might_add_lazy_constraints_(might_add_lazy_constraints) {}
339void GurobiMPCallbackContext::UpdateFromGurobiState(
340 const GurobiInternalCallbackContext& gurobi_internal_context) {
341 current_gurobi_internal_callback_context_ = gurobi_internal_context;
342 variable_values_extracted_ =
false;
345int64 GurobiMPCallbackContext::NumExploredNodes() {
347 case MPCallbackEvent::kMipNode:
348 return static_cast<int64>(GurobiCallbackGet<double>(
350 case MPCallbackEvent::kMipSolution:
351 return static_cast<int64>(GurobiCallbackGet<double>(
354 LOG(
FATAL) <<
"Node count is supported only for callback events MIP_NODE "
355 "and MIP_SOL, but was requested at: "
361T GurobiMPCallbackContext::GurobiCallbackGet(
362 const GurobiInternalCallbackContext& gurobi_internal_context,
363 const int callback_code) {
366 GRBcbget(gurobi_internal_context.gurobi_internal_callback_data,
367 gurobi_internal_context.where, callback_code,
368 static_cast<void*
>(&result)));
373 switch (current_gurobi_internal_callback_context_.where) {
375 return MPCallbackEvent::kPolling;
377 return MPCallbackEvent::kPresolve;
379 return MPCallbackEvent::kSimplex;
381 return MPCallbackEvent::kMip;
383 return MPCallbackEvent::kMipSolution;
385 return MPCallbackEvent::kMipNode;
387 return MPCallbackEvent::kMessage;
389 return MPCallbackEvent::kBarrier;
395 << current_gurobi_internal_callback_context_.where;
396 return MPCallbackEvent::kUnknown;
400bool GurobiMPCallbackContext::CanQueryVariableValues() {
402 if (
where == MPCallbackEvent::kMipSolution) {
405 if (
where == MPCallbackEvent::kMipNode) {
406 const int gurobi_node_status = GurobiCallbackGet<int>(
413double GurobiMPCallbackContext::VariableValue(
const MPVariable* variable) {
414 CHECK(variable !=
nullptr);
415 if (!variable_values_extracted_) {
417 CHECK(
where == MPCallbackEvent::kMipSolution ||
418 where == MPCallbackEvent::kMipNode)
419 <<
"You can only call VariableValue at "
420 <<
ToString(MPCallbackEvent::kMipSolution) <<
" or "
421 <<
ToString(MPCallbackEvent::kMipNode)
423 const int gurobi_get_var_param =
where == MPCallbackEvent::kMipNode
427 gurobi_variable_values_.resize(num_gurobi_vars_);
429 current_gurobi_internal_callback_context_.gurobi_internal_callback_data,
430 current_gurobi_internal_callback_context_.where, gurobi_get_var_param,
431 static_cast<void*
>(gurobi_variable_values_.data())));
432 variable_values_extracted_ =
true;
434 return gurobi_variable_values_[mp_var_to_gurobi_var_->at(variable->index())];
437template <
typename GRBConstra
intFunction>
438void GurobiMPCallbackContext::AddGeneratedConstraint(
439 const LinearRange& linear_range,
440 GRBConstraintFunction grb_constraint_function) {
441 std::vector<int> variable_indices;
442 std::vector<double> variable_coefficients;
443 const int num_terms = linear_range.linear_expr().terms().size();
444 variable_indices.reserve(num_terms);
445 variable_coefficients.reserve(num_terms);
446 for (
const auto& var_coef_pair : linear_range.linear_expr().terms()) {
447 variable_indices.push_back(
448 mp_var_to_gurobi_var_->at(var_coef_pair.first->index()));
449 variable_coefficients.push_back(var_coef_pair.second);
451 if (std::isfinite(linear_range.upper_bound())) {
452 CheckedGurobiCall(grb_constraint_function(
453 current_gurobi_internal_callback_context_.gurobi_internal_callback_data,
454 variable_indices.size(), variable_indices.data(),
456 linear_range.upper_bound()));
458 if (std::isfinite(linear_range.lower_bound())) {
459 CheckedGurobiCall(grb_constraint_function(
460 current_gurobi_internal_callback_context_.gurobi_internal_callback_data,
461 variable_indices.size(), variable_indices.data(),
463 linear_range.lower_bound()));
467void GurobiMPCallbackContext::AddCut(
const LinearRange& cutting_plane) {
468 CHECK(might_add_cuts_);
471 <<
"Cuts can only be added at MIP_NODE, tried to add cut at: "
473 AddGeneratedConstraint(cutting_plane,
GRBcbcut);
476void GurobiMPCallbackContext::AddLazyConstraint(
477 const LinearRange& lazy_constraint) {
478 CHECK(might_add_lazy_constraints_);
481 where == MPCallbackEvent::kMipSolution)
482 <<
"Lazy constraints can only be added at MIP_NODE or MIP_SOL, tried to "
483 "add lazy constraint at: "
485 AddGeneratedConstraint(lazy_constraint,
GRBcblazy);
488double GurobiMPCallbackContext::SuggestSolution(
489 const absl::flat_hash_map<const MPVariable*, double>& solution) {
492 <<
"Feasible solutions can only be added at MIP_NODE, tried to add "
496 std::vector<double> full_solution(num_gurobi_vars_,
GRB_UNDEFINED);
497 for (
const auto& variable_value : solution) {
498 const MPVariable*
var = variable_value.first;
499 full_solution[mp_var_to_gurobi_var_->at(
var->index())] =
500 variable_value.second;
505 current_gurobi_internal_callback_context_.gurobi_internal_callback_data,
506 full_solution.data(), &objval));
511struct MPCallbackWithGurobiContext {
519 int where,
void* raw_model_and_callback) {
520 MPCallbackWithGurobiContext*
const callback_with_context =
521 static_cast<MPCallbackWithGurobiContext*
>(raw_model_and_callback);
522 CHECK(callback_with_context !=
nullptr);
523 CHECK(callback_with_context->context !=
nullptr);
524 CHECK(callback_with_context->callback !=
nullptr);
525 GurobiInternalCallbackContext gurobi_internal_context{
527 callback_with_context->context->UpdateFromGurobiState(
528 gurobi_internal_context);
529 callback_with_context->callback->RunCallback(callback_with_context->context);
535void GurobiInterface::CheckedGurobiCall(
int err)
const {
536 ::operations_research::CheckedGurobiCall(err, env_);
539void GurobiInterface::SetIntAttr(
const char*
name,
int value) {
543int GurobiInterface::GetIntAttr(
const char*
name)
const {
549void GurobiInterface::SetDoubleAttr(
const char*
name,
double value) {
553double GurobiInterface::GetDoubleAttr(
const char*
name)
const {
559void GurobiInterface::SetIntAttrElement(
const char*
name,
int index,
564int GurobiInterface::GetIntAttrElement(
const char*
name,
int index)
const {
570void GurobiInterface::SetDoubleAttrElement(
const char*
name,
int index,
574double GurobiInterface::GetDoubleAttrElement(
const char*
name,
581std::vector<double> GurobiInterface::GetDoubleAttrArray(
const char*
name,
583 std::vector<double> results(elements);
589void GurobiInterface::SetCharAttrElement(
const char*
name,
int index,
593char GurobiInterface::GetCharAttrElement(
const char*
name,
int index)
const {
600GurobiInterface::GurobiInterface(
MPSolver*
const solver,
bool mip)
605 current_solution_index_(0) {
616 absl::GetFlag(FLAGS_num_gurobi_threads)));
628 const absl::MutexLock lock(&hold_interruptions_mutex_);
653 mp_var_to_gurobi_var_.clear();
654 mp_cons_to_gurobi_linear_cons_.clear();
655 num_gurobi_vars_ = 0;
656 num_gurobi_linear_cons_ = 0;
657 had_nonincremental_change_ =
false;
668 SetDoubleAttrElement(
GRB_DBL_ATTR_LB, mp_var_to_gurobi_var_.at(var_index),
670 SetDoubleAttrElement(
GRB_DBL_ATTR_UB, mp_var_to_gurobi_var_.at(var_index),
696 had_nonincremental_change_ =
true;
713 had_nonincremental_change_ =
true;
724 double new_value,
double old_value) {
729 int grb_var = mp_var_to_gurobi_var_.at(variable->
index());
730 int grb_cons = mp_cons_to_gurobi_linear_cons_.at(constraint->
index());
732 had_nonincremental_change_ =
true;
737 GRBchgcoeffs(model_, 1, &grb_cons, &grb_var, &new_value));
745 had_nonincremental_change_ =
true;
757 mp_var_to_gurobi_var_.at(variable->
index()),
766 if (!had_nonincremental_change_) {
775 if (!had_nonincremental_change_) {
777 for (
const auto& entry :
solver_->objective_->coefficients_) {
786 update_branching_priorities_ =
true;
795 return static_cast<int64>(iter);
803 LOG(DFATAL) <<
"Number of nodes only available for discrete problems.";
809 int gurobi_basis_status)
const {
810 switch (gurobi_basis_status) {
820 LOG(DFATAL) <<
"Unknown GRB basis status.";
826 int gurobi_basis_status,
int constraint_index)
const {
827 const int grb_index = mp_cons_to_gurobi_linear_cons_.at(constraint_index);
829 LOG(DFATAL) <<
"Basis status not available for nonlinear constraints.";
832 switch (gurobi_basis_status) {
837 double tolerance = 0.0;
842 VLOG(4) <<
"constraint " << constraint_index <<
" , slack = " << slack
843 <<
" , sense = " << sense;
844 if (fabs(slack) <= tolerance) {
865 LOG(DFATAL) <<
"Basis status only available after a solution has "
870 LOG(DFATAL) <<
"Basis status only available for continuous problems.";
873 const int grb_index = mp_cons_to_gurobi_linear_cons_.at(constraint_index);
875 LOG(DFATAL) <<
"Basis status not available for nonlinear constraints.";
878 const int gurobi_basis_status =
880 return TransformGRBConstraintBasisStatus(gurobi_basis_status,
888 LOG(DFATAL) <<
"Basis status only available after a solution has "
893 LOG(DFATAL) <<
"Basis status only available for continuous problems.";
896 const int grb_index = mp_var_to_gurobi_var_.at(variable_index);
897 const int gurobi_basis_status =
899 return TransformGRBVarBasisStatus(gurobi_basis_status);
904 const int total_num_vars =
solver_->variables_.size();
916 var->name().empty() ?
nullptr :
var->name().c_str()));
917 mp_var_to_gurobi_var_.push_back(num_gurobi_vars_++);
921 std::vector<int> grb_cons_ind;
922 std::vector<int> grb_var_ind;
923 std::vector<double>
coef;
930 const int grb_ct_idx = mp_cons_to_gurobi_linear_cons_.at(
ct->index());
932 DCHECK(
ct->indicator_variable() ==
nullptr);
933 for (
const auto& entry :
ct->coefficients_) {
934 const int var_index = entry.first->index();
938 grb_cons_ind.push_back(grb_ct_idx);
939 grb_var_ind.push_back(mp_var_to_gurobi_var_.at(var_index));
940 coef.push_back(entry.second);
944 if (!grb_cons_ind.empty()) {
945 CheckedGurobiCall(
GRBchgcoeffs(model_, grb_cons_ind.size(),
946 grb_cons_ind.data(), grb_var_ind.data(),
955 int total_num_rows =
solver_->constraints_.size();
961 const int size =
ct->coefficients_.size();
962 std::vector<int> grb_vars;
963 std::vector<double> coefs;
964 grb_vars.reserve(size);
966 for (
const auto& entry :
ct->coefficients_) {
967 const int var_index = entry.first->index();
969 grb_vars.push_back(mp_var_to_gurobi_var_.at(var_index));
970 coefs.push_back(entry.second);
973 ct->name().empty() ? nullptr :
const_cast<char*
>(
ct->name().c_str());
974 if (
ct->indicator_variable() !=
nullptr) {
975 const int grb_ind_var =
976 mp_var_to_gurobi_var_.at(
ct->indicator_variable()->index());
977 if (
ct->lb() > -std::numeric_limits<double>::infinity()) {
979 model_,
name, grb_ind_var,
ct->indicator_value(), size,
980 grb_vars.data(), coefs.data(),
983 if (
ct->ub() < std::numeric_limits<double>::infinity() &&
984 ct->lb() !=
ct->ub()) {
986 model_,
name, grb_ind_var,
ct->indicator_value(), size,
989 mp_cons_to_gurobi_linear_cons_.push_back(-1);
993 if (
ct->lb() ==
ct->ub()) {
994 CheckedGurobiCall(
GRBaddconstr(model_, size, grb_vars.data(),
997 }
else if (
ct->lb() == -std::numeric_limits<double>::infinity()) {
998 CheckedGurobiCall(
GRBaddconstr(model_, size, grb_vars.data(),
1001 }
else if (
ct->ub() == std::numeric_limits<double>::infinity()) {
1002 CheckedGurobiCall(
GRBaddconstr(model_, size, grb_vars.data(),
1007 coefs.data(),
ct->lb(),
ct->ub(),
1013 mp_cons_to_gurobi_linear_cons_.push_back(num_gurobi_linear_cons_++);
1035bool GurobiInterface::SetSolverSpecificParametersAsString(
1040void GurobiInterface::SetRelativeMipGap(
double value) {
1045 LOG(
WARNING) <<
"The relative MIP gap is only available "
1046 <<
"for discrete problems.";
1056void GurobiInterface::SetPrimalTolerance(
double value) {
1067void GurobiInterface::SetDualTolerance(
double value) {
1072void GurobiInterface::SetPresolveMode(
int value) {
1091void GurobiInterface::SetScalingMode(
int value) {
1111void GurobiInterface::SetLpAlgorithm(
int value) {
1131int GurobiInterface::SolutionCount()
const {
1135bool GurobiInterface::ModelIsNonincremental()
const {
1137 if (c->indicator_variable() !=
nullptr) {
1150 ModelIsNonincremental() || had_nonincremental_change_) {
1161 VLOG(1) << absl::StrFormat(
"Model built in %s.",
1165 for (
const std::pair<const MPVariable*, double>& p :
1168 mp_var_to_gurobi_var_.at(p.first->index()), p.second);
1172 if (update_branching_priorities_) {
1175 mp_var_to_gurobi_var_.at(
var->index()),
1176 var->branching_priority());
1178 update_branching_priorities_ =
false;
1193 SetParameters(param);
1195 solver_->solver_specific_parameter_string_);
1197 std::unique_ptr<GurobiMPCallbackContext> gurobi_context;
1198 MPCallbackWithGurobiContext mp_callback_with_context;
1199 int gurobi_precrush = 0;
1200 int gurobi_lazy_constraint = 0;
1201 if (callback_ ==
nullptr) {
1204 gurobi_context = absl::make_unique<GurobiMPCallbackContext>(
1205 env_, &mp_var_to_gurobi_var_, num_gurobi_vars_,
1207 mp_callback_with_context.context = gurobi_context.get();
1208 mp_callback_with_context.callback = callback_;
1210 model_, CallbackImpl,
static_cast<void*
>(&mp_callback_with_context)));
1226 VLOG(1) << absl::StrFormat(
"Solved in %s.",
1232 VLOG(1) << absl::StrFormat(
"Solution status %d.\n", optimization_status);
1233 const int solution_count = SolutionCount();
1235 switch (optimization_status) {
1251 if (solution_count > 0) {
1265 <<
"Best objective bound is not available, error=" << error
1272 current_solution_index_ = 0;
1278 const std::vector<double> grb_variable_values =
1280 for (
int i = 0; i <
solver_->variables_.size(); ++i) {
1282 const double val = grb_variable_values.at(mp_var_to_gurobi_var_.at(i));
1283 var->set_solution_value(val);
1284 VLOG(3) <<
var->name() <<
", value = " << val;
1289 const std::vector<double> grb_reduced_costs =
1291 for (
int i = 0; i <
solver_->variables_.size(); ++i) {
1293 const double rc = grb_reduced_costs.at(mp_var_to_gurobi_var_.at(i));
1294 var->set_reduced_cost(rc);
1295 VLOG(4) <<
var->name() <<
", reduced cost = " << rc;
1300 std::vector<double> grb_dual_values =
1302 for (
int i = 0; i <
solver_->constraints_.size(); ++i) {
1304 const double dual_value =
1305 grb_dual_values.at(mp_cons_to_gurobi_linear_cons_.at(i));
1306 ct->set_dual_value(dual_value);
1307 VLOG(4) <<
"row " <<
ct->index() <<
", dual value = " << dual_value;
1319 const MPModelRequest& request) {
1323 if (status_or.ok())
return status_or.value();
1326 if (absl::IsUnimplemented(status_or.status()))
return absl::nullopt;
1328 if (request.enable_internal_solver_output()) {
1329 LOG(
INFO) <<
"Invalid Gurobi status: " << status_or.status();
1332 response.set_status(MPSOLVER_NOT_SOLVED);
1333 response.set_status_str(status_or.status().ToString());
1339 if (!mip_)
return false;
1346 if (current_solution_index_ + 1 >= SolutionCount()) {
1349 current_solution_index_++;
1355 const std::vector<double> grb_variable_values =
1358 for (
int i = 0; i <
solver_->variables_.size(); ++i) {
1360 var->set_solution_value(
1361 grb_variable_values.at(mp_var_to_gurobi_var_.at(i)));
1375 VLOG(1) <<
"Writing Gurobi model file \"" << filename <<
"\".";
1376 const int status =
GRBwrite(model_, filename.c_str());
1387 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
int64 nodes() const 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
std::string SolverVersion() const override
void AddVariable(MPVariable *const var) override
void ExtractNewVariables() override
void SetVariableBounds(int var_index, double lb, double ub) override
bool IsLP() const override
bool IsMIP() const override
absl::optional< MPSolutionResponse > DirectlySolveProto(const MPModelRequest &request) override
bool AddIndicatorConstraint(MPConstraint *const ct) override
bool NextSolution() override
void SetOptimizationDirection(bool maximize) override
MPSolver::BasisStatus column_status(int variable_index) const override
int64 iterations() 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_.
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.
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...
static constexpr int64 kUnknownNumberOfNodes
virtual void SetIntegerParamToUnsupportedValue(MPSolverParameters::IntegerParam param, int value)
static constexpr int64 kUnknownNumberOfIterations
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
double best_objective_bound_
bool CheckSolutionIsSynchronizedAndExists() const
bool CheckSolutionIsSynchronized() const
void ResetExtractionInformation()
bool variable_is_extracted(int var_index) const
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...
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
std::function< int(GRBenv *, GRBmodel **, const char *, int numvars, double *, double *, double *, char *, char **)> GRBnewmodel
std::function< void(int *, int *, int *)> GRBversion
std::function< int(GRBmodel *model, int numnz, int *cind, double *cval, char sense, double rhs, const char *constrname)> GRBaddconstr
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
std::function< void(GRBenv *)> GRBfreeenv
std::function< int(GRBmodel *, const char *, int, char)> GRBsetcharattrelement
const absl::string_view ToString(MPSolver::OptimizationProblemType optimization_problem_type)
std::function< char *(GRBenv *)> GRBgeterrormsg
std::function< int(GRBmodel *, const char *, int)> GRBsetintattr
std::function< int(GRBmodel *, const char *)> GRBwrite
std::function< int(GRBmodel *model, int(STDCALL *cb)(CB_ARGS), void *usrdata)> GRBsetcallbackfunc
std::function< int(void *cbdata, int lazylen, const int *lazyind, const double *lazyval, char lazysense, double lazyrhs)> GRBcblazy
std::function< int(void *cbdata, int where, int what, void *resultP)> GRBcbget
std::function< int(GRBmodel *, const char *, int *)> GRBgetintattr
std::function< int(GRBmodel *, const char *, int, int *)> GRBgetintattrelement
std::function< int(GRBenv *, const char *, double)> GRBsetdblparam
std::function< void(GRBmodel *)> GRBterminate
std::function< int(GRBenv *dest, GRBenv *src)> GRBcopyparams
std::function< int(GRBmodel *, const char *, double)> GRBsetdblattr
std::function< int(GRBmodel *)> GRBoptimize
std::function< int(GRBmodel *)> GRBupdatemodel
std::function< int(GRBmodel *)> GRBfreemodel
std::function< int(GRBmodel *, const char *, int, int, double *)> GRBgetdblattrarray
std::function< int(GRBmodel *, const char *, int, char *)> GRBgetcharattrelement
std::function< int(GRBenv *)> GRBresetparams
absl::Status SetSolverSpecificParameters(const std::string ¶meters, GRBenv *gurobi)
absl::StatusOr< MPSolutionResponse > GurobiSolveProto(const MPModelRequest &request, GRBenv *gurobi_env)
std::function< int(GRBmodel *model, const char *attrname, int element, int newvalue)> GRBsetintattrelement
std::function< int(GRBmodel *model, int numchgs, int *cind, int *vind, double *val)> GRBchgcoeffs
std::function< int(void *cbdata, const double *solution, double *objvalP)> GRBcbsolution
std::function< int(GRBenv *, const char *, double *)> GRBgetdblparam
std::function< int(GRBmodel *, const char *, double *)> GRBgetdblattr
absl::Status LoadGurobiEnvironment(GRBenv **env)
std::function< int(GRBmodel *, const char *, int, double)> GRBsetdblattrelement
std::function< int(GRBmodel *, const char *, int, double *)> GRBgetdblattrelement
std::function< int(void *cbdata, int cutlen, const int *cutind, const double *cutval, char cutsense, double cutrhs)> GRBcbcut
std::function< GRBenv *(GRBmodel *)> GRBgetenv
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 *, int, int *, double *, double, double, const char *)> GRBaddrangeconstr
std::function< int(GRBenv *, const char *, int)> GRBsetintparam