55#include "absl/status/status.h"
56#include "absl/strings/match.h"
57#include "absl/strings/str_format.h"
69 "Number of threads available for Gurobi.");
86 const MPModelRequest& request, std::atomic<bool>* interrupt)
override;
89 void Write(
const std::string& filename)
override;
93 void Reset()
override;
107 const MPVariable*
const variable,
double new_value,
108 double old_value)
override;
124 int64_t
nodes()
const override;
134 bool IsLP()
const override {
return !mip_; }
135 bool IsMIP()
const override {
return mip_; }
142 int major, minor, technical;
144 return absl::StrFormat(
"Gurobi library version %d.%d.%d\n", major, minor,
149 const absl::MutexLock lock(&hold_interruptions_mutex_);
158 LOG(DFATAL) <<
"ComputeExactConditionNumber not implemented for"
159 <<
" GUROBI_MIXED_INTEGER_PROGRAMMING";
164 LOG(DFATAL) <<
"ComputeExactConditionNumber not implemented for"
165 <<
" GUROBI_LINEAR_PROGRAMMING";
199 bool SetSolverSpecificParametersAsString(
202 void SetRelativeMipGap(
double value)
override;
203 void SetPrimalTolerance(
double value)
override;
204 void SetDualTolerance(
double value)
override;
205 void SetPresolveMode(
int value)
override;
206 void SetScalingMode(
int value)
override;
207 void SetLpAlgorithm(
int value)
override;
210 int gurobi_basis_status)
const;
212 int gurobi_basis_status,
int constraint_index)
const;
215 bool ModelIsNonincremental()
const;
217 void SetIntAttr(
const char*
name,
int value);
218 int GetIntAttr(
const char*
name)
const;
219 void SetDoubleAttr(
const char*
name,
double value);
220 double GetDoubleAttr(
const char*
name)
const;
222 int GetIntAttrElement(
const char*
name,
int index)
const;
223 void SetDoubleAttrElement(
const char*
name,
int index,
double value);
224 double GetDoubleAttrElement(
const char*
name,
int index)
const;
225 std::vector<double> GetDoubleAttrArray(
const char*
name,
int elements);
227 char GetCharAttrElement(
const char*
name,
int index)
const;
229 void CheckedGurobiCall(
int err)
const;
231 int SolutionCount()
const;
236 int current_solution_index_;
238 bool update_branching_priorities_ =
false;
244 std::vector<int> mp_var_to_gurobi_var_;
249 std::vector<int> mp_cons_to_gurobi_linear_cons_;
251 int num_gurobi_vars_ = 0;
254 int num_gurobi_linear_cons_ = 0;
256 bool had_nonincremental_change_ =
false;
261 mutable absl::Mutex hold_interruptions_mutex_;
266void CheckedGurobiCall(
int err,
GRBenv*
const env) {
267 CHECK_EQ(0, err) <<
"Fatal error with code " << err <<
", due to "
272struct GurobiInternalCallbackContext {
278class GurobiMPCallbackContext :
public MPCallbackContext {
280 GurobiMPCallbackContext(
GRBenv* env,
281 const std::vector<int>* mp_var_to_gurobi_var,
282 int num_gurobi_vars,
bool might_add_cuts,
283 bool might_add_lazy_constraints);
287 bool CanQueryVariableValues()
override;
288 double VariableValue(
const MPVariable* variable)
override;
289 void AddCut(
const LinearRange& cutting_plane)
override;
290 void AddLazyConstraint(
const LinearRange& lazy_constraint)
override;
291 double SuggestSolution(
292 const absl::flat_hash_map<const MPVariable*, double>& solution)
override;
293 int64_t NumExploredNodes()
override;
297 void UpdateFromGurobiState(
298 const GurobiInternalCallbackContext& gurobi_internal_context);
304 template <
typename T>
306 const GurobiInternalCallbackContext& gurobi_internal_context,
308 void CheckedGurobiCall(
int gurobi_error_code)
const;
310 template <
typename GRBConstra
intFunction>
311 void AddGeneratedConstraint(
const LinearRange& linear_range,
312 GRBConstraintFunction grb_constraint_function);
315 const std::vector<int>*
const mp_var_to_gurobi_var_;
316 const int num_gurobi_vars_;
318 const bool might_add_cuts_;
319 const bool might_add_lazy_constraints_;
322 GurobiInternalCallbackContext current_gurobi_internal_callback_context_;
323 bool variable_values_extracted_ =
false;
324 std::vector<double> gurobi_variable_values_;
327void GurobiMPCallbackContext::CheckedGurobiCall(
int gurobi_error_code)
const {
328 ::operations_research::CheckedGurobiCall(gurobi_error_code, env_);
331GurobiMPCallbackContext::GurobiMPCallbackContext(
332 GRBenv* env,
const std::vector<int>* mp_var_to_gurobi_var,
333 int num_gurobi_vars,
bool might_add_cuts,
bool might_add_lazy_constraints)
336 num_gurobi_vars_(num_gurobi_vars),
337 might_add_cuts_(might_add_cuts),
338 might_add_lazy_constraints_(might_add_lazy_constraints) {}
340void GurobiMPCallbackContext::UpdateFromGurobiState(
341 const GurobiInternalCallbackContext& gurobi_internal_context) {
342 current_gurobi_internal_callback_context_ = gurobi_internal_context;
343 variable_values_extracted_ =
false;
346int64_t GurobiMPCallbackContext::NumExploredNodes() {
348 case MPCallbackEvent::kMipNode:
349 return static_cast<int64_t
>(GurobiCallbackGet<double>(
351 case MPCallbackEvent::kMipSolution:
352 return static_cast<int64_t
>(GurobiCallbackGet<double>(
355 LOG(
FATAL) <<
"Node count is supported only for callback events MIP_NODE "
356 "and MIP_SOL, but was requested at: "
362T GurobiMPCallbackContext::GurobiCallbackGet(
363 const GurobiInternalCallbackContext& gurobi_internal_context,
364 const int callback_code) {
367 GRBcbget(gurobi_internal_context.gurobi_internal_callback_data,
368 gurobi_internal_context.where, callback_code,
369 static_cast<void*
>(&result)));
374 switch (current_gurobi_internal_callback_context_.where) {
376 return MPCallbackEvent::kPolling;
378 return MPCallbackEvent::kPresolve;
380 return MPCallbackEvent::kSimplex;
382 return MPCallbackEvent::kMip;
384 return MPCallbackEvent::kMipSolution;
386 return MPCallbackEvent::kMipNode;
388 return MPCallbackEvent::kMessage;
390 return MPCallbackEvent::kBarrier;
396 << current_gurobi_internal_callback_context_.where;
397 return MPCallbackEvent::kUnknown;
401bool GurobiMPCallbackContext::CanQueryVariableValues() {
403 if (
where == MPCallbackEvent::kMipSolution) {
406 if (
where == MPCallbackEvent::kMipNode) {
407 const int gurobi_node_status = GurobiCallbackGet<int>(
414double GurobiMPCallbackContext::VariableValue(
const MPVariable* variable) {
415 CHECK(variable !=
nullptr);
416 if (!variable_values_extracted_) {
418 CHECK(
where == MPCallbackEvent::kMipSolution ||
419 where == MPCallbackEvent::kMipNode)
420 <<
"You can only call VariableValue at "
421 <<
ToString(MPCallbackEvent::kMipSolution) <<
" or "
422 <<
ToString(MPCallbackEvent::kMipNode)
424 const int gurobi_get_var_param =
where == MPCallbackEvent::kMipNode
428 gurobi_variable_values_.resize(num_gurobi_vars_);
430 current_gurobi_internal_callback_context_.gurobi_internal_callback_data,
431 current_gurobi_internal_callback_context_.where, gurobi_get_var_param,
432 static_cast<void*
>(gurobi_variable_values_.data())));
433 variable_values_extracted_ =
true;
435 return gurobi_variable_values_[mp_var_to_gurobi_var_->at(variable->index())];
438template <
typename GRBConstra
intFunction>
439void GurobiMPCallbackContext::AddGeneratedConstraint(
440 const LinearRange& linear_range,
441 GRBConstraintFunction grb_constraint_function) {
442 std::vector<int> variable_indices;
443 std::vector<double> variable_coefficients;
444 const int num_terms = linear_range.linear_expr().terms().size();
445 variable_indices.reserve(num_terms);
446 variable_coefficients.reserve(num_terms);
447 for (
const auto& var_coef_pair : linear_range.linear_expr().terms()) {
448 variable_indices.push_back(
449 mp_var_to_gurobi_var_->at(var_coef_pair.first->index()));
450 variable_coefficients.push_back(var_coef_pair.second);
452 if (std::isfinite(linear_range.upper_bound())) {
453 CheckedGurobiCall(grb_constraint_function(
454 current_gurobi_internal_callback_context_.gurobi_internal_callback_data,
455 variable_indices.size(), variable_indices.data(),
457 linear_range.upper_bound()));
459 if (std::isfinite(linear_range.lower_bound())) {
460 CheckedGurobiCall(grb_constraint_function(
461 current_gurobi_internal_callback_context_.gurobi_internal_callback_data,
462 variable_indices.size(), variable_indices.data(),
464 linear_range.lower_bound()));
468void GurobiMPCallbackContext::AddCut(
const LinearRange& cutting_plane) {
469 CHECK(might_add_cuts_);
472 <<
"Cuts can only be added at MIP_NODE, tried to add cut at: "
474 AddGeneratedConstraint(cutting_plane,
GRBcbcut);
477void GurobiMPCallbackContext::AddLazyConstraint(
478 const LinearRange& lazy_constraint) {
479 CHECK(might_add_lazy_constraints_);
482 where == MPCallbackEvent::kMipSolution)
483 <<
"Lazy constraints can only be added at MIP_NODE or MIP_SOL, tried to "
484 "add lazy constraint at: "
486 AddGeneratedConstraint(lazy_constraint,
GRBcblazy);
489double GurobiMPCallbackContext::SuggestSolution(
490 const absl::flat_hash_map<const MPVariable*, double>& solution) {
493 <<
"Feasible solutions can only be added at MIP_NODE, tried to add "
497 std::vector<double> full_solution(num_gurobi_vars_,
GRB_UNDEFINED);
498 for (
const auto& variable_value : solution) {
499 const MPVariable*
var = variable_value.first;
500 full_solution[mp_var_to_gurobi_var_->at(
var->index())] =
501 variable_value.second;
506 current_gurobi_internal_callback_context_.gurobi_internal_callback_data,
507 full_solution.data(), &objval));
512struct MPCallbackWithGurobiContext {
521 void* raw_model_and_callback) {
522 MPCallbackWithGurobiContext*
const callback_with_context =
523 static_cast<MPCallbackWithGurobiContext*
>(raw_model_and_callback);
524 CHECK(callback_with_context !=
nullptr);
525 CHECK(callback_with_context->context !=
nullptr);
526 CHECK(callback_with_context->callback !=
nullptr);
527 GurobiInternalCallbackContext gurobi_internal_context{
529 callback_with_context->context->UpdateFromGurobiState(
530 gurobi_internal_context);
531 callback_with_context->callback->RunCallback(callback_with_context->context);
537void GurobiInterface::CheckedGurobiCall(
int err)
const {
538 ::operations_research::CheckedGurobiCall(err, env_);
541void GurobiInterface::SetIntAttr(
const char*
name,
int value) {
545int GurobiInterface::GetIntAttr(
const char*
name)
const {
551void GurobiInterface::SetDoubleAttr(
const char*
name,
double value) {
555double GurobiInterface::GetDoubleAttr(
const char*
name)
const {
561void GurobiInterface::SetIntAttrElement(
const char*
name,
int index,
566int GurobiInterface::GetIntAttrElement(
const char*
name,
int index)
const {
572void GurobiInterface::SetDoubleAttrElement(
const char*
name,
int index,
576double GurobiInterface::GetDoubleAttrElement(
const char*
name,
583std::vector<double> GurobiInterface::GetDoubleAttrArray(
const char*
name,
585 std::vector<double> results(elements);
591void GurobiInterface::SetCharAttrElement(
const char*
name,
int index,
595char GurobiInterface::GetCharAttrElement(
const char*
name,
int index)
const {
602GurobiInterface::GurobiInterface(
MPSolver*
const solver,
bool mip)
607 current_solution_index_(0) {
618 absl::GetFlag(FLAGS_num_gurobi_threads)));
630 const absl::MutexLock lock(&hold_interruptions_mutex_);
655 mp_var_to_gurobi_var_.clear();
656 mp_cons_to_gurobi_linear_cons_.clear();
657 num_gurobi_vars_ = 0;
658 num_gurobi_linear_cons_ = 0;
659 had_nonincremental_change_ =
false;
670 SetDoubleAttrElement(
GRB_DBL_ATTR_LB, mp_var_to_gurobi_var_.at(var_index),
672 SetDoubleAttrElement(
GRB_DBL_ATTR_UB, mp_var_to_gurobi_var_.at(var_index),
698 had_nonincremental_change_ =
true;
715 had_nonincremental_change_ =
true;
726 double new_value,
double old_value) {
731 int grb_var = mp_var_to_gurobi_var_.at(variable->
index());
732 int grb_cons = mp_cons_to_gurobi_linear_cons_.at(constraint->
index());
734 had_nonincremental_change_ =
true;
739 GRBchgcoeffs(model_, 1, &grb_cons, &grb_var, &new_value));
747 had_nonincremental_change_ =
true;
759 mp_var_to_gurobi_var_.at(variable->
index()),
768 if (!had_nonincremental_change_) {
777 if (!had_nonincremental_change_) {
779 for (
const auto& entry :
solver_->objective_->coefficients_) {
788 update_branching_priorities_ =
true;
797 return static_cast<int64_t
>(iter);
805 LOG(DFATAL) <<
"Number of nodes only available for discrete problems.";
811 int gurobi_basis_status)
const {
812 switch (gurobi_basis_status) {
822 LOG(DFATAL) <<
"Unknown GRB basis status.";
828 int gurobi_basis_status,
int constraint_index)
const {
829 const int grb_index = mp_cons_to_gurobi_linear_cons_.at(constraint_index);
831 LOG(DFATAL) <<
"Basis status not available for nonlinear constraints.";
834 switch (gurobi_basis_status) {
839 double tolerance = 0.0;
844 VLOG(4) <<
"constraint " << constraint_index <<
" , slack = " << slack
845 <<
" , sense = " << sense;
846 if (fabs(slack) <= tolerance) {
867 LOG(DFATAL) <<
"Basis status only available after a solution has "
872 LOG(DFATAL) <<
"Basis status only available for continuous problems.";
875 const int grb_index = mp_cons_to_gurobi_linear_cons_.at(constraint_index);
877 LOG(DFATAL) <<
"Basis status not available for nonlinear constraints.";
880 const int gurobi_basis_status =
882 return TransformGRBConstraintBasisStatus(gurobi_basis_status,
890 LOG(DFATAL) <<
"Basis status only available after a solution has "
895 LOG(DFATAL) <<
"Basis status only available for continuous problems.";
898 const int grb_index = mp_var_to_gurobi_var_.at(variable_index);
899 const int gurobi_basis_status =
901 return TransformGRBVarBasisStatus(gurobi_basis_status);
906 const int total_num_vars =
solver_->variables_.size();
918 var->name().empty() ?
nullptr :
var->name().c_str()));
919 mp_var_to_gurobi_var_.push_back(num_gurobi_vars_++);
923 std::vector<int> grb_cons_ind;
924 std::vector<int> grb_var_ind;
925 std::vector<double>
coef;
932 const int grb_ct_idx = mp_cons_to_gurobi_linear_cons_.at(
ct->index());
934 DCHECK(
ct->indicator_variable() ==
nullptr);
935 for (
const auto& entry :
ct->coefficients_) {
936 const int var_index = entry.first->index();
940 grb_cons_ind.push_back(grb_ct_idx);
941 grb_var_ind.push_back(mp_var_to_gurobi_var_.at(var_index));
942 coef.push_back(entry.second);
946 if (!grb_cons_ind.empty()) {
947 CheckedGurobiCall(
GRBchgcoeffs(model_, grb_cons_ind.size(),
948 grb_cons_ind.data(), grb_var_ind.data(),
957 int total_num_rows =
solver_->constraints_.size();
963 const int size =
ct->coefficients_.size();
964 std::vector<int> grb_vars;
965 std::vector<double> coefs;
966 grb_vars.reserve(size);
968 for (
const auto& entry :
ct->coefficients_) {
969 const int var_index = entry.first->index();
971 grb_vars.push_back(mp_var_to_gurobi_var_.at(var_index));
972 coefs.push_back(entry.second);
975 ct->name().empty() ? nullptr :
const_cast<char*
>(
ct->name().c_str());
976 if (
ct->indicator_variable() !=
nullptr) {
977 const int grb_ind_var =
978 mp_var_to_gurobi_var_.at(
ct->indicator_variable()->index());
979 if (
ct->lb() > -std::numeric_limits<double>::infinity()) {
981 model_,
name, grb_ind_var,
ct->indicator_value(), size,
982 grb_vars.data(), coefs.data(),
985 if (
ct->ub() < std::numeric_limits<double>::infinity() &&
986 ct->lb() !=
ct->ub()) {
988 model_,
name, grb_ind_var,
ct->indicator_value(), size,
991 mp_cons_to_gurobi_linear_cons_.push_back(-1);
995 if (
ct->lb() ==
ct->ub()) {
996 CheckedGurobiCall(
GRBaddconstr(model_, size, grb_vars.data(),
999 }
else if (
ct->lb() == -std::numeric_limits<double>::infinity()) {
1000 CheckedGurobiCall(
GRBaddconstr(model_, size, grb_vars.data(),
1003 }
else if (
ct->ub() == std::numeric_limits<double>::infinity()) {
1004 CheckedGurobiCall(
GRBaddconstr(model_, size, grb_vars.data(),
1009 coefs.data(),
ct->lb(),
ct->ub(),
1015 mp_cons_to_gurobi_linear_cons_.push_back(num_gurobi_linear_cons_++);
1037bool GurobiInterface::SetSolverSpecificParametersAsString(
1042void GurobiInterface::SetRelativeMipGap(
double value) {
1047 LOG(
WARNING) <<
"The relative MIP gap is only available "
1048 <<
"for discrete problems.";
1058void GurobiInterface::SetPrimalTolerance(
double value) {
1069void GurobiInterface::SetDualTolerance(
double value) {
1074void GurobiInterface::SetPresolveMode(
int value) {
1093void GurobiInterface::SetScalingMode(
int value) {
1113void GurobiInterface::SetLpAlgorithm(
int value) {
1133int GurobiInterface::SolutionCount()
const {
1137bool GurobiInterface::ModelIsNonincremental()
const {
1139 if (c->indicator_variable() !=
nullptr) {
1152 ModelIsNonincremental() || had_nonincremental_change_) {
1163 VLOG(1) << absl::StrFormat(
"Model built in %s.",
1167 for (
const std::pair<const MPVariable*, double>& p :
1170 mp_var_to_gurobi_var_.at(p.first->index()), p.second);
1174 if (update_branching_priorities_) {
1177 mp_var_to_gurobi_var_.at(
var->index()),
1178 var->branching_priority());
1180 update_branching_priorities_ =
false;
1195 SetParameters(param);
1197 solver_->solver_specific_parameter_string_);
1199 std::unique_ptr<GurobiMPCallbackContext> gurobi_context;
1200 MPCallbackWithGurobiContext mp_callback_with_context;
1201 int gurobi_precrush = 0;
1202 int gurobi_lazy_constraint = 0;
1203 if (callback_ ==
nullptr) {
1206 gurobi_context = absl::make_unique<GurobiMPCallbackContext>(
1207 env_, &mp_var_to_gurobi_var_, num_gurobi_vars_,
1209 mp_callback_with_context.context = gurobi_context.get();
1210 mp_callback_with_context.callback = callback_;
1212 model_, CallbackImpl,
static_cast<void*
>(&mp_callback_with_context)));
1228 VLOG(1) << absl::StrFormat(
"Solved in %s.",
1234 VLOG(1) << absl::StrFormat(
"Solution status %d.\n", optimization_status);
1235 const int solution_count = SolutionCount();
1237 switch (optimization_status) {
1253 if (solution_count > 0) {
1267 <<
"Best objective bound is not available, error=" << error
1274 current_solution_index_ = 0;
1280 const std::vector<double> grb_variable_values =
1282 for (
int i = 0; i <
solver_->variables_.size(); ++i) {
1284 const double val = grb_variable_values.at(mp_var_to_gurobi_var_.at(i));
1285 var->set_solution_value(val);
1286 VLOG(3) <<
var->name() <<
", value = " << val;
1291 const std::vector<double> grb_reduced_costs =
1293 for (
int i = 0; i <
solver_->variables_.size(); ++i) {
1295 const double rc = grb_reduced_costs.at(mp_var_to_gurobi_var_.at(i));
1296 var->set_reduced_cost(rc);
1297 VLOG(4) <<
var->name() <<
", reduced cost = " << rc;
1302 std::vector<double> grb_dual_values =
1304 for (
int i = 0; i <
solver_->constraints_.size(); ++i) {
1306 const double dual_value =
1307 grb_dual_values.at(mp_cons_to_gurobi_linear_cons_.at(i));
1308 ct->set_dual_value(dual_value);
1309 VLOG(4) <<
"row " <<
ct->index() <<
", dual value = " << dual_value;
1323 if (interrupt !=
nullptr)
return absl::nullopt;
1328 if (status_or.ok())
return status_or.value();
1331 if (absl::IsUnimplemented(status_or.status()))
return absl::nullopt;
1334 LOG(
INFO) <<
"Invalid Gurobi status: " << status_or.status();
1338 response.set_status_str(status_or.status().ToString());
1344 if (!mip_)
return false;
1351 if (current_solution_index_ + 1 >= SolutionCount()) {
1354 current_solution_index_++;
1360 const std::vector<double> grb_variable_values =
1363 for (
int i = 0; i <
solver_->variables_.size(); ++i) {
1365 var->set_solution_value(
1366 grb_variable_values.at(mp_var_to_gurobi_var_.at(i)));
1380 VLOG(1) <<
"Writing Gurobi model file \"" << filename <<
"\".";
1381 const int status =
GRBwrite(model_, filename.c_str());
1392 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