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  UInt64Type 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 
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 
285  LazyFlipperFusion
286  };
287 
288 
289  class Parameter {
290  public:
292  const UInt64Type fuseNth=1,
293  const FusionSolver fusionSolver=LazyFlipperFusion,
294  const typename INFERENCE::Parameter & infParam = typename INFERENCE::Parameter(),
295  const UInt64Type maxSubgraphSize=2,
296  const bool reducedInf = false,
297  const bool tentacles = false,
298  const bool connectedComponents = false,
299  const double fusionTimeLimit = 100.0,
300  const size_t numStopIt = 10
301  )
302  : fuseNth_(fuseNth),
303  fusionSolver_(fusionSolver),
304  infParam_(infParam),
305  maxSubgraphSize_(maxSubgraphSize),
306  reducedInf_(reducedInf),
307  connectedComponents_(connectedComponents),
308  tentacles_(tentacles),
309  fusionTimeLimit_(fusionTimeLimit),
310  numStopIt_(numStopIt)
311  {
312 
313  }
316  typename INFERENCE::Parameter infParam_;
322  size_t numStopIt_;
323  };
324 
325  SelfFusion(const GraphicalModelType&, const Parameter& = Parameter());
326  std::string name() const;
327  const GraphicalModelType& graphicalModel() const;
328  InferenceTermination infer();
329  template<class VisitorType>
330  InferenceTermination infer(VisitorType&);
331  void setStartingPoint(typename std::vector<LabelType>::const_iterator);
332  virtual InferenceTermination arg(std::vector<LabelType>&, const size_t = 1) const ;
333 
334  ValueType value()const{
335  return value_;
336  }
337 
338  ValueType bound()const{
339  return bound_;
340  }
341 
342  const Parameter & parameter()const{
343  return param_;
344  }
345  const size_t maxOrder()const{
346  return maxOrder_;
347  }
348 
349 private:
350 
351  Parameter param_;
352  size_t maxOrder_;
353 
354 
355  const GraphicalModelType& gm_;
356 
357 
358  std::vector<LabelType> argBest_;
359  ValueType value_;
360  ValueType bound_;
361 };
362 
363 
364 
365 template<class INFERENCE>
367 (
368  const GraphicalModelType& gm,
369  const Parameter& parameter
370 )
371 : gm_(gm),
372  param_(parameter),
373  argBest_(gm.numberOfVariables()),
374  value_(),
375  maxOrder_(gm.factorOrder())
376 {
377  AccumulationType::neutral(value_);
378 }
379 
380 
381 
382 template<class INFERENCE>
383 inline void
385 (
386  typename std::vector<typename SelfFusion<INFERENCE>::LabelType>::const_iterator begin
387 ) {
388 
389 }
390 
391 template<class INFERENCE>
392 inline std::string
394 {
395  return "SelfFusion";
396 }
397 
398 template<class INFERENCE>
399 inline const typename SelfFusion<INFERENCE>::GraphicalModelType&
401 {
402  return gm_;
403 }
404 
405 template<class INFERENCE>
408 {
409  EmptyVisitorType v;
410  //VerboseVisitorType v;
411  return infer(v);
412 }
413 
414 
415 template<class INFERENCE>
416 template<class VisitorType>
418 (
419  VisitorType& visitor
420 )
421 {
422  AccumulationType::ineutral(bound_);
423  AccumulationType::neutral(value_);
424 
425  visitor.begin(*this);
426  visitor.addLog("infValue");
427  // the fusion visitor will do the job...
428  FusionVisitor<INFERENCE,SelfType,VisitorType> fusionVisitor(*this,visitor,argBest_,value_,bound_,param_.fuseNth_);
429 
430  INFERENCE inf(gm_,param_.infParam_);
431  inf.infer(fusionVisitor);
432  visitor.end(*this);
433  return NORMAL;
434 }
435 
436 template<class INFERENCE>
439 (
440  std::vector<LabelType>& x,
441  const size_t N
442 ) const
443 {
444  x.resize(gm_.numberOfVariables());
445  for(IndexType vi=0;vi<gm_.numberOfVariables();++vi){
446  x[vi]=argBest_[vi];
447  }
448  return NORMAL;
449 }
450 
451 } // namespace opengm
452 
453 #endif // #ifndef OPENGM_SELF_FUSION_HXX
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
INFERENCE::Parameter infParam_
size_t fuseVisit(INF &inference)
SelfFusionVisitorType & selfFusionVisitor_
const GraphicalModelType & gm_
std::string name() const
ValueType value() const
return the solution (value)
void begin(INF &inf)
Definition: self_fusion.hxx:85
ValueType bound() const
return a bound on the solution
IndexType numberOfFusionMoveVariable() const
SelfFusion(const GraphicalModelType &, const Parameter &=Parameter())
size_t operator()(INF &inf)
Definition: self_fusion.hxx:96
detail_types::UInt64Type UInt64Type
uint64
Definition: config.hxx:300
FusionMoverType::SubGmType SubGmType
Definition: self_fusion.hxx:43
InferenceTermination infer()
std::vector< LabelType > & argBest_
opengm::LazyFlipper< SubGmType, AccumulationType > LazyFlipperSubInf
Definition: self_fusion.hxx:45
SelfFusion< INFERENCE > SelfType
const Parameter & parameter() const
Optimization by Linear Programming (LP) or Integer LP using IBM ILOG CPLEX http://www.ilog.com/products/cplex/.
Definition: lpcplex.hxx:38
QPBO Algorithm.
std::vector< LabelType > argFromInf_
Inference algorithm interface.
Definition: inference.hxx:34
std::vector< LabelType > argOut_
visitors::TimingVisitor< SelfFusion< INFERENCE > > TimingVisitorType
INFERENCE::GraphicalModelType GraphicalModelType
const GraphicalModelType & graphicalModel() const
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
Parameter(const UInt64Type fuseNth=1, const FusionSolver fusionSolver=LazyFlipperFusion, const typename INFERENCE::Parameter &infParam=typename INFERENCE::Parameter(), const UInt64Type maxSubgraphSize=2, const bool reducedInf=false, const bool tentacles=false, const bool connectedComponents=false, const double fusionTimeLimit=100.0, const size_t numStopIt=10)
virtual InferenceTermination arg(std::vector< LabelType > &, const size_t=1) const
output a solution
void setStartingPoint(typename std::vector< LabelType >::const_iterator)
set initial labeling
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
FusionVisitor(SelfFusionType &selfFusion, SelfFusionVisitorType &selfFusionVisitor, std::vector< LabelType > &argBest, ValueType &value, ValueType &bound, UInt64Type fuseNth=1)
Definition: self_fusion.hxx:60
FusionMover< GraphicalModelType, AccumulationType > FusionMoverType
Definition: self_fusion.hxx:41
InferenceTermination
Definition: inference.hxx:24