OpenGM  2.3.x
Discrete Graphical Model Library
lpcplex.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_LP_CPLEX_HXX
3 #define OPENGM_LP_CPLEX_HXX
4 
5 #include <vector>
6 #include <string>
7 #include <iostream>
8 #include <fstream>
9 #include <stdexcept>
10 #include <typeinfo>
11 
12 #include <ilcplex/ilocplex.h>
13 
15 #include "opengm/opengm.hxx"
22 
23 namespace opengm {
24 
37 template<class GM, class ACC>
38 class LPCplex : public Inference<GM, ACC>, public LPDef {
39 public:
40  typedef ACC AccumulationType;
41  typedef ACC AccumulatorType;
42  typedef GM GraphicalModelType;
47 
48  template<class _GM>
49  struct RebindGm{
51  };
52 
53  template<class _GM,class _ACC>
56  };
57 
58 
59 // enum LP_SOLVER {LP_SOLVER_AUTO, LP_SOLVER_PRIMAL_SIMPLEX, LP_SOLVER_DUAL_SIMPLEX, LP_SOLVER_NETWORK_SIMPLEX, LP_SOLVER_BARRIER, LP_SOLVER_SIFTING, LP_SOLVER_CONCURRENT};
60 // enum LP_PRESOLVE{LP_PRESOLVE_AUTO, LP_PRESOLVE_OFF, LP_PRESOLVE_CONSEVATIVE, LP_PRESOLVE_AGRESSIVE};
61 // enum MIP_EMPHASIS{MIP_EMPHASIS_BALANCED, MIP_EMPHASIS_FEASIBILITY, MIP_EMPHASIS_OPTIMALITY, MIP_EMPHASIS_BESTBOUND, MIP_EMPHASIS_HIDDENFEAS};
62 
63  class Parameter {
64  public:
65  bool integerConstraint_;// ILP=true, 1order-LP=false
66  int numberOfThreads_; // number of threads (0=autosect)
67  bool verbose_; // switch on/off verbode mode
68  double cutUp_; // upper cutoff
69  double epOpt_; // Optimality tolerance
70  double epMrk_; // Markowitz tolerance
71  double epRHS_; // Feasibility Tolerance
72  double epInt_; // amount by which an integer variable can differ from an integer
73  double epAGap_; // Absolute MIP gap tolerance
74  double epGap_; // Relative MIP gap tolerance
75  double workMem_; // maximal ammount of memory in MB used for workspace
76  double treeMemoryLimit_; // maximal ammount of memory in MB used for treee
77  double timeLimit_; // maximal time in seconds the solver has
79  //int coverCutLevel_;
80  //int disjunctiverCutLevel_;
81  //int cliqueCutLevel_;
82  //int MIRCutLevel_;
87  MIP_CUT cutLevel_; // Determines whether or not to cuts for the problem and how aggressively (will be overruled by specific ones).
88  MIP_CUT cliqueCutLevel_; // Determines whether or not to generate clique cuts for the problem and how aggressively.
89  MIP_CUT coverCutLevel_; // Determines whether or not to generate cover cuts for the problem and how aggressively.
90  MIP_CUT gubCutLevel_; // Determines whether or not to generate generalized upper bound (GUB) cuts for the problem and how aggressively.
91  MIP_CUT mirCutLevel_; // Determines whether or not mixed integer rounding (MIR) cuts should be generated for the problem and how aggressively.
92  MIP_CUT iboundCutLevel_; // Determines whether or not to generate implied bound cuts for the problem and how aggressively.
93  MIP_CUT flowcoverCutLevel_; //Determines whether or not to generate flow cover cuts for the problem and how aggressively.
94  MIP_CUT flowpathCutLevel_; //Determines whether or not to generate flow path cuts for the problem and how aggressively.
95  MIP_CUT disjunctCutLevel_; // Determines whether or not to generate disjunctive cuts for the problem and how aggressively.
96  MIP_CUT gomoryCutLevel_; // Determines whether or not to generate gomory fractional cuts for the problem and how aggressively.
97 
98  template<class P>
100  const P & p
101  ):
102 
103  integerConstraint_(p.integerConstraint_),
104  numberOfThreads_(p.numberOfThreads_),
105  verbose_(p.verbose_),
106  cutUp_(p.cutUp_),
107  epOpt_(p.epOpt_),
108  epMrk_(p.epMrk_),
109  epRHS_(p.epRHS_),
110  epInt_(p.epInt_),
111  epAGap_(p.epAGap_),
112  epGap_(p.epGap_),
113  workMem_(p.workMem_),
114  treeMemoryLimit_(p.treeMemoryLimit_),
115  timeLimit_(p.timeLimit_),
116  probeingLevel_(p.probeingLevel_),
117  rootAlg_(p.rootAlg_),
118  nodeAlg_(p.nodeAlg_),
119  presolve_(p.presolve_),
120  mipEmphasis_(p.mipEmphasis_),
121  cutLevel_(p.cutLevel_),
122  cliqueCutLevel_(p.cliqueCutLevel_),
123  coverCutLevel_(p.coverCutLevel_),
124  gubCutLevel_(p.gubCutLevel_),
125  mirCutLevel_(p.mirCutLevel_),
126  iboundCutLevel_(p.iboundCutLevel_),
127  flowcoverCutLevel_(p.flowcoverCutLevel_),
128  flowpathCutLevel_(p.flowpathCutLevel_),
129  disjunctCutLevel_(p.disjunctCutLevel_),
130  gomoryCutLevel_(p.gomoryCutLevel_)
131  {
132 
133  }
134 
138  Parameter
139  (
140  int numberOfThreads = 0
141  )
142  : numberOfThreads_(numberOfThreads),
143  //integerConstraint_(false),
144  verbose_(false),
145  workMem_(128.0),
146  treeMemoryLimit_(1e+75),
147  timeLimit_(1e+75),
148  probeingLevel_(0),
149  // coverCutLevel_(0),
150  //disjunctiverCutLevel_(0),
151  //cliqueCutLevel_(0),
152  //MIRCutLevel_(0),
153  rootAlg_(LP_SOLVER_AUTO),
154  nodeAlg_(LP_SOLVER_AUTO),
155  presolve_(LP_PRESOLVE_AUTO),
156  mipEmphasis_(MIP_EMPHASIS_BALANCED),
157  cutLevel_(MIP_CUT_AUTO),
158  cliqueCutLevel_(MIP_CUT_AUTO),
159  coverCutLevel_(MIP_CUT_AUTO),
160  gubCutLevel_(MIP_CUT_AUTO),
161  mirCutLevel_(MIP_CUT_AUTO),
162  iboundCutLevel_(MIP_CUT_AUTO),
163  flowcoverCutLevel_(MIP_CUT_AUTO),
164  flowpathCutLevel_(MIP_CUT_AUTO),
165  disjunctCutLevel_(MIP_CUT_AUTO),
166  gomoryCutLevel_(MIP_CUT_AUTO)
167  {
168  numberOfThreads_ = numberOfThreads;
169  integerConstraint_ = false;
170  LPDef lpdef;
171  cutUp_ = lpdef.default_cutUp_;
172  epOpt_ = lpdef.default_epOpt_;
173  epMrk_ = lpdef.default_epMrk_;
174  epRHS_ = lpdef.default_epRHS_;
175  epInt_ = lpdef.default_epInt_;
176  epAGap_= lpdef.default_epAGap_;
177  epGap_ = lpdef.default_epGap_;
178  };
179 
181  switch(cl){
182  case MIP_CUT_AUTO:
183  return 0;
184  case MIP_CUT_OFF:
185  return -1;
186  case MIP_CUT_ON:
187  return 1;
188  case MIP_CUT_AGGRESSIVE:
189  return 2;
191  return 3;
192  }
193  return 0;
194  }
195  };
196 
197  LPCplex(const GraphicalModelType&, const Parameter& = Parameter());
198  ~LPCplex();
199  virtual std::string name() const
200  { return "LPCplex"; }
201  const GraphicalModelType& graphicalModel() const;
202  virtual InferenceTermination infer();
203  template<class VisitorType>
204  InferenceTermination infer(VisitorType&);
205  virtual InferenceTermination arg(std::vector<LabelType>&, const size_t = 1) const;
206  virtual InferenceTermination args(std::vector<std::vector<LabelType> >&) const
207  { return UNKNOWN; };
208  void variable(const size_t, IndependentFactorType& out) const;
209  void factorVariable(const size_t, IndependentFactorType& out) const;
210  typename GM::ValueType bound() const;
211  typename GM::ValueType value() const;
212  void setStartingPoint( typename std::vector<LabelType>::const_iterator );
213 
214 
215  size_t lpNodeVi(const IndexType variableIndex,const LabelType label)const;
216  size_t lpFactorVi(const IndexType factorIndex,const size_t labelingIndex)const;
217  template<class LABELING_ITERATOR>
218  size_t lpFactorVi(const IndexType factorIndex,LABELING_ITERATOR labelingBegin,LABELING_ITERATOR labelingEnd)const;
219  template<class LPVariableIndexIterator, class CoefficientIterator>
220  void addConstraint(LPVariableIndexIterator, LPVariableIndexIterator, CoefficientIterator,const ValueType&, const ValueType&, const char * name=0);
221 
222 private:
223  const GraphicalModelType& gm_;
224  Parameter parameter_;
225  std::vector<size_t> idNodesBegin_;
226  std::vector<size_t> idFactorsBegin_;
227  std::vector<std::vector<size_t> > unaryFactors_;
228  bool inferenceStarted_;
229 
230  IloEnv env_;
231  IloModel model_;
232  IloNumVarArray x_;
233  IloRangeArray c_;
234  IloObjective obj_;
235  IloNumArray sol_;
236  IloCplex cplex_;
237  ValueType constValue_;
238 };
239 
240 template<class GM, class ACC>
242 (
243  const GraphicalModelType& gm,
244  const Parameter& para
245 )
246 : gm_(gm), inferenceStarted_(false)
247 {
248  if(typeid(OperatorType) != typeid(opengm::Adder)) {
249  throw RuntimeError("This implementation does only supports Min-Plus-Semiring and Max-Plus-Semiring.");
250  }
251  parameter_ = para;
252  idNodesBegin_.resize(gm_.numberOfVariables());
253  unaryFactors_.resize(gm_.numberOfVariables());
254  idFactorsBegin_.resize(gm_.numberOfFactors());
255 
256  // temporal variables
257  IloInt numberOfElements = 0;
258  IloInt numberOfVariableElements = 0;
259  IloInt numberOfFactorElements = 0;
260  // enumerate variables
261  size_t idCounter = 0;
262  for(size_t node = 0; node < gm_.numberOfVariables(); ++node) {
263  numberOfVariableElements += gm_.numberOfLabels(node);
264  idNodesBegin_[node] = idCounter;
265  idCounter += gm_.numberOfLabels(node);
266  }
267  // enumerate factors
268  constValue_ = 0;
269  for(size_t f = 0; f < gm_.numberOfFactors(); ++f) {
270  if(gm_[f].numberOfVariables() == 0) {
271  LabelType l = 0;
272  constValue_ += gm_[f](&l);
273  }
274  else if(gm_[f].numberOfVariables() == 1) {
275  size_t node = gm_[f].variableIndex(0);
276  unaryFactors_[node].push_back(f);
277  idFactorsBegin_[f] = idNodesBegin_[node];
278  }
279  else {
280  idFactorsBegin_[f] = idCounter;
281  idCounter += gm_[f].size();
282  numberOfFactorElements += gm_[f].size();
283  }
284  }
285  numberOfElements = numberOfVariableElements + numberOfFactorElements;
286  // build LP
287  model_ = IloModel(env_);
288  x_ = IloNumVarArray(env_);
289  c_ = IloRangeArray(env_);
290  sol_ = IloNumArray(env_);
291 
292  if(typeid(ACC) == typeid(opengm::Minimizer)) {
293  obj_ = IloMinimize(env_);
294  } else if(typeid(ACC) == typeid(opengm::Maximizer)){
295  obj_ = IloMaximize(env_);
296  } else {
297  throw RuntimeError("This implementation does only support Minimizer or Maximizer accumulators");
298  }
299  // set variables and objective
300  if(parameter_.integerConstraint_) {
301  x_.add(IloNumVarArray(env_, numberOfVariableElements, 0, 1, ILOBOOL));
302  }
303  else {
304  x_.add(IloNumVarArray(env_, numberOfVariableElements, 0, 1));
305  }
306  x_.add(IloNumVarArray(env_, numberOfFactorElements, 0, 1));
307  IloNumArray obj(env_, numberOfElements);
308 
309  for(size_t node = 0; node < gm_.numberOfVariables(); ++node) {
310  for(size_t i = 0; i < gm_.numberOfLabels(node); ++i) {
311  ValueType t = 0;
312  for(size_t n=0; n<unaryFactors_[node].size();++n) {
313  t += gm_[unaryFactors_[node][n]](&i);
314  }
315  OPENGM_ASSERT_OP(idNodesBegin_[node]+i,<,numberOfElements);
316  obj[idNodesBegin_[node]+i] = t;
317  }
318  }
319  for(size_t f = 0; f < gm_.numberOfFactors(); ++f) {
320  if(gm_[f].numberOfVariables() == 2) {
321  size_t index[2];
322  size_t counter = idFactorsBegin_[f];
323  for(index[1]=0; index[1]<gm_[f].numberOfLabels(1);++index[1])
324  for(index[0]=0; index[0]<gm_[f].numberOfLabels(0);++index[0])
325  obj[counter++] = gm_[f](index);
326  }
327  else if(gm_[f].numberOfVariables() == 3) {
328  size_t index[3];
329  size_t counter = idFactorsBegin_[f] ;
330  for(index[2]=0; index[2]<gm_[f].numberOfLabels(2);++index[2])
331  for(index[1]=0; index[1]<gm_[f].numberOfLabels(1);++index[1])
332  for(index[0]=0; index[0]<gm_[f].numberOfLabels(0);++index[0])
333  obj[counter++] = gm_[f](index);
334  }
335  else if(gm_[f].numberOfVariables() == 4) {
336  size_t index[4];
337  size_t counter = idFactorsBegin_[f];
338  for(index[3]=0; index[3]<gm_[f].numberOfLabels(3);++index[3])
339  for(index[2]=0; index[2]<gm_[f].numberOfLabels(2);++index[2])
340  for(index[1]=0; index[1]<gm_[f].numberOfLabels(1);++index[1])
341  for(index[0]=0; index[0]<gm_[f].numberOfLabels(0);++index[0])
342  obj[counter++] = gm_[f](index);
343  }
344  else if(gm_[f].numberOfVariables() > 4) {
345  size_t counter = idFactorsBegin_[f];
346  std::vector<size_t> coordinate(gm_[f].numberOfVariables());
347  marray::Marray<bool> temp(gm_[f].shapeBegin(), gm_[f].shapeEnd());
348  for(marray::Marray<bool>::iterator mit = temp.begin(); mit != temp.end(); ++mit) {
349  mit.coordinate(coordinate.begin());
350  obj[counter++] = gm_[f](coordinate.begin());
351  }
352  }
353  }
354  obj_.setLinearCoefs(x_, obj);
355  // set constraints
356  size_t constraintCounter = 0;
357  // \sum_i \mu_i = 1
358  for(size_t node = 0; node < gm_.numberOfVariables(); ++node) {
359  c_.add(IloRange(env_, 1, 1));
360  for(size_t i = 0; i < gm_.numberOfLabels(node); ++i) {
361  c_[constraintCounter].setLinearCoef(x_[idNodesBegin_[node]+i], 1);
362  }
363  ++constraintCounter;
364  }
365  // \sum_i \mu_{f;i_1,...,i_n} - \mu{b;j}= 0
366  for(size_t f = 0; f < gm_.numberOfFactors(); ++f) {
367  if(gm_[f].numberOfVariables() > 1) {
368  marray::Marray<size_t> temp(gm_[f].shapeBegin(), gm_[f].shapeEnd());
369  size_t counter = idFactorsBegin_[f];
370  for(marray::Marray<size_t>::iterator mit = temp.begin(); mit != temp.end(); ++mit) {
371  *mit = counter++;
372  }
373  for(size_t n = 0; n < gm_[f].numberOfVariables(); ++n) {
374  size_t node = gm_[f].variableIndex(n);
375  for(size_t i = 0; i < gm_.numberOfLabels(node); ++i) {
376  c_.add(IloRange(env_, 0, 0));
377  c_[constraintCounter].setLinearCoef(x_[idNodesBegin_[node]+i], -1);
378  marray::View<size_t> view = temp.boundView(n, i);
379  for(marray::View<size_t>::iterator vit = view.begin(); vit != view.end(); ++vit) {
380  c_[constraintCounter].setLinearCoef(x_[*vit], 1);
381  }
382  ++constraintCounter;
383  }
384  }
385  }
386  }
387  model_.add(obj_);
388  model_.add(c_);
389  // initialize solver
390  try {
391  cplex_ = IloCplex(model_);
392  }
393  catch(IloCplex::Exception& e) {
394  throw std::runtime_error("CPLEX exception");
395  }
396 }
397 
398 template <class GM, class ACC>
401  EmptyVisitorType v;
402  return infer(v);
403 }
404 
405 template<class GM, class ACC>
406 template<class VisitorType>
409 (
410  VisitorType& visitor
411 ) {
412  visitor.begin(*this);
413  inferenceStarted_ = true;
414  try {
415  // Root Algorithm
416  switch(parameter_.rootAlg_) {
417  case LP_SOLVER_AUTO:
418  cplex_.setParam(IloCplex::RootAlg, 0);
419  break;
421  cplex_.setParam(IloCplex::RootAlg, 1);
422  break;
424  cplex_.setParam(IloCplex::RootAlg, 2);
425  break;
427  cplex_.setParam(IloCplex::RootAlg, 3);
428  break;
429  case LP_SOLVER_BARRIER:
430  cplex_.setParam(IloCplex::RootAlg, 4);
431  break;
432  case LP_SOLVER_SIFTING:
433  cplex_.setParam(IloCplex::RootAlg, 5);
434  break;
436  cplex_.setParam(IloCplex::RootAlg, 6);
437  break;
438  }
439 
440  // Node Algorithm
441  switch(parameter_.nodeAlg_) {
442  case LP_SOLVER_AUTO:
443  cplex_.setParam(IloCplex::NodeAlg, 0);
444  break;
446  cplex_.setParam(IloCplex::NodeAlg, 1);
447  break;
449  cplex_.setParam(IloCplex::NodeAlg, 2);
450  break;
452  cplex_.setParam(IloCplex::NodeAlg, 3);
453  break;
454  case LP_SOLVER_BARRIER:
455  cplex_.setParam(IloCplex::NodeAlg, 4);
456  break;
457  case LP_SOLVER_SIFTING:
458  cplex_.setParam(IloCplex::NodeAlg, 5);
459  break;
461  cplex_.setParam(IloCplex::NodeAlg, 6);
462  break;
463  }
464 
465  // presolve
466  switch(parameter_.presolve_) {
467  case LP_PRESOLVE_AUTO:
468  cplex_.setParam(IloCplex::PreInd, CPX_ON);
469  cplex_.setParam(IloCplex::RelaxPreInd, -1);
470  break;
471  case LP_PRESOLVE_OFF:
472  cplex_.setParam(IloCplex::PreInd, CPX_OFF);
473  cplex_.setParam(IloCplex::RelaxPreInd, 0);
474  break;
476  cplex_.setParam(IloCplex::PreInd, CPX_ON);
477  cplex_.setParam(IloCplex::RelaxPreInd, -1);
478  break;
480  cplex_.setParam(IloCplex::PreInd, CPX_ON);
481  cplex_.setParam(IloCplex::RelaxPreInd, 1);
482  break;
483  }
484 
485  // MIP EMPHASIS
486  switch(parameter_.mipEmphasis_) {
488  cplex_.setParam(IloCplex::MIPEmphasis, 0);
489  break;
491  cplex_.setParam(IloCplex::MIPEmphasis, 1);
492  break;
494  cplex_.setParam(IloCplex::MIPEmphasis, 2);
495  break;
497  cplex_.setParam(IloCplex::MIPEmphasis, 3);
498  break;
500  cplex_.setParam(IloCplex::MIPEmphasis, 4);
501  break;
502  }
503 
504  // verbose options
505  if(parameter_.verbose_ == false) {
506  cplex_.setParam(IloCplex::MIPDisplay, 0);
507  cplex_.setParam(IloCplex::BarDisplay, 0);
508  cplex_.setParam(IloCplex::SimDisplay, 0);
509  cplex_.setParam(IloCplex::NetDisplay, 0);
510  cplex_.setParam(IloCplex::SiftDisplay, 0);
511  }
512 
513  // tolarance settings
514  cplex_.setParam(IloCplex::EpOpt, parameter_.epOpt_); // Optimality Tolerance
515  cplex_.setParam(IloCplex::EpMrk, parameter_.epMrk_); // Markowitz tolerance
516  cplex_.setParam(IloCplex::EpRHS, parameter_.epRHS_); // Feasibility Tolerance
517  cplex_.setParam(IloCplex::EpInt, parameter_.epInt_); // amount by which an integer variable can differ from an integer
518  cplex_.setParam(IloCplex::EpAGap, parameter_.epAGap_); // Absolute MIP gap tolerance
519  cplex_.setParam(IloCplex::EpGap, parameter_.epGap_); // Relative MIP gap tolerance
520 
521  // set hints
522  cplex_.setParam(IloCplex::CutUp, parameter_.cutUp_);
523 
524  // memory setting
525  cplex_.setParam(IloCplex::WorkMem, parameter_.workMem_);
526  cplex_.setParam(IloCplex::ClockType,2);//wall-clock-time=2 cpu-time=1
527  cplex_.setParam(IloCplex::TreLim,parameter_.treeMemoryLimit_);
528  cplex_.setParam(IloCplex::MemoryEmphasis, 1);
529 
530  // time limit
531  cplex_.setParam(IloCplex::TiLim, parameter_.timeLimit_);
532 
533  // multo-threading options
534  cplex_.setParam(IloCplex::Threads, parameter_.numberOfThreads_);
535 
536  // Tuning
537  cplex_.setParam(IloCplex::Probe, parameter_.probeingLevel_);
538  if(parameter_.cutLevel_ != MIP_CUT_DEFAULT){
539  int cl = parameter_.getCutLevel(parameter_.cutLevel_);
540  cplex_.setParam(IloCplex::Covers, cl);
541  cplex_.setParam(IloCplex::Cliques, cl);
542  cplex_.setParam(IloCplex::DisjCuts, cl);
543  cplex_.setParam(IloCplex::Cliques, cl);
544  cplex_.setParam(IloCplex::MIRCuts, cl);
545  cplex_.setParam(IloCplex::GUBCovers, cl);
546  cplex_.setParam(IloCplex::FlowCovers, cl);
547  cplex_.setParam(IloCplex::FlowPaths, cl);
548  cplex_.setParam(IloCplex::ImplBd, cl);
549  cplex_.setParam(IloCplex::FracCuts, cl);
550  }
551 
552  // cplex_.setParam(IloCplex::Covers, parameter_.coverCutLevel_);
553  //cplex_.setParam(IloCplex::DisjCuts, parameter_.disjunctiverCutLevel_);
554  //cplex_.setParam(IloCplex::Cliques, parameter_.cliqueCutLevel_);
555  //cplex_.setParam(IloCplex::MIRCuts, parameter_.MIRCutLevel_);
556 
557  // solve problem
558 
559  if(!cplex_.solve()) {
560  std::cout << "failed to optimize. " <<cplex_.getStatus() << std::endl;
561  inferenceStarted_ = 0;
562  return UNKNOWN;
563  }
564  cplex_.getValues(sol_, x_);
565  }
566  catch(IloCplex::Exception e) {
567  std::cout << "caught CPLEX exception: " << e << std::endl;
568  return UNKNOWN;
569  }
570  visitor.end(*this);
571  return NORMAL;
572 }
573 
574 template <class GM, class ACC>
576  env_.end();
577 }
578 
579 template <class GM, class ACC>
582 (
583  std::vector<typename LPCplex<GM, ACC>::LabelType>& x,
584  const size_t N
585 ) const {
586  x.resize(gm_.numberOfVariables());
587  if(inferenceStarted_) {
588  for(size_t node = 0; node < gm_.numberOfVariables(); ++node) {
589  ValueType value = sol_[idNodesBegin_[node]];
590  size_t state = 0;
591  for(size_t i = 1; i < gm_.numberOfLabels(node); ++i) {
592  if(sol_[idNodesBegin_[node]+i] > value) {
593  value = sol_[idNodesBegin_[node]+i];
594  state = i;
595  }
596  }
597  x[node] = state;
598  }
599  return NORMAL;
600  } else {
601  for(size_t node = 0; node < gm_.numberOfVariables(); ++node) {
602  x[node] = 0;
603  }
604  return UNKNOWN;
605  }
606 
607 }
608 
609 template <class GM, class ACC>
611 (
612  const size_t nodeId,
614 ) const {
615  size_t var[] = {nodeId};
616  size_t shape[] = {gm_.numberOfLabels(nodeId)};
617  out.assign(var, var + 1, shape, shape + 1);
618  for(size_t i = 0; i < gm_.numberOfLabels(nodeId); ++i) {
619  out(i) = sol_[idNodesBegin_[nodeId]+i];
620  }
621  //return UNKNOWN;
622 }
623 
624 template <class GM, class ACC>
626 (
627  const size_t factorId,
629 ) const {
630  std::vector<size_t> var(gm_[factorId].numberOfVariables());
631  std::vector<size_t> shape(gm_[factorId].numberOfVariables());
632  for(size_t i = 0; i < gm_[factorId].numberOfVariables(); ++i) {
633  var[i] = gm_[factorId].variableIndex(i);
634  shape[i] = gm_[factorId].shape(i);
635  }
636  out.assign(var.begin(), var.end(), shape.begin(), shape.end());
637  if(gm_[factorId].numberOfVariables() == 1) {
638  size_t nodeId = gm_[factorId].variableIndex(0);
639  marginal(nodeId, out);
640  }
641  else {
642  size_t c = 0;
643  for(size_t n = idFactorsBegin_[factorId]; n<idFactorsBegin_[factorId]+gm_[factorId].size(); ++n) {
644  out(c++) = sol_[n];
645  }
646  }
647  //return UNKNOWN;
648 }
649 
650 template<class GM, class ACC>
651 inline void
653  typename std::vector<typename LPCplex<GM, ACC>::LabelType>::const_iterator begin
654 ) {
655  IloNumVarArray vars(env_);
656  IloNumArray values(env_);
657  for(IndexType var=0; var<gm_.numberOfVariables(); ++var){
658  const IloNumVar lpvar = x_[lpNodeVi(var,*(begin+var))];
659  vars.add(lpvar);
660  values.add(1);
661  }
662  cplex_.addMIPStart(vars, values);
663 }
664 
665 
666 
667 template<class GM, class ACC>
668 inline const typename LPCplex<GM, ACC>::GraphicalModelType&
670 {
671  return gm_;
672 }
673 
674 template<class GM, class ACC>
675 typename GM::ValueType LPCplex<GM, ACC>::value() const {
676  std::vector<LabelType> states;
677  arg(states);
678  return gm_.evaluate(states);
679 }
680 
681 template<class GM, class ACC>
682 typename GM::ValueType LPCplex<GM, ACC>::bound() const {
683  if(inferenceStarted_) {
684  if(parameter_.integerConstraint_) {
685  return cplex_.getBestObjValue()+constValue_;
686  }
687  else{
688  return cplex_.getObjValue()+constValue_;
689  }
690  }
691  else{
692  return ACC::template ineutral<ValueType>();
693  }
694 }
695 
696 
697 template <class GM, class ACC>
698 inline size_t
700 (
701  const typename LPCplex<GM, ACC>::IndexType variableIndex,
702  const typename LPCplex<GM, ACC>::LabelType label
703 )const{
704  OPENGM_ASSERT(variableIndex<gm_.numberOfVariables());
705  OPENGM_ASSERT(label<gm_.numberOfLabels(variableIndex));
706  return idNodesBegin_[variableIndex]+label;
707 }
708 
709 
710 template <class GM, class ACC>
711 inline size_t
713 (
714  const typename LPCplex<GM, ACC>::IndexType factorIndex,
715  const size_t labelingIndex
716 )const{
717  OPENGM_ASSERT(factorIndex<gm_.numberOfFactors());
718  OPENGM_ASSERT(labelingIndex<gm_[factorIndex].size());
719  return idFactorsBegin_[factorIndex]+labelingIndex;
720 }
721 
722 
723 template <class GM, class ACC>
724 template<class LABELING_ITERATOR>
725 inline size_t
727 (
728  const typename LPCplex<GM, ACC>::IndexType factorIndex,
729  LABELING_ITERATOR labelingBegin,
730  LABELING_ITERATOR labelingEnd
731 )const{
732  OPENGM_ASSERT(factorIndex<gm_.numberOfFactors());
733  OPENGM_ASSERT(std::distance(labelingBegin,labelingEnd)==gm_[factorIndex].numberOfVariables());
734  const size_t numVar=gm_[factorIndex].numberOfVariables();
735  size_t labelingIndex=labelingBegin[0];
736  size_t strides=gm_[factorIndex].numberOfLabels(0);
737  for(size_t vi=1;vi<numVar;++vi){
738  OPENGM_ASSERT(labelingBegin[vi]<gm_[factorIndex].numberOfLabels(vi));
739  labelingIndex+=strides*labelingBegin[vi];
740  strides*=gm_[factorIndex].numberOfLabels(vi);
741  }
742  return idFactorsBegin_[factorIndex]+labelingIndex;
743 }
744 
745 
746 
747 
759 template<class GM, class ACC>
760 template<class LPVariableIndexIterator, class CoefficientIterator>
762  LPVariableIndexIterator viBegin,
763  LPVariableIndexIterator viEnd,
764  CoefficientIterator coefficient,
765  const ValueType& lowerBound,
766  const ValueType& upperBound,
767  const char * name
768 ) {
769  IloRange constraint(env_, lowerBound, upperBound, name);
770  while(viBegin != viEnd) {
771  constraint.setLinearCoef(x_[*viBegin], *coefficient);
772  ++viBegin;
773  ++coefficient;
774  }
775  model_.add(constraint);
776  // adding constraints does not require a re-initialization of the
777  // object cplex_. cplex_ is initialized in the constructor.
778 }
779 
780 } // end namespace opengm
781 
782 #endif
void setStartingPoint(typename std::vector< LabelType >::const_iterator)
set initial labeling
Definition: lpcplex.hxx:652
The OpenGM namespace.
Definition: config.hxx:43
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
visitors::VerboseVisitor< LPCplex< GM, ACC > > VerboseVisitorType
Definition: lpcplex.hxx:44
MIP_EMPHASIS mipEmphasis_
Definition: lpcplex.hxx:86
iterator end()
Get the end-iterator.
Definition: marray.hxx:2727
static const double default_cutUp_
Definition: lpdef.hxx:14
static const double default_epInt_
Definition: lpdef.hxx:18
LPCplex< _GM, _ACC > type
Definition: lpcplex.hxx:55
int getCutLevel(MIP_CUT cl)
Definition: lpcplex.hxx:180
Array-Interface to an interval of memory.
Definition: marray.hxx:44
#define OPENGM_ASSERT(expression)
Definition: opengm.hxx:77
const GraphicalModelType & graphicalModel() const
Definition: lpcplex.hxx:669
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
void variable(const size_t, IndependentFactorType &out) const
Definition: lpcplex.hxx:611
visitors::TimingVisitor< LPCplex< GM, ACC > > TimingVisitorType
Definition: lpcplex.hxx:46
iterator begin()
Get an iterator to the beginning.
Definition: marray.hxx:2714
virtual InferenceTermination arg(std::vector< LabelType > &, const size_t=1) const
output a solution
Definition: lpcplex.hxx:582
LPCplex(const GraphicalModelType &, const Parameter &=Parameter())
Definition: lpcplex.hxx:242
GM GraphicalModelType
Definition: lpcplex.hxx:42
static const double default_epMrk_
Definition: lpdef.hxx:16
GraphicalModelType::IndexType IndexType
Definition: inference.hxx:49
static const double default_epGap_
Definition: lpdef.hxx:20
#define OPENGM_ASSERT_OP(a, op, b)
runtime assertion
Definition: opengm.hxx:53
size_t lpNodeVi(const IndexType variableIndex, const LabelType label) const
Definition: lpcplex.hxx:700
Optimization by Linear Programming (LP) or Integer LP using IBM ILOG CPLEX http://www.ilog.com/products/cplex/.
Definition: lpcplex.hxx:38
GraphicalModelType::ValueType ValueType
Definition: inference.hxx:50
visitors::EmptyVisitor< LPCplex< GM, ACC > > EmptyVisitorType
Definition: lpcplex.hxx:45
Inference algorithm interface.
Definition: inference.hxx:43
GM::ValueType value() const
return the solution (value)
Definition: lpcplex.hxx:675
virtual InferenceTermination marginal(const size_t, IndependentFactorType &) const
output a solution for a marginal for a specific variable
Definition: inference.hxx:114
GM::ValueType bound() const
return a bound on the solution
Definition: lpcplex.hxx:682
Runtime-flexible multi-dimensional array.
Definition: marray.hxx:52
LPCplex< _GM, ACC > type
Definition: lpcplex.hxx:50
GraphicalModelType::LabelType LabelType
Definition: inference.hxx:48
virtual std::string name() const
Definition: lpcplex.hxx:199
Minimization as a unary accumulation.
Definition: minimizer.hxx:12
Maximization as a unary accumulation.
Definition: maximizer.hxx:10
ACC AccumulatorType
Definition: lpcplex.hxx:41
virtual InferenceTermination args(std::vector< std::vector< LabelType > > &) const
Definition: lpcplex.hxx:206
void factorVariable(const size_t, IndependentFactorType &out) const
Definition: lpcplex.hxx:626
ACC AccumulationType
Definition: lpcplex.hxx:40
virtual InferenceTermination infer()
Definition: lpcplex.hxx:400
OpenGM runtime error.
Definition: opengm.hxx:100
size_t lpFactorVi(const IndexType factorIndex, const size_t labelingIndex) const
void addConstraint(LPVariableIndexIterator, LPVariableIndexIterator, CoefficientIterator, const ValueType &, const ValueType &, const char *name=0)
add constraint
Definition: lpcplex.hxx:761
InferenceTermination
Definition: inference.hxx:24
GraphicalModelType::IndependentFactorType IndependentFactorType
Definition: inference.hxx:53