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