OpenGM  2.3.x
Discrete Graphical Model Library
lpgurobi.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_LP_GURPBI_HXX
3 #define OPENGM_LP_GURPBI_HXX
4 
5 #include <vector>
6 #include <string>
7 #include <iostream>
8 #include <fstream>
9 #include <stdexcept>
10 #include <typeinfo>
11 
12 #include "gurobi_c++.h"
13 
15 #include "opengm/opengm.hxx"
22 
23 namespace opengm {
24 
37 template<class GM, class ACC>
38 class LPGurobi : public Inference<GM, ACC>, public LPDef {
39 public:
40  typedef ACC AccumulationType;
41  typedef ACC AccumulatorType;
42  typedef GM GraphicalModelType;
47 
48 
49  class Parameter {
50  public:
51  bool integerConstraint_; // ILP=true, 1order-LP=false
52  int numberOfThreads_; // number of threads (0=autosect)
53  bool verbose_; // switch on/off verbode mode
54  double cutUp_; // upper cutoff
55  double epOpt_; // Optimality tolerance
56  double epMrk_; // Markowitz tolerance
57  double epRHS_; // Feasibility Tolerance
58  double epInt_; // amount by which an integer variable can differ from an integer
59  double epAGap_; // Absolute MIP gap tolerance
60  double epGap_; // Relative MIP gap tolerance
61  double workMem_; // maximal ammount of memory in MB used for workspace
62  double treeMemoryLimit_; // maximal ammount of memory in MB used for treee
63  double timeLimit_; // maximal time in seconds the solver has
65  //int coverCutLevel_;
66  //int disjunctiverCutLevel_;
67  //int cliqueCutLevel_;
68  //int MIRCutLevel_;
69  //int presolveLevel_;
74  MIP_CUT cutLevel_; // Determines whether or not to cuts for the problem and how aggressively (will be overruled by specific ones).
75  MIP_CUT cliqueCutLevel_; // Determines whether or not to generate clique cuts for the problem and how aggressively.
76  MIP_CUT coverCutLevel_; // Determines whether or not to generate cover cuts for the problem and how aggressively.
77  MIP_CUT gubCutLevel_; // Determines whether or not to generate generalized upper bound (GUB) cuts for the problem and how aggressively.
78  MIP_CUT mirCutLevel_; // Determines whether or not mixed integer rounding (MIR) cuts should be generated for the problem and how aggressively.
79  MIP_CUT iboundCutLevel_; // Determines whether or not to generate implied bound cuts for the problem and how aggressively.
80  MIP_CUT flowcoverCutLevel_; //Determines whether or not to generate flow cover cuts for the problem and how aggressively.
81  MIP_CUT flowpathCutLevel_; //Determines whether or not to generate flow path cuts for the problem and how aggressively.
82  MIP_CUT disjunctCutLevel_; // Determines whether or not to generate disjunctive cuts for the problem and how aggressively.
83  MIP_CUT gomoryCutLevel_; // Determines whether or not to generate gomory fractional cuts for the problem and how aggressively.
84 
88  Parameter
89  (
90  int numberOfThreads = 0
91  )
92  : numberOfThreads_(numberOfThreads),
93  //integerConstraint_(false),
94  verbose_(false),
95  workMem_(128.0),
96  treeMemoryLimit_(1e+75),
97  timeLimit_(1e+75),
98  probeingLevel_(0),
99  //coverCutLevel_(0),
100  //disjunctiverCutLevel_(0),
101  //cliqueCutLevel_(0),
102  //MIRCutLevel_(0),
103  //presolveLevel_(-1),
118  {
119  numberOfThreads_ = numberOfThreads;
120  integerConstraint_ = false;
121  LPDef lpdef;
122  cutUp_ = lpdef.default_cutUp_;
123  epOpt_ = lpdef.default_epOpt_;
124  epMrk_ = lpdef.default_epMrk_;
125  epRHS_ = lpdef.default_epRHS_;
126  epInt_ = lpdef.default_epInt_;
127  epAGap_= lpdef.default_epAGap_;
128  epGap_ = lpdef.default_epGap_;
129  };
131  switch(cl){
132  case MIP_CUT_AUTO:
133  return -1;
134  case MIP_CUT_OFF:
135  return 0;
136  case MIP_CUT_ON:
137  return 1;
138  case MIP_CUT_AGGRESSIVE:
139  return 2;
141  return 3;
142  }
143  return -1;
144  };
145  };
146 
147  LPGurobi(const GraphicalModelType&, const Parameter& = Parameter());
148  ~LPGurobi();
149  virtual std::string name() const
150  { return "LPGurobi"; }
151  const GraphicalModelType& graphicalModel() const;
152  virtual InferenceTermination infer();
153  template<class VisitorType>
154  InferenceTermination infer(VisitorType&);
155  virtual InferenceTermination arg(std::vector<LabelType>&, const size_t = 1) const;
156  virtual InferenceTermination args(std::vector<std::vector<LabelType> >&) const
157  { return UNKNOWN; };
158  void variable(const size_t, IndependentFactorType& out) const;
159  void factorVariable(const size_t, IndependentFactorType& out) const;
160  typename GM::ValueType bound() const;
161  typename GM::ValueType value() const;
162 
163  size_t lpNodeVi(const IndexType variableIndex,const LabelType label)const;
164  size_t lpFactorVi(const IndexType factorIndex,const size_t labelingIndex)const;
165  template<class LABELING_ITERATOR>
166  size_t lpFactorVi(const IndexType factorIndex,LABELING_ITERATOR labelingBegin,LABELING_ITERATOR labelingEnd)const;
167  template<class LPVariableIndexIterator, class CoefficientIterator>
168  void addConstraint(LPVariableIndexIterator, LPVariableIndexIterator, CoefficientIterator,const ValueType&, const ValueType&, const char * name=0);
169 
170 
171  void writeModelToDisk(const std::string & filename)const{
172  try {
173  if( filename.size()!=0)
174  model_->write(filename);
175  }
176  catch(GRBException e) {
177  std::cout << "**Error code = " << e.getErrorCode() << "\n";
178  std::cout << e.getMessage() <<"\n";
179  throw opengm::RuntimeError( e.getMessage() );
180  }
181  catch(...) {
182  std::cout << "Exception during write" <<"\n";
183  throw opengm::RuntimeError( "Exception during write" );
184  }
185 
186  }
187 
188 private:
189  void updateIfDirty();
190 
191  const GraphicalModelType& gm_;
192  Parameter param_;
193  std::vector<size_t> idNodesBegin_;
194  std::vector<size_t> idFactorsBegin_;
195  std::vector<std::vector<size_t> > unaryFactors_;
196  bool inferenceStarted_;
197 
198  bool dirty_;
199 
200  std::vector<double> lpArg_;
201  std::vector<LabelType> arg_;
202  size_t nLpVar_;
203  // gurobi members
204  GRBEnv * env_ ;
205  GRBModel * model_;
206  GRBVar * vars_;
207 
208  //
209  ValueType bound_;
210  ValueType value_;
211 };
212 
213 
214 
215 template<class GM, class ACC>
217 (
218  const GraphicalModelType& gm,
219  const Parameter& para
220 )
221 : gm_(gm),
222  param_(para),
223  idNodesBegin_(gm_.numberOfVariables()),
224  idFactorsBegin_(gm_.numberOfFactors()),
225  unaryFactors_(gm_.numberOfVariables()),
226  inferenceStarted_(false),
227  dirty_(false),
228  lpArg_(),
229  arg_(gm_.numberOfVariables(),0),
230  nLpVar_(0),
231  env_(),
232  model_(),
233  vars_(),
234  bound_(),
235  value_()
236 {
237 
238  ACC::neutral(value_);
239  ACC::ineutral(bound_);
240  //std::cout<<"setup basic env\n";
241  try {
242  env_ = new GRBEnv();
243  env_->set(GRB_IntParam_LogToConsole,int(param_.verbose_));
244 
245  // Root Algorithm
246  switch(param_.nodeAlg_) {
247  case LP_SOLVER_AUTO:
248  env_->set(GRB_IntParam_NodeMethod,1);
249  break;
250  case LP_SOLVER_PRIMAL_SIMPLEX:
251  env_->set(GRB_IntParam_NodeMethod,0);
252  break;
253  case LP_SOLVER_DUAL_SIMPLEX:
254  env_->set(GRB_IntParam_NodeMethod,1);
255  break;
256  case LP_SOLVER_NETWORK_SIMPLEX:
257  throw RuntimeError("Gurobi does not support Network Simplex");
258  break;
259  case LP_SOLVER_BARRIER:
260  env_->set(GRB_IntParam_NodeMethod,2);
261  break;
262  case LP_SOLVER_SIFTING:
263  throw RuntimeError("Gurobi does not support Sifting");
264  break;
265  case LP_SOLVER_CONCURRENT:
266  throw RuntimeError("Gurobi does not concurrent solvers");
267  break;
268  }
269 
270  // Node Algorithm
271  switch(param_.rootAlg_) {
272  case LP_SOLVER_AUTO:
273  env_->set(GRB_IntParam_Method,-1);
274  break;
275  case LP_SOLVER_PRIMAL_SIMPLEX:
276  env_->set(GRB_IntParam_Method,0);
277  break;
278  case LP_SOLVER_DUAL_SIMPLEX:
279  env_->set(GRB_IntParam_Method,1);
280  break;
281  case LP_SOLVER_NETWORK_SIMPLEX:
282  throw RuntimeError("Gurobi does not support Network Simplex");
283  break;
284  case LP_SOLVER_BARRIER:
285  env_->set(GRB_IntParam_Method,2);
286  break;
287  case LP_SOLVER_SIFTING:
288  env_->set(GRB_IntParam_Method,1);
289  env_->set(GRB_IntParam_SiftMethod,1);
290  break;
291  case LP_SOLVER_CONCURRENT:
292  env_->set(GRB_IntParam_Method,4);
293  break;
294  }
295 
296  // presolve
297  switch(param_.presolve_) {
298  case LP_PRESOLVE_AUTO:
299  env_->set(GRB_IntParam_Presolve,-1);
300  break;
301  case LP_PRESOLVE_OFF:
302  env_->set(GRB_IntParam_Presolve,0);
303  break;
304  case LP_PRESOLVE_CONSERVATIVE:
305  env_->set(GRB_IntParam_Presolve,1);
306  break;
307  case LP_PRESOLVE_AGGRESSIVE:
308  env_->set(GRB_IntParam_Presolve,2);
309  break;
310  }
311 
312  // MIP FOCUS
313  switch(param_.mipFocus_) {
314  case MIP_EMPHASIS_BALANCED:
315  env_->set(GRB_IntParam_MIPFocus,0);
316  break;
317  case MIP_EMPHASIS_FEASIBILITY:
318  env_->set(GRB_IntParam_MIPFocus,1);
319  break;
320  case MIP_EMPHASIS_OPTIMALITY:
321  env_->set(GRB_IntParam_MIPFocus,2);
322  break;
323  case MIP_EMPHASIS_BESTBOUND:
324  env_->set(GRB_IntParam_MIPFocus,3);
325  break;
326  case MIP_EMPHASIS_HIDDENFEAS:
327  throw RuntimeError("Gurobi does not support hidden feasibility as MIP-focus");
328  break;
329  }
330 
331  // tolarance settings
332  env_->set(GRB_DoubleParam_Cutoff ,param_.cutUp_); // Optimality Tolerance
333  env_->set(GRB_DoubleParam_OptimalityTol ,param_.epOpt_); // Optimality Tolerance
334  env_->set(GRB_DoubleParam_IntFeasTol ,param_.epInt_); // amount by which an integer variable can differ from an integer
335  env_->set(GRB_DoubleParam_MIPGapAbs ,param_.epAGap_); // Absolute MIP gap tolerance
336  env_->set(GRB_DoubleParam_MIPGap ,param_.epGap_); // Relative MIP gap tolerance
337  env_->set(GRB_DoubleParam_FeasibilityTol,param_.epRHS_);
338  env_->set(GRB_DoubleParam_MarkowitzTol ,param_.epMrk_);
339 
340  // set hints
341  // CutUp is missing http://www.gurobi.com/resources/switching-to-gurobi/switching-from-cplex#setting
342 
343  // memory settings
344  // -missing
345 
346  // time limit
347  env_->set(GRB_DoubleParam_TimeLimit ,param_.timeLimit_); // time limit
348 
349  // threadding
350  if(param_.numberOfThreads_!=0)
351  env_->set(GRB_IntParam_Threads ,param_.numberOfThreads_); // threads
352 
353 
354  // tuning
355  // *Probe missing
356  // *DisjCuts missing
357  if(param_.cutLevel_ != MIP_CUT_DEFAULT)
358  env_->set(GRB_IntParam_Cuts ,param_.getCutLevel(param_.cutLevel_));
359  if(param_.cliqueCutLevel_ != MIP_CUT_DEFAULT)
360  env_->set(GRB_IntParam_CliqueCuts ,param_.getCutLevel(param_.cliqueCutLevel_));
361  if(param_.coverCutLevel_ != MIP_CUT_DEFAULT)
362  env_->set(GRB_IntParam_CoverCuts ,param_.getCutLevel(param_.coverCutLevel_));
363  if(param_.gubCutLevel_ != MIP_CUT_DEFAULT)
364  env_->set(GRB_IntParam_GUBCoverCuts ,param_.getCutLevel(param_.gubCutLevel_));
365  if(param_.mirCutLevel_ != MIP_CUT_DEFAULT)
366  env_->set(GRB_IntParam_MIRCuts ,param_.getCutLevel(param_.mirCutLevel_));
367  if(param_.iboundCutLevel_ != MIP_CUT_DEFAULT)
368  env_->set(GRB_IntParam_ImpliedCuts ,param_.getCutLevel(param_.iboundCutLevel_));
369  if(param_.flowcoverCutLevel_ != MIP_CUT_DEFAULT)
370  env_->set(GRB_IntParam_FlowCoverCuts ,param_.getCutLevel(param_.flowcoverCutLevel_));
371  if(param_.flowpathCutLevel_ != MIP_CUT_DEFAULT)
372  env_->set(GRB_IntParam_FlowPathCuts ,param_.getCutLevel(param_.flowpathCutLevel_));
373  // *DisjCuts missing
374  // *Gomory missing
375  model_ = new GRBModel(*env_);
376  }
377  catch(GRBException e) {
378  std::cout << "Error code = " << e.getErrorCode() << "\n";
379  std::cout << e.getMessage() <<"\n";
380  throw opengm::RuntimeError( e.getMessage() );
381  } catch(...) {
382  std::cout << "Exception during construction of gurobi solver" <<"\n";
383  throw opengm::RuntimeError( "Exception during construction of gurobi solver" );
384  }
385 
386 
387  if(typeid(OperatorType) != typeid(opengm::Adder)) {
388  throw RuntimeError("This implementation does only supports Min-Plus-Semiring");
389  }
390  //std::cout<<"enumerate stuff\n";
391  param_ = para;
392  idNodesBegin_.resize(gm_.numberOfVariables());
393  unaryFactors_.resize(gm_.numberOfVariables());
394  idFactorsBegin_.resize(gm_.numberOfFactors());
395 
396  // temporal variables
397  size_t numberOfElements = 0;
398  size_t numberOfVariableElements = 0;
399  size_t numberOfFactorElements = 0;
400  size_t maxLabel = 0 ;
401  size_t maxFacSize = 0;
402  // enumerate variables
403  size_t idCounter = 0;
404  for(size_t node = 0; node < gm_.numberOfVariables(); ++node) {
405  numberOfVariableElements += gm_.numberOfLabels(node);
406  maxLabel=std::max(size_t(gm_.numberOfLabels(node)),maxLabel);
407 
408  idNodesBegin_[node] = idCounter;
409  idCounter += gm_.numberOfLabels(node);
410  }
411  // enumerate factors
412  for(size_t f = 0; f < gm_.numberOfFactors(); ++f) {
413  if(gm_[f].numberOfVariables() == 1) {
414  size_t node = gm_[f].variableIndex(0);
415  unaryFactors_[node].push_back(f);
416  idFactorsBegin_[f] = idNodesBegin_[node];
417  }
418  else {
419  idFactorsBegin_[f] = idCounter;
420  idCounter += gm_[f].size();
421  maxFacSize=std::max(size_t(gm_[f].size()),maxFacSize);
422  numberOfFactorElements += gm_[f].size();
423  }
424  }
425  numberOfElements = numberOfVariableElements + numberOfFactorElements;
426  nLpVar_=numberOfElements; // refactor me
427 
428  if(typeid(ACC) == typeid(opengm::Minimizer)) {
429  }
430  else {
431  throw RuntimeError("This implementation does only support Minimizer or Maximizer accumulators");
432  }
433 
434  //std::cout<<"fill obj ptrs \n";
435  lpArg_.resize(nLpVar_);
436  std::vector<double> lb(numberOfElements,0.0);
437  std::vector<double> ub(numberOfElements,1.0);
438  std::vector<double> obj(numberOfElements);
439  std::vector<char> vtype(numberOfElements,GRB_CONTINUOUS);
440  // set variables and objective
441  if(param_.integerConstraint_) {
442  std::fill(vtype.begin(),vtype.begin()+numberOfVariableElements,GRB_BINARY);
443  }
444 
445 
446  for(size_t node = 0; node < gm_.numberOfVariables(); ++node) {
447  for(size_t i = 0; i < gm_.numberOfLabels(node); ++i) {
448  ValueType t = 0;
449  for(size_t n=0; n<unaryFactors_[node].size();++n) {
450  t += gm_[unaryFactors_[node][n]](&i);
451  }
452  obj[idNodesBegin_[node]+i] = t;
453 
454  }
455  }
456  for(size_t f = 0; f < gm_.numberOfFactors(); ++f) {
457  if(gm_[f].numberOfVariables() == 2) {
458  size_t index[2];
459  size_t counter = idFactorsBegin_[f];
460  for(index[1]=0; index[1]<gm_[f].numberOfLabels(1);++index[1])
461  for(index[0]=0; index[0]<gm_[f].numberOfLabels(0);++index[0])
462  obj[counter++] = gm_[f](index);
463  }
464  else if(gm_[f].numberOfVariables() == 3) {
465  size_t index[3];
466  size_t counter = idFactorsBegin_[f] ;
467  for(index[2]=0; index[2]<gm_[f].numberOfLabels(2);++index[2])
468  for(index[1]=0; index[1]<gm_[f].numberOfLabels(1);++index[1])
469  for(index[0]=0; index[0]<gm_[f].numberOfLabels(0);++index[0])
470  obj[counter++] = gm_[f](index);
471  }
472  else if(gm_[f].numberOfVariables() == 4) {
473  size_t index[4];
474  size_t counter = idFactorsBegin_[f];
475  for(index[3]=0; index[3]<gm_[f].numberOfLabels(3);++index[3])
476  for(index[2]=0; index[2]<gm_[f].numberOfLabels(2);++index[2])
477  for(index[1]=0; index[1]<gm_[f].numberOfLabels(1);++index[1])
478  for(index[0]=0; index[0]<gm_[f].numberOfLabels(0);++index[0])
479  obj[counter++] = gm_[f](index);
480  }
481  else if(gm_[f].numberOfVariables() > 4) {
482  size_t counter = idFactorsBegin_[f];
483  std::vector<size_t> coordinate(gm_[f].numberOfVariables());
484  marray::Marray<bool> temp(gm_[f].shapeBegin(), gm_[f].shapeEnd());
485  for(marray::Marray<bool>::iterator mit = temp.begin(); mit != temp.end(); ++mit) {
486  mit.coordinate(coordinate.begin());
487  obj[counter++] = gm_[f](coordinate.begin());
488  }
489  }
490  }
491 
492  //std::cout<<"add obj ptrs \n";
493  try {
494  // add all variables at once with an allready setup objective
495  vars_ = model_->addVars(&lb[0],&ub[0],&obj[0],&vtype[0],NULL,numberOfElements);
496  //integrate new variales
497  model_->update();
498  }
499  catch(GRBException e) {
500  std::cout << "**Error code = " << e.getErrorCode() << "\n";
501  std::cout << e.getMessage() <<"\n";
502  throw opengm::RuntimeError( e.getMessage() );
503  } catch(...) {
504  std::cout << "Exception during construction of gurobi model" <<"\n";
505  throw opengm::RuntimeError( "Exception during construction of gurobi model" );
506  }
507 
508  //std::cout<<"count constr \n";
509  // count the needed constraints
510  size_t constraintCounter = 0;
511  // \sum_i \mu_i = 1
512  for(size_t node = 0; node < gm_.numberOfVariables(); ++node) {
513  ++constraintCounter;
514  }
515 
516  // \sum_i \mu_{f;i_1,...,i_n} - \mu{b;j}= 0
517  for(size_t f = 0; f < gm_.numberOfFactors(); ++f) {
518  if(gm_[f].numberOfVariables() > 1) {
519  for(size_t n = 0; n < gm_[f].numberOfVariables(); ++n) {
520  size_t node = gm_[f].variableIndex(n);
521  for(size_t i = 0; i < gm_.numberOfLabels(node); ++i) {
522  ++constraintCounter;
523  }
524  }
525  }
526  }
527 
528 
529 
530 
531 
532  std::vector<GRBLinExpr> lhsExprs(constraintCounter);
533  std::vector<char> sense(constraintCounter,GRB_EQUAL);
534  std::vector<double> rhsVals(constraintCounter,0.0);
535  std::vector<std::string> names(constraintCounter,std::string());
536 
537  std::fill(rhsVals.begin(),rhsVals.begin()+gm_.numberOfVariables(),1.0);
538 
539 
540 
541  //std::cout<<"setup constr \n";
542 
543  // set constraints
544  constraintCounter = 0;
545  // \sum_i \mu_i = 1
546 
547  const size_t buffferSize = std::max(maxLabel,size_t(maxFacSize+1));
548  std::vector<GRBVar> localVars(buffferSize);
549  std::vector<double> localVal(buffferSize,1.0);
550 
551  for(size_t node = 0; node < gm_.numberOfVariables(); ++node) {
552  for(size_t i = 0; i < gm_.numberOfLabels(node); ++i) {
553  localVars[i]=vars_[idNodesBegin_[node]+i];
554  }
555  lhsExprs[constraintCounter].addTerms(&localVal[0],&localVars[0],gm_.numberOfLabels(node));
556  ++constraintCounter;
557  }
558 
559  localVal[0]=-1.0;
560 
561  // \sum_i \mu_{f;i_1,...,i_n} - \mu{b;j}= 0
562  for(size_t f = 0; f < gm_.numberOfFactors(); ++f) {
563  if(gm_[f].numberOfVariables() > 1) {
564  marray::Marray<size_t> temp(gm_[f].shapeBegin(), gm_[f].shapeEnd());
565  size_t counter = idFactorsBegin_[f];
566  for(marray::Marray<size_t>::iterator mit = temp.begin(); mit != temp.end(); ++mit) {
567  *mit = counter++;
568  }
569  for(size_t n = 0; n < gm_[f].numberOfVariables(); ++n) {
570  size_t node = gm_[f].variableIndex(n);
571  for(size_t i = 0; i < gm_.numberOfLabels(node); ++i) {
572  //c_.add(IloRange(env_, 0, 0));
573  //c_[constraintCounter].setLinearCoef(x_[idNodesBegin_[node]+i], -1);
574  //double mone =-1.0;
575  //lhsExprs[constraintCounter].addTerms(&mone,&vars_[idNodesBegin_[node]+i],1);
576  size_t localCounter=1;
577  localVars[0]=vars_[idNodesBegin_[node]+i];
578  marray::View<size_t> view = temp.boundView(n, i);
579  for(marray::View<size_t>::iterator vit = view.begin(); vit != view.end(); ++vit) {
580  //c_[constraintCounter].setLinearCoef(x_[*vit], 1);
581  //double one =1.0;
582  //lhsExprs[constraintCounter].addTerms(&one,&vars_[*vit],1);
583  localVars[localCounter]=vars_[*vit];
584  ++localCounter;
585  }
586  lhsExprs[constraintCounter].addTerms(&localVal[0],&localVars[0],localCounter);
587  ++constraintCounter;
588  }
589  }
590  }
591  }
592 
593 
594  try {
595 
596  //std::cout<<"add constr \n";
597  // add all constraints at once to the model
598  GRBConstr* constr = model_->addConstrs(&lhsExprs[0],&sense[0],&rhsVals[0],&names[0],constraintCounter);
599  //std::cout<<"done\n";
600  }
601  catch(GRBException e) {
602  std::cout << "**Error code = " << e.getErrorCode() << "\n";
603  std::cout << e.getMessage() <<"\n";
604  throw opengm::RuntimeError( e.getMessage() );
605  } catch(...) {
606  std::cout << "Exception during adding constring to gurobi model" <<"\n";
607  throw opengm::RuntimeError( "Exception during adding constring to gurobi model" );
608  }
609 
610  // test if it help for write model to file
611  model_->update();
612 }
613 
614 template <class GM, class ACC>
617  EmptyVisitorType v;
618  return infer(v);
619 }
620 
621 template<class GM, class ACC>
622 template<class VisitorType>
625 (
626  VisitorType& visitor
627 ) {
628  updateIfDirty();
629  visitor.begin(*this);
630  inferenceStarted_ = true;
631  try {
632  model_->optimize();
633  if(param_.integerConstraint_){
634  bound_ = model_->get(GRB_DoubleAttr_ObjBound);
635  }
636  else{
637  bound_ = model_->get(GRB_DoubleAttr_ObjVal);
638  }
639  //std::cout << "Bound: " <<bound_ << "\n";
640  for(size_t lpvi=0;lpvi<nLpVar_;++lpvi){
641  lpArg_[lpvi]=vars_[lpvi].get(GRB_DoubleAttr_X);
642  //td::cout<<"lpvi "<<lpvi<<" "<<lpArg_[lpvi]<<"\n";
643  }
644 
645  }
646  catch(GRBException e) {
647  std::cout << "Error code = " << e.getErrorCode() << "\n";
648  std::cout << e.getMessage() <<"\n";
649  } catch(...) {
650  std::cout << "Exception during optimization" <<"\n";
651  }
652  visitor.end(*this);
653  return NORMAL;
654 }
655 
656 template <class GM, class ACC>
658  delete model_;
659  delete env_;
660 }
661 
662 template <class GM, class ACC>
665 (
666  std::vector<typename LPGurobi<GM, ACC>::LabelType>& x,
667  const size_t N
668 ) const {
669 
670  x.resize(gm_.numberOfVariables());
671  if(inferenceStarted_) {
672  for(size_t node = 0; node < gm_.numberOfVariables(); ++node) {
673  ValueType value = lpArg_[idNodesBegin_[node]];
674  size_t state = 0;
675  for(size_t i = 1; i < gm_.numberOfLabels(node); ++i) {
676  if(lpArg_[idNodesBegin_[node]+i] > value) {
677  value = lpArg_[idNodesBegin_[node]+i];
678  state = i;
679  }
680  }
681  x[node] = state;
682  }
683  return NORMAL;
684  }
685  else{
686  for(size_t node = 0; node < gm_.numberOfVariables(); ++node) {
687  x[node] = 0;
688  }
689  return UNKNOWN;
690  }
691 }
692 
693 template <class GM, class ACC>
695 (
696  const size_t nodeId,
698 ) const {
699 
700  size_t var[] = {nodeId};
701  size_t shape[] = {gm_.numberOfLabels(nodeId)};
702  out.assign(var, var + 1, shape, shape + 1);
703  for(size_t i = 0; i < gm_.numberOfLabels(nodeId); ++i) {
704  out(i) = lpArg_[idNodesBegin_[nodeId]+i];
705  }
706  //return UNKNOWN;
707 
708 }
709 
710 template <class GM, class ACC>
712 (
713  const size_t factorId,
715 ) const {
716 
717  std::vector<size_t> var(gm_[factorId].numberOfVariables());
718  std::vector<size_t> shape(gm_[factorId].numberOfVariables());
719  for(size_t i = 0; i < gm_[factorId].numberOfVariables(); ++i) {
720  var[i] = gm_[factorId].variableIndex(i);
721  shape[i] = gm_[factorId].shape(i);
722  }
723  out.assign(var.begin(), var.end(), shape.begin(), shape.end());
724  if(gm_[factorId].numberOfVariables() == 1) {
725  size_t nodeId = gm_[factorId].variableIndex(0);
726  marginal(nodeId, out);
727  }
728  else {
729  size_t c = 0;
730  for(size_t n = idFactorsBegin_[factorId]; n<idFactorsBegin_[factorId]+gm_[factorId].size(); ++n) {
731  out(c++) = lpArg_[n];
732  }
733  }
734  //return UNKNOWN;
735 }
736 
737 template<class GM, class ACC>
738 inline const typename LPGurobi<GM, ACC>::GraphicalModelType&
740 {
741  return gm_;
742 }
743 
744 template<class GM, class ACC>
745 typename GM::ValueType LPGurobi<GM, ACC>::value() const {
746  std::vector<LabelType> states;
747  arg(states);
748  return gm_.evaluate(states);
749 }
750 
751 template<class GM, class ACC>
752 typename GM::ValueType LPGurobi<GM, ACC>::bound() const {
753 
754  if(param_.integerConstraint_) {
755  return bound_;
756  }
757  else{
758  return bound_;
759  }
760 
761 }
762 
763 
764 template <class GM, class ACC>
765 inline size_t
767 (
768  const typename LPGurobi<GM, ACC>::IndexType variableIndex,
769  const typename LPGurobi<GM, ACC>::LabelType label
770 )const{
771  OPENGM_ASSERT(variableIndex<gm_.numberOfVariables());
772  OPENGM_ASSERT(label<gm_.numberOfLabels(variableIndex));
773  return idNodesBegin_[variableIndex]+label;
774 }
775 
776 
777 template <class GM, class ACC>
778 inline size_t
780 (
781  const typename LPGurobi<GM, ACC>::IndexType factorIndex,
782  const size_t labelingIndex
783 )const{
784  OPENGM_ASSERT(factorIndex<gm_.numberOfFactors());
785  OPENGM_ASSERT(labelingIndex<gm_[factorIndex].size());
786  return idFactorsBegin_[factorIndex]+labelingIndex;
787 }
788 
789 
790 template <class GM, class ACC>
791 template<class LABELING_ITERATOR>
792 inline size_t
794 (
795  const typename LPGurobi<GM, ACC>::IndexType factorIndex,
796  LABELING_ITERATOR labelingBegin,
797  LABELING_ITERATOR labelingEnd
798 )const{
799  OPENGM_ASSERT(factorIndex<gm_.numberOfFactors());
800  OPENGM_ASSERT(std::distance(labelingBegin,labelingEnd)==gm_[factorIndex].numberOfVariables());
801  const size_t numVar=gm_[factorIndex].numberOfVariables();
802  size_t labelingIndex=labelingBegin[0];
803  size_t strides=gm_[factorIndex].numberOfLabels(0);
804  for(size_t vi=1;vi<numVar;++vi){
805  OPENGM_ASSERT(labelingBegin[vi]<gm_[factorIndex].numberOfLabels(vi));
806  labelingIndex+=strides*labelingBegin[vi];
807  strides*=gm_[factorIndex].numberOfLabels(vi);
808  }
809  return idFactorsBegin_[factorIndex]+labelingIndex;
810 }
811 
812 
813 
814 
826 template<class GM, class ACC>
827 template<class LPVariableIndexIterator, class CoefficientIterator>
829  LPVariableIndexIterator viBegin,
830  LPVariableIndexIterator viEnd,
831  CoefficientIterator coefficient,
832  const ValueType& lowerBound,
833  const ValueType& upperBound,
834  const char * name
835 ) {
836  // construct linear constraint expression
837  GRBLinExpr expr;
838  while(viBegin != viEnd) {
839  expr += vars_[*viBegin] * (*coefficient);
840  ++viBegin;
841  ++coefficient;
842  }
843 
844  // add constraints for upper and lower bound
845  model_->addConstr(expr, GRB_LESS_EQUAL, upperBound, name);
846  model_->addConstr(expr, GRB_GREATER_EQUAL, lowerBound, name);
847 
848  // Gurobi needs a model update after adding a constraint
849  dirty_ = true;
850 }
851 
852 template<class GM, class ACC>
854 {
855  if(dirty_) {
856  model_->update();
857  dirty_ = false;
858  }
859 }
860 
861 } // end namespace opengm
862 
863 #endif
The OpenGM namespace.
Definition: config.hxx:43
GM::ValueType bound() const
return a bound on the solution
Definition: lpgurobi.hxx:752
STL-compliant random access iterator for View and Marray.
Definition: marray.hxx:49
Addition as a binary operation.
Definition: adder.hxx:10
static const double default_epRHS_
Definition: lpdef.hxx:17
size_t lpNodeVi(const IndexType variableIndex, const LabelType label) const
Definition: lpgurobi.hxx:767
static const double default_cutUp_
Definition: lpdef.hxx:14
Optimization by Linear Programming (LP) or Integer LP using Guroi http://www.gurobi.com.
Definition: lpgurobi.hxx:38
virtual InferenceTermination infer()
Definition: lpgurobi.hxx:616
const GraphicalModelType & graphicalModel() const
Definition: lpgurobi.hxx:739
static const double default_epInt_
Definition: lpdef.hxx:18
LPGurobi(const GraphicalModelType &, const Parameter &=Parameter())
Definition: lpgurobi.hxx:217
Array-Interface to an interval of memory.
Definition: marray.hxx:44
visitors::VerboseVisitor< LPGurobi< GM, ACC > > VerboseVisitorType
Definition: lpgurobi.hxx:44
#define OPENGM_ASSERT(expression)
Definition: opengm.hxx:77
static const double default_epOpt_
Definition: lpdef.hxx:15
static const double default_epAGap_
Definition: lpdef.hxx:19
GraphicalModelType::OperatorType OperatorType
Definition: inference.hxx:42
Parameter(int numberOfThreads=0)
constructor
Definition: lpgurobi.hxx:89
static const double default_epMrk_
Definition: lpdef.hxx:16
void variable(const size_t, IndependentFactorType &out) const
Definition: lpgurobi.hxx:695
GM::ValueType value() const
return the solution (value)
Definition: lpgurobi.hxx:745
visitors::TimingVisitor< LPGurobi< GM, ACC > > TimingVisitorType
Definition: lpgurobi.hxx:45
GraphicalModelType::IndexType IndexType
Definition: inference.hxx:40
static const double default_epGap_
Definition: lpdef.hxx:20
void writeModelToDisk(const std::string &filename) const
Definition: lpgurobi.hxx:171
void addConstraint(LPVariableIndexIterator, LPVariableIndexIterator, CoefficientIterator, const ValueType &, const ValueType &, const char *name=0)
add constraint
Definition: lpgurobi.hxx:828
View< T, isConst, A > boundView(const size_t, const size_t=0) const
GraphicalModelType::ValueType ValueType
Definition: inference.hxx:41
Inference algorithm interface.
Definition: inference.hxx:34
visitors::EmptyVisitor< LPGurobi< GM, ACC > > EmptyVisitorType
Definition: lpgurobi.hxx:46
int getCutLevel(MIP_CUT cl)
Definition: lpgurobi.hxx:130
void factorVariable(const size_t, IndependentFactorType &out) const
Definition: lpgurobi.hxx:712
virtual InferenceTermination args(std::vector< std::vector< LabelType > > &) const
Definition: lpgurobi.hxx:156
Runtime-flexible multi-dimensional array.
Definition: marray.hxx:52
virtual std::string name() const
Definition: lpgurobi.hxx:149
GraphicalModelType::LabelType LabelType
Definition: inference.hxx:39
Minimization as a unary accumulation.
Definition: minimizer.hxx:12
OpenGM runtime error.
Definition: opengm.hxx:100
size_t lpFactorVi(const IndexType factorIndex, const size_t labelingIndex) const
InferenceTermination
Definition: inference.hxx:24
GraphicalModelType::IndependentFactorType IndependentFactorType
Definition: inference.hxx:44
virtual InferenceTermination arg(std::vector< LabelType > &, const size_t=1) const
output a solution
Definition: lpgurobi.hxx:665