OpenGM  2.3.x
Discrete Graphical Model Library
self_fusion.hxx
Go to the documentation of this file.
1 #ifndef OPENGM_SELF_FUSION_HXX
2 #define OPENGM_SELF_FUSION_HXX
3 
4 #include <vector>
5 #include <string>
6 #include <iostream>
7 
8 #include "opengm/opengm.hxx"
11 
12 
13 // Fusion Move Solver
15 
17 
18 
19 #ifdef WITH_CPLEX
21 #endif
22 #ifdef WITH_QPBO
23 #include "QPBO.h"
26 #endif
27 
28 // fusion move model generator
30 
31 
32 namespace opengm {
33 
34 template<class INF,class SELF_FUSION,class SELF_FUSION_VISITOR>
36 
37  typedef typename INF::AccumulationType AccumulationType;
38  typedef typename INF::GraphicalModelType GraphicalModelType;
40 
42 
44  // sub-inf-lf
46 
47 
48  #ifdef WITH_QPBO
49  typedef kolmogorov::qpbo::QPBO<double> QpboSubInf;
50  typedef opengm::external::QPBO<SubGmType> QPBOSubInf;
52  #endif
53  #ifdef WITH_CPLEX
55  #endif
56 
57  typedef SELF_FUSION SelfFusionType;
58  typedef SELF_FUSION_VISITOR SelfFusionVisitorType;
59 
61  SelfFusionType & selfFusion,
62  SelfFusionVisitorType & selfFusionVisitor,
63  std::vector<LabelType> & argBest,
64  ValueType & value,
65  ValueType & bound,
66  size_t fuseNth=1
67  )
68  : gm_(selfFusion.graphicalModel()),
69  selfFusion_(selfFusion),
70  selfFusionVisitor_(selfFusionVisitor),
71  fusionMover_(selfFusion.graphicalModel()),
72  iteration_(0),
73  fuseNth_(fuseNth),
74  value_(value),
75  bound_(bound),
76  argFromInf_(selfFusion.graphicalModel().numberOfVariables()),
77  argBest_(argBest),
78  argOut_(selfFusion.graphicalModel().numberOfVariables()),
79  returnFlag_(visitors::VisitorReturnFlag::ContinueInf),
81  {
82 
83  }
84 
85  void begin(
86  INF & inf
87  ){
89  selfFusionVisitor_.log("infValue",inf.value());
90  }
91  void end(
92  INF & inf
93  ){
94  }
95 
96  size_t operator()(
97  INF & inf
98  ){
99  return this->fuseVisit(inf);
100  }
101 
102 
103 
104 
105 
106 
107  size_t fuseVisit(INF & inference){
108 
109  const typename SelfFusionType::Parameter & param = selfFusion_.parameter();
110 
111  ValueType oldValue = value_;
112 
113  if(iteration_==0 ){
114  inference.arg(argBest_);
115  ValueType value = inference.value();
116  if(AccumulationType::bop(value,value_)){
117  std::copy(argOut_.begin(),argOut_.end(),argBest_.begin());
118  value_ = value;
119  }
121  selfFusionVisitor_.log("infValue",value);
122  }
123  else if(iteration_%fuseNth_==0){
124 
125  inference.arg(argFromInf_);
126 
127  const ValueType infValue = inference.value();
128  bound_ = inference.bound();
129  lastInfValue_=infValue;
130  IndexType nLocalVar=0;
131  for(IndexType vi=0;vi<gm_.numberOfVariables();++vi){
132  if(argBest_[vi]!=argFromInf_[vi]){
133  ++nLocalVar;
134  }
135  }
136 
137 
138  // setup which to labels should be fused and declare
139  // output label vector
141  // get the number of fusion-move variables
142  const IndexType nFuseMoveVar=fusionMover_.numberOfFusionMoveVariable();
143 
144  if(nFuseMoveVar>0){
145 
146 
147  if(param.fusionSolver_==SelfFusionType::LazyFlipperFusion){
148  //std::cout<<"fuse with lazy flipper "<<param.maxSubgraphSize_<<"\n";
149  value_ = fusionMover_. template fuse<LazyFlipperSubInf> (
150  typename LazyFlipperSubInf::Parameter(param.maxSubgraphSize_),true
151  );
152 
153  }
154  #ifdef WITH_CPLEX
155  else if(param.fusionSolver_==SelfFusionType::CplexFusion ){
156 #ifdef WITH_QPBO
157  // NON reduced inference
158  if(param.reducedInf_==false){
159 #endif
160  //std::cout <<"ILP"<<std::endl;
161  typename CplexSubInf::Parameter p;
162  p.integerConstraint_ = true;
163  p.numberOfThreads_ = 1;
164  p.timeLimit_ = param.fusionTimeLimit_;
165  value_ = fusionMover_. template fuse<CplexSubInf> (p,true);
166  #ifdef WITH_QPBO
167  }
168  // reduced inference
169  else{
170  //std::cout <<"RILP"<<std::endl;
171  typedef typename ReducedInferenceHelper<SubGmType>::InfGmType ReducedGmType;
174  typename _CplexSubInf::Parameter _subInfParam;
175  _subInfParam.integerConstraint_ = true;
176  _subInfParam.numberOfThreads_ = 1;
177  _subInfParam.timeLimit_ = param.fusionTimeLimit_;
178  typename CplexReducedSubInf::Parameter subInfParam(true,param.tentacles_,param.connectedComponents_,_subInfParam);
179  value_ = fusionMover_. template fuse<CplexReducedSubInf> (subInfParam,true);
180  }
181 
182  #endif
183 
184  }
185  #endif
186 
187  #ifdef WITH_QPBO
188  else if(param.fusionSolver_==SelfFusionType::QpboFusion ){
189 
190  if(selfFusion_.maxOrder()<=2){
191  //std::cout<<"fuse with qpbo\n";
192  value_ = fusionMover_. template fuseQpbo<QpboSubInf> ();
193  //typename QPBOSubInf::Parameter subInfParam;
194  //subInfParam.strongPersistency_ = false;
195  //subInfParam.label_ = argBest_;
196  //value_ = fusionMover_. template fuse<QPBOSubInf> (subInfParam,false);
197  }
198  else{
199  //std::cout<<"fuse with fix-qpbo\n";
200  //value_ = fusionMover_. template fuseFixQpbo<QpboSubInf> ();
201  typename HQPBOSubInf::Parameter subInfParam;
202  value_ = fusionMover_. template fuse<HQPBOSubInf> (subInfParam,true);
203  }
204  }
205  #endif
206  else{
207  throw std::runtime_error("Unknown Fusion Type! Maybe caused by missing linking!");
208  }
209 
210 
211  // write fusion result into best arg
212  std::copy(argOut_.begin(),argOut_.end(),argBest_.begin());
213 
214  //std::cout<<"fusionValue "<<value_<<" infValue "<<infValue<<"\n";
215 
217  selfFusionVisitor_.log("infValue",infValue);
218  }
219 
220  else{
222  selfFusionVisitor_.log("infValue",value_);
223  }
224  }
225  ++iteration_;
226 
227  if(oldValue == value_){
228  ++numNoProgress_;
229  }else{
230  numNoProgress_=0;
231  }
232 
233  if(numNoProgress_>=param.numStopIt_)
235 
236  return returnFlag_;
237  }
238 
239 
240 
241 
242  const GraphicalModelType & gm_;
243  SelfFusionType & selfFusion_;
244  SelfFusionVisitorType & selfFusionVisitor_;
245 
246  FusionMoverType fusionMover_;
247 
248  size_t iteration_;
249  size_t fuseNth_;
250 
251  ValueType & value_;
252  ValueType & bound_;
253 
254  std::vector<LabelType> argFromInf_;
255  std::vector<LabelType> & argBest_;
256  std::vector<LabelType> argOut_;
257 
258  ValueType lastInfValue_;
259  size_t returnFlag_;
261 
262 };
263 
264 
265 template<class INFERENCE>
267 {
268 public:
269 
270  typedef typename INFERENCE::AccumulationType AccumulationType;
271  typedef typename INFERENCE::GraphicalModelType GraphicalModelType;
273 
277 
279 
280  typedef INFERENCE ToFuseInferenceType;
281 
283  QpboFusion=0,
284  CplexFusion=1,
285  LazyFlipperFusion=2
286  };
287 
288 
289  template<class _GM>
290  struct RebindGm{
291  typedef typename INFERENCE:: template RebindGm<_GM>::type RebindedInf;
293  };
294 
295  template<class _GM,class _ACC>
297  typedef typename INFERENCE:: template RebindGmAndAcc<_GM, _ACC>::type RebindedInf;
299  };
300 
301 
302  class Parameter {
303  public:
305  const size_t fuseNth=1,
306  const FusionSolver fusionSolver=LazyFlipperFusion,
307  const typename INFERENCE::Parameter & infParam = typename INFERENCE::Parameter(),
308  const size_t maxSubgraphSize=2,
309  const bool reducedInf = false,
310  const bool tentacles = false,
311  const bool connectedComponents = false,
312  const double fusionTimeLimit = 100.0,
313  const size_t numStopIt = 10
314  )
315  : fuseNth_(fuseNth),
316  fusionSolver_(fusionSolver),
317  infParam_(infParam),
318  maxSubgraphSize_(maxSubgraphSize),
319  reducedInf_(reducedInf),
320  connectedComponents_(connectedComponents),
321  tentacles_(tentacles),
322  fusionTimeLimit_(fusionTimeLimit),
323  numStopIt_(numStopIt)
324  {
325 
326  }
327 
328  template<class P>
330  const P & p
331  )
332  : fuseNth_(p.fuseNth_),
333  fusionSolver_(),
334  infParam_(p.infParam_),
335  maxSubgraphSize_(p.maxSubgraphSize_),
336  reducedInf_(p.reducedInf_),
337  connectedComponents_(p.connectedComponents_),
338  tentacles_(p.tentacles_),
339  fusionTimeLimit_(p.fusionTimeLimit_),
340  numStopIt_(p.numStopIt_)
341  {
342  if(p.fusionSolver_ == 0){
343  fusionSolver_ = QpboFusion;
344  }
345  else if(p.fusionSolver_ == 1){
346  fusionSolver_ = CplexFusion;
347  }
348  else if(p.fusionSolver_ == 2){
349  fusionSolver_ = LazyFlipperFusion;
350  }
351  }
352 
353  size_t fuseNth_;
355  typename INFERENCE::Parameter infParam_;
361  size_t numStopIt_;
362  };
363 
364  SelfFusion(const GraphicalModelType&, const Parameter& = Parameter());
365  std::string name() const;
366  const GraphicalModelType& graphicalModel() const;
368  template<class VisitorType>
369  InferenceTermination infer(VisitorType&);
370  void setStartingPoint(typename std::vector<LabelType>::const_iterator);
371  virtual InferenceTermination arg(std::vector<LabelType>&, const size_t = 1) const ;
372 
373  ValueType value()const{
374  return value_;
375  }
376 
377  ValueType bound()const{
378  return bound_;
379  }
380 
381  const Parameter & parameter()const{
382  return param_;
383  }
384  const size_t maxOrder()const{
385  return maxOrder_;
386  }
387 
388 private:
389 
390  Parameter param_;
391  size_t maxOrder_;
392 
393 
394  const GraphicalModelType& gm_;
395 
396 
397  std::vector<LabelType> argBest_;
400 };
401 
402 
403 
404 template<class INFERENCE>
406 (
407  const GraphicalModelType& gm,
408  const Parameter& parameter
409 )
410 : gm_(gm),
411  param_(parameter),
412  argBest_(gm.numberOfVariables()),
413  value_(),
414  maxOrder_(gm.factorOrder())
415 {
416  AccumulationType::neutral(value_);
417 }
418 
419 
420 
421 template<class INFERENCE>
422 inline void
424 (
425  typename std::vector<typename SelfFusion<INFERENCE>::LabelType>::const_iterator begin
426 ) {
427 
428 }
429 
430 template<class INFERENCE>
431 inline std::string
433 {
434  return "SelfFusion";
435 }
436 
437 template<class INFERENCE>
438 inline const typename SelfFusion<INFERENCE>::GraphicalModelType&
440 {
441  return gm_;
442 }
443 
444 template<class INFERENCE>
447 {
448  EmptyVisitorType v;
449  //VerboseVisitorType v;
450  return infer(v);
451 }
452 
453 
454 template<class INFERENCE>
455 template<class VisitorType>
457 (
458  VisitorType& visitor
459 )
460 {
461  AccumulationType::ineutral(bound_);
462  AccumulationType::neutral(value_);
463 
464  visitor.begin(*this);
465  visitor.addLog("infValue");
466  // the fusion visitor will do the job...
467  FusionVisitor<INFERENCE,SelfType,VisitorType> fusionVisitor(*this,visitor,argBest_,value_,bound_,param_.fuseNth_);
468 
469  INFERENCE inf(gm_,param_.infParam_);
470  inf.infer(fusionVisitor);
471  visitor.end(*this);
472  return NORMAL;
473 }
474 
475 template<class INFERENCE>
478 (
479  std::vector<LabelType>& x,
480  const size_t N
481 ) const
482 {
483  x.resize(gm_.numberOfVariables());
484  for(IndexType vi=0;vi<gm_.numberOfVariables();++vi){
485  x[vi]=argBest_[vi];
486  }
487  return NORMAL;
488 }
489 
490 } // namespace opengm
491 
492 #endif // #ifndef OPENGM_SELF_FUSION_HXX
IndexType numberOfFusionMoveVariable() const
void end(INF &inf)
Definition: self_fusion.hxx:91
INF::AccumulationType AccumulationType
Definition: self_fusion.hxx:37
FusionMoverType fusionMover_
SELF_FUSION SelfFusionType
Definition: self_fusion.hxx:57
SELF_FUSION_VISITOR SelfFusionVisitorType
Definition: self_fusion.hxx:58
The OpenGM namespace.
Definition: config.hxx:43
INFERENCE::AccumulationType AccumulationType
std::string name() const
INFERENCE::Parameter infParam_
Parameter(const size_t fuseNth=1, const FusionSolver fusionSolver=LazyFlipperFusion, const typename INFERENCE::Parameter &infParam=typename INFERENCE::Parameter(), const size_t maxSubgraphSize=2, const bool reducedInf=false, const bool tentacles=false, const bool connectedComponents=false, const double fusionTimeLimit=100.0, const size_t numStopIt=10)
size_t fuseVisit(INF &inference)
SelfFusionVisitorType & selfFusionVisitor_
const GraphicalModelType & gm_
void begin(INF &inf)
Definition: self_fusion.hxx:85
void infer(const typename INF::GraphicalModelType &gm, const typename INF::Parameter &param, std::vector< typename INF::LabelType > &conf)
Definition: inference.hxx:34
virtual InferenceTermination arg(std::vector< LabelType > &, const size_t=1) const
FusionVisitor(SelfFusionType &selfFusion, SelfFusionVisitorType &selfFusionVisitor, std::vector< LabelType > &argBest, ValueType &value, ValueType &bound, size_t fuseNth=1)
Definition: self_fusion.hxx:60
SelfFusion< RebindedInf > type
SelfFusion< RebindedInf > type
SelfFusion(const GraphicalModelType &, const Parameter &=Parameter())
size_t operator()(INF &inf)
Definition: self_fusion.hxx:96
ValueType value() const
return the solution (value)
FusionMoverType::SubGmType SubGmType
Definition: self_fusion.hxx:43
InferenceTermination infer()
std::vector< LabelType > & argBest_
const GraphicalModelType & graphicalModel() const
opengm::LazyFlipper< SubGmType, AccumulationType > LazyFlipperSubInf
Definition: self_fusion.hxx:45
const Parameter & parameter() const
SelfFusion< INFERENCE > SelfType
Optimization by Linear Programming (LP) or Integer LP using IBM ILOG CPLEX http://www.ilog.com/products/cplex/.
Definition: lpcplex.hxx:38
INFERENCE::template RebindGm< _GM >::type RebindedInf
QPBO Algorithm.
std::vector< LabelType > argFromInf_
Inference algorithm interface.
Definition: inference.hxx:43
std::vector< LabelType > argOut_
visitors::TimingVisitor< SelfFusion< INFERENCE > > TimingVisitorType
INFERENCE::template RebindGmAndAcc< _GM, _ACC >::type RebindedInf
INFERENCE::GraphicalModelType GraphicalModelType
INFERENCE ToFuseInferenceType
void setup(const std::vector< LabelType > &argA, const std::vector< LabelType > &argB, std::vector< LabelType > &resultArg, const ValueType valueA, const ValueType valueB)
HQPBO Algorithm .
Definition: hqpbo.hxx:22
const size_t maxOrder() const
visitors::VerboseVisitor< SelfFusion< INFERENCE > > VerboseVisitorType
void setStartingPoint(typename std::vector< LabelType >::const_iterator)
visitors::EmptyVisitor< SelfFusion< INFERENCE > > EmptyVisitorType
A generalization of ICM B. Andres, J. H. Kappes, U. Koethe and Hamprecht F. A., The Lazy Flipper: MA...
SelfFusionType & selfFusion_
[class reducedinference] Reduced Inference Implementation of the reduction techniques proposed in J...
INF::GraphicalModelType GraphicalModelType
Definition: self_fusion.hxx:38
ValueType bound() const
return a bound on the solution
FusionMover< GraphicalModelType, AccumulationType > FusionMoverType
Definition: self_fusion.hxx:41
InferenceTermination
Definition: inference.hxx:24