OpenGM  2.3.x
Discrete Graphical Model Library
lp_solver_gurobi.hxx
Go to the documentation of this file.
1 #ifndef OPENGM_LP_SOLVER_GUROBI_HXX_
2 #define OPENGM_LP_SOLVER_GUROBI_HXX_
3 
4 #include <gurobi_c++.h>
5 
9 
10 /*********************
11  * class definition *
12  *********************/
13 namespace opengm {
14 
15 class LPSolverGurobi : public LPSolverInterface<LPSolverGurobi, double, int, std::vector<double>::const_iterator, double> {
16 public:
17  // typedefs
18  typedef double GurobiValueType;
19  typedef int GurobiIndexType;
20  typedef std::vector<GurobiValueType>::const_iterator GurobiSolutionIteratorType;
21  typedef double GurobiTimingType;
22 
24 
25  // constructor
26  LPSolverGurobi(const Parameter& parameter = Parameter());
27 
28  // destructor
30 
31 protected:
32  // Storage for Gurobi variables
34  mutable GRBModel gurobiModel_; // model is mutable as GRBModel::write() is not marked as const. However exporting a Model to file is expected to not change the model itself. Is the missing const intended by Gurobi?
35  std::vector<GRBVar> gurobiVariables_;
36  mutable std::vector<GurobiValueType> gurobiSolution_;
37  mutable bool gurobiSolutionValid_;
38 
39  // methods for class LPSolverInterface
40  // Gurobi infinity value
41  static GurobiValueType infinity_impl();
42 
43  // add Variables
44  void addContinuousVariables_impl(const GurobiIndexType numVariables, const GurobiValueType lowerBound, const GurobiValueType upperBound);
45  void addIntegerVariables_impl(const GurobiIndexType numVariables, const GurobiValueType lowerBound, const GurobiValueType upperBound);
46  void addBinaryVariables_impl(const GurobiIndexType numVariables);
47 
48  // objective function
49  void setObjective_impl(const Objective objective);
50  void setObjectiveValue_impl(const GurobiIndexType variable, const GurobiValueType value);
51  template<class ITERATOR_TYPE>
52  void setObjectiveValue_impl(ITERATOR_TYPE begin, const ITERATOR_TYPE end);
53  template<class VARIABLES_ITERATOR_TYPE, class COEFFICIENTS_ITERATOR_TYPE>
54  void setObjectiveValue_impl(VARIABLES_ITERATOR_TYPE variableIDsBegin, const VARIABLES_ITERATOR_TYPE variableIDsEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin);
55 
56  // constraints
57  template<class VARIABLES_ITERATOR_TYPE, class COEFFICIENTS_ITERATOR_TYPE>
58  void addEqualityConstraint_impl(VARIABLES_ITERATOR_TYPE variableIDsBegin, const VARIABLES_ITERATOR_TYPE variableIDsEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin, const GurobiValueType bound, const std::string& constraintName = "");
59  template<class VARIABLES_ITERATOR_TYPE, class COEFFICIENTS_ITERATOR_TYPE>
60  void addLessEqualConstraint_impl(VARIABLES_ITERATOR_TYPE variableIDsBegin, const VARIABLES_ITERATOR_TYPE variableIDsEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin, const GurobiValueType bound, const std::string& constraintName = "");
61  template<class VARIABLES_ITERATOR_TYPE, class COEFFICIENTS_ITERATOR_TYPE>
62  void addGreaterEqualConstraint_impl(VARIABLES_ITERATOR_TYPE variableIDsBegin, const VARIABLES_ITERATOR_TYPE variableIDsEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin, const GurobiValueType bound, const std::string& constraintName = "");
63 
65  void addConstraintsFinished_impl(GurobiTimingType& timing);
66 
67  // parameter
68  template <class PARAMETER_TYPE, class PARAMETER_VALUE_TYPE>
69  void setParameter_impl(const PARAMETER_TYPE parameter, const PARAMETER_VALUE_TYPE value);
70 
71  // solve
72  bool solve_impl();
73  bool solve_impl(GurobiTimingType& timing);
74 
75  // solution
76  GurobiSolutionIteratorType solutionBegin_impl() const;
77  GurobiSolutionIteratorType solutionEnd_impl() const;
78  GurobiValueType solution_impl(const GurobiIndexType variable) const;
79 
80  GurobiValueType objectiveFunctionValue_impl() const;
81  GurobiValueType objectiveFunctionValueBound_impl() const;
82 
83  // model export
84  void exportModel_impl(const std::string& filename) const;
85 
86  // helper functions
87  void updateSolution() const;
88  static int getCutLevelValue(const LPDef::MIP_CUT cutLevel);
89 
90  // friend
91  friend class LPSolverInterface<LPSolverGurobi, GurobiValueType, GurobiIndexType, GurobiSolutionIteratorType, GurobiTimingType>;
92 };
93 
94 } // namespace opengm
95 
96 /***********************
97  * class documentation *
98  ***********************/
466 /******************
467  * implementation *
468  ******************/
469 namespace opengm {
470 
471 inline LPSolverGurobi::LPSolverGurobi(const Parameter& parameter)
472  : LPSolverBaseClass(parameter), gurobiEnvironment_(),
474  gurobiSolutionValid_(false) {
475  // set parameter
476  try {
477  // multi-threading options
478  gurobiModel_.getEnv().set(GRB_IntParam_Threads, parameter_.numberOfThreads_);
479 
480  // verbose options
481  if(!parameter_.verbose_) {
482  gurobiModel_.getEnv().set(GRB_IntParam_OutputFlag, 0);
483  gurobiModel_.getEnv().set(GRB_IntParam_TuneOutput, 0);
484  gurobiModel_.getEnv().set(GRB_IntParam_LogToConsole, 0);
485  }
486 
487  // set hints
488  // CutUp is missing http://www.gurobi.com/resources/switching-to-gurobi/switching-from-cplex#setting
489 
490  // tolerance settings
491  //gurobiModel_.getEnv().set(GRB_DoubleParam_Cutoff, parameter_.cutUp_); // Optimality Tolerance
492  gurobiModel_.getEnv().set(GRB_DoubleParam_OptimalityTol, parameter_.epOpt_); // Optimality Tolerance
493  gurobiModel_.getEnv().set(GRB_DoubleParam_IntFeasTol, parameter_.epInt_); // amount by which an integer variable can differ from an integer
494  gurobiModel_.getEnv().set(GRB_DoubleParam_MIPGapAbs, parameter_.epAGap_); // Absolute MIP gap tolerance
495  gurobiModel_.getEnv().set(GRB_DoubleParam_MIPGap, parameter_.epGap_); // Relative MIP gap tolerance
496  gurobiModel_.getEnv().set(GRB_DoubleParam_FeasibilityTol, parameter_.epRHS_);
497  gurobiModel_.getEnv().set(GRB_DoubleParam_MarkowitzTol, parameter_.epMrk_);
498 
499  // memory setting
500  // missing
501 
502  // time limit
503  gurobiModel_.getEnv().set(GRB_DoubleParam_TimeLimit, parameter_.timeLimit_);
504 
505  // Root Algorithm
506  switch(parameter_.rootAlg_) {
507  case LPDef::LP_SOLVER_AUTO: {
508  gurobiModel_.getEnv().set(GRB_IntParam_Method, -1);
509  break;
510  }
512  gurobiModel_.getEnv().set(GRB_IntParam_Method, 0);
513  break;
514  }
516  gurobiModel_.getEnv().set(GRB_IntParam_Method, 1);
517  break;
518  }
520  throw std::runtime_error("Gurobi does not support Network Simplex");
521  break;
522  }
524  gurobiModel_.getEnv().set(GRB_IntParam_Method, 2);
525  break;
526  }
528  gurobiModel_.getEnv().set(GRB_IntParam_Method, 1);
529  gurobiModel_.getEnv().set(GRB_IntParam_SiftMethod, 1);
530  break;
531  }
533  gurobiModel_.getEnv().set(GRB_IntParam_Method, 4);
534  break;
535  }
536  default: {
537  throw std::runtime_error("Unknown Root Algorithm");
538  }
539  }
540 
541  // Node Algorithm
542  switch(parameter_.nodeAlg_) {
543  case LPDef::LP_SOLVER_AUTO: {
544  gurobiModel_.getEnv().set(GRB_IntParam_NodeMethod, 1);
545  break;
546  }
548  gurobiModel_.getEnv().set(GRB_IntParam_NodeMethod, 0);
549  break;
550  }
552  gurobiModel_.getEnv().set(GRB_IntParam_NodeMethod, 1);
553  break;
554  }
556  throw std::runtime_error("Gurobi does not support Network Simplex");
557  break;
558  }
560  gurobiModel_.getEnv().set(GRB_IntParam_NodeMethod, 2);
561  break;
562  }
564  throw std::runtime_error("Gurobi does not support Sifting as node algorithm");
565  break;
566  }
568  throw std::runtime_error("Gurobi does not support concurrent solvers as node algorithm");
569  break;
570  }
571  default: {
572  throw std::runtime_error("Unknown Node Algorithm");
573  }
574  }
575 
576  // presolve
577  switch(parameter_.presolve_) {
579  gurobiModel_.getEnv().set(GRB_IntParam_Presolve, -1);
580  break;
581  }
582  case LPDef::LP_PRESOLVE_OFF: {
583  gurobiModel_.getEnv().set(GRB_IntParam_Presolve, 0);
584  break;
585  }
587  gurobiModel_.getEnv().set(GRB_IntParam_Presolve, 1);
588  break;
589  }
591  gurobiModel_.getEnv().set(GRB_IntParam_Presolve, 2);
592  break;
593  }
594  default: {
595  throw std::runtime_error("Unknown Presolve Option");
596  }
597  }
598 
599  // MIP EMPHASIS
600  switch(parameter_.mipEmphasis_) {
602  gurobiModel_.getEnv().set(GRB_IntParam_MIPFocus, 0);
603  break;
604  }
606  gurobiModel_.getEnv().set(GRB_IntParam_MIPFocus, 1);
607  break;
608  }
610  gurobiModel_.getEnv().set(GRB_IntParam_MIPFocus, 2);
611  break;
612  }
614  gurobiModel_.getEnv().set(GRB_IntParam_MIPFocus, 3);
615  break;
616  }
618  throw std::runtime_error("Gurobi does not support hidden feasibility as MIP-focus");
619  break;
620  }
621  default: {
622  throw std::runtime_error("Unknown MIP Emphasis Option");
623  }
624  }
625 
626  // Tuning
627  // Probing missing
628  if(parameter_.cutLevel_ != LPDef::MIP_CUT_DEFAULT) {
629  gurobiModel_.getEnv().set(GRB_IntParam_Cuts, getCutLevelValue(parameter_.cutLevel_));
630  }
631  if(parameter_.cliqueCutLevel_ != LPDef::MIP_CUT_DEFAULT) {
632  gurobiModel_.getEnv().set(GRB_IntParam_CliqueCuts, getCutLevelValue(parameter_.cliqueCutLevel_));
633  }
634  if(parameter_.coverCutLevel_ != LPDef::MIP_CUT_DEFAULT) {
635  gurobiModel_.getEnv().set(GRB_IntParam_CoverCuts, getCutLevelValue(parameter_.coverCutLevel_));
636  }
637  if(parameter_.gubCutLevel_ != LPDef::MIP_CUT_DEFAULT) {
638  gurobiModel_.getEnv().set(GRB_IntParam_GUBCoverCuts, getCutLevelValue(parameter_.gubCutLevel_));
639  }
640  if(parameter_.mirCutLevel_ != LPDef::MIP_CUT_DEFAULT) {
641  gurobiModel_.getEnv().set(GRB_IntParam_MIRCuts, getCutLevelValue(parameter_.mirCutLevel_));
642  }
643  if(parameter_.iboundCutLevel_ != LPDef::MIP_CUT_DEFAULT) {
644  gurobiModel_.getEnv().set(GRB_IntParam_ImpliedCuts, getCutLevelValue(parameter_.iboundCutLevel_));
645  }
646  if(parameter_.flowcoverCutLevel_ != LPDef::MIP_CUT_DEFAULT) {
647  gurobiModel_.getEnv().set(GRB_IntParam_FlowCoverCuts, getCutLevelValue(parameter_.flowcoverCutLevel_));
648  }
649  if(parameter_.flowpathCutLevel_ != LPDef::MIP_CUT_DEFAULT) {
650  gurobiModel_.getEnv().set(GRB_IntParam_FlowPathCuts, getCutLevelValue(parameter_.flowpathCutLevel_));
651  }
652  // DisjCuts missing
653  // Gomory missing
654  } catch(const GRBException& e) {
655  std::cout << "Gurobi Error code = " << e.getErrorCode() << std::endl;
656  std::cout << e.getMessage() << std::endl;
657  throw std::runtime_error(e.getMessage());
658  } catch(...) {
659  std::cout << "Exception while setting parameter for Gurobi model." << std::endl;
660  throw std::runtime_error("Exception while setting parameter for Gurobi model.");
661  }
662 }
663 
665 
666 }
667 
669  return GRB_INFINITY;
670 }
671 
672 inline void LPSolverGurobi::addContinuousVariables_impl(const GurobiIndexType numVariables, const GurobiValueType lowerBound, const GurobiValueType upperBound) {
673  gurobiVariables_.reserve(numVariables + gurobiVariables_.size());
674  // according to the Gurobi documentation, adding variables separately does not have any performance impact
675  try {
676  for(GurobiIndexType i = 0; i < numVariables; ++i) {
677  gurobiVariables_.push_back(gurobiModel_.addVar(lowerBound, upperBound, 0.0, GRB_CONTINUOUS));
678  }
679  gurobiSolution_.resize(gurobiVariables_.size());
680  gurobiSolutionValid_ = false;
681  gurobiModel_.update();
682  } catch(const GRBException& e) {
683  std::cout << "Gurobi Error code = " << e.getErrorCode() << std::endl;
684  std::cout << e.getMessage() << std::endl;
685  throw std::runtime_error(e.getMessage());
686  } catch(...) {
687  std::cout << "Exception while adding continuous variables to Gurobi model." << std::endl;
688  throw std::runtime_error("Exception while adding continuous variables to Gurobi model.");
689  }
690 }
691 
692 inline void LPSolverGurobi::addIntegerVariables_impl(const GurobiIndexType numVariables, const GurobiValueType lowerBound, const GurobiValueType upperBound) {
693  gurobiVariables_.reserve(numVariables + gurobiVariables_.size());
694  // according to the Gurobi documentation, adding variables separately does not have any performance impact
695  try {
696  for(GurobiIndexType i = 0; i < numVariables; ++i) {
697  gurobiVariables_.push_back(gurobiModel_.addVar(lowerBound, upperBound, 0.0, GRB_INTEGER));
698  }
699  gurobiSolution_.resize(gurobiVariables_.size());
700  gurobiSolutionValid_ = false;
701  gurobiModel_.update();
702  } catch(const GRBException& e) {
703  std::cout << "Gurobi Error code = " << e.getErrorCode() << std::endl;
704  std::cout << e.getMessage() << std::endl;
705  throw std::runtime_error(e.getMessage());
706  } catch(...) {
707  std::cout << "Exception while adding integer variables to Gurobi model." << std::endl;
708  throw std::runtime_error("Exception while adding integer variables to Gurobi model.");
709  }
710 }
711 
713  gurobiVariables_.reserve(numVariables + gurobiVariables_.size());
714  // according to the Gurobi documentation, adding variables separately does not have any performance impact
715  try {
716  for(GurobiIndexType i = 0; i < numVariables; ++i) {
717  gurobiVariables_.push_back(gurobiModel_.addVar(0.0, 1.0, 0.0, GRB_BINARY));
718  }
719  gurobiSolution_.resize(gurobiVariables_.size());
720  gurobiSolutionValid_ = false;
721  gurobiModel_.update();
722  } catch(const GRBException& e) {
723  std::cout << "Gurobi Error code = " << e.getErrorCode() << std::endl;
724  std::cout << e.getMessage() << std::endl;
725  throw std::runtime_error(e.getMessage());
726  } catch(...) {
727  std::cout << "Exception while adding binary variables to Gurobi model." << std::endl;
728  throw std::runtime_error("Exception while adding binary variables to Gurobi model.");
729  }
730 }
731 
732 inline void LPSolverGurobi::setObjective_impl(const Objective objective) {
733  switch(objective) {
734  case Minimize: {
735  try {
736  gurobiModel_.set(GRB_IntAttr_ModelSense, 1);
737  } catch(const GRBException& e) {
738  std::cout << "Gurobi Error code = " << e.getErrorCode() << std::endl;
739  std::cout << e.getMessage() << std::endl;
740  throw std::runtime_error(e.getMessage());
741  } catch(...) {
742  std::cout << "Exception while setting objective of Gurobi model." << std::endl;
743  throw std::runtime_error("Exception while setting objective of Gurobi model.");
744  }
745  break;
746  }
747  case Maximize: {
748  try {
749  gurobiModel_.set(GRB_IntAttr_ModelSense, -1);
750  } catch(const GRBException& e) {
751  std::cout << "Gurobi Error code = " << e.getErrorCode() << std::endl;
752  std::cout << e.getMessage() << std::endl;
753  throw std::runtime_error(e.getMessage());
754  } catch(...) {
755  std::cout << "Exception while setting objective of Gurobi model." << std::endl;
756  throw std::runtime_error("Exception while setting objective of Gurobi model.");
757  }
758  break;
759  }
760  default: {
761  throw std::runtime_error("Unknown Objective");
762  }
763  }
764 }
765 
767  try {
768  gurobiVariables_[variable].set(GRB_DoubleAttr_Obj, value);
769  } catch(const GRBException& e) {
770  std::cout << "Gurobi Error code = " << e.getErrorCode() << std::endl;
771  std::cout << e.getMessage() << std::endl;
772  throw std::runtime_error(e.getMessage());
773  } catch(...) {
774  std::cout << "Exception while setting objective value of Gurobi model." << std::endl;
775  throw std::runtime_error("Exception while setting objective value of Gurobi model.");
776  }
777 }
778 
779 template<class ITERATOR_TYPE>
780 inline void LPSolverGurobi::setObjectiveValue_impl(ITERATOR_TYPE begin, const ITERATOR_TYPE end) {
781  try {
782  GRBLinExpr objective;
783  objective.addTerms(&(*begin), &gurobiVariables_[0], gurobiVariables_.size());
784  gurobiModel_.setObjective(objective);
785  } catch(const GRBException& e) {
786  std::cout << "Gurobi Error code = " << e.getErrorCode() << std::endl;
787  std::cout << e.getMessage() << std::endl;
788  throw std::runtime_error(e.getMessage());
789  } catch(...) {
790  std::cout << "Exception while setting objective value of Gurobi model." << std::endl;
791  throw std::runtime_error("Exception while setting objective value of Gurobi model.");
792  }
793 }
794 
795 template<class VARIABLES_ITERATOR_TYPE, class COEFFICIENTS_ITERATOR_TYPE>
796 inline void LPSolverGurobi::setObjectiveValue_impl(VARIABLES_ITERATOR_TYPE variableIDsBegin, const VARIABLES_ITERATOR_TYPE variableIDsEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin) {
797  try {
798  while(variableIDsBegin != variableIDsEnd) {
799  gurobiVariables_[*variableIDsBegin].set(GRB_DoubleAttr_Obj, *coefficientsBegin);
800  ++variableIDsBegin;
801  ++coefficientsBegin;
802  }
803  } catch(const GRBException& e) {
804  std::cout << "Gurobi Error code = " << e.getErrorCode() << std::endl;
805  std::cout << e.getMessage() << std::endl;
806  throw std::runtime_error(e.getMessage());
807  } catch(...) {
808  std::cout << "Exception while setting objective value of Gurobi model." << std::endl;
809  throw std::runtime_error("Exception while setting objective value of Gurobi model.");
810  }
811 }
812 
813 template<class VARIABLES_ITERATOR_TYPE, class COEFFICIENTS_ITERATOR_TYPE>
814 inline void LPSolverGurobi::addEqualityConstraint_impl(VARIABLES_ITERATOR_TYPE variableIDsBegin, const VARIABLES_ITERATOR_TYPE variableIDsEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin, const GurobiValueType bound, const std::string& constraintName) {
815  const GurobiIndexType numConstraintVariables = std::distance(variableIDsBegin, variableIDsEnd);
816  std::vector<GRBVar> constraintVariables;
817  constraintVariables.reserve(numConstraintVariables);
818  while(variableIDsBegin != variableIDsEnd) {
819  constraintVariables.push_back(gurobiVariables_[*variableIDsBegin]);
820  ++variableIDsBegin;
821  }
822 
823  try {
824  GRBLinExpr constraint;
825  constraint.addTerms(&(*coefficientsBegin), &constraintVariables[0], numConstraintVariables);
826  gurobiModel_.addConstr(constraint, GRB_EQUAL, bound, constraintName);
827  } catch(const GRBException& e) {
828  std::cout << "Gurobi Error code = " << e.getErrorCode() << std::endl;
829  std::cout << e.getMessage() << std::endl;
830  throw std::runtime_error(e.getMessage());
831  } catch(...) {
832  std::cout << "Exception while adding equality constraint to Gurobi model." << std::endl;
833  throw std::runtime_error("Exception while adding equality constraint to Gurobi model.");
834  }
835 }
836 
837 template<class VARIABLES_ITERATOR_TYPE, class COEFFICIENTS_ITERATOR_TYPE>
838 inline void LPSolverGurobi::addLessEqualConstraint_impl(VARIABLES_ITERATOR_TYPE variableIDsBegin, const VARIABLES_ITERATOR_TYPE variableIDsEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin, const GurobiValueType bound, const std::string& constraintName) {
839  const GurobiIndexType numConstraintVariables = std::distance(variableIDsBegin, variableIDsEnd);
840  std::vector<GRBVar> constraintVariables;
841  constraintVariables.reserve(numConstraintVariables);
842  while(variableIDsBegin != variableIDsEnd) {
843  constraintVariables.push_back(gurobiVariables_[*variableIDsBegin]);
844  ++variableIDsBegin;
845  }
846 
847  try {
848  GRBLinExpr constraint;
849  constraint.addTerms(&(*coefficientsBegin), &constraintVariables[0], numConstraintVariables);
850  gurobiModel_.addConstr(constraint, GRB_LESS_EQUAL, bound, constraintName);
851  } catch(const GRBException& e) {
852  std::cout << "Gurobi Error code = " << e.getErrorCode() << std::endl;
853  std::cout << e.getMessage() << std::endl;
854  throw std::runtime_error(e.getMessage());
855  } catch(...) {
856  std::cout << "Exception while adding less equal constraint to Gurobi model." << std::endl;
857  throw std::runtime_error("Exception while adding less equal constraint to Gurobi model.");
858  }
859 }
860 
861 template<class VARIABLES_ITERATOR_TYPE, class COEFFICIENTS_ITERATOR_TYPE>
862 inline void LPSolverGurobi::addGreaterEqualConstraint_impl(VARIABLES_ITERATOR_TYPE variableIDsBegin, const VARIABLES_ITERATOR_TYPE variableIDsEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin, const GurobiValueType bound, const std::string& constraintName) {
863  const GurobiIndexType numConstraintVariables = std::distance(variableIDsBegin, variableIDsEnd);
864  std::vector<GRBVar> constraintVariables;
865  constraintVariables.reserve(numConstraintVariables);
866  while(variableIDsBegin != variableIDsEnd) {
867  constraintVariables.push_back(gurobiVariables_[*variableIDsBegin]);
868  ++variableIDsBegin;
869  }
870 
871  try {
872  GRBLinExpr constraint;
873  constraint.addTerms(&(*coefficientsBegin), &constraintVariables[0], numConstraintVariables);
874  gurobiModel_.addConstr(constraint, GRB_GREATER_EQUAL, bound, constraintName);
875  } catch(const GRBException& e) {
876  std::cout << "Gurobi Error code = " << e.getErrorCode() << std::endl;
877  std::cout << e.getMessage() << std::endl;
878  throw std::runtime_error(e.getMessage());
879  } catch(...) {
880  std::cout << "Exception while adding greater equal constraint to Gurobi model." << std::endl;
881  throw std::runtime_error("Exception while adding greater equal constraint to Gurobi model.");
882  }
883 }
884 
886  try {
887  gurobiModel_.update();
888  } catch(const GRBException& e) {
889  std::cout << "Gurobi Error code = " << e.getErrorCode() << std::endl;
890  std::cout << e.getMessage() << std::endl;
891  throw std::runtime_error(e.getMessage());
892  } catch(...) {
893  std::cout << "Exception while incorporating constraints into Gurobi model." << std::endl;
894  throw std::runtime_error("Exception while incorporating constraints into Gurobi model.");
895  }
896 }
897 
899  try {
900  Timer timer;
901  timer.tic();
902  gurobiModel_.update();
903  timer.toc();
904  timing = timer.elapsedTime();
905  } catch(const GRBException& e) {
906  std::cout << "Gurobi Error code = " << e.getErrorCode() << std::endl;
907  std::cout << e.getMessage() << std::endl;
908  throw std::runtime_error(e.getMessage());
909  } catch(...) {
910  std::cout << "Exception while incorporating constraints into Gurobi model." << std::endl;
911  throw std::runtime_error("Exception while incorporating constraints into Gurobi model.");
912  }
913 }
914 
915 template <class PARAMETER_TYPE, class PARAMETER_VALUE_TYPE>
916 inline void LPSolverGurobi::setParameter_impl(const PARAMETER_TYPE parameter, const PARAMETER_VALUE_TYPE value) {
917  try {
918  gurobiModel_.getEnv().set(parameter, value);
919  } catch(const GRBException& e) {
920  std::cout << "Gurobi Error code = " << e.getErrorCode() << std::endl;
921  std::cout << e.getMessage() << std::endl;
922  throw std::runtime_error(e.getMessage());
923  } catch(...) {
924  std::cout << "Exception while setting parameter for Gurobi model." << std::endl;
925  throw std::runtime_error("Exception while setting parameter for Gurobi model.");
926  }
927 }
928 
930  gurobiSolutionValid_ = false;
931  try {
932  gurobiModel_.optimize();
933  if(gurobiModel_.get(GRB_IntAttr_Status) == GRB_OPTIMAL) {
934  return true;
935  } else {
936  return false;
937  }
938  } catch(const GRBException& e) {
939  std::cout << "Gurobi Error code = " << e.getErrorCode() << std::endl;
940  std::cout << e.getMessage() << std::endl;
941  throw std::runtime_error(e.getMessage());
942  } catch(...) {
943  std::cout << "Exception while solving Gurobi model." << std::endl;
944  throw std::runtime_error("Exception while solving Gurobi model.");
945  }
946 }
947 
949  gurobiSolutionValid_ = false;
950  try {
951  gurobiModel_.optimize();
952  timing = gurobiModel_.get(GRB_DoubleAttr_Runtime);
953  if(gurobiModel_.get(GRB_IntAttr_Status) == GRB_OPTIMAL) {
954  return true;
955  } else {
956  return false;
957  }
958  } catch(const GRBException& e) {
959  std::cout << "Gurobi Error code = " << e.getErrorCode() << std::endl;
960  std::cout << e.getMessage() << std::endl;
961  throw std::runtime_error(e.getMessage());
962  } catch(...) {
963  std::cout << "Exception while solving Gurobi model." << std::endl;
964  throw std::runtime_error("Exception while solving Gurobi model.");
965  }
966 }
967 
969  updateSolution();
970  return gurobiSolution_.begin();
971 }
972 
974  updateSolution();
975  return gurobiSolution_.end();
976 }
977 
979  try {
980  return gurobiVariables_[variable].get(GRB_DoubleAttr_X);
981  } catch(const GRBException& e) {
982  std::cout << "Gurobi Error code = " << e.getErrorCode() << std::endl;
983  std::cout << e.getMessage() << std::endl;
984  throw std::runtime_error(e.getMessage());
985  } catch(...) {
986  std::cout << "Exception while accessing Gurobi solution of variable." << std::endl;
987  throw std::runtime_error("Exception while accessing Gurobi solution of variable.");
988  }
989 }
990 
992  try {
993  return gurobiModel_.get(GRB_DoubleAttr_ObjVal);
994  } catch(const GRBException& e) {
995  std::cout << "Gurobi Error code = " << e.getErrorCode() << std::endl;
996  std::cout << e.getMessage() << std::endl;
997  throw std::runtime_error(e.getMessage());
998  } catch(...) {
999  std::cout << "Exception while accessing Gurobi solution for objective function value." << std::endl;
1000  throw std::runtime_error("Exception while accessing Gurobi solution for objective function value.");
1001  }
1002 }
1003 
1005  try {
1006  if(gurobiModel_.get(GRB_IntAttr_IsMIP)) {
1007  return gurobiModel_.get(GRB_DoubleAttr_ObjBound);
1008  } else {
1009  return gurobiModel_.get(GRB_DoubleAttr_ObjVal);
1010  }
1011  } catch(const GRBException& e) {
1012  std::cout << "Gurobi Error code = " << e.getErrorCode() << std::endl;
1013  std::cout << e.getMessage() << std::endl;
1014  throw std::runtime_error(e.getMessage());
1015  } catch(...) {
1016  std::cout << "Exception while accessing Gurobi bound for objective function value." << std::endl;
1017  throw std::runtime_error("Exception while accessing Gurobi bound for objective function value.");
1018  }
1019 }
1020 
1021 inline void LPSolverGurobi::exportModel_impl(const std::string& filename) const {
1022  try {
1023  gurobiModel_.write(filename);
1024  } catch(const GRBException& e) {
1025  std::cout << "Gurobi Error code = " << e.getErrorCode() << std::endl;
1026  std::cout << e.getMessage() << std::endl;
1027  throw std::runtime_error(e.getMessage());
1028  } catch(...) {
1029  std::cout << "Exception while writing Gurobi model to file." << std::endl;
1030  throw std::runtime_error("Exception while writing Gurobi model to file.");
1031  }
1032 }
1033 
1034 inline void LPSolverGurobi::updateSolution() const {
1035  if(!gurobiSolutionValid_) {
1036  try {
1037  for(GurobiIndexType i = 0; i < static_cast<GurobiIndexType>(gurobiVariables_.size()); ++i) {
1038  gurobiSolution_[i] = gurobiVariables_[i].get(GRB_DoubleAttr_X);
1039  }
1040  gurobiSolutionValid_ = true;
1041  } catch(const GRBException& e) {
1042  std::cout << "Gurobi Error code = " << e.getErrorCode() << std::endl;
1043  std::cout << e.getMessage() << std::endl;
1044  throw std::runtime_error(e.getMessage());
1045  } catch(...) {
1046  std::cout << "Exception while updating Gurobi solution." << std::endl;
1047  throw std::runtime_error("Exception while updating Gurobi solution.");
1048  }
1049  }
1050 }
1051 
1053  switch(cutLevel){
1055  case LPDef::MIP_CUT_AUTO:
1056  return -1;
1057  case LPDef::MIP_CUT_OFF:
1058  return 0;
1059  case LPDef::MIP_CUT_ON:
1060  return 1;
1062  return 2;
1064  return 3;
1065  default:
1066  throw std::runtime_error("Unknown Cut level.");
1067  }
1068 }
1069 
1070 } // namespace opengm
1071 
1072 #endif /* OPENGM_LP_SOLVER_GUROBI_HXX_ */
void setObjective_impl(const Objective objective)
Set objective to minimize or maximize.
The OpenGM namespace.
Definition: config.hxx:43
GurobiValueType objectiveFunctionValueBound_impl() const
Get the best known bound for the optimal solution of the current model.
LPSolverInterface< LPSolverGurobi, GurobiValueType, GurobiIndexType, GurobiSolutionIteratorType, GurobiTimingType > LPSolverBaseClass
Defines the type of the base class.
void addContinuousVariables_impl(const GurobiIndexType numVariables, const GurobiValueType lowerBound, const GurobiValueType upperBound)
Add new continuous variables to the model.
Objective
This enum defines the type of the objective. It is used to select either to minimize or to maxime the...
Wrapper class for the Gurobi optimizer.
void toc()
Definition: timer.hxx:109
Platform-independent runtime measurements.
Definition: timer.hxx:29
static GurobiValueType infinity_impl()
Get the value which is used by Gurobi to represent infinity.
void addBinaryVariables_impl(const GurobiIndexType numVariables)
Add new binary variables to the model.
Provides Interface definition for wrapper of LP Solvers like CPLEX and Gurobi.
GRBModel gurobiModel_
The Gurobi model of the LP/MIP problem.
void exportModel_impl(const std::string &filename) const
Export model to file.
void addConstraintsFinished_impl()
Join all constraints added via LPSolverGurobi::addEqualityConstraint, LPSolverGurobi::addLessEqualCon...
Interface definition for wrapper of LP Solvers like CPLEX and Gurobi.
double GurobiTimingType
Defines the timing type used by Gurobi.
void addLessEqualConstraint_impl(VARIABLES_ITERATOR_TYPE variableIDsBegin, const VARIABLES_ITERATOR_TYPE variableIDsEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin, const GurobiValueType bound, const std::string &constraintName="")
Add a new less equal constraint to the model.
GurobiValueType solution_impl(const GurobiIndexType variable) const
Get the solution value of a variable computed by Gurobi.
int GurobiIndexType
Defines the index type used by Gurobi.
void tic()
Definition: timer.hxx:96
void addGreaterEqualConstraint_impl(VARIABLES_ITERATOR_TYPE variableIDsBegin, const VARIABLES_ITERATOR_TYPE variableIDsEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin, const GurobiValueType bound, const std::string &constraintName="")
Add a new greater equal constraint to the model.
std::vector< GurobiValueType >::const_iterator GurobiSolutionIteratorType
Defines the iterator type which can be used to iterate over the solution of Gurobi.
~LPSolverGurobi()
Destructor for LPSolverGurobi.
double GurobiValueType
Defines the value type used by Gurobi.
std::vector< GRBVar > gurobiVariables_
The variables which are present in the model.
GurobiSolutionIteratorType solutionBegin_impl() const
Get an iterator which is pointing to the begin of the solution computed by Gurobi.
double elapsedTime() const
Definition: timer.hxx:130
void addIntegerVariables_impl(const GurobiIndexType numVariables, const GurobiValueType lowerBound, const GurobiValueType upperBound)
Add new integer variables to the model.
GurobiValueType objectiveFunctionValue_impl() const
Get the objective function value from Gurobi.
void updateSolution() const
Update solution if required.
bool solve_impl()
Solve the current model.
void setObjectiveValue_impl(const GurobiIndexType variable, const GurobiValueType value)
Set the coefficient of a variable in the objective function.
static int getCutLevelValue(const LPDef::MIP_CUT cutLevel)
Translate LPDef::MIP_CUT into corresponding Gurobi int value.
bool gurobiSolutionValid_
Tell if the currently stored solution is valid.
void addEqualityConstraint_impl(VARIABLES_ITERATOR_TYPE variableIDsBegin, const VARIABLES_ITERATOR_TYPE variableIDsEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin, const GurobiValueType bound, const std::string &constraintName="")
Add a new equality constraint to the model.
std::vector< GurobiValueType > gurobiSolution_
Storage for the solution computed by Gurobi.
GRBEnv gurobiEnvironment_
The Gurobi environment.
GurobiSolutionIteratorType solutionEnd_impl() const
Get an iterator which is pointing to the end of the solution computed by Gurobi.
void setParameter_impl(const PARAMETER_TYPE parameter, const PARAMETER_VALUE_TYPE value)
Set Gurobi parameter.
LPSolverGurobi(const Parameter &parameter=Parameter())
Default constructor for LPSolverGurobi.