OR-Tools  8.0
gurobi_interface.cc
Go to the documentation of this file.
1 // Copyright 2010-2018 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 #include <cmath>
15 #include <cstddef>
16 #include <limits>
17 #include <memory>
18 #include <stdexcept>
19 #include <string>
20 #include <utility>
21 #include <vector>
22 
23 #include "absl/status/status.h"
24 #include "absl/strings/match.h"
25 #include "absl/strings/str_format.h"
28 #include "ortools/base/logging.h"
29 #include "ortools/base/map_util.h"
30 #include "ortools/base/statusor.h"
31 #include "ortools/base/timer.h"
36 
37 DEFINE_int32(num_gurobi_threads, 4, "Number of threads available for Gurobi.");
38 
39 namespace operations_research {
40 
42  public:
43  // Constructor that takes a name for the underlying GRB solver.
44  explicit GurobiInterface(MPSolver* const solver, bool mip);
45  ~GurobiInterface() override;
46 
47  // Sets the optimization direction (min/max).
48  void SetOptimizationDirection(bool maximize) override;
49 
50  // ----- Solve -----
51  // Solves the problem using the parameter values specified.
52  MPSolver::ResultStatus Solve(const MPSolverParameters& param) override;
53  absl::optional<MPSolutionResponse> DirectlySolveProto(
54  const MPModelRequest& request) override;
55 
56  // Writes the model.
57  void Write(const std::string& filename) override;
58 
59  // ----- Model modifications and extraction -----
60  // Resets extracted model
61  void Reset() override;
62 
63  // Modifies bounds.
64  void SetVariableBounds(int var_index, double lb, double ub) override;
65  void SetVariableInteger(int var_index, bool integer) override;
66  void SetConstraintBounds(int row_index, double lb, double ub) override;
67 
68  // Adds Constraint incrementally.
69  void AddRowConstraint(MPConstraint* const ct) override;
70  bool AddIndicatorConstraint(MPConstraint* const ct) override;
71  // Adds variable incrementally.
72  void AddVariable(MPVariable* const var) override;
73  // Changes a coefficient in a constraint.
74  void SetCoefficient(MPConstraint* const constraint,
75  const MPVariable* const variable, double new_value,
76  double old_value) override;
77  // Clears a constraint from all its terms.
78  void ClearConstraint(MPConstraint* const constraint) override;
79  // Changes a coefficient in the linear objective
80  void SetObjectiveCoefficient(const MPVariable* const variable,
81  double coefficient) override;
82  // Changes the constant term in the linear objective.
83  void SetObjectiveOffset(double value) override;
84  // Clears the objective from all its terms.
85  void ClearObjective() override;
86  bool CheckBestObjectiveBoundExists() const override;
87  void BranchingPriorityChangedForVariable(int var_index) override;
88 
89  // ------ Query statistics on the solution and the solve ------
90  // Number of simplex or interior-point iterations
91  int64 iterations() const override;
92  // Number of branch-and-bound nodes. Only available for discrete problems.
93  int64 nodes() const override;
94  // Best objective bound. Only available for discrete problems.
95  double best_objective_bound() const override;
96 
97  // Returns the basis status of a row.
98  MPSolver::BasisStatus row_status(int constraint_index) const override;
99  // Returns the basis status of a column.
100  MPSolver::BasisStatus column_status(int variable_index) const override;
101 
102  // ----- Misc -----
103  // Queries problem type.
104  bool IsContinuous() const override { return IsLP(); }
105  bool IsLP() const override { return !mip_; }
106  bool IsMIP() const override { return mip_; }
107 
108  void ExtractNewVariables() override;
109  void ExtractNewConstraints() override;
110  void ExtractObjective() override;
111 
112  std::string SolverVersion() const override {
113  int major, minor, technical;
114  GRBversion(&major, &minor, &technical);
115  return absl::StrFormat("Gurobi library version %d.%d.%d\n", major, minor,
116  technical);
117  }
118 
119  bool InterruptSolve() override {
120  if (model_ != nullptr) GRBterminate(model_);
121  return true;
122  }
123 
124  void* underlying_solver() override { return reinterpret_cast<void*>(model_); }
125 
126  double ComputeExactConditionNumber() const override {
127  if (!IsContinuous()) {
128  LOG(DFATAL) << "ComputeExactConditionNumber not implemented for"
129  << " GUROBI_MIXED_INTEGER_PROGRAMMING";
130  return 0.0;
131  }
132 
133  // TODO(user,user): Not yet working.
134  LOG(DFATAL) << "ComputeExactConditionNumber not implemented for"
135  << " GUROBI_LINEAR_PROGRAMMING";
136  return 0.0;
137 
138  // double cond = 0.0;
139  // const int status = GRBgetdblattr(model_, GRB_DBL_ATTR_KAPPA, &cond);
140  // if (0 == status) {
141  // return cond;
142  // } else {
143  // LOG(DFATAL) << "Condition number only available for "
144  // << "continuous problems";
145  // return 0.0;
146  // }
147  }
148 
149  // Iterates through the solutions in Gurobi's solution pool.
150  bool NextSolution() override;
151 
152  void SetCallback(MPCallback* mp_callback) override;
153  bool SupportsCallbacks() const override { return true; }
154 
155  private:
156  // Sets all parameters in the underlying solver.
157  void SetParameters(const MPSolverParameters& param) override;
158  // Sets each parameter in the underlying solver.
159  void SetRelativeMipGap(double value) override;
160  void SetPrimalTolerance(double value) override;
161  void SetDualTolerance(double value) override;
162  void SetPresolveMode(int value) override;
163  void SetScalingMode(int value) override;
164  void SetLpAlgorithm(int value) override;
165 
166  bool ReadParameterFile(const std::string& filename) override;
167  std::string ValidFileExtensionForParameterFile() const override;
168 
169  MPSolver::BasisStatus TransformGRBVarBasisStatus(
170  int gurobi_basis_status) const;
171  MPSolver::BasisStatus TransformGRBConstraintBasisStatus(
172  int gurobi_basis_status, int constraint_index) const;
173 
174  void CheckedGurobiCall(int err) const;
175 
176  int SolutionCount() const;
177 
178  GRBmodel* model_;
179  GRBenv* env_;
180  bool mip_;
181  int current_solution_index_;
182  MPCallback* callback_ = nullptr;
183  bool update_branching_priorities_ = false;
184 };
185 
186 namespace {
187 
188 void CheckedGurobiCall(int err, GRBenv* const env) {
189  CHECK_EQ(0, err) << "Fatal error with code " << err << ", due to "
190  << GRBgeterrormsg(env);
191 }
192 
193 // For interacting directly with the Gurobi C API for callbacks.
194 struct GurobiInternalCallbackContext {
197  int where;
198 };
199 
200 class GurobiMPCallbackContext : public MPCallbackContext {
201  public:
202  GurobiMPCallbackContext(GRBenv* env, bool might_add_cuts,
203  bool might_add_lazy_constraints);
204 
205  // Implementation of the interface.
206  MPCallbackEvent Event() override;
207  bool CanQueryVariableValues() override;
208  double VariableValue(const MPVariable* variable) override;
209  void AddCut(const LinearRange& cutting_plane) override;
210  void AddLazyConstraint(const LinearRange& lazy_constraint) override;
211  double SuggestSolution(
212  const absl::flat_hash_map<const MPVariable*, double>& solution) override;
213  int64 NumExploredNodes() override;
214 
215  // Call this method to update the internal state of the callback context
216  // before passing it to MPCallback::RunCallback().
217  void UpdateFromGurobiState(
218  const GurobiInternalCallbackContext& gurobi_internal_context);
219 
220  private:
221  // Wraps GRBcbget(), used to query the state of the solver. See
222  // http://www.gurobi.com/documentation/8.0/refman/callback_codes.html#sec:CallbackCodes
223  // for callback_code values.
224  template <typename T>
225  T GurobiCallbackGet(
226  const GurobiInternalCallbackContext& gurobi_internal_context,
227  int callback_code);
228  void CheckedGurobiCall(int gurobi_error_code) const;
229 
230  template <typename GRBConstraintFunction>
231  void AddGeneratedConstraint(const LinearRange& linear_range,
232  GRBConstraintFunction grb_constraint_function);
233 
234  // Returns the number of variables in the Gurobi model.
235  // WARNING(rander): This is not the same as solver_->variables_.size(), the
236  // use of range constraints adds new variables to the Gurobi model.
237  int NumGurobiVariables() const;
238 
239  GRBenv* const env_;
240 
241  const bool might_add_cuts_;
242  const bool might_add_lazy_constraints_;
243 
244  // Stateful, updated before each call to the callback.
245  GurobiInternalCallbackContext current_gurobi_internal_callback_context_;
246  bool variable_values_extracted_ = false;
247  std::vector<double> variable_values_;
248 };
249 
250 void GurobiMPCallbackContext::CheckedGurobiCall(int gurobi_error_code) const {
251  ::operations_research::CheckedGurobiCall(gurobi_error_code, env_);
252 }
253 
254 GurobiMPCallbackContext::GurobiMPCallbackContext(
255  GRBenv* env, bool might_add_cuts, bool might_add_lazy_constraints)
256  : env_(ABSL_DIE_IF_NULL(env)),
257  might_add_cuts_(might_add_cuts),
258  might_add_lazy_constraints_(might_add_lazy_constraints) {}
259 
260 void GurobiMPCallbackContext::UpdateFromGurobiState(
261  const GurobiInternalCallbackContext& gurobi_internal_context) {
262  current_gurobi_internal_callback_context_ = gurobi_internal_context;
263  variable_values_extracted_ = false;
264 }
265 
266 int64 GurobiMPCallbackContext::NumExploredNodes() {
267  switch (Event()) {
268  case MPCallbackEvent::kMipNode:
269  return static_cast<int64>(GurobiCallbackGet<double>(
270  current_gurobi_internal_callback_context_, GRB_CB_MIPNODE_NODCNT));
271  case MPCallbackEvent::kMipSolution:
272  return static_cast<int64>(GurobiCallbackGet<double>(
273  current_gurobi_internal_callback_context_, GRB_CB_MIPSOL_NODCNT));
274  default:
275  LOG(FATAL) << "Node count is supported only for callback events MIP_NODE "
276  "and MIP_SOL, but was requested at: "
277  << ToString(Event());
278  }
279 }
280 
281 template <typename T>
282 T GurobiMPCallbackContext::GurobiCallbackGet(
283  const GurobiInternalCallbackContext& gurobi_internal_context,
284  const int callback_code) {
285  T result = 0;
286  CheckedGurobiCall(
287  GRBcbget(gurobi_internal_context.gurobi_internal_callback_data,
288  gurobi_internal_context.where, callback_code,
289  static_cast<void*>(&result)));
290  return result;
291 }
292 
293 MPCallbackEvent GurobiMPCallbackContext::Event() {
294  switch (current_gurobi_internal_callback_context_.where) {
295  case GRB_CB_POLLING:
296  return MPCallbackEvent::kPolling;
297  case GRB_CB_PRESOLVE:
298  return MPCallbackEvent::kPresolve;
299  case GRB_CB_SIMPLEX:
300  return MPCallbackEvent::kSimplex;
301  case GRB_CB_MIP:
302  return MPCallbackEvent::kMip;
303  case GRB_CB_MIPSOL:
304  return MPCallbackEvent::kMipSolution;
305  case GRB_CB_MIPNODE:
306  return MPCallbackEvent::kMipNode;
307  case GRB_CB_MESSAGE:
308  return MPCallbackEvent::kMessage;
309  case GRB_CB_BARRIER:
310  return MPCallbackEvent::kBarrier;
311  // TODO(b/112427356): in Gurobi 8.0, there is a new callback location.
312  // case GRB_CB_MULTIOBJ:
313  // return MPCallbackEvent::kMultiObj;
314  default:
315  LOG_FIRST_N(ERROR, 1) << "Gurobi callback at unknown where="
316  << current_gurobi_internal_callback_context_.where;
317  return MPCallbackEvent::kUnknown;
318  }
319 }
320 
321 bool GurobiMPCallbackContext::CanQueryVariableValues() {
322  const MPCallbackEvent where = Event();
323  if (where == MPCallbackEvent::kMipSolution) {
324  return true;
325  }
326  if (where == MPCallbackEvent::kMipNode) {
327  const int gurobi_node_status = GurobiCallbackGet<int>(
328  current_gurobi_internal_callback_context_, GRB_CB_MIPNODE_STATUS);
329  return gurobi_node_status == GRB_OPTIMAL;
330  }
331  return false;
332 }
333 
334 double GurobiMPCallbackContext::VariableValue(const MPVariable* variable) {
335  CHECK(variable != nullptr);
336  if (!variable_values_extracted_) {
337  const MPCallbackEvent where = Event();
338  CHECK(where == MPCallbackEvent::kMipSolution ||
339  where == MPCallbackEvent::kMipNode)
340  << "You can only call VariableValue at "
341  << ToString(MPCallbackEvent::kMipSolution) << " or "
342  << ToString(MPCallbackEvent::kMipNode)
343  << " but called from: " << ToString(where);
344  const int gurobi_get_var_param = where == MPCallbackEvent::kMipNode
347 
348  variable_values_.resize(NumGurobiVariables());
349  CheckedGurobiCall(GRBcbget(
350  current_gurobi_internal_callback_context_.gurobi_internal_callback_data,
351  current_gurobi_internal_callback_context_.where, gurobi_get_var_param,
352  static_cast<void*>(variable_values_.data())));
353  variable_values_extracted_ = true;
354  }
355  return variable_values_[variable->index()];
356 }
357 
358 template <typename GRBConstraintFunction>
359 void GurobiMPCallbackContext::AddGeneratedConstraint(
360  const LinearRange& linear_range,
361  GRBConstraintFunction grb_constraint_function) {
362  std::vector<int> variable_indices;
363  std::vector<double> variable_coefficients;
364  const int num_terms = linear_range.linear_expr().terms().size();
365  variable_indices.reserve(num_terms);
366  variable_coefficients.reserve(num_terms);
367  for (const auto& var_coef_pair : linear_range.linear_expr().terms()) {
368  variable_indices.push_back(var_coef_pair.first->index());
369  variable_coefficients.push_back(var_coef_pair.second);
370  }
371  if (std::isfinite(linear_range.upper_bound())) {
372  CheckedGurobiCall(grb_constraint_function(
373  current_gurobi_internal_callback_context_.gurobi_internal_callback_data,
374  variable_indices.size(), variable_indices.data(),
375  variable_coefficients.data(), GRB_LESS_EQUAL,
376  linear_range.upper_bound()));
377  }
378  if (std::isfinite(linear_range.lower_bound())) {
379  CheckedGurobiCall(grb_constraint_function(
380  current_gurobi_internal_callback_context_.gurobi_internal_callback_data,
381  variable_indices.size(), variable_indices.data(),
382  variable_coefficients.data(), GRB_GREATER_EQUAL,
383  linear_range.lower_bound()));
384  }
385 }
386 
387 void GurobiMPCallbackContext::AddCut(const LinearRange& cutting_plane) {
388  CHECK(might_add_cuts_);
389  const MPCallbackEvent where = Event();
390  CHECK(where == MPCallbackEvent::kMipNode)
391  << "Cuts can only be added at MIP_NODE, tried to add cut at: "
392  << ToString(where);
393  AddGeneratedConstraint(cutting_plane, GRBcbcut);
394 }
395 
396 void GurobiMPCallbackContext::AddLazyConstraint(
397  const LinearRange& lazy_constraint) {
398  CHECK(might_add_lazy_constraints_);
399  const MPCallbackEvent where = Event();
400  CHECK(where == MPCallbackEvent::kMipNode ||
401  where == MPCallbackEvent::kMipSolution)
402  << "Lazy constraints can only be added at MIP_NODE or MIP_SOL, tried to "
403  "add lazy constraint at: "
404  << ToString(where);
405  AddGeneratedConstraint(lazy_constraint, GRBcblazy);
406 }
407 
408 double GurobiMPCallbackContext::SuggestSolution(
409  const absl::flat_hash_map<const MPVariable*, double>& solution) {
410  const MPCallbackEvent where = Event();
411  CHECK(where == MPCallbackEvent::kMipNode)
412  << "Feasible solutions can only be added at MIP_NODE, tried to add "
413  "solution at: "
414  << ToString(where);
415 
416  std::vector<double> full_solution(NumGurobiVariables(), GRB_UNDEFINED);
417  for (const auto& variable_value : solution) {
418  const MPVariable* var = variable_value.first;
419  full_solution[var->index()] = variable_value.second;
420  }
421 
422  double objval;
423  CheckedGurobiCall(GRBcbsolution(
424  current_gurobi_internal_callback_context_.gurobi_internal_callback_data,
425  full_solution.data(), &objval));
426 
427  return objval;
428 }
429 
430 int GurobiMPCallbackContext::NumGurobiVariables() const {
431  int num_gurobi_variables = 0;
432  CheckedGurobiCall(
433  GRBgetintattr(current_gurobi_internal_callback_context_.model, "NumVars",
434  &num_gurobi_variables));
435  return num_gurobi_variables;
436 }
437 
438 struct MPCallbackWithGurobiContext {
439  GurobiMPCallbackContext* context;
440  MPCallback* callback;
441 };
442 
443 // NOTE(user): This function must have this exact API, because we are passing
444 // it to Gurobi as a callback.
445 int STDCALL CallbackImpl(GRBmodel* model, void* gurobi_internal_callback_data,
446  int where, void* raw_model_and_callback) {
447  MPCallbackWithGurobiContext* const callback_with_context =
448  static_cast<MPCallbackWithGurobiContext*>(raw_model_and_callback);
449  CHECK(callback_with_context != nullptr);
450  CHECK(callback_with_context->context != nullptr);
451  CHECK(callback_with_context->callback != nullptr);
452  GurobiInternalCallbackContext gurobi_internal_context{
454  callback_with_context->context->UpdateFromGurobiState(
455  gurobi_internal_context);
456  callback_with_context->callback->RunCallback(callback_with_context->context);
457  return 0;
458 }
459 
460 } // namespace
461 
462 void GurobiInterface::CheckedGurobiCall(int err) const {
463  ::operations_research::CheckedGurobiCall(err, env_);
464 }
465 
466 // Creates a LP/MIP instance with the specified name and minimization objective.
467 GurobiInterface::GurobiInterface(MPSolver* const solver, bool mip)
468  : MPSolverInterface(solver),
469  model_(nullptr),
470  env_(nullptr),
471  mip_(mip),
472  current_solution_index_(0) {
474  CheckedGurobiCall(GRBnewmodel(env_, &model_, solver_->name_.c_str(),
475  0, // numvars
476  nullptr, // obj
477  nullptr, // lb
478  nullptr, // ub
479  nullptr, // vtype
480  nullptr)); // varnanes
481  CheckedGurobiCall(
482  GRBsetintattr(model_, GRB_INT_ATTR_MODELSENSE, maximize_ ? -1 : 1));
483 
484  CheckedGurobiCall(
485  GRBsetintparam(env_, GRB_INT_PAR_THREADS, FLAGS_num_gurobi_threads));
486 }
487 
489  CheckedGurobiCall(GRBfreemodel(model_));
490  GRBfreeenv(env_);
491 }
492 
493 // ------ Model modifications and extraction -----
494 
496  CheckedGurobiCall(GRBfreemodel(model_));
497  CheckedGurobiCall(GRBnewmodel(env_, &model_, solver_->name_.c_str(),
498  0, // numvars
499  nullptr, // obj
500  nullptr, // lb
501  nullptr, // ub
502  nullptr, // vtype
503  nullptr)); // varnames
505 }
506 
509  // TODO(user,user): Fix, not yet working.
510  // InvalidateSolutionSynchronization();
511  // CheckedGurobiCall(GRBsetintattr(model_,
512  // GRB_INT_ATTR_MODELSENSE,
513  // maximize_ ? -1 : 1));
514 }
515 
516 void GurobiInterface::SetVariableBounds(int var_index, double lb, double ub) {
518 }
519 
520 // Modifies integrality of an extracted variable.
522  char current_type;
523  CheckedGurobiCall(
524  GRBgetcharattrelement(model_, GRB_CHAR_ATTR_VTYPE, index, &current_type));
525 
526  if ((integer &&
527  (current_type == GRB_INTEGER || current_type == GRB_BINARY)) ||
528  (!integer && current_type == GRB_CONTINUOUS)) {
529  return;
530  }
531 
534  char type_var;
535  if (integer) {
536  type_var = GRB_INTEGER;
537  } else {
538  type_var = GRB_CONTINUOUS;
539  }
540  CheckedGurobiCall(
541  GRBsetcharattrelement(model_, GRB_CHAR_ATTR_VTYPE, index, type_var));
542  } else {
544  }
545 }
546 
547 void GurobiInterface::SetConstraintBounds(int index, double lb, double ub) {
549 }
550 
553 }
554 
557  return !IsContinuous();
558 }
559 
562 }
563 
565  const MPVariable* const variable,
566  double new_value, double old_value) {
568 }
569 
572 }
573 
575  double coefficient) {
577 }
578 
581  // TODO(user,user): make it work.
582  // InvalidateSolutionSynchronization();
583  // CheckedGurobiCall(GRBsetdblattr(model_,
584  // GRB_DBL_ATTR_OBJCON,
585  // solver_->Objective().offset()));
586  // CheckedGurobiCall(GRBupdatemodel(model_));
587 }
588 
590 
592  update_branching_priorities_ = true;
593 }
594 
595 // ------ Query statistics on the solution and the solve ------
596 
598  double iter;
600  CheckedGurobiCall(GRBgetdblattr(model_, GRB_DBL_ATTR_ITERCOUNT, &iter));
601  return static_cast<int64>(iter);
602 }
603 
605  if (mip_) {
607  double nodes = 0;
608  CheckedGurobiCall(GRBgetdblattr(model_, GRB_DBL_ATTR_NODECOUNT, &nodes));
609  return static_cast<int64>(nodes);
610  } else {
611  LOG(DFATAL) << "Number of nodes only available for discrete problems.";
612  return kUnknownNumberOfNodes;
613  }
614 }
615 
617  double value;
618  const int error = GRBgetdblattr(model_, GRB_DBL_ATTR_OBJBOUND, &value);
619  return error == 0;
620 }
621 
622 // Returns the best objective bound. Only available for discrete problems.
624  if (mip_) {
627  }
628  if (solver_->variables_.empty() && solver_->constraints_.empty()) {
629  // Special case for empty model.
630  return solver_->Objective().offset();
631  }
632  double value;
633  const int error = GRBgetdblattr(model_, GRB_DBL_ATTR_OBJBOUND, &value);
635  error == GRB_ERROR_DATA_NOT_AVAILABLE) {
636  // Special case for when presolve removes all the variables so the model
637  // becomes empty after the presolve phase.
638  return objective_value_;
639  }
640  CheckedGurobiCall(error);
641  return value;
642  } else {
643  LOG(DFATAL) << "Best objective bound only available for discrete problems.";
645  }
646 }
647 
648 MPSolver::BasisStatus GurobiInterface::TransformGRBVarBasisStatus(
649  int gurobi_basis_status) const {
650  switch (gurobi_basis_status) {
651  case GRB_BASIC:
652  return MPSolver::BASIC;
653  case GRB_NONBASIC_LOWER:
655  case GRB_NONBASIC_UPPER:
657  case GRB_SUPERBASIC:
658  return MPSolver::FREE;
659  default:
660  LOG(DFATAL) << "Unknown GRB basis status.";
661  return MPSolver::FREE;
662  }
663 }
664 
665 MPSolver::BasisStatus GurobiInterface::TransformGRBConstraintBasisStatus(
666  int gurobi_basis_status, int constraint_index) const {
667  switch (gurobi_basis_status) {
668  case GRB_BASIC:
669  return MPSolver::BASIC;
670  default: {
671  // Non basic.
672  double slack = 0.0;
673  double tolerance = 0.0;
674  CheckedGurobiCall(GRBgetdblparam(GRBgetenv(model_),
675  GRB_DBL_PAR_FEASIBILITYTOL, &tolerance));
676  CheckedGurobiCall(GRBgetdblattrelement(model_, GRB_DBL_ATTR_SLACK,
677  constraint_index, &slack));
678  char sense;
679  CheckedGurobiCall(GRBgetcharattrelement(model_, GRB_CHAR_ATTR_SENSE,
680  constraint_index, &sense));
681  VLOG(4) << "constraint " << constraint_index << " , slack = " << slack
682  << " , sense = " << sense;
683  if (fabs(slack) <= tolerance) {
684  switch (sense) {
685  case GRB_EQUAL:
686  case GRB_LESS_EQUAL:
688  case GRB_GREATER_EQUAL:
690  default:
691  return MPSolver::FREE;
692  }
693  } else {
694  return MPSolver::FREE;
695  }
696  }
697  }
698 }
699 
700 // Returns the basis status of a row.
702  int optim_status = 0;
703  CheckedGurobiCall(GRBgetintattr(model_, GRB_INT_ATTR_STATUS, &optim_status));
704  if (optim_status != GRB_OPTIMAL && optim_status != GRB_SUBOPTIMAL) {
705  LOG(DFATAL) << "Basis status only available after a solution has "
706  << "been found.";
707  return MPSolver::FREE;
708  }
709  if (mip_) {
710  LOG(DFATAL) << "Basis status only available for continuous problems.";
711  return MPSolver::FREE;
712  }
713  int gurobi_basis_status = 0;
714  CheckedGurobiCall(GRBgetintattrelement(
715  model_, GRB_INT_ATTR_CBASIS, constraint_index, &gurobi_basis_status));
716  return TransformGRBConstraintBasisStatus(gurobi_basis_status,
717  constraint_index);
718 }
719 
720 // Returns the basis status of a column.
722  int optim_status = 0;
723  CheckedGurobiCall(GRBgetintattr(model_, GRB_INT_ATTR_STATUS, &optim_status));
724  if (optim_status != GRB_OPTIMAL && optim_status != GRB_SUBOPTIMAL) {
725  LOG(DFATAL) << "Basis status only available after a solution has "
726  << "been found.";
727  return MPSolver::FREE;
728  }
729  if (mip_) {
730  LOG(DFATAL) << "Basis status only available for continuous problems.";
731  return MPSolver::FREE;
732  }
733  int gurobi_basis_status = 0;
734  CheckedGurobiCall(GRBgetintattrelement(model_, GRB_INT_ATTR_VBASIS,
735  variable_index, &gurobi_basis_status));
736  return TransformGRBVarBasisStatus(gurobi_basis_status);
737 }
738 
739 // Extracts new variables.
741  CHECK(last_variable_index_ == 0 ||
742  last_variable_index_ == solver_->variables_.size());
743  CHECK(last_constraint_index_ == 0 ||
744  last_constraint_index_ == solver_->constraints_.size());
745  const int total_num_vars = solver_->variables_.size();
746  if (total_num_vars > last_variable_index_) {
747  int num_new_variables = total_num_vars - last_variable_index_;
748  std::unique_ptr<double[]> obj_coeffs(new double[num_new_variables]);
749  std::unique_ptr<double[]> lb(new double[num_new_variables]);
750  std::unique_ptr<double[]> ub(new double[num_new_variables]);
751  std::unique_ptr<char[]> ctype(new char[num_new_variables]);
752  std::unique_ptr<const char*[]> colname(new const char*[num_new_variables]);
753 
754  for (int j = 0; j < num_new_variables; ++j) {
755  MPVariable* const var = solver_->variables_[last_variable_index_ + j];
756  set_variable_as_extracted(var->index(), true);
757  lb[j] = var->lb();
758  ub[j] = var->ub();
759  ctype.get()[j] = var->integer() && mip_ ? GRB_INTEGER : GRB_CONTINUOUS;
760  if (!var->name().empty()) {
761  colname[j] = var->name().c_str();
762  }
763  obj_coeffs[j] = solver_->objective_->GetCoefficient(var);
764  }
765 
766  CheckedGurobiCall(GRBaddvars(model_, num_new_variables, 0, nullptr, nullptr,
767  nullptr, obj_coeffs.get(), lb.get(), ub.get(),
768  ctype.get(),
769  const_cast<char**>(colname.get())));
770  }
771  CheckedGurobiCall(GRBupdatemodel(model_));
772 }
773 
775  CHECK(last_variable_index_ == 0 ||
776  last_variable_index_ == solver_->variables_.size());
777  CHECK(last_constraint_index_ == 0 ||
778  last_constraint_index_ == solver_->constraints_.size());
779  int total_num_rows = solver_->constraints_.size();
780  if (last_constraint_index_ < total_num_rows) {
781  // Find the length of the longest row.
782  int max_row_length = 0;
783  for (int row = last_constraint_index_; row < total_num_rows; ++row) {
784  MPConstraint* const ct = solver_->constraints_[row];
785  CHECK(!constraint_is_extracted(row));
787  if (ct->coefficients_.size() > max_row_length) {
788  max_row_length = ct->coefficients_.size();
789  }
790  }
791 
792  max_row_length = std::max(1, max_row_length);
793  std::unique_ptr<int[]> col_indices(new int[max_row_length]);
794  std::unique_ptr<double[]> coeffs(new double[max_row_length]);
795 
796  // Add each new constraint.
797  for (int row = last_constraint_index_; row < total_num_rows; ++row) {
798  MPConstraint* const ct = solver_->constraints_[row];
800  const int size = ct->coefficients_.size();
801  int col = 0;
802  for (const auto& entry : ct->coefficients_) {
803  const int var_index = entry.first->index();
804  CHECK(variable_is_extracted(var_index));
805  col_indices[col] = var_index;
806  coeffs[col] = entry.second;
807  col++;
808  }
809  char* const name =
810  ct->name().empty() ? nullptr : const_cast<char*>(ct->name().c_str());
811  if (ct->indicator_variable() != nullptr) {
812  if (ct->lb() > -std::numeric_limits<double>::infinity()) {
813  CheckedGurobiCall(GRBaddgenconstrIndicator(
814  model_, name, ct->indicator_variable()->index(),
815  ct->indicator_value(), size, col_indices.get(), coeffs.get(),
816  ct->ub() == ct->lb() ? GRB_EQUAL : GRB_GREATER_EQUAL, ct->lb()));
817  }
818  if (ct->ub() < std::numeric_limits<double>::infinity() &&
819  ct->lb() != ct->ub()) {
820  CheckedGurobiCall(GRBaddgenconstrIndicator(
821  model_, name, ct->indicator_variable()->index(),
822  ct->indicator_value(), size, col_indices.get(), coeffs.get(),
823  GRB_LESS_EQUAL, ct->ub()));
824  }
825  } else {
826  // Using GRBaddrangeconstr for constraints that don't require it adds
827  // a slack which is not always removed by presolve.
828  if (ct->lb() == ct->ub()) {
829  CheckedGurobiCall(GRBaddconstr(model_, size, col_indices.get(),
830  coeffs.get(), GRB_EQUAL, ct->lb(),
831  name));
832  } else if (ct->lb() == -std::numeric_limits<double>::infinity()) {
833  CheckedGurobiCall(GRBaddconstr(model_, size, col_indices.get(),
834  coeffs.get(), GRB_LESS_EQUAL, ct->ub(),
835  name));
836  } else if (ct->ub() == std::numeric_limits<double>::infinity()) {
837  CheckedGurobiCall(GRBaddconstr(model_, size, col_indices.get(),
838  coeffs.get(), GRB_GREATER_EQUAL,
839  ct->lb(), name));
840  } else {
841  CheckedGurobiCall(GRBaddrangeconstr(model_, size, col_indices.get(),
842  coeffs.get(), ct->lb(), ct->ub(),
843  name));
844  }
845  }
846  }
847  }
848  CheckedGurobiCall(GRBupdatemodel(model_));
849 }
850 
852  CheckedGurobiCall(
853  GRBsetintattr(model_, GRB_INT_ATTR_MODELSENSE, maximize_ ? -1 : 1));
854  CheckedGurobiCall(GRBsetdblattr(model_, GRB_DBL_ATTR_OBJCON,
855  solver_->Objective().offset()));
856 }
857 
858 // ------ Parameters -----
859 
860 void GurobiInterface::SetParameters(const MPSolverParameters& param) {
861  SetCommonParameters(param);
862  if (mip_) {
863  SetMIPParameters(param);
864  }
865 }
866 
867 void GurobiInterface::SetRelativeMipGap(double value) {
868  if (mip_) {
869  CheckedGurobiCall(
871  } else {
872  LOG(WARNING) << "The relative MIP gap is only available "
873  << "for discrete problems.";
874  }
875 }
876 
877 // Gurobi has two different types of primal tolerance (feasibility tolerance):
878 // constraint and integrality. We need to set them both.
879 // See:
880 // http://www.gurobi.com/documentation/6.0/refman/feasibilitytol.html
881 // and
882 // http://www.gurobi.com/documentation/6.0/refman/intfeastol.html
883 void GurobiInterface::SetPrimalTolerance(double value) {
884  CheckedGurobiCall(
886  CheckedGurobiCall(
888 }
889 
890 // As opposed to primal (feasibility) tolerance, the dual (optimality) tolerance
891 // applies only to the reduced costs in the improving direction.
892 // See:
893 // http://www.gurobi.com/documentation/6.0/refman/optimalitytol.html
894 void GurobiInterface::SetDualTolerance(double value) {
895  CheckedGurobiCall(
897 }
898 
899 void GurobiInterface::SetPresolveMode(int value) {
900  switch (value) {
902  CheckedGurobiCall(
904  break;
905  }
907  CheckedGurobiCall(
909  break;
910  }
911  default: {
913  }
914  }
915 }
916 
917 // Sets the scaling mode.
918 void GurobiInterface::SetScalingMode(int value) {
919  switch (value) {
921  CheckedGurobiCall(
923  break;
925  CheckedGurobiCall(
927  CheckedGurobiCall(
929  break;
930  default:
931  // Leave the parameters untouched.
932  break;
933  }
934 }
935 
936 // Sets the LP algorithm : primal, dual or barrier. Note that GRB
937 // offers automatic selection
938 void GurobiInterface::SetLpAlgorithm(int value) {
939  switch (value) {
941  CheckedGurobiCall(GRBsetintparam(GRBgetenv(model_), GRB_INT_PAR_METHOD,
942  GRB_METHOD_DUAL));
943  break;
945  CheckedGurobiCall(GRBsetintparam(GRBgetenv(model_), GRB_INT_PAR_METHOD,
947  break;
949  CheckedGurobiCall(GRBsetintparam(GRBgetenv(model_), GRB_INT_PAR_METHOD,
951  break;
952  default:
954  value);
955  }
956 }
957 
958 int GurobiInterface::SolutionCount() const {
959  int solution_count = 0;
960  CheckedGurobiCall(
961  GRBgetintattr(model_, GRB_INT_ATTR_SOLCOUNT, &solution_count));
962  return solution_count;
963 }
964 
966  WallTimer timer;
967  timer.Start();
968 
971  Reset();
972  }
973 
974  // TODO(user,user): Support incrementality.
975  if (sync_status_ == MUST_RELOAD) {
976  Reset();
977  }
978 
979  // Set log level.
980  CheckedGurobiCall(
982 
983  ExtractModel();
984  // Sync solver.
985  CheckedGurobiCall(GRBupdatemodel(model_));
986  VLOG(1) << absl::StrFormat("Model built in %s.",
987  absl::FormatDuration(timer.GetDuration()));
988 
989  // Set solution hints if any.
990  for (const std::pair<const MPVariable*, double>& p :
991  solver_->solution_hint_) {
992  CheckedGurobiCall(
993  GRBsetdblattrelement(model_, "Start", p.first->index(), p.second));
994  }
995 
996  // Pass branching priority annotations if at least one has been updated.
997  if (update_branching_priorities_) {
998  for (const MPVariable* var : solver_->variables_) {
999  CheckedGurobiCall(
1001  var->index(), var->branching_priority()));
1002  }
1003  update_branching_priorities_ = false;
1004  }
1005 
1006  // Time limit.
1007  if (solver_->time_limit() != 0) {
1008  VLOG(1) << "Setting time limit = " << solver_->time_limit() << " ms.";
1009  CheckedGurobiCall(GRBsetdblparam(GRBgetenv(model_), GRB_DBL_PAR_TIMELIMIT,
1011  }
1012 
1013  // We first set our internal MPSolverParameters from 'param' and then set
1014  // any user-specified internal solver parameters via
1015  // solver_specific_parameter_string_.
1016  // Default MPSolverParameters can override custom parameters (for example for
1017  // presolving) and therefore we apply MPSolverParameters first.
1018  SetParameters(param);
1020  solver_->solver_specific_parameter_string_);
1021 
1022  std::unique_ptr<GurobiMPCallbackContext> gurobi_context;
1023  MPCallbackWithGurobiContext mp_callback_with_context;
1024  int gurobi_precrush = 0;
1025  int gurobi_lazy_constraint = 0;
1026  if (callback_ == nullptr) {
1027  CheckedGurobiCall(GRBsetcallbackfunc(model_, nullptr, nullptr));
1028  } else {
1029  gurobi_context = absl::make_unique<GurobiMPCallbackContext>(
1030  env_, callback_->might_add_cuts(),
1031  callback_->might_add_lazy_constraints());
1032  mp_callback_with_context.context = gurobi_context.get();
1033  mp_callback_with_context.callback = callback_;
1034  CheckedGurobiCall(GRBsetcallbackfunc(
1035  model_, CallbackImpl, static_cast<void*>(&mp_callback_with_context)));
1036  gurobi_precrush = callback_->might_add_cuts();
1037  gurobi_lazy_constraint = callback_->might_add_lazy_constraints();
1038  }
1039  CheckedGurobiCall(
1040  GRBsetintparam(GRBgetenv(model_), GRB_INT_PAR_PRECRUSH, gurobi_precrush));
1041  CheckedGurobiCall(GRBsetintparam(
1042  GRBgetenv(model_), GRB_INT_PAR_LAZYCONSTRAINTS, gurobi_lazy_constraint));
1043 
1044  // Solve
1045  timer.Restart();
1046  const int status = GRBoptimize(model_);
1047 
1048  if (status) {
1049  VLOG(1) << "Failed to optimize MIP." << GRBgeterrormsg(env_);
1050  } else {
1051  VLOG(1) << absl::StrFormat("Solved in %s.",
1052  absl::FormatDuration(timer.GetDuration()));
1053  }
1054 
1055  // Get the status.
1056  int optimization_status = 0;
1057  CheckedGurobiCall(
1058  GRBgetintattr(model_, GRB_INT_ATTR_STATUS, &optimization_status));
1059  VLOG(1) << absl::StrFormat("Solution status %d.\n", optimization_status);
1060  const int solution_count = SolutionCount();
1061 
1062  switch (optimization_status) {
1063  case GRB_OPTIMAL:
1065  break;
1066  case GRB_INFEASIBLE:
1068  break;
1069  case GRB_UNBOUNDED:
1071  break;
1072  case GRB_INF_OR_UNBD:
1073  // TODO(user,user): We could introduce our own "infeasible or
1074  // unbounded" status.
1076  break;
1077  default: {
1078  if (solution_count > 0) {
1080  } else {
1082  }
1083  break;
1084  }
1085  }
1086 
1087  if (solution_count > 0 && (result_status_ == MPSolver::FEASIBLE ||
1089  current_solution_index_ = 0;
1090  // Get the results.
1091  const int total_num_rows = solver_->constraints_.size();
1092  const int total_num_cols = solver_->variables_.size();
1093 
1094  {
1095  std::vector<double> variable_values(total_num_cols);
1096  CheckedGurobiCall(
1098  CheckedGurobiCall(GRBgetdblattrarray(
1099  model_, GRB_DBL_ATTR_X, 0, total_num_cols, variable_values.data()));
1100 
1101  VLOG(1) << "objective = " << objective_value_;
1102  for (int i = 0; i < solver_->variables_.size(); ++i) {
1103  MPVariable* const var = solver_->variables_[i];
1104  var->set_solution_value(variable_values[i]);
1105  VLOG(3) << var->name() << ", value = " << variable_values[i];
1106  }
1107  }
1108  if (!mip_) {
1109  {
1110  std::vector<double> reduced_costs(total_num_cols);
1111  CheckedGurobiCall(GRBgetdblattrarray(
1112  model_, GRB_DBL_ATTR_RC, 0, total_num_cols, reduced_costs.data()));
1113  for (int i = 0; i < solver_->variables_.size(); ++i) {
1114  MPVariable* const var = solver_->variables_[i];
1115  var->set_reduced_cost(reduced_costs[i]);
1116  VLOG(4) << var->name() << ", reduced cost = " << reduced_costs[i];
1117  }
1118  }
1119 
1120  {
1121  std::vector<double> dual_values(total_num_rows);
1122  CheckedGurobiCall(GRBgetdblattrarray(
1123  model_, GRB_DBL_ATTR_PI, 0, total_num_rows, dual_values.data()));
1124  for (int i = 0; i < solver_->constraints_.size(); ++i) {
1125  MPConstraint* const ct = solver_->constraints_[i];
1126  ct->set_dual_value(dual_values[i]);
1127  VLOG(4) << "row " << ct->index()
1128  << ", dual value = " << dual_values[i];
1129  }
1130  }
1131  }
1132  }
1133 
1135  GRBresetparams(GRBgetenv(model_));
1136  return result_status_;
1137 }
1138 
1139 absl::optional<MPSolutionResponse> GurobiInterface::DirectlySolveProto(
1140  const MPModelRequest& request) {
1141  const auto status_or = GurobiSolveProto(request);
1142  if (status_or.ok()) return status_or.value();
1143  // Special case: if something is not implemented yet, fall back to solving
1144  // through MPSolver.
1145  if (absl::IsUnimplemented(status_or.status())) return absl::nullopt;
1146 
1147  if (request.enable_internal_solver_output()) {
1148  LOG(INFO) << "Invalid Gurobi status: " << status_or.status();
1149  }
1150  MPSolutionResponse response;
1151  response.set_status(MPSOLVER_NOT_SOLVED);
1152  response.set_status_str(status_or.status().ToString());
1153  return std::move(response);
1154 }
1155 
1157  // Next solution only supported for MIP
1158  if (!mip_) return false;
1159 
1160  // Make sure we have successfully solved the problem and not modified it.
1162  return false;
1163  }
1164  // Check if we are out of solutions.
1165  if (current_solution_index_ + 1 >= SolutionCount()) {
1166  return false;
1167  }
1168  current_solution_index_++;
1169 
1170  const int total_num_cols = solver_->variables_.size();
1171  std::vector<double> variable_values(total_num_cols);
1172 
1173  CheckedGurobiCall(GRBsetintparam(
1174  GRBgetenv(model_), GRB_INT_PAR_SOLUTIONNUMBER, current_solution_index_));
1175 
1176  CheckedGurobiCall(
1178  CheckedGurobiCall(GRBgetdblattrarray(model_, GRB_DBL_ATTR_XN, 0,
1179  total_num_cols, variable_values.data()));
1180  for (int i = 0; i < solver_->variables_.size(); ++i) {
1181  MPVariable* const var = solver_->variables_[i];
1182  var->set_solution_value(variable_values[i]);
1183  }
1184  // TODO(user,user): This reset may not be necessary, investigate.
1185  GRBresetparams(GRBgetenv(model_));
1186  return true;
1187 }
1188 
1189 void GurobiInterface::Write(const std::string& filename) {
1190  if (sync_status_ == MUST_RELOAD) {
1191  Reset();
1192  }
1193  ExtractModel();
1194  // Sync solver.
1195  CheckedGurobiCall(GRBupdatemodel(model_));
1196  VLOG(1) << "Writing Gurobi model file \"" << filename << "\".";
1197  const int status = GRBwrite(model_, filename.c_str());
1198  if (status) {
1199  LOG(WARNING) << "Failed to write MIP." << GRBgeterrormsg(env_);
1200  }
1201 }
1202 
1203 bool GurobiInterface::ReadParameterFile(const std::string& filename) {
1204  // A non-zero return value indicates that a problem occurred.
1205  return GRBreadparams(GRBgetenv(model_), filename.c_str()) == 0;
1206 }
1207 
1208 std::string GurobiInterface::ValidFileExtensionForParameterFile() const {
1209  return ".prm";
1210 }
1211 
1214  return new GurobiInterface(solver, mip);
1215 }
1216 
1218  callback_ = mp_callback;
1219 }
1220 
1221 } // namespace operations_research
operations_research::MPSolverInterface::variable_is_extracted
bool variable_is_extracted(int var_index) const
Definition: linear_solver.h:1658
GRB_UNBOUNDED
#define GRB_UNBOUNDED
Definition: gurobi_environment.h:439
var
IntVar * var
Definition: expr_array.cc:1858
operations_research::GurobiInterface::ExtractObjective
void ExtractObjective() override
Definition: gurobi_interface.cc:851
GRB_DBL_ATTR_OBJBOUND
#define GRB_DBL_ATTR_OBJBOUND
Definition: gurobi_environment.h:258
GRB_DBL_PAR_FEASIBILITYTOL
#define GRB_DBL_PAR_FEASIBILITYTOL
Definition: gurobi_environment.h:462
operations_research::MPSolverParameters::GetIntegerParam
int GetIntegerParam(MPSolverParameters::IntegerParam param) const
Returns the value of an integer parameter.
Definition: linear_solver.cc:1973
operations_research::MPSolverParameters::LP_ALGORITHM
@ LP_ALGORITHM
Algorithm to solve linear programs.
Definition: linear_solver.h:1381
response
SharedResponseManager * response
Definition: cp_model_solver.cc:2027
integral_types.h
map_util.h
CHECK_OK
#define CHECK_OK(x)
Definition: base/logging.h:29
operations_research::MPVariable
The class for variables of a Mathematical Programming (MP) model.
Definition: linear_solver.h:1050
operations_research::MPSolver
This mathematical programming (MP) solver class is the main class though which users build and solve ...
Definition: linear_solver.h:177
STDCALL
#define STDCALL
Definition: gurobi_environment.h:25
operations_research::MPSolverInterface::MUST_RELOAD
@ MUST_RELOAD
Definition: linear_solver.h:1519
GRB_METHOD_DUAL
#define GRB_METHOD_DUAL
Definition: gurobi_environment.h:622
operations_research::MPSolverParameters::PRESOLVE_OFF
@ PRESOLVE_OFF
Presolve is off.
Definition: linear_solver.h:1391
operations_research::MPSolverInterface::result_status_
MPSolver::ResultStatus result_status_
Definition: linear_solver.h:1723
max
int64 max
Definition: alldiff_cst.cc:139
operations_research::GRBaddgenconstrIndicator
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
Definition: gurobi_environment.cc:95
GRB_INFEASIBLE
#define GRB_INFEASIBLE
Definition: gurobi_environment.h:437
where
int where
Definition: gurobi_interface.cc:197
GRB_DBL_ATTR_OBJCON
#define GRB_DBL_ATTR_OBJCON
Definition: gurobi_environment.h:197
GRB_INT_PAR_PRECRUSH
#define GRB_INT_PAR_PRECRUSH
Definition: gurobi_environment.h:572
GRB_INT_PAR_METHOD
#define GRB_INT_PAR_METHOD
Definition: gurobi_environment.h:469
operations_research::GurobiInterface::best_objective_bound
double best_objective_bound() const override
Definition: gurobi_interface.cc:623
GRB_DBL_PAR_MIPGAP
#define GRB_DBL_PAR_MIPGAP
Definition: gurobi_environment.h:465
GRB_CB_MIPSOL_NODCNT
#define GRB_CB_MIPSOL_NODCNT
Definition: gurobi_environment.h:410
operations_research::MPConstraint
The class for constraints of a Mathematical Programming (MP) model.
Definition: linear_solver.h:1175
GRB_INT_ATTR_VBASIS
#define GRB_INT_ATTR_VBASIS
Definition: gurobi_environment.h:274
GRB_DBL_ATTR_X
#define GRB_DBL_ATTR_X
Definition: gurobi_environment.h:269
operations_research::MPSolver::FEASIBLE
@ FEASIBLE
feasible, or stopped by limit.
Definition: linear_solver.h:429
operations_research::MPSolverInterface::objective_value_
double objective_value_
Definition: linear_solver.h:1733
GRB_DBL_ATTR_RC
#define GRB_DBL_ATTR_RC
Definition: gurobi_environment.h:272
operations_research::GurobiInterface::row_status
MPSolver::BasisStatus row_status(int constraint_index) const override
Definition: gurobi_interface.cc:701
GRB_CB_SIMPLEX
#define GRB_CB_SIMPLEX
Definition: gurobi_environment.h:381
operations_research::GRBsetcallbackfunc
std::function< int(GRBmodel *model, int(STDCALL *cb)(CB_ARGS), void *usrdata)> GRBsetcallbackfunc
Definition: gurobi_environment.cc:100
operations_research::MPSolverParameters::SCALING_OFF
@ SCALING_OFF
Scaling is off.
Definition: linear_solver.h:1421
operations_research::GRBsetintparam
std::function< int(GRBenv *, const char *, int)> GRBsetintparam
Definition: gurobi_environment.cc:74
logging.h
operations_research::GurobiInterface::AddVariable
void AddVariable(MPVariable *const var) override
Definition: gurobi_interface.cc:560
DEFINE_int32
DEFINE_int32(num_gurobi_threads, 4, "Number of threads available for Gurobi.")
GRB_CHAR_ATTR_VTYPE
#define GRB_CHAR_ATTR_VTYPE
Definition: gurobi_environment.h:213
operations_research::GurobiInterface::SetVariableInteger
void SetVariableInteger(int var_index, bool integer) override
Definition: gurobi_interface.cc:521
operations_research::MPSolver::time_limit
int64 time_limit() const
Definition: linear_solver.h:777
GRB_DBL_ATTR_NODECOUNT
#define GRB_DBL_ATTR_NODECOUNT
Definition: gurobi_environment.h:266
GRB_METHOD_PRIMAL
#define GRB_METHOD_PRIMAL
Definition: gurobi_environment.h:621
GRB_CB_POLLING
#define GRB_CB_POLLING
Definition: gurobi_environment.h:379
operations_research::GRBcbget
std::function< int(void *cbdata, int where, int what, void *resultP)> GRBcbget
Definition: gurobi_environment.cc:79
operations_research::MPObjective::offset
double offset() const
Gets the constant term in the objective.
Definition: linear_solver.h:959
GRB_NONBASIC_LOWER
#define GRB_NONBASIC_LOWER
Definition: gurobi_environment.h:451
operations_research::MPSolver::AT_LOWER_BOUND
@ AT_LOWER_BOUND
Definition: linear_solver.h:642
operations_research::GRBcblazy
std::function< int(void *cbdata, int lazylen, const int *lazyind, const double *lazyval, char lazysense, double lazyrhs)> GRBcblazy
Definition: gurobi_environment.cc:86
GRB_INT_ATTR_SOLCOUNT
#define GRB_INT_ATTR_SOLCOUNT
Definition: gurobi_environment.h:263
WallTimer::GetDuration
absl::Duration GetDuration() const
Definition: timer.h:48
value
int64 value
Definition: demon_profiler.cc:43
operations_research::MPSolverParameters::DUAL
@ DUAL
Dual simplex.
Definition: linear_solver.h:1399
operations_research::MPSolverInterface::set_variable_as_extracted
void set_variable_as_extracted(int var_index, bool extracted)
Definition: linear_solver.h:1661
statusor.h
operations_research::MPSolverInterface::MODEL_SYNCHRONIZED
@ MODEL_SYNCHRONIZED
Definition: linear_solver.h:1523
GRB_CB_MIPSOL
#define GRB_CB_MIPSOL
Definition: gurobi_environment.h:383
GRB_GREATER_EQUAL
#define GRB_GREATER_EQUAL
Definition: gurobi_environment.h:165
GRB_INF_OR_UNBD
#define GRB_INF_OR_UNBD
Definition: gurobi_environment.h:438
GRB_CB_MIPNODE
#define GRB_CB_MIPNODE
Definition: gurobi_environment.h:384
GRB_CB_MIPSOL_SOL
#define GRB_CB_MIPSOL_SOL
Definition: gurobi_environment.h:406
operations_research
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
Definition: dense_doubly_linked_list.h:21
GRB_BASIC
#define GRB_BASIC
Definition: gurobi_environment.h:450
operations_research::GRBgeterrormsg
std::function< char *(GRBenv *)> GRBgeterrormsg
Definition: gurobi_environment.cc:56
operations_research::GurobiInterface::IsContinuous
bool IsContinuous() const override
Definition: gurobi_interface.cc:104
GRB_CHAR_ATTR_SENSE
#define GRB_CHAR_ATTR_SENSE
Definition: gurobi_environment.h:226
operations_research::LoadGurobiEnvironment
absl::Status LoadGurobiEnvironment(GRBenv **env)
Definition: gurobi_environment.cc:26
operations_research::GurobiInterface::SetCallback
void SetCallback(MPCallback *mp_callback) override
Definition: gurobi_interface.cc:1217
GRB_INTEGER
#define GRB_INTEGER
Definition: gurobi_environment.h:169
operations_research::GurobiInterface::SetCoefficient
void SetCoefficient(MPConstraint *const constraint, const MPVariable *const variable, double new_value, double old_value) override
Definition: gurobi_interface.cc:564
operations_research::GRBwrite
std::function< int(GRBmodel *, const char *)> GRBwrite
Definition: gurobi_environment.cc:78
operations_research::GurobiInterface::SetObjectiveCoefficient
void SetObjectiveCoefficient(const MPVariable *const variable, double coefficient) override
Definition: gurobi_interface.cc:574
operations_research::GRBreadparams
std::function< int(GRBenv *, const char *)> GRBreadparams
Definition: gurobi_environment.cc:65
operations_research::MPSolverInterface::last_variable_index_
int last_variable_index_
Definition: linear_solver.h:1730
int64
int64_t int64
Definition: integral_types.h:34
operations_research::MPSolverParameters
This class stores parameter settings for LP and MIP solvers.
Definition: linear_solver.h:1358
operations_research::GRBgetdblparam
std::function< int(GRBenv *, const char *, double *)> GRBgetdblparam
Definition: gurobi_environment.cc:54
operations_research::GurobiInterface::SetOptimizationDirection
void SetOptimizationDirection(bool maximize) override
Definition: gurobi_interface.cc:507
GRB_UNDEFINED
#define GRB_UNDEFINED
Definition: gurobi_environment.h:177
operations_research::ToString
const absl::string_view ToString(MPSolver::OptimizationProblemType optimization_problem_type)
Definition: linear_solver.cc:568
operations_research::MPSolverInterface::CheckSolutionIsSynchronized
bool CheckSolutionIsSynchronized() const
Definition: linear_solver.cc:1648
operations_research::GurobiInterface::Reset
void Reset() override
Definition: gurobi_interface.cc:495
index
int index
Definition: pack.cc:508
context
GurobiMPCallbackContext * context
Definition: gurobi_interface.cc:439
operations_research::GRBgetdblattr
std::function< int(GRBmodel *, const char *, double *)> GRBgetdblattr
Definition: gurobi_environment.cc:49
operations_research::GurobiInterface::SupportsCallbacks
bool SupportsCallbacks() const override
Definition: gurobi_interface.cc:153
operations_research::MPSolverParameters::INCREMENTALITY
@ INCREMENTALITY
Advanced usage: incrementality from one solve to the next.
Definition: linear_solver.h:1383
operations_research::GRBfreemodel
std::function< int(GRBmodel *)> GRBfreemodel
Definition: gurobi_environment.cc:46
operations_research::GRBnewmodel
std::function< int(GRBenv *, GRBmodel **, const char *, int numvars, double *, double *, double *, char *, char **)> GRBnewmodel
Definition: gurobi_environment.cc:63
GRB_DBL_ATTR_PI
#define GRB_DBL_ATTR_PI
Definition: gurobi_environment.h:275
operations_research::MPSolverInterface::SetIntegerParamToUnsupportedValue
virtual void SetIntegerParamToUnsupportedValue(MPSolverParameters::IntegerParam param, int value)
Definition: linear_solver.cc:1748
operations_research::GRBsetintattr
std::function< int(GRBmodel *, const char *, int)> GRBsetintattr
Definition: gurobi_environment.cc:73
operations_research::GRBresetparams
std::function< int(GRBenv *)> GRBresetparams
Definition: gurobi_environment.cc:66
operations_research::GRBgetdblattrarray
std::function< int(GRBmodel *, const char *, int, int, double *)> GRBgetdblattrarray
Definition: gurobi_environment.cc:51
GRB_INT_ATTR_MODELSENSE
#define GRB_INT_ATTR_MODELSENSE
Definition: gurobi_environment.h:196
operations_research::MPSolverInterface::SetCommonParameters
void SetCommonParameters(const MPSolverParameters &param)
Definition: linear_solver.cc:1707
operations_research::GRBcbcut
std::function< int(void *cbdata, int cutlen, const int *cutind, const double *cutval, char cutsense, double cutrhs)> GRBcbcut
Definition: gurobi_environment.cc:83
operations_research::GurobiInterface::SetConstraintBounds
void SetConstraintBounds(int row_index, double lb, double ub) override
Definition: gurobi_interface.cc:547
operations_research::MPCallback
Definition: linear_solver_callback.h:140
operations_research::GurobiInterface::underlying_solver
void * underlying_solver() override
Definition: gurobi_interface.cc:124
operations_research::MPSolverInterface::ExtractModel
void ExtractModel()
Definition: linear_solver.cc:1612
GRB_NONBASIC_UPPER
#define GRB_NONBASIC_UPPER
Definition: gurobi_environment.h:452
GRB_CB_PRESOLVE
#define GRB_CB_PRESOLVE
Definition: gurobi_environment.h:380
operations_research::GurobiInterface::ClearConstraint
void ClearConstraint(MPConstraint *const constraint) override
Definition: gurobi_interface.cc:570
operations_research::MPCallbackEvent
MPCallbackEvent
Definition: linear_solver_callback.h:35
operations_research::MPSolverInterface::CheckSolutionIsSynchronizedAndExists
bool CheckSolutionIsSynchronizedAndExists() const
Definition: linear_solver.h:1635
GRB_INT_PAR_LAZYCONSTRAINTS
#define GRB_INT_PAR_LAZYCONSTRAINTS
Definition: gurobi_environment.h:565
WallTimer::Restart
void Restart()
Definition: timer.h:35
operations_research::GRBsetintattrelement
std::function< int(GRBmodel *model, const char *attrname, int element, int newvalue)> GRBsetintattrelement
Definition: gurobi_environment.cc:98
operations_research::GurobiInterface::SetObjectiveOffset
void SetObjectiveOffset(double value) override
Definition: gurobi_interface.cc:579
GRB_EQUAL
#define GRB_EQUAL
Definition: gurobi_environment.h:166
operations_research::GurobiInterface::GurobiInterface
GurobiInterface(MPSolver *const solver, bool mip)
Definition: gurobi_interface.cc:467
GRB_INT_PAR_OUTPUTFLAG
#define GRB_INT_PAR_OUTPUTFLAG
Definition: gurobi_environment.h:571
GRB_ERROR_DATA_NOT_AVAILABLE
#define GRB_ERROR_DATA_NOT_AVAILABLE
Definition: gurobi_environment.h:136
GRB_DBL_ATTR_ITERCOUNT
#define GRB_DBL_ATTR_ITERCOUNT
Definition: gurobi_environment.h:264
operations_research::MPSolverParameters::PRIMAL
@ PRIMAL
Primal simplex.
Definition: linear_solver.h:1401
operations_research::GRBsetcharattrelement
std::function< int(GRBmodel *, const char *, int, char)> GRBsetcharattrelement
Definition: gurobi_environment.cc:67
operations_research::GurobiInterface::NextSolution
bool NextSolution() override
Definition: gurobi_interface.cc:1156
timer.h
GRB_INT_PAR_PRESOLVE
#define GRB_INT_PAR_PRESOLVE
Definition: gurobi_environment.h:577
operations_research::MPSolverInterface::set_constraint_as_extracted
void set_constraint_as_extracted(int ct_index, bool extracted)
Definition: linear_solver.h:1667
operations_research::GRBsetdblattrelement
std::function< int(GRBmodel *, const char *, int, double)> GRBsetdblattrelement
Definition: gurobi_environment.cc:70
operations_research::MPSolver::LoadGurobiSharedLibrary
static bool LoadGurobiSharedLibrary()
Definition: gurobi_environment.cc:245
GRB_DBL_ATTR_XN
#define GRB_DBL_ATTR_XN
Definition: gurobi_environment.h:270
GRB_INT_PAR_SCALEFLAG
#define GRB_INT_PAR_SCALEFLAG
Definition: gurobi_environment.h:472
operations_research::MPSolverInterface::ResetExtractionInformation
void ResetExtractionInformation()
Definition: linear_solver.cc:1640
GRB_DBL_PAR_OPTIMALITYTOL
#define GRB_DBL_PAR_OPTIMALITYTOL
Definition: gurobi_environment.h:467
operations_research::MPSolverInterface::kUnknownNumberOfNodes
static constexpr int64 kUnknownNumberOfNodes
Definition: linear_solver.h:1534
operations_research::MPSolverInterface::quiet_
bool quiet_
Definition: linear_solver.h:1736
operations_research::MPCallback::might_add_cuts
bool might_add_cuts() const
Definition: linear_solver_callback.h:155
operations_research::MPSolverParameters::INCREMENTALITY_OFF
@ INCREMENTALITY_OFF
Start solve from scratch.
Definition: linear_solver.h:1409
operations_research::GurobiInterface::BranchingPriorityChangedForVariable
void BranchingPriorityChangedForVariable(int var_index) override
Definition: gurobi_interface.cc:591
operations_research::GRBversion
std::function< void(int *, int *, int *)> GRBversion
Definition: gurobi_environment.cc:77
GRB_DBL_PAR_TIMELIMIT
#define GRB_DBL_PAR_TIMELIMIT
Definition: gurobi_environment.h:459
operations_research::MPSolverInterface::maximize_
bool maximize_
Definition: linear_solver.h:1725
operations_research::GurobiSolveProto
absl::StatusOr< MPSolutionResponse > GurobiSolveProto(const MPModelRequest &request)
Definition: gurobi_proto_solver.cc:248
GRB_SUBOPTIMAL
#define GRB_SUBOPTIMAL
Definition: gurobi_environment.h:447
GRB_OPTIMAL
#define GRB_OPTIMAL
Definition: gurobi_environment.h:436
operations_research::GurobiInterface::column_status
MPSolver::BasisStatus column_status(int variable_index) const override
Definition: gurobi_interface.cc:721
GRB_INT_PAR_THREADS
#define GRB_INT_PAR_THREADS
Definition: gurobi_environment.h:586
WallTimer
Definition: timer.h:23
GRB_CB_MIP
#define GRB_CB_MIP
Definition: gurobi_environment.h:382
operations_research::GRBsetdblattr
std::function< int(GRBmodel *, const char *, double)> GRBsetdblattr
Definition: gurobi_environment.cc:69
ct
const Constraint * ct
Definition: demon_profiler.cc:42
operations_research::GurobiInterface::iterations
int64 iterations() const override
Definition: gurobi_interface.cc:597
GRB_CB_BARRIER
#define GRB_CB_BARRIER
Definition: gurobi_environment.h:386
operations_research::GRBaddrangeconstr
std::function< int(GRBmodel *, int, int *, double *, double, double, const char *)> GRBaddrangeconstr
Definition: gurobi_environment.cc:41
GRB_METHOD_BARRIER
#define GRB_METHOD_BARRIER
Definition: gurobi_environment.h:623
GRB_CB_MIPNODE_NODCNT
#define GRB_CB_MIPNODE_NODCNT
Definition: gurobi_environment.h:417
operations_research::GRBcbsolution
std::function< int(void *cbdata, const double *solution, double *objvalP)> GRBcbsolution
Definition: gurobi_environment.cc:88
operations_research::MPSolverParameters::SCALING_ON
@ SCALING_ON
Scaling is on.
Definition: linear_solver.h:1423
GRB_SUPERBASIC
#define GRB_SUPERBASIC
Definition: gurobi_environment.h:453
operations_research::GRBgetintattr
std::function< int(GRBmodel *, const char *, int *)> GRBgetintattr
Definition: gurobi_environment.cc:57
operations_research::MPSOLVER_NOT_SOLVED
@ MPSOLVER_NOT_SOLVED
Definition: linear_solver.pb.h:234
operations_research::GurobiInterface::AddIndicatorConstraint
bool AddIndicatorConstraint(MPConstraint *const ct) override
Definition: gurobi_interface.cc:555
GRB_INT_PAR_SOLUTIONNUMBER
#define GRB_INT_PAR_SOLUTIONNUMBER
Definition: gurobi_environment.h:505
operations_research::MPSolverInterface::SetMIPParameters
void SetMIPParameters(const MPSolverParameters &param)
Definition: linear_solver.cc:1728
GRB_DBL_ATTR_POOLOBJVAL
#define GRB_DBL_ATTR_POOLOBJVAL
Definition: gurobi_environment.h:261
operations_research::GurobiInterface::Solve
MPSolver::ResultStatus Solve(const MPSolverParameters &param) override
Definition: gurobi_interface.cc:965
operations_research::MPSolverInterface
Definition: linear_solver.h:1514
callback
MPCallback * callback
Definition: gurobi_interface.cc:440
GRBenv
struct _GRBenv GRBenv
Definition: gurobi_environment.h:30
operations_research::MPSolver::AT_UPPER_BOUND
@ AT_UPPER_BOUND
Definition: linear_solver.h:643
operations_research::MPSolverParameters::PRESOLVE
@ PRESOLVE
Advanced usage: presolve mode.
Definition: linear_solver.h:1379
model
GRBmodel * model
Definition: gurobi_interface.cc:195
operations_research::GurobiInterface::nodes
int64 nodes() const override
Definition: gurobi_interface.cc:604
operations_research::GurobiInterface::InterruptSolve
bool InterruptSolve() override
Definition: gurobi_interface.cc:119
operations_research::MPSolver::SetSolverSpecificParametersAsString
bool SetSolverSpecificParametersAsString(const std::string &parameters)
Advanced usage: pass solver specific parameters in text format.
Definition: linear_solver.cc:345
operations_research::GRBoptimize
std::function< int(GRBmodel *)> GRBoptimize
Definition: gurobi_environment.cc:64
operations_research::MPSolver::Objective
const MPObjective & Objective() const
Returns the objective object.
Definition: linear_solver.h:414
operations_research::MPSolver::OPTIMAL
@ OPTIMAL
optimal.
Definition: linear_solver.h:427
GRB_DBL_PAR_INTFEASTOL
#define GRB_DBL_PAR_INTFEASTOL
Definition: gurobi_environment.h:463
GRB_LESS_EQUAL
#define GRB_LESS_EQUAL
Definition: gurobi_environment.h:164
operations_research::MPSolver::ResultStatus
ResultStatus
The status of solving the problem.
Definition: linear_solver.h:425
WallTimer::Start
void Start()
Definition: timer.h:31
coefficient
int64 coefficient
Definition: routing_search.cc:973
col
ColIndex col
Definition: markowitz.cc:176
operations_research::MPSolver::FREE
@ FREE
Definition: linear_solver.h:641
operations_research::GurobiInterface::IsLP
bool IsLP() const override
Definition: gurobi_interface.cc:105
GRB_DBL_ATTR_SLACK
#define GRB_DBL_ATTR_SLACK
Definition: gurobi_environment.h:277
GRB_BINARY
#define GRB_BINARY
Definition: gurobi_environment.h:168
operations_research::GurobiInterface::ClearObjective
void ClearObjective() override
Definition: gurobi_interface.cc:589
ABSL_DIE_IF_NULL
#define ABSL_DIE_IF_NULL
Definition: base/logging.h:28
row
RowIndex row
Definition: markowitz.cc:175
gurobi_internal_callback_data
void * gurobi_internal_callback_data
Definition: gurobi_interface.cc:196
operations_research::GurobiInterface::AddRowConstraint
void AddRowConstraint(MPConstraint *const ct) override
Definition: gurobi_interface.cc:551
operations_research::GurobiInterface::SolverVersion
std::string SolverVersion() const override
Definition: gurobi_interface.cc:112
GRB_CONTINUOUS
#define GRB_CONTINUOUS
Definition: gurobi_environment.h:167
operations_research::MPSolverParameters::BARRIER
@ BARRIER
Barrier algorithm.
Definition: linear_solver.h:1403
gurobi_environment.h
GRB_CB_MIPNODE_STATUS
#define GRB_CB_MIPNODE_STATUS
Definition: gurobi_environment.h:413
operations_research::GRBgetenv
std::function< GRBenv *(GRBmodel *)> GRBgetenv
Definition: gurobi_environment.cc:55
GRB_DBL_ATTR_OBJVAL
#define GRB_DBL_ATTR_OBJVAL
Definition: gurobi_environment.h:257
linear_solver.h
operations_research::GurobiInterface::~GurobiInterface
~GurobiInterface() override
Definition: gurobi_interface.cc:488
GRB_DBL_PAR_OBJSCALE
#define GRB_DBL_PAR_OBJSCALE
Definition: gurobi_environment.h:471
GRB_CB_MESSAGE
#define GRB_CB_MESSAGE
Definition: gurobi_environment.h:385
operations_research::GurobiInterface::DirectlySolveProto
absl::optional< MPSolutionResponse > DirectlySolveProto(const MPModelRequest &request) override
Definition: gurobi_interface.cc:1139
operations_research::GRBupdatemodel
std::function< int(GRBmodel *)> GRBupdatemodel
Definition: gurobi_environment.cc:76
operations_research::MPSolver::time_limit_in_secs
double time_limit_in_secs() const
Definition: linear_solver.h:787
operations_research::MPSolverInterface::solver_
MPSolver *const solver_
Definition: linear_solver.h:1718
operations_research::GRBgetcharattrelement
std::function< int(GRBmodel *, const char *, int, char *)> GRBgetcharattrelement
Definition: gurobi_environment.cc:48
operations_research::MPSolver::BasisStatus
BasisStatus
Advanced usage: possible basis status values for a variable and the slack variable of a linear constr...
Definition: linear_solver.h:640
operations_research::BuildGurobiInterface
MPSolverInterface * BuildGurobiInterface(bool mip, MPSolver *const solver)
Definition: gurobi_interface.cc:1212
operations_research::MPCallback::might_add_lazy_constraints
bool might_add_lazy_constraints() const
Definition: linear_solver_callback.h:156
operations_research::MPSolverInterface::SOLUTION_SYNCHRONIZED
@ SOLUTION_SYNCHRONIZED
Definition: linear_solver.h:1526
linear_solver_callback.h
GRBmodel
struct _GRBmodel GRBmodel
Definition: gurobi_environment.h:29
operations_research::GRBsetdblparam
std::function< int(GRBenv *, const char *, double)> GRBsetdblparam
Definition: gurobi_environment.cc:72
operations_research::MPSolverInterface::constraint_is_extracted
bool constraint_is_extracted(int ct_index) const
Definition: linear_solver.h:1664
operations_research::GRBgetdblattrelement
std::function< int(GRBmodel *, const char *, int, double *)> GRBgetdblattrelement
Definition: gurobi_environment.cc:53
operations_research::GurobiInterface::IsMIP
bool IsMIP() const override
Definition: gurobi_interface.cc:106
operations_research::GRBgetintattrelement
std::function< int(GRBmodel *, const char *, int, int *)> GRBgetintattrelement
Definition: gurobi_environment.cc:58
operations_research::GurobiInterface::CheckBestObjectiveBoundExists
bool CheckBestObjectiveBoundExists() const override
Definition: gurobi_interface.cc:616
operations_research::MPSolverInterface::kUnknownNumberOfIterations
static constexpr int64 kUnknownNumberOfIterations
Definition: linear_solver.h:1531
operations_research::GurobiInterface::SetVariableBounds
void SetVariableBounds(int var_index, double lb, double ub) override
Definition: gurobi_interface.cc:516
operations_research::GurobiInterface::ComputeExactConditionNumber
double ComputeExactConditionNumber() const override
Definition: gurobi_interface.cc:126
operations_research::GRBterminate
std::function< void(GRBmodel *)> GRBterminate
Definition: gurobi_environment.cc:75
operations_research::MPSolverInterface::last_constraint_index_
int last_constraint_index_
Definition: linear_solver.h:1728
operations_research::MPSolverParameters::PRESOLVE_ON
@ PRESOLVE_ON
Presolve is on.
Definition: linear_solver.h:1393
operations_research::GRBfreeenv
std::function< void(GRBenv *)> GRBfreeenv
Definition: gurobi_environment.cc:45
gurobi_proto_solver.h
operations_research::MPSolverInterface::trivial_worst_objective_bound
double trivial_worst_objective_bound() const
Definition: linear_solver.cc:1682
operations_research::GRBaddconstr
std::function< int(GRBmodel *model, int numnz, int *cind, double *cval, char sense, double rhs, const char *constrname)> GRBaddconstr
Definition: gurobi_environment.cc:91
commandlineflags.h
operations_research::GurobiInterface::ExtractNewConstraints
void ExtractNewConstraints() override
Definition: gurobi_interface.cc:774
operations_research::GurobiInterface::ExtractNewVariables
void ExtractNewVariables() override
Definition: gurobi_interface.cc:740
name
const std::string name
Definition: default_search.cc:807
operations_research::GurobiInterface::Write
void Write(const std::string &filename) override
Definition: gurobi_interface.cc:1189
operations_research::MPSolver::INFEASIBLE
@ INFEASIBLE
proven infeasible.
Definition: linear_solver.h:431
GRB_INT_ATTR_STATUS
#define GRB_INT_ATTR_STATUS
Definition: gurobi_environment.h:256
operations_research::GRBaddvars
std::function< int(GRBmodel *, int, int, int *, int *, double *, double *, double *, double *, char *, char **)> GRBaddvars
Definition: gurobi_environment.cc:44
operations_research::MPSolverInterface::sync_status_
SynchronizationStatus sync_status_
Definition: linear_solver.h:1720
GRB_CB_MIPNODE_REL
#define GRB_CB_MIPNODE_REL
Definition: gurobi_environment.h:414
operations_research::MPSolver::BASIC
@ BASIC
Definition: linear_solver.h:645
operations_research::MPSolverInterface::InvalidateSolutionSynchronization
void InvalidateSolutionSynchronization()
Definition: linear_solver.cc:1692
GRB_INT_ATTR_CBASIS
#define GRB_INT_ATTR_CBASIS
Definition: gurobi_environment.h:280
GRB_INT_ATTR_BRANCHPRIORITY
#define GRB_INT_ATTR_BRANCHPRIORITY
Definition: gurobi_environment.h:216
operations_research::GurobiInterface
Definition: gurobi_interface.cc:41
operations_research::MPSolver::UNBOUNDED
@ UNBOUNDED
proven unbounded.
Definition: linear_solver.h:433
operations_research::MPSolver::NOT_SOLVED
@ NOT_SOLVED
not been solved yet.
Definition: linear_solver.h:439