OpenGM  2.3.x
Discrete Graphical Model Library
lp_solver_cplex.hxx
Go to the documentation of this file.
1 #ifndef OPENGM_LP_SOLVER_CPLEX_HXX_
2 #define OPENGM_LP_SOLVER_CPLEX_HXX_
3 
4 #include <iterator>
5 
6 #include <ilcplex/ilocplex.h>
7 
10 
11 /*********************
12  * class definition *
13  *********************/
14 namespace opengm {
15 
16 class IloNumArrayIterator : public std::iterator<std::random_access_iterator_tag, IloNum> {
17 public:
18  // construction
20  IloNumArrayIterator(const IloNumArray& array, const IloInt position = 0);
21 
22  // comparison
23  bool operator!=(const IloNumArrayIterator& iter) const;
24  bool operator==(const IloNumArrayIterator& iter) const;
25 
26  // constant access
27  const IloNum& operator*() const;
28  const IloNum& operator[](const IloInt n) const;
29 
30  // increment
32 
33  // decrement
34  difference_type operator-(const IloNumArrayIterator& iter) const;
35 protected:
36  // storage
37  const IloNumArray* array_;
38  IloInt position_;
39 };
40 
41 class LPSolverCplex : public LPSolverInterface<LPSolverCplex, IloNum, IloInt, IloNumArrayIterator, IloNum> {
42 public:
43  // typedefs
44  typedef IloNum CplexValueType;
45  typedef IloInt CplexIndexType;
47  typedef IloNum CplexTimingType;
48 
50 
51  // constructor
52  LPSolverCplex(const Parameter& parameter = Parameter());
53 
54  // destructor
56 
57 protected:
58  // Storage for CPLEX variables
60  IloModel cplexModel_;
61  IloNumVarArray cplexVariables_;
62  IloObjective cplexObjective_;
63  IloRangeArray cplexConstraints_;
64  IloNumArray cplexSolution_;
65  mutable bool cplexSolutionValid_;
66  IloCplex cplexSolver_;
67 
68  // methods for class LPSolverInterface
69  // CPLEX infinity value
70  static CplexValueType infinity_impl();
71 
72  // add Variables
73  void addContinuousVariables_impl(const CplexIndexType numVariables, const CplexValueType lowerBound, const CplexValueType upperBound);
74  void addIntegerVariables_impl(const CplexIndexType numVariables, const CplexValueType lowerBound, const CplexValueType upperBound);
75  void addBinaryVariables_impl(const CplexIndexType numVariables);
76 
77  // objective function
78  void setObjective_impl(const Objective objective);
79  void setObjectiveValue_impl(const CplexIndexType variable, const CplexValueType value);
80  template<class ITERATOR_TYPE>
81  void setObjectiveValue_impl(ITERATOR_TYPE begin, const ITERATOR_TYPE end);
82  template<class VARIABLES_ITERATOR_TYPE, class COEFFICIENTS_ITERATOR_TYPE>
83  void setObjectiveValue_impl(VARIABLES_ITERATOR_TYPE variableIDsBegin, const VARIABLES_ITERATOR_TYPE variableIDsEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin);
84 
85  // constraints
86  template<class VARIABLES_ITERATOR_TYPE, class COEFFICIENTS_ITERATOR_TYPE>
87  void addEqualityConstraint_impl(VARIABLES_ITERATOR_TYPE variableIDsBegin, const VARIABLES_ITERATOR_TYPE variableIDsEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin, const CplexValueType bound, const std::string& constraintName = "");
88  template<class VARIABLES_ITERATOR_TYPE, class COEFFICIENTS_ITERATOR_TYPE>
89  void addLessEqualConstraint_impl(VARIABLES_ITERATOR_TYPE variableIDsBegin, const VARIABLES_ITERATOR_TYPE variableIDsEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin, const CplexValueType bound, const std::string& constraintName = "");
90  template<class VARIABLES_ITERATOR_TYPE, class COEFFICIENTS_ITERATOR_TYPE>
91  void addGreaterEqualConstraint_impl(VARIABLES_ITERATOR_TYPE variableIDsBegin, const VARIABLES_ITERATOR_TYPE variableIDsEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin, const CplexValueType bound, const std::string& constraintName = "");
92 
94  void addConstraintsFinished_impl(CplexTimingType& timing);
95 
96  // parameter
97  template <class PARAMETER_TYPE, class PARAMETER_VALUE_TYPE>
98  void setParameter_impl(const PARAMETER_TYPE parameter, const PARAMETER_VALUE_TYPE value);
99 
100  // solve
101  bool solve_impl();
102  bool solve_impl(CplexTimingType& timing);
103 
104  // solution
105  CplexSolutionIteratorType solutionBegin_impl() const;
106  CplexSolutionIteratorType solutionEnd_impl() const;
107  CplexValueType solution_impl(const CplexIndexType variable) const;
108 
109  CplexValueType objectiveFunctionValue_impl() const;
110  CplexValueType objectiveFunctionValueBound_impl() const;
111 
112  // model export
113  void exportModel_impl(const std::string& filename) const;
114 
115  // helper functions
116  void updateSolution() const;
117  static int getCutLevelValue(const LPDef::MIP_CUT cutLevel);
118 
119  // friend
120  friend class LPSolverInterface<LPSolverCplex, CplexValueType, CplexIndexType, CplexSolutionIteratorType, CplexTimingType>;
121 };
122 
123 } // namespace opengm
124 
125 /***********************
126  * class documentation *
127  ***********************/
593 /******************
594  * implementation *
595  ******************/
596 namespace opengm {
597 
599  : array_(), position_() {
600 
601 }
602 
603 inline IloNumArrayIterator::IloNumArrayIterator(const IloNumArray& array, const IloInt position)
604  : array_(&array), position_(position) {
605 
606 }
607 
608 inline bool IloNumArrayIterator::operator!=(const IloNumArrayIterator& iter) const {
609  return (array_ != iter.array_) || (position_ != iter.position_);
610 }
611 
612 inline bool IloNumArrayIterator::operator==(const IloNumArrayIterator& iter) const {
613  return (array_ == iter.array_) && (position_ == iter.position_);
614 }
615 
616 inline const IloNum& IloNumArrayIterator::operator*() const {
617  return array_->operator [](position_);
618 }
619 
620 inline const IloNum& IloNumArrayIterator::operator[](const IloInt n) const {
621  return array_->operator [](position_ + n);
622 }
623 
625  ++position_;
626  return *this;
627 }
628 
629 inline IloNumArrayIterator::difference_type IloNumArrayIterator:: operator-(const IloNumArrayIterator& iter) const {
630  return static_cast<difference_type>(position_) - static_cast<difference_type>(iter.position_);
631 }
632 
633 inline LPSolverCplex::LPSolverCplex(const Parameter& parameter)
634  : LPSolverBaseClass(parameter), cplexEnvironment_(),
635  cplexModel_(cplexEnvironment_), cplexVariables_(cplexEnvironment_),
636  cplexObjective_(cplexEnvironment_), cplexConstraints_(cplexEnvironment_),
637  cplexSolution_(cplexEnvironment_), cplexSolutionValid_(false),
638  cplexSolver_() {
639  // initialize solver
640  try {
641  cplexSolver_ = IloCplex(cplexModel_);
644  } catch(const IloException& e) {
645  std::cout << e << std::endl;
646  throw std::runtime_error("CPLEX exception");
647  }
648 
649  // set parameter
650  try {
651  // multi-threading options
652  cplexSolver_.setParam(IloCplex::Threads, parameter_.numberOfThreads_);
653 
654  // verbose options
655  if(!parameter_.verbose_) {
656  cplexSolver_.setParam(IloCplex::MIPDisplay, 0);
657  cplexSolver_.setParam(IloCplex::BarDisplay, 0);
658  cplexSolver_.setParam(IloCplex::SimDisplay, 0);
659  cplexSolver_.setParam(IloCplex::NetDisplay, 0);
660  cplexSolver_.setParam(IloCplex::SiftDisplay, 0);
661  }
662 
663  // set hints
664  cplexSolver_.setParam(IloCplex::CutUp, parameter_.cutUp_);
665 
666  // tolerance settings
667  cplexSolver_.setParam(IloCplex::EpOpt, parameter_.epOpt_); // Optimality Tolerance
668  cplexSolver_.setParam(IloCplex::EpMrk, parameter_.epMrk_); // Markowitz tolerance
669  cplexSolver_.setParam(IloCplex::EpRHS, parameter_.epRHS_); // Feasibility Tolerance
670  cplexSolver_.setParam(IloCplex::EpInt, parameter_.epInt_); // amount by which an integer variable can differ from an integer
671  cplexSolver_.setParam(IloCplex::EpAGap, parameter_.epAGap_); // Absolute MIP gap tolerance
672  cplexSolver_.setParam(IloCplex::EpGap, parameter_.epGap_); // Relative MIP gap tolerance
673 
674  // memory setting
675  cplexSolver_.setParam(IloCplex::WorkMem, parameter_.workMem_);
676  cplexSolver_.setParam(IloCplex::TreLim, parameter_.treeMemoryLimit_);
677  cplexSolver_.setParam(IloCplex::MemoryEmphasis, 1);
678 
679  // time limit
680  cplexSolver_.setParam(IloCplex::ClockType, 2); //wall-clock-time=2 cpu-time=1
681  cplexSolver_.setParam(IloCplex::TiLim, parameter_.timeLimit_);
682 
683  // Root Algorithm
684  switch(parameter_.rootAlg_) {
685  case LPDef::LP_SOLVER_AUTO: {
686  cplexSolver_.setParam(IloCplex::RootAlg, 0);
687  break;
688  }
690  cplexSolver_.setParam(IloCplex::RootAlg, 1);
691  break;
692  }
694  cplexSolver_.setParam(IloCplex::RootAlg, 2);
695  break;
696  }
698  cplexSolver_.setParam(IloCplex::RootAlg, 3);
699  break;
700  }
702  cplexSolver_.setParam(IloCplex::RootAlg, 4);
703  break;
704  }
706  cplexSolver_.setParam(IloCplex::RootAlg, 5);
707  break;
708  }
710  cplexSolver_.setParam(IloCplex::RootAlg, 6);
711  break;
712  }
713  default: {
714  throw std::runtime_error("Unknown Root Algorithm");
715  }
716  }
717 
718  // Node Algorithm
719  switch(parameter_.nodeAlg_) {
720  case LPDef::LP_SOLVER_AUTO: {
721  cplexSolver_.setParam(IloCplex::NodeAlg, 0);
722  break;
723  }
725  cplexSolver_.setParam(IloCplex::NodeAlg, 1);
726  break;
727  }
729  cplexSolver_.setParam(IloCplex::NodeAlg, 2);
730  break;
731  }
733  cplexSolver_.setParam(IloCplex::NodeAlg, 3);
734  break;
735  }
737  cplexSolver_.setParam(IloCplex::NodeAlg, 4);
738  break;
739  }
741  cplexSolver_.setParam(IloCplex::NodeAlg, 5);
742  break;
743  }
745  cplexSolver_.setParam(IloCplex::NodeAlg, 6);
746  break;
747  }
748  default: {
749  throw std::runtime_error("Unknown Node Algorithm");
750  }
751  }
752 
753  // presolve
754  switch(parameter_.presolve_) {
756  cplexSolver_.setParam(IloCplex::PreInd, CPX_ON);
757  cplexSolver_.setParam(IloCplex::RelaxPreInd, -1);
758  break;
759  }
760  case LPDef::LP_PRESOLVE_OFF: {
761  cplexSolver_.setParam(IloCplex::PreInd, CPX_OFF);
762  cplexSolver_.setParam(IloCplex::RelaxPreInd, 0);
763  break;
764  }
766  cplexSolver_.setParam(IloCplex::PreInd, CPX_ON);
767  cplexSolver_.setParam(IloCplex::RelaxPreInd, -1);
768  break;
769  }
771  cplexSolver_.setParam(IloCplex::PreInd, CPX_ON);
772  cplexSolver_.setParam(IloCplex::RelaxPreInd, 1);
773  break;
774  }
775  default: {
776  throw std::runtime_error("Unknown Presolve Option");
777  }
778  }
779 
780  // MIP EMPHASIS
781  switch(parameter_.mipEmphasis_) {
783  cplexSolver_.setParam(IloCplex::MIPEmphasis, 0);
784  break;
785  }
787  cplexSolver_.setParam(IloCplex::MIPEmphasis, 1);
788  break;
789  }
791  cplexSolver_.setParam(IloCplex::MIPEmphasis, 2);
792  break;
793  }
795  cplexSolver_.setParam(IloCplex::MIPEmphasis, 3);
796  break;
797  }
799  cplexSolver_.setParam(IloCplex::MIPEmphasis, 4);
800  break;
801  }
802  default: {
803  throw std::runtime_error("Unknown MIP Emphasis Option");
804  }
805  }
806 
807  // Tuning
808  cplexSolver_.setParam(IloCplex::Probe, parameter_.probingLevel_);
809 
810  if(parameter_.cutLevel_ != LPDef::MIP_CUT_DEFAULT){
811  const int cl = getCutLevelValue(parameter_.cutLevel_);
812  cplexSolver_.setParam(IloCplex::Cliques, cl);
813  cplexSolver_.setParam(IloCplex::Covers, cl);
814  cplexSolver_.setParam(IloCplex::GUBCovers, cl);
815  cplexSolver_.setParam(IloCplex::MIRCuts, cl);
816  cplexSolver_.setParam(IloCplex::ImplBd, cl);
817  cplexSolver_.setParam(IloCplex::FlowCovers, cl);
818  cplexSolver_.setParam(IloCplex::FlowPaths, cl);
819  cplexSolver_.setParam(IloCplex::DisjCuts, cl);
820  cplexSolver_.setParam(IloCplex::FracCuts, cl);
821  }
822 
823  if(parameter_.cliqueCutLevel_ != LPDef::MIP_CUT_DEFAULT){
824  const int cl = getCutLevelValue(parameter_.cliqueCutLevel_);
825  cplexSolver_.setParam(IloCplex::Cliques, cl);
826  }
827  if(parameter_.coverCutLevel_ != LPDef::MIP_CUT_DEFAULT){
828  const int cl = getCutLevelValue(parameter_.coverCutLevel_);
829  cplexSolver_.setParam(IloCplex::Covers, cl);
830  }
831  if(parameter_.gubCutLevel_ != LPDef::MIP_CUT_DEFAULT){
832  const int cl = getCutLevelValue(parameter_.gubCutLevel_);
833  cplexSolver_.setParam(IloCplex::GUBCovers, cl);
834  }
835  if(parameter_.mirCutLevel_ != LPDef::MIP_CUT_DEFAULT){
836  const int cl = getCutLevelValue(parameter_.mirCutLevel_);
837  cplexSolver_.setParam(IloCplex::MIRCuts, cl);
838  }
839  if(parameter_.iboundCutLevel_ != LPDef::MIP_CUT_DEFAULT){
840  const int cl = getCutLevelValue(parameter_.iboundCutLevel_);
841  cplexSolver_.setParam(IloCplex::ImplBd, cl);
842  }
843  if(parameter_.flowcoverCutLevel_ != LPDef::MIP_CUT_DEFAULT){
844  const int cl = getCutLevelValue(parameter_.flowcoverCutLevel_);
845  cplexSolver_.setParam(IloCplex::FlowCovers, cl);
846  }
847  if(parameter_.flowpathCutLevel_ != LPDef::MIP_CUT_DEFAULT){
848  const int cl = getCutLevelValue(parameter_.flowpathCutLevel_);
849  cplexSolver_.setParam(IloCplex::FlowPaths, cl);
850  }
851  if(parameter_.disjunctCutLevel_ != LPDef::MIP_CUT_DEFAULT){
852  const int cl = getCutLevelValue(parameter_.disjunctCutLevel_);
853  cplexSolver_.setParam(IloCplex::DisjCuts, cl);
854  }
855  if(parameter_.gomoryCutLevel_ != LPDef::MIP_CUT_DEFAULT){
856  const int cl = getCutLevelValue(parameter_.gomoryCutLevel_);
857  cplexSolver_.setParam(IloCplex::FracCuts, cl);
858  }
859  } catch(const IloException& e) {
860  std::cout << e << std::endl;
861  throw std::runtime_error("CPLEX exception");
862  }
863 }
864 
866  cplexEnvironment_.end();
867 }
868 
870  return IloInfinity;
871 }
872 
873 inline void LPSolverCplex::addContinuousVariables_impl(const CplexIndexType numVariables, const CplexValueType lowerBound, const CplexValueType upperBound) {
874  try {
875  cplexVariables_.add(IloNumVarArray(cplexEnvironment_, numVariables, lowerBound, upperBound));
877  } catch(const IloException& e) {
878  std::cout << e << std::endl;
879  throw std::runtime_error("CPLEX exception");
880  }
881 }
882 
883 inline void LPSolverCplex::addIntegerVariables_impl(const CplexIndexType numVariables, const CplexValueType lowerBound, const CplexValueType upperBound) {
884  try {
885  cplexVariables_.add(IloNumVarArray(cplexEnvironment_, numVariables, lowerBound, upperBound, ILOINT));
887  } catch(const IloException& e) {
888  std::cout << e << std::endl;
889  throw std::runtime_error("CPLEX exception");
890  }
891 }
892 
894  try {
895  cplexVariables_.add(IloNumVarArray(cplexEnvironment_, numVariables, 0, 1, ILOBOOL));
897  } catch(const IloException& e) {
898  std::cout << e << std::endl;
899  throw std::runtime_error("CPLEX exception");
900  }
901 }
902 
903 inline void LPSolverCplex::setObjective_impl(const Objective objective) {
904  switch(objective) {
905  case Minimize: {
906  try {
907  cplexObjective_.setSense(IloObjective::Minimize);
908  } catch(const IloException& e) {
909  std::cout << e << std::endl;
910  throw std::runtime_error("CPLEX exception");
911  }
912  break;
913  }
914  case Maximize: {
915  try {
916  cplexObjective_.setSense(IloObjective::Maximize);
917  } catch(const IloException& e) {
918  std::cout << e << std::endl;
919  throw std::runtime_error("CPLEX exception");
920  }
921  break;
922  }
923  default: {
924  throw std::runtime_error("Unknown Objective");
925  }
926  }
927 }
928 
929 inline void LPSolverCplex::setObjectiveValue_impl(const CplexIndexType variable, const CplexValueType value) {
930  try {
931  cplexObjective_.setLinearCoef(cplexVariables_[variable], value);
932  } catch(const IloException& e) {
933  std::cout << e << std::endl;
934  throw std::runtime_error("CPLEX exception");
935  }
936 }
937 
938 template<class ITERATOR_TYPE>
939 inline void LPSolverCplex::setObjectiveValue_impl(ITERATOR_TYPE begin, const ITERATOR_TYPE end) {
940  const CplexIndexType numObjectiveVariables = std::distance(begin, end);
941 
942  IloNumArray objective(cplexEnvironment_, numObjectiveVariables);
943 
944  for(CplexIndexType i = 0; i < numObjectiveVariables; ++i) {
945  objective[i] = *begin;
946  ++begin;
947  }
948 
949  try {
950  cplexObjective_.setLinearCoefs(cplexVariables_, objective);
951  } catch(const IloException& e) {
952  std::cout << e << std::endl;
953  throw std::runtime_error("CPLEX exception");
954  }
955 }
956 
957 template<class VARIABLES_ITERATOR_TYPE, class COEFFICIENTS_ITERATOR_TYPE>
958 inline void LPSolverCplex::setObjectiveValue_impl(VARIABLES_ITERATOR_TYPE variableIDsBegin, const VARIABLES_ITERATOR_TYPE variableIDsEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin) {
959  const CplexIndexType numObjectiveVariables = std::distance(variableIDsBegin, variableIDsEnd);
960 
961  IloNumArray objective(cplexEnvironment_, numObjectiveVariables);
962  IloNumVarArray variables(cplexEnvironment_, numObjectiveVariables);
963 
964  for(CplexIndexType i = 0; i < numObjectiveVariables; ++i) {
965  objective[i] = *coefficientsBegin;
966  variables[i] = cplexVariables_[*variableIDsBegin];
967  ++coefficientsBegin;
968  ++variableIDsBegin;
969  }
970 
971  try {
972  cplexObjective_.setLinearCoefs(variables, objective);
973  } catch(const IloException& e) {
974  std::cout << e << std::endl;
975  throw std::runtime_error("CPLEX exception");
976  }
977 }
978 
979 template<class VARIABLES_ITERATOR_TYPE, class COEFFICIENTS_ITERATOR_TYPE>
980 inline void LPSolverCplex::addEqualityConstraint_impl(VARIABLES_ITERATOR_TYPE variableIDsBegin, const VARIABLES_ITERATOR_TYPE variableIDsEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin, const CplexValueType bound, const std::string& constraintName) {
981  IloRange constraint(cplexEnvironment_, bound, bound, constraintName.c_str());
982  while(variableIDsBegin != variableIDsEnd) {
983  constraint.setLinearCoef(cplexVariables_[*variableIDsBegin], *coefficientsBegin);
984  ++variableIDsBegin;
985  ++coefficientsBegin;
986  }
987 
988  try {
989  cplexConstraints_.add(constraint);
990  } catch(const IloException& e) {
991  std::cout << e << std::endl;
992  throw std::runtime_error("CPLEX exception");
993  }
994 }
995 
996 template<class VARIABLES_ITERATOR_TYPE, class COEFFICIENTS_ITERATOR_TYPE>
997 inline void LPSolverCplex::addLessEqualConstraint_impl(VARIABLES_ITERATOR_TYPE variableIDsBegin, const VARIABLES_ITERATOR_TYPE variableIDsEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin, const CplexValueType bound, const std::string& constraintName) {
998  IloRange constraint(cplexEnvironment_, -IloInfinity, bound, constraintName.c_str());
999  while(variableIDsBegin != variableIDsEnd) {
1000  constraint.setLinearCoef(cplexVariables_[*variableIDsBegin], *coefficientsBegin);
1001  ++variableIDsBegin;
1002  ++coefficientsBegin;
1003  }
1004 
1005  try {
1006  cplexConstraints_.add(constraint);
1007  } catch(const IloException& e) {
1008  std::cout << e << std::endl;
1009  throw std::runtime_error("CPLEX exception");
1010  }
1011 }
1012 
1013 template<class VARIABLES_ITERATOR_TYPE, class COEFFICIENTS_ITERATOR_TYPE>
1014 inline void LPSolverCplex::addGreaterEqualConstraint_impl(VARIABLES_ITERATOR_TYPE variableIDsBegin, const VARIABLES_ITERATOR_TYPE variableIDsEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin, const CplexValueType bound, const std::string& constraintName) {
1015  IloRange constraint(cplexEnvironment_, bound, IloInfinity, constraintName.c_str());
1016  while(variableIDsBegin != variableIDsEnd) {
1017  constraint.setLinearCoef(cplexVariables_[*variableIDsBegin], *coefficientsBegin);
1018  ++variableIDsBegin;
1019  ++coefficientsBegin;
1020  }
1021 
1022  try {
1023  cplexConstraints_.add(constraint);
1024  } catch(const IloException& e) {
1025  std::cout << e << std::endl;
1026  throw std::runtime_error("CPLEX exception");
1027  }
1028 }
1029 
1031  try {
1032  // add constraints to model
1034 
1035  // clear constraints as they are now present in the model
1036  cplexConstraints_.clear();
1037  } catch(const IloException& e) {
1038  std::cout << e << std::endl;
1039  throw std::runtime_error("CPLEX exception");
1040  }
1041 }
1042 
1044  try {
1045  const CplexTimingType begin = cplexSolver_.getCplexTime();
1046  // add constraints to model
1048 
1049  // clear constraints as they are now present in the model
1050  cplexConstraints_.clear();
1051  const CplexTimingType end = cplexSolver_.getCplexTime();
1052  timing = end - begin;
1053  } catch(const IloException& e) {
1054  std::cout << e << std::endl;
1055  throw std::runtime_error("CPLEX exception");
1056  }
1057 }
1058 
1059 template <class PARAMETER_TYPE, class PARAMETER_VALUE_TYPE>
1060 inline void LPSolverCplex::setParameter_impl(const PARAMETER_TYPE parameter, const PARAMETER_VALUE_TYPE value) {
1061  try {
1062  cplexSolver_.setParam(parameter, value);
1063  } catch(const IloException& e) {
1064  std::cout << e << std::endl;
1065  throw std::runtime_error("CPLEX exception");
1066  }
1067 }
1068 
1070  cplexSolutionValid_ = false;
1071  try {
1072  // solve problem
1073  if(!cplexSolver_.solve()) {
1074  IloCplex::CplexStatus status = cplexSolver_.getCplexStatus();
1075  std::cout << "failed to optimize(CPLEX Status: " << status << ")." << std::endl;
1076  return false;
1077  } else {
1078  return true;
1079  }
1080  } catch(const IloException& e) {
1081  std::cout << "caught CPLEX exception: " << e << std::endl;
1082  return false;
1083  }
1084 }
1085 
1087  cplexSolutionValid_ = false;
1088  try {
1089  // solve problem
1090  const CplexTimingType begin = cplexSolver_.getCplexTime();
1091  if(!cplexSolver_.solve()) {
1092  IloCplex::CplexStatus status = cplexSolver_.getCplexStatus();
1093  std::cout << "failed to optimize(CPLEX Status: " << status << ")." << std::endl;
1094  const CplexTimingType end = cplexSolver_.getCplexTime();
1095  timing = end - begin;
1096  return false;
1097  } else {
1098  const CplexTimingType end = cplexSolver_.getCplexTime();
1099  timing = end - begin;
1100  return true;
1101  }
1102  } catch(const IloException& e) {
1103  std::cout << "caught CPLEX exception: " << e << std::endl;
1104  return false;
1105  }
1106 }
1107 
1109  updateSolution();
1111 }
1112 
1114  updateSolution();
1116 }
1117 
1119  updateSolution();
1120  try {
1121  return cplexSolution_[variable];
1122  } catch(const IloException& e) {
1123  std::cout << e << std::endl;
1124  throw std::runtime_error("CPLEX exception");
1125  }
1126 }
1127 
1129  try {
1130  return cplexSolver_.getObjValue();
1131  } catch(const IloException& e) {
1132  std::cout << e << std::endl;
1133  throw std::runtime_error("CPLEX exception");
1134  }
1135 }
1136 
1138  try {
1139  if(cplexSolver_.isMIP()) {
1140  return cplexSolver_.getBestObjValue();
1141  } else {
1142  return cplexSolver_.getObjValue();
1143  }
1144  } catch(const IloException& e) {
1145  std::cout << e << std::endl;
1146  throw std::runtime_error("CPLEX exception");
1147  }
1148 }
1149 
1150 inline void LPSolverCplex::exportModel_impl(const std::string& filename) const {
1151  try {
1152  return cplexSolver_.exportModel(filename.c_str());
1153  } catch(const IloException& e) {
1154  std::cout << e << std::endl;
1155  throw std::runtime_error("CPLEX exception");
1156  }
1157 }
1158 
1159 inline void LPSolverCplex::updateSolution() const {
1160  if(!cplexSolutionValid_) {
1161  try {
1163  cplexSolutionValid_ = true;
1164  } catch(const IloException& e) {
1165  std::cout << e << std::endl;
1166  throw std::runtime_error("CPLEX exception");
1167  }
1168  }
1169 }
1170 
1172  switch(cutLevel) {
1174  case LPDef::MIP_CUT_AUTO:
1175  return 0;
1176  case LPDef::MIP_CUT_OFF:
1177  return -1;
1178  case LPDef::MIP_CUT_ON:
1179  return 1;
1181  return 2;
1183  return 3;
1184  default:
1185  throw std::runtime_error("Unknown Cut level.");
1186  }
1187 }
1188 
1189 } // namespace opengm
1190 
1191 #endif /* OPENGM_LP_SOLVER_CPLEX_HXX_ */
void addBinaryVariables_impl(const CplexIndexType numVariables)
Add new binary variables to the model.
void addLessEqualConstraint_impl(VARIABLES_ITERATOR_TYPE variableIDsBegin, const VARIABLES_ITERATOR_TYPE variableIDsEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin, const CplexValueType bound, const std::string &constraintName="")
Add a new less equal constraint to the model.
bool operator==(const IloNumArrayIterator &iter) const
Comparison operator to test if two iterators point to the same element.
The OpenGM namespace.
Definition: config.hxx:43
void setObjective_impl(const Objective objective)
Set objective to minimize or maximize.
CplexValueType objectiveFunctionValueBound_impl() const
Get the best known bound for the optimal solution of the current model.
void setObjectiveValue_impl(const CplexIndexType variable, const CplexValueType value)
Set the coefficient of a variable in the objective function.
~LPSolverCplex()
Destructor for LPSolverCplex.
bool operator!=(const IloNumArrayIterator &iter) const
Comparison operator to test if two iterators point to different elements.
void addEqualityConstraint_impl(VARIABLES_ITERATOR_TYPE variableIDsBegin, const VARIABLES_ITERATOR_TYPE variableIDsEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin, const CplexValueType bound, const std::string &constraintName="")
Add a new equality constraint to the model.
IloCplex cplexSolver_
The CPLEX solver.
difference_type operator-(const IloNumArrayIterator &iter) const
The difference operator computes the difference of two IloNumArrayIterators.
IloInt CplexIndexType
Defines the index type used by CPLEX.
IloObjective cplexObjective_
The objective function.
LPSolverCplex(const Parameter &parameter=Parameter())
Default constructor for LPSolverCplex.
IloRangeArray cplexConstraints_
Puffer for the constraints which are added by CPlexSolver::addEqualityConstraint, CPlexSolver::addLes...
Provides Interface definition for wrapper of LP Solvers like CPLEX and Gurobi.
CplexSolutionIteratorType solutionEnd_impl() const
Get an iterator which is pointing to the end of the solution computed by CPLEX.
bool cplexSolutionValid_
Tell if the currently stored solution is valid.
IloNum CplexTimingType
Defines the timing type used by CPLEX.
Interface definition for wrapper of LP Solvers like CPLEX and Gurobi.
Wrapper class for the IBM ILOG CPLEX optimizer.
IloNum CplexValueType
Defines the value type used by CPLEX.
IloNumVarArray cplexVariables_
The variables which are present in the model.
bool solve_impl()
Solve the current model.
void setParameter_impl(const PARAMETER_TYPE parameter, const PARAMETER_VALUE_TYPE value)
Set CPLEX parameter.
CplexValueType solution_impl(const CplexIndexType variable) const
Get the solution value of a variable computed by CPLEX.
IloNumArrayIterator & operator++()
The increment operator increases the position at which the iterator is pointing by one...
void exportModel_impl(const std::string &filename) const
Export model to file.
IloNumArray cplexSolution_
Storage for the solution computed by CPLEX.
Iterator to iterate over an array of type IloNumArray.
IloNumArrayIterator()
Default constructor to create an empty IloNumArrayIterator.
IloEnv cplexEnvironment_
The CPLEX environment.
CplexSolutionIteratorType solutionBegin_impl() const
Get an iterator which is pointing to the begin of the solution computed by CPLEX. ...
LPSolverInterface< LPSolverCplex, CplexValueType, CplexIndexType, CplexSolutionIteratorType, CplexTimingType > LPSolverBaseClass
Defines the type of the base class.
void addContinuousVariables_impl(const CplexIndexType numVariables, const CplexValueType lowerBound, const CplexValueType upperBound)
Add new continuous variables to the model.
const IloNum & operator[](const IloInt n) const
The subscript operator provides constant access to the element in the sequence which is n elements be...
IloInt position_
Index of the element in the sequence at which the iterator is pointing at the moment.
void addIntegerVariables_impl(const CplexIndexType numVariables, const CplexValueType lowerBound, const CplexValueType upperBound)
Add new integer variables to the model.
IloNumArrayIterator CplexSolutionIteratorType
Defines the iterator type which can be used to iterate over the solution of CPLEX.
void addGreaterEqualConstraint_impl(VARIABLES_ITERATOR_TYPE variableIDsBegin, const VARIABLES_ITERATOR_TYPE variableIDsEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin, const CplexValueType bound, const std::string &constraintName="")
Add a new greater equal constraint to the model.
IloModel cplexModel_
The CPLEX model of the LP/MIP problem.
void addConstraintsFinished_impl()
Join all constraints added via LPSolverCplex::addEqualityConstraint, LPSolverCplex::addLessEqualConst...
void updateSolution() const
Update solution if required.
static CplexValueType infinity_impl()
Get the value which is used by CPLEX to represent infinity.
static int getCutLevelValue(const LPDef::MIP_CUT cutLevel)
Translate LPDef::MIP_CUT into corresponding CPLEX int value.
const IloNumArray * array_
Constant pointer to the IloNumArray over which the iterator will iterate.
CplexValueType objectiveFunctionValue_impl() const
Get the objective function value from CPLEX.
const IloNum & operator*() const
The dereference operator provides constant access to the element at which the iterator is pointing...