OpenGM  2.3.x
Discrete Graphical Model Library
submodel2.hxx
Go to the documentation of this file.
1 #ifndef OPENGM_HMC_SUBMODEL2
2 #define OPENGM_HMC_SUBMODEL2
3 
4 #include <deque>
5 
6 #include <boost/format.hpp>
7 #include <boost/unordered_map.hpp>
8 
9 #ifdef WITH_CPLEX
11 #endif
12 #ifdef WITH_QPBO
13 #include "QPBO.h"
14 #endif
15 
16 #if defined(WITH_BLOSSOM5) && defined(WITH_PLANARITY)
18 #endif
19 #include <opengm/opengm.hxx>
21 
22 
23 #undef OPENGM_CHECK_OP
24 #define OPENGM_CHECK_OP(A,OP,B,TXT)
25 
26 
27 #undef OPENGM_CHECK
28 #define OPENGM_CHECK(B,TXT)
29 
30 
31 template<class GM>
33 public:
34  typedef typename GM::ValueType ValueType;
35  typedef typename GM::IndexType IndexType;
36  typedef typename GM::LabelType LabelType;
37 
38  typedef std::vector<ValueType> ValueVector;
39  typedef std::vector<double > DoubleVector;
40  typedef std::vector<IndexType> IndexVector;
41  typedef std::vector<LabelType> LabelVector;
42  typedef std::vector<bool> BoolVector;
43  typedef std::vector<unsigned char> PseudoBoolVector;
44 
45  typedef std::pair<int,ValueType> IVPairType;
46 
47  // set up map from node pair to edge index
48  typedef std::pair<size_t,size_t> Edge;
49  typedef std::pair<Edge, size_t> EdgeMapEntry;
50  typedef boost::unordered_map<Edge,size_t> EdgeMap;
51 
52  enum Mode {
55  };
56 
57  // constructor from graphical model
58  SubmodelCGC(const GM & gm,const IndexType maxBruteForceSize2,const IndexType maxBruteForceSize4,const bool useBfs);
59 
60 
62  // function to infer submodel //
64  ValueType inferMulticut(Mode mode);
65  ValueType inferQPBOI(Mode mode);
66  ValueType inferPlanarMaxCut();
67  ValueType inferBruteForce2();
68  ValueType inferBruteForce4();
69 
78  template<class ARG>
79  IVPairType inferSubset(
80  ARG & globalArg,
81  const LabelType colorCC,
82  const IndexType viCC,
83  IndexType offset,
84  std::deque<IndexType> & deque,
85  const bool planar,
86  bool verbose = false
87  );
88 
95  template<class ARG>
96  IVPairType infer2Subsets(
97  ARG & globalArg,
98  const LabelType colorCC0,
99  const LabelType colorCC1,
100  const IndexType viCC0,
101  const IndexType viCC1,
102  IndexType offset,
103  const bool planar=true
104  );
105 
106 
107 
108 
124  void updateDirtyness(std::vector<unsigned char>& dirtyFactors, const bool changes){
125  OPENGM_CHECK_OP(dirtyFactors.size(),==,gm_.numberOfFactors(), " ");
126 
127  OPENGM_CHECK_OP(nInsideFactors_,>,0, " ");
128  OPENGM_CHECK_OP(nBorderFactors_,>,0, " ");
129 
130  // make inside undirty if there are no changes
131  if(!changes){
132  for(IndexType f=0;f<nInsideFactors_;++f){
133  if(dirtyFactors[insideFactors_[f]] == 2) {
134  OPENGM_CHECK(false, "shouldn't happen");
135  }
136  dirtyFactors[insideFactors_[f]] = 0;
137  }
138  }
139  // if there are improvements
140  else{
141 
142  // mark inside as clean and border as dirty
143  if(lastNCC_<=2){
144 
145  // inside to clean
146  for(IndexType f=0;f<nInsideFactors_;++f){
147  if(dirtyFactors[insideFactors_[f]] == 2) {
148  OPENGM_CHECK(false, "shouldn't happen");
149  }
150  dirtyFactors[insideFactors_[f]] = 0;
151  }
152  // border to dirty
153  for(IndexType f=0;f<nBorderFactors_;++f){
154  if(dirtyFactors[borderFactor_[f]] == 2) {
155  continue;
156  }
157  dirtyFactors[borderFactor_[f]] = 1;
158  }
159 
160  }
161 
162  // mark inside and border as diry
163  else{
164  //std::cout<<"\n\n\n\n\n JOOOO \n\n\n";
165  for(IndexType f=0;f<nInsideFactors_;++f){
166  if(dirtyFactors[insideFactors_[f]] == 2) {
167  OPENGM_CHECK(false, "shouldn't happen");
168  }
169  dirtyFactors[insideFactors_[f]] = 1;
170  }
171  for(IndexType f=0;f<nBorderFactors_;++f){
172  if(dirtyFactors[borderFactor_[f]] == 2) {
173  continue;
174  }
175  dirtyFactors[borderFactor_[f]] = 1;
176  }
177  }
178  }
179 
180 
181  /*
182  for(IndexType f=0;f<nInsideFactors_;++f){
183  if(dirtyFactors[insideFactors_[f]] == 2) {
184  OPENGM_CHECK(false, "shouldn't happen");
185  }
186  dirtyFactors[insideFactors_[f]] = 0;
187  }
188  if(changes){
189  for(IndexType f=0;f<nBorderFactors_;++f){
190  if(dirtyFactors[borderFactor_[f]] == 2) {
191  continue;
192  }
193  dirtyFactors[borderFactor_[f]] = 1;
194  }
195  }
196  */
197  }
198 
200  nInsideFactors_=0;
201  nBorderFactors_=0;
202  }
203 
204 private:
205 
210  template<class ARG>
211  void setSubVarImplicit(const ARG & arg, const LabelType color,const IndexType vi);
212  template<class ARG>
213  void setSubVarImplicitBfs(const ARG & arg, const LabelType color,const IndexType vi);
219  template<class ARG>
220  void setSubVarImplicit(const ARG & arg,
221  const LabelType color0,const LabelType color1,
222  const IndexType vi0,const IndexType vi1
223  );
224  template<class ARG>
225  void setSubVarImplicitBfs(const ARG & arg,
226  const LabelType color0,const LabelType color1,
227  const IndexType vi0,const IndexType vi1
228  );
229 
230 
234  IndexType ccFromLocalArg(const IndexType offset);
235 
236  void getEmbeddingGraph();
237  void freeEmbeddingGraph();
238 
239  // set up variables of submodel from explicit var
240  void setUpSubFactors();
241  // unset variables
242  void unsetSubVar();
243 
244  // global graphical model
245  const GM & gm_;
246 
247  // local<->global var mapping
248  IndexVector subVarToGlobal_;
249  IndexVector globalVarToLocal_;
250 
251  // inclued factors and variables in submodel
252  PseudoBoolVector incluedGlobalVar_;
253  BoolVector incluedGlobalFactors_;
254  BoolVector isABorderFactor_;
255 
256 
257  // local arg buffer
258  LabelVector localArg_;
259  LabelVector localArgTest_;
260 
261  // local factor - global factor mapping
262  marray::Marray<IndexType> localFactorVis_;
263 
264  // local and global lambdas
265  ValueVector globalLambdas_;
266  DoubleVector localLambdas_;
267 
268  // inside factor (buffer)
269  // outside factor (buffer)
270  IndexVector insideFactors_;
271  IndexVector borderFactor_;
272  IndexType nInsideFactors_;
273  IndexType nBorderFactors_;
274 
275  // number of Xxx for easy reading
276  IndexType numSubVar_;
277  IndexType numSubFactors_;
278 
279  // sub edge map
280  EdgeMap localEdgemap_;
281 
282  // parameters
283  IndexType maxBruteForceSize2_;
284  IndexType maxBruteForceSize4_;
285  bool greedyMode_;
286 
287  ValueType oldCutValue_;
288  bool isOptCut_;
289 
290  bool useBfs_;
291 
292  std::vector<opengm::RandomAccessSet<IndexType> > visAdj_;
293 
294  std::vector<IndexType> stack_;
295 
296  IndexType lastNCC_;
297 };
298 
299 //------------------------------------------------------------------------------------------------------------//
300 // IMPLEMENTATION
301 //------------------------------------------------------------------------------------------------------------//
302 
303 template<class GM>
304 template<class ARG>
307  ARG & globalArg,
308  typename SubmodelCGC<GM>::LabelType colorCC0,
309  typename SubmodelCGC<GM>::LabelType colorCC1,
310  const typename SubmodelCGC<GM>::IndexType viCC0,
311  const typename SubmodelCGC<GM>::IndexType viCC1,
312  typename SubmodelCGC<GM>::IndexType offset,
313  const bool planar
314 ){
315 
316  OPENGM_CHECK_OP(colorCC0,!=,colorCC1,"must be different colors");
317 
318  //std::cout<<"set up sub var \n";
319  if(useBfs_){
320  this->setSubVarImplicitBfs(globalArg,colorCC0,colorCC1,viCC0,viCC1);
321  }
322  else{
323  this->setSubVarImplicit(globalArg,colorCC0,colorCC1,viCC0,viCC1);
324  }
325  if(numSubVar_<=1){
326  this->unsetSubVar();
327  return IVPairType(-1,0.0);
328  }
329  //std::cout<<"set up sub factors \n";
330  this->setUpSubFactors();
331 
332  if(false && isOptCut_==true){
333  this->unsetSubVar();
334  return IVPairType(-3,oldCutValue_);
335  }
336 
337  ValueType valueOfArg=0.0;
338  if(numSubVar_<= maxBruteForceSize2_ && planar==true){
339  //std::cout<<"do bruteforce on "<<numSubVar_<<" vars "<<numSubFactors_<<"facs \n";
340  if(numSubVar_<maxBruteForceSize4_ && numSubVar_>=3)
341  valueOfArg=this->inferBruteForce4();
342  else
343  valueOfArg=this->inferBruteForce2();
344  }
345  else if(planar==true){
346  OPENGM_CHECK(planar,"");
347  //this->getEmbeddingGraph();
348  //valueOfArg=this->inferIsInf();
349  //this->freeEmbeddingGraph();
350  valueOfArg = this->inferPlanarMaxCut();
351  }
352  else{
353  //std::cout<<"do multicut on "<<numSubVar_<<" vars "<<numSubFactors_<<"facs \n";
354  //valueOfArg = this->inferMulticut(TwoSubsets);
355  valueOfArg = this->inferQPBOI(TwoSubsets);
356  }
357 
358  OPENGM_CHECK(greedyMode_," ");
359  if(oldCutValue_<valueOfArg){
360  //std::cout<<"we are worse or equal same..."<<valueOfArg <<" old "<<oldCutValue_<<"\n";
361 
362  //std::cout<<"no improvement \n";
363  this->unsetSubVar();
364  return IVPairType(-2,oldCutValue_);
365  }
366  else if(valueOfArg+0.0000001<oldCutValue_){
367  //std::cout<<"better....\n";
368  //std::cout<<" old "<<oldCutValue_<<"\n";
369  //std::cout<<" new "<<valueOfArg<<"\n";
370 
371  }
372  else{
373  //std::cout<<"same....\n";
374  //std::cout<<" old "<<oldCutValue_<<"\n";
375  //std::cout<<" new "<<valueOfArg<<"\n";
376  this->unsetSubVar();
377  return IVPairType(-2,oldCutValue_);
378  }
379 
380 
381  //std::cout<<"get ccs \n";
382  // infer local probel and get cc's
383  IndexType numCC = this->ccFromLocalArg(offset);
384  lastNCC_ = numCC; //remember for later
385  //std::cout<<"write back -- offset is "<<offset<<"\n";
386 
387  std::vector<IndexType> exampleForCC(numCC);
388 
389  // write back to global arg
390  for(IndexType localVi=0;localVi<numSubVar_;++localVi){
391  const LabelType ccLabel = localArg_[localVi];
392  const IndexType globalVi = subVarToGlobal_[localVi];
393  OPENGM_CHECK_OP(ccLabel-offset,<,numCC," ");
394  exampleForCC[ccLabel-offset]=globalVi;
395  globalArg[globalVi]=ccLabel;
396  }
397 
398  // free stuff and unset variables
399  this->unsetSubVar();
400  return IVPairType(numCC,valueOfArg-oldCutValue_);
401  //return boost::python::make_tuple(numCC,valueOfArg-oldCutValue_);
402 }
403 
404 
405 template<class GM>
406 template<class ARG>
409  ARG & globalArg,
410  typename SubmodelCGC<GM>::LabelType colorCC,
411  typename SubmodelCGC<GM>::IndexType viCC,
412  typename SubmodelCGC<GM>::IndexType offset,
413  std::deque<typename SubmodelCGC<GM>::IndexType> & deque,
414  const bool planar,
415  bool verbose
416 ){
417  using boost::format;
418 
419  // set up local problem
420  if(useBfs_){
421  this->setSubVarImplicitBfs(globalArg,colorCC,viCC);
422  }
423  else{
424  this->setSubVarImplicit(globalArg,colorCC,viCC);
425  }
426 
427  if(verbose) {
428  std::cout << format(" inferSubset with %d variables") % numSubVar_ << std::endl;
429  }
430 
431  if(numSubVar_<=1){
432  this->unsetSubVar();
433  return IVPairType(-1.0,0.0);
434  }
435  //std::cout<<"set up sub factors \n";
436  this->setUpSubFactors();
437 
438  ValueType valueOfArg=0.0;
439  if(planar){
440  if(numSubVar_<= maxBruteForceSize2_){
441  if(numSubVar_<maxBruteForceSize4_ && numSubVar_>=3)
442  valueOfArg=this->inferBruteForce4();
443  else
444  valueOfArg=this->inferBruteForce2();
445  }
446  else{
447  //std::cout<<"get embedding graph \n";
448  //this->getEmbeddingGraph();
449  //valueOfArg=this->inferIsInf();
450  //this->freeEmbeddingGraph();
451  valueOfArg = this->inferPlanarMaxCut();
452  }
453  }
454  else{
455  //valueOfArg=this->inferMulticut(SingleSubset);
456  valueOfArg=this->inferQPBOI(SingleSubset);
457  }
458 
459  //std::cout<<"get ccs \n";
460  // infer local probel and get cc's
461  IndexType numCC = this->ccFromLocalArg(offset);
462 
463  //std::cout<<"write back -- offset is "<<offset<<"\n";
464 
465  std::vector<IndexType> exampleForCC(numCC);
466 
467  if(numCC>1){
468  // write back to global arg
469  for(IndexType localVi=0;localVi<numSubVar_;++localVi){
470  const LabelType ccLabel = localArg_[localVi];
471  const IndexType globalVi = subVarToGlobal_[localVi];
472  OPENGM_CHECK_OP(ccLabel-offset,<,numCC," ");
473  exampleForCC[ccLabel-offset]=globalVi;
474  globalArg[globalVi]=ccLabel;
475  }
476 
477  if(true){
478  for(size_t i=0;i<exampleForCC.size();++i){
479  deque.push_back(exampleForCC[i]);
480  }
481  }
482  }
483 
484  // free stuff and unset variables
485  this->unsetSubVar();
486  return IVPairType(numCC,valueOfArg);
487 
488 }
489 
490 template<class GM>
491 template<class ARG>
493  const ARG & arg,
494  const typename SubmodelCGC<GM>::LabelType ccColor,
495  const typename SubmodelCGC<GM>::IndexType vi
496 ){
497  greedyMode_=false;
498  IndexType viLocal=0;
499  for(IndexType viGlobal=0;viGlobal<gm_.numberOfVariables();++viGlobal){
500  if(arg[viGlobal]==ccColor){
501  subVarToGlobal_[viLocal]=viGlobal;
502  globalVarToLocal_[viGlobal]=viLocal;
503  OPENGM_CHECK_OP(incluedGlobalVar_[viGlobal],==,0,"internal inconsistency");
504  incluedGlobalVar_[viGlobal]=1;
505  ++viLocal;
506  }
507  }
508  numSubVar_=viLocal;
509 }
510 
511 template<class GM>
512 template<class ARG>
514  const ARG & arg,
515  const typename SubmodelCGC<GM>::LabelType ccColor,
516  const typename SubmodelCGC<GM>::IndexType vi
517 ){
518  greedyMode_=false;
519  IndexType viLocal=0;
520  for(IndexType viGlobal=0;viGlobal<gm_.numberOfVariables();++viGlobal){
521  if(arg[viGlobal]==ccColor){
522  subVarToGlobal_[viLocal]=viGlobal;
523  globalVarToLocal_[viGlobal]=viLocal;
524  OPENGM_CHECK_OP(incluedGlobalVar_[viGlobal],==,0,"internal inconsistency");
525  incluedGlobalVar_[viGlobal]=1;
526  ++viLocal;
527  }
528  }
529  numSubVar_=viLocal;
530 }
531 
532 
533 
534 template<class GM>
535 template<class ARG>
537  const ARG & arg,
538  const typename SubmodelCGC<GM>::LabelType ccColor0,
539  const typename SubmodelCGC<GM>::LabelType ccColor1,
540  const typename SubmodelCGC<GM>::IndexType vi0,
541  const typename SubmodelCGC<GM>::IndexType vi1
542 ){
543  greedyMode_=true;
544  IndexType viLocal=0;
545  for(IndexType viGlobal=0;viGlobal<gm_.numberOfVariables();++viGlobal){
546 
547  const LabelType cVi=arg[viGlobal];
548  if(cVi==ccColor0 || cVi==ccColor1){
549  subVarToGlobal_[viLocal]=viGlobal;
550  globalVarToLocal_[viGlobal]=viLocal;
551  OPENGM_CHECK_OP(incluedGlobalVar_[viGlobal],==,0,"internal inconsistency");
552  incluedGlobalVar_[viGlobal] = cVi==ccColor0 ? 1 : 2;
553  ++viLocal;
554  }
555  }
556  numSubVar_=viLocal;
557 }
558 
559 template<class GM>
560 template<class ARG>
562  const ARG & arg,
563  const typename SubmodelCGC<GM>::LabelType ccColor0,
564  const typename SubmodelCGC<GM>::LabelType ccColor1,
565  const typename SubmodelCGC<GM>::IndexType vi0,
566  const typename SubmodelCGC<GM>::IndexType vi1
567 ){
568  greedyMode_=true;
569 
570 
571  //std::cout<<"fill bfs\n";
572  //std::cout<<" v0 "<< vi0 << " c0 "<< ccColor0<<"\n";
573  //std::cout<<" v1 "<< vi1 << " c1 "<< ccColor1<<"\n";
574 
575 
576  //std::queue<IndexType> cQueue;
577 
578  IndexType ssize = 2;
579  stack_[0]=vi0;
580  stack_[1]=vi1;
581 
582  //cQueue.push(vi0);
583  //cQueue.push(vi1);
584  subVarToGlobal_[0]=vi0;
585  subVarToGlobal_[1]=vi1;
586  incluedGlobalVar_[vi0]=1;
587  incluedGlobalVar_[vi1]=2;
588  numSubVar_=2;
589 
590  while(ssize>0){
591 
592  const IndexType vi=stack_[ssize-1];
593  --ssize;
594 
595  if(incluedGlobalVar_[vi]==0){
596  incluedGlobalVar_[vi]= (arg[vi]==ccColor0 ? 1 : 2);
597  // need to be sorted later
598  subVarToGlobal_[numSubVar_]=vi;
599  ++numSubVar_;
600  }
601 
602  for(IndexType n=0;n<visAdj_[vi].size();++n){
603  const IndexType nvi = visAdj_[vi][n];
604  const LabelType cvi = arg[nvi];
605 
606  if(incluedGlobalVar_[nvi]==0 && (cvi==ccColor0 || cvi==ccColor1)){
607 
608  incluedGlobalVar_[nvi]= (arg[nvi]==ccColor0 ? 1 : 2);
609  // need to be sorted later
610  subVarToGlobal_[numSubVar_]=nvi;
611 
612  ++numSubVar_;
613 
614  stack_[ssize]=nvi;
615  ++ssize;
616  OPENGM_CHECK_OP(ssize,<=,gm_.numberOfVariables()*2,"");
617  }
618  }
619  }
620 
621  //(std::cout<<" n local var bfs "<<numSubVar_<<"\n";
622  //std::cout<<"sort stuff\n";
623 
624  std::sort(subVarToGlobal_.begin(),subVarToGlobal_.begin()+numSubVar_);
625 
626  //std::cout<<"global to local\n";
627 
628  for(IndexType lvi=0;lvi<numSubVar_;++lvi){
629  const IndexType gvi=subVarToGlobal_[lvi];
630  globalVarToLocal_[gvi]=lvi;
631  }
632 
633 
634  //std::cout<<"bfs done\n";
635 }
636 
637 template<class GM>
639  const GM & gm,
640  const IndexType maxBruteForceSize2,
641  const IndexType maxBruteForceSize4,
642  const bool useBfs
643 )
644 : gm_(gm),
645  subVarToGlobal_(gm.numberOfVariables()),
646  globalVarToLocal_(gm.numberOfVariables()),
647  incluedGlobalVar_(gm.numberOfVariables(),false),
648  incluedGlobalFactors_(gm.numberOfFactors(),false),
649  isABorderFactor_(gm.numberOfFactors(),false),
650  localArg_(gm.numberOfVariables()),
651  localArgTest_(gm.numberOfVariables()),
652  localFactorVis_(),
653  globalLambdas_(gm.numberOfFactors()),
654  localLambdas_(gm.numberOfFactors()),
655  insideFactors_(gm.numberOfFactors()),
656  borderFactor_(gm.numberOfFactors()),
657  nInsideFactors_(0),
658  nBorderFactors_(0),
659  numSubVar_(0),
660  numSubFactors_(0),
661  localEdgemap_(),
662  maxBruteForceSize2_(0),//maxBruteForceSize2<4 ? 4 : maxBruteForceSize2),
663  maxBruteForceSize4_(0)//maxBruteForceSize4<4 ? 4 : maxBruteForceSize4)
664 {
665  gm_.variableAdjacencyList(visAdj_);
666  stack_.resize(gm_.numberOfVariables()*2);
667  useBfs_=useBfs;
668  std::fill(incluedGlobalVar_.begin(),incluedGlobalVar_.end(),false);
669  // resize factor Vis
670  IndexType shape[2]={gm.numberOfFactors(),3};
671  localFactorVis_.resize(shape,shape+2);
672  //
673  LabelType lAA[2] = { 0, 0};
674  LabelType lAB[2] = { 0, 1};
675  for(IndexType fi=0;fi<gm_.numberOfFactors();++fi){
676  globalLambdas_[fi]=gm[fi].operator()(lAB)-gm[fi].operator()(lAA);
677  }
678 }
679 
680 
681 template<class GM>
684 (
685  const IndexType offset
686 ){
687  // merge with UFD (and primal to dual arg)
688  opengm::Partition<IndexType> ufd(numSubVar_);
689  for(IndexType f=0;f<numSubFactors_;++f){
690  const IndexType sv0=localFactorVis_(f,0);
691  const IndexType sv1=localFactorVis_(f,1);
692  if( localArg_[sv0] == localArg_[sv1]){
693  ufd.merge(sv0,sv1);
694  }
695  }
696 
697  // relabel with UFD MAP
698  // and write to final result
699  const IndexType numberOfCCs=ufd.numberOfSets();
700  std::map<IndexType,IndexType> repLabeling;
701  ufd.representativeLabeling(repLabeling);
702 
703  for(IndexType subVi=0;subVi<numSubVar_;++subVi){
704  const IndexType findSubVi = ufd.find(subVi);
705  const IndexType denseLabel = repLabeling[findSubVi];
706  localArg_[subVi]=denseLabel + offset;
707  }
708  return numberOfCCs;
709 }
710 
711 
712 
713 
714 template<class GM>
716  Mode mode
717 ){
718  #ifdef WITH_CPLEX
720  typename Multicut::Parameter para;
721  para.workFlow_="(IC)(CC-I)";
722  Multicut mc(numSubVar_,numSubFactors_,localFactorVis_,localLambdas_,para);
723 
724  if(mode == SingleSubset) {
725  std::cout << " [SS] MC with #var=" << numSubVar_ << ", #factors=" << numSubFactors_ << std::flush;
726  }
727  else {
728  std::cout << " [TS] MC with #var=" << numSubVar_ << ", #factors=" << numSubFactors_ << std::flush;
729  }
730 
731 
732  std::vector<IndexType> mcarg;
733  //std::cout<<"run multicut \n";
734  //McVerboseVisitor visitor;
735  opengm::Timer t; t.tic();
736  mc.infer();
737  t.toc();
738  double e = t.elapsedTime();
739  std::cout << " ... " << std::fixed << 1000.0*e << " msec." << std::endl;
740 
741  //std::cout<<"get multicut arg\n";
742  mc.arg(mcarg);
743 
744  std::copy(mcarg.begin(),mcarg.end(),localArg_.begin());
745 
746 
747  //std::cout<<"get multicut value\n";
748  ValueType value=0;
749 
750  for(IndexType fiLocal=0;fiLocal<numSubFactors_;++fiLocal){
751  const IndexType localVi0 = localFactorVis_(fiLocal,0);
752  const IndexType localVi1 = localFactorVis_(fiLocal,1);
753  if(localArg_[localVi0]!=localArg_[localVi1])
754  value+=localLambdas_[fiLocal];
755  }
756  //std::cout<<"return value\n";
757  return value;
758  #else
759  throw opengm::RuntimeError("inferMulticut needs WITH_CPLEX");
760  #endif
761 }
762 
763 template<class GM>
765  Mode mode
766 ){
767 #ifdef WITH_QPBO
768  typedef double REAL;
769  typedef typename kolmogorov::qpbo::QPBO<REAL>::NodeId NodeId;
770  typedef typename kolmogorov::qpbo::QPBO<REAL>::EdgeId EdgeId;
771  typedef typename kolmogorov::qpbo::QPBO<REAL>::ProbeOptions ProbeOptions;
772 
773  kolmogorov::qpbo::QPBO<REAL>* qpbo = new kolmogorov::qpbo::QPBO<REAL>(numSubVar_, numSubFactors_); // construct with an error message function
774  qpbo->AddNode(numSubVar_);
775  qpbo->AddUnaryTerm(0, 0.0, 10000000.0);
776  for(size_t i=0; i<numSubFactors_; ++i){
777  qpbo->AddPairwiseTerm( (NodeId)localFactorVis_(i,0), (NodeId)localFactorVis_(i,1), (REAL)0.0, (REAL)localLambdas_[i],(REAL)localLambdas_[i],(REAL)0.0 );
778  }
779  qpbo->MergeParallelEdges();
780  for(size_t i=0; i < numSubVar_ ; ++i)
781  qpbo->SetLabel(i, 0);
782 
783  srand( 42 );
784  qpbo->Improve();
785 
786  // get the labels
787  for ( size_t i=0; i < numSubVar_ ; ++i ) {
788  localArg_[i] = qpbo->GetLabel(i);
789  }
790 
791  ValueType value=0;
792  for(IndexType fiLocal=0;fiLocal<numSubFactors_;++fiLocal){
793  const IndexType localVi0 = localFactorVis_(fiLocal,0);
794  const IndexType localVi1 = localFactorVis_(fiLocal,1);
795  if(localArg_[localVi0]!=localArg_[localVi1])
796  value+=localLambdas_[fiLocal];
797  }
798  delete qpbo;
799  return value;
800 #else
801  throw opengm::RuntimeError("inferQPBOI needs WITH_QPBO");
802  return 0.0;
803 #endif
804 
805 
806 }
807 
808 
809 template<class GM>
811 
812 ){
813 #if defined(WITH_BLOSSOM5) && defined(WITH_PLANARITY)
814  opengm::external::PlanarMaxCut solver(numSubVar_, numSubFactors_);
815  for(size_t i=0; i<numSubFactors_; ++i){
816  solver.addEdge(localFactorVis_(i,0),localFactorVis_(i,1), -1.0*localLambdas_[i]);
817  }
818  solver.calculateCut();
819  solver.getLabeling(localArg_);
820 
821 
822  ValueType value=0;
823  for(IndexType i=0;i<numSubFactors_;++i){
824  const IndexType localVi0 = localFactorVis_(i,0);
825  const IndexType localVi1 = localFactorVis_(i,1);
826  if(localArg_[localVi0]!=localArg_[localVi1])
827  value+=localLambdas_[i];
828  }
829  return value;
830 #else
831  throw opengm::RuntimeError("inferPlanarMaxCut needs WITH_BLOSSOM5 and WITH_PLANARITY");
832  return 0.0;
833 #endif
834 }
835 
836 
837 
838 template<class GM>
839 typename GM::ValueType SubmodelCGC<GM>::inferBruteForce2(){
840  OPENGM_CHECK_OP(numSubVar_,<=,64,"too many variables for brute force");
841  // INFER
842  ValueType bestVal=0.0;
843  const opengm::UInt64Type numFlipVar=numSubVar_-1;
844  const opengm::UInt64Type numConfig=2^numFlipVar;
845  localArgTest_[0]=0;
846  std::fill(localArgTest_.begin(),localArgTest_.begin()+numSubVar_,0);
847  std::fill(localArg_.begin() ,localArg_.begin()+numSubVar_,0);
848  for ( opengm::UInt64Type i = 0 ; i < numConfig ; i++ ){
849 
850  for ( opengm::UInt64Type j = 0 ; j < numFlipVar ; j++ ){
851  localArgTest_[j+1] = static_cast<opengm::UInt64Type>(bool( i & (1 << j) ));
852  }
853  // EVALUATE
854  ValueType newVal = 0.0;
855  for(IndexType f=0;f<numSubFactors_;++f){
856 
857  if(localArgTest_[localFactorVis_(f,0)]!=localArgTest_[localFactorVis_(f,1)])
858  newVal+=localLambdas_[f];
859  }
860  // CHECK WHICH IS BETTER
861  if(newVal<bestVal){
862  bestVal=newVal;
863  std::copy(localArgTest_.begin(),localArgTest_.begin()+numSubVar_,localArg_.begin());
864  }
865  }
866  return bestVal;
867 }
868 
869 template<class GM>
870 typename GM::ValueType SubmodelCGC<GM>::inferBruteForce4(){
871  OPENGM_CHECK_OP(numSubVar_,<=,15,"to many variables for brute force 4");
872  // INFER
873  ValueType bestVal=0.0;
874  const opengm::UInt64Type numFlipVar=numSubVar_-1;
875  const opengm::UInt64Type numConfig=std::pow(4,numFlipVar);
876  localArgTest_[0]=0;
877  std::fill(localArgTest_.begin(),localArgTest_.begin()+numSubVar_,0);
878  std::fill(localArg_.begin() ,localArg_.begin()+numSubVar_,0);
879  for ( opengm::UInt64Type i = 0 ; i < numConfig ; i++ ){
880 
881  for ( opengm::UInt64Type j = 0 ; j < numFlipVar ; j++ ){
882  const opengm::UInt64Type ba = static_cast<bool>(i & ( 1 << (j*2) ) );
883  opengm::UInt64Type bb = static_cast<bool>(i & ( 1 << (j*2 +1) ) );
884  bb=bb<<1;
885  const opengm::UInt64Type c = ba | bb;
886  //std::cout<<"c "<<c<<"\n";
887  localArgTest_[j+1] = c;
888  }
889  // EVALUATE
890  ValueType newVal = 0.0;
891  for(IndexType f=0;f<numSubFactors_;++f){
892 
893  if(localArgTest_[localFactorVis_(f,0)]!=localArgTest_[localFactorVis_(f,1)])
894  newVal+=localLambdas_[f];
895  }
896  // CHECK WHICH IS BETTER
897  if(newVal<bestVal){
898  bestVal=newVal;
899  std::copy(localArgTest_.begin(),localArgTest_.begin()+numSubVar_,localArg_.begin());
900  }
901  }
902  return bestVal;
903 }
904 
905 
906 
907 
908 
909 template<class GM>
911 
912  OPENGM_CHECK_OP(numSubFactors_,==,0,"internal inconsistency");
913  OPENGM_CHECK_OP(numSubVar_,>,0,"internal inconsistency");
914  //OPENGM_CHECK_OP(nInsideFactors_,==,0,"internal inconsistency");
915  //OPENGM_CHECK_OP(nBorderFactors_,==,0,"internal inconsistency");
916  nBorderFactors_=0;
917  nInsideFactors_=0;
918  oldCutValue_=0.0;
919  isOptCut_=true;
920  for(IndexType viLocal=0;viLocal<numSubVar_;++viLocal){
921  const IndexType viGlobal=subVarToGlobal_[viLocal];
922  const IndexType numFacVar = gm_.numberOfFactors(viGlobal);
923  for(IndexType f=0; f<numFacVar; ++f){
924  const IndexType fiGlobal=gm_.factorOfVariable(viGlobal,f);
925 
926  if(incluedGlobalFactors_[fiGlobal]==false){
927  const IndexType viA = gm_.variableOfFactor(fiGlobal,0);
928  const IndexType viB = gm_.variableOfFactor(fiGlobal,1);
929  const IndexType viGlobalOther = viA==viGlobal ? viB : viA;
930 
931  const IndexType viGlobal0 = viGlobal<viGlobalOther ? viGlobal : viGlobalOther;
932  const IndexType viGlobal1 = viGlobal<viGlobalOther ? viGlobalOther : viGlobal;
933 
934  // check if the other variable of the factor is
935  // also in the sub-problem
936  if(incluedGlobalVar_[viGlobalOther]!=0){
937  // this is a inside factors
938  OPENGM_CHECK_OP(nInsideFactors_,<,gm_.numberOfFactors(),"");
939  insideFactors_[nInsideFactors_]=fiGlobal;
940  ++nInsideFactors_;
941 
942 
943 
944  incluedGlobalFactors_[fiGlobal]=true;
945  // subgraph
946  localFactorVis_(numSubFactors_,0)=globalVarToLocal_[viGlobal0];
947  localFactorVis_(numSubFactors_,1)=globalVarToLocal_[viGlobal1];
948  localFactorVis_(numSubFactors_,2)=fiGlobal;
949  // local lambda
950  const ValueType lamb=globalLambdas_[fiGlobal];
951  if(incluedGlobalVar_[viGlobalOther]!=incluedGlobalVar_[viGlobal]){
952  oldCutValue_+=lamb;
953  if(lamb>=0.0){
954  isOptCut_=false;
955  }
956  }
957 
958  localLambdas_[numSubFactors_]=lamb;
959  ++numSubFactors_;
960  }
961  else{
962  // this is a border factor
963  OPENGM_CHECK_OP(nBorderFactors_,<,gm_.numberOfFactors(),"");
964  borderFactor_[nBorderFactors_]=fiGlobal;
965  ++nBorderFactors_;
966  }
967  }
968  }
969  }
970 
971  //std::cout<<"inside factor "<<nInsideFactors_<<"\n";
972  //std::cout<<"border factor "<<nBorderFactors_<<"\n";
973 
974 
975 }
976 
977 template<class GM>
978 inline void SubmodelCGC<GM>::unsetSubVar(){
979  OPENGM_CHECK_OP(numSubVar_,>,0,"internal inconsistency");
980  for(IndexType viLocal=0;viLocal<numSubVar_;++viLocal){
981  const IndexType viGlobal=subVarToGlobal_[viLocal];
982  OPENGM_CHECK(incluedGlobalVar_[viGlobal]>0,"internal inconsistency");
983  incluedGlobalVar_[viGlobal]=0;
984  }
985  for(IndexType fiLocal=0;fiLocal<numSubFactors_;++fiLocal){
986  OPENGM_CHECK(incluedGlobalFactors_[localFactorVis_(fiLocal,2)],"internal inconsistency");
987  incluedGlobalFactors_[localFactorVis_(fiLocal,2)]=false;
988  }
989  numSubVar_=0;
990  numSubFactors_=0;
991  //nInsideFactors_=0;
992  //nBorderFactors_=0;
993 
994 
995  localEdgemap_.clear();
996 }
997 
998 #endif /* OPENGM_HMC_SUBMODEL2 */
std::pair< size_t, size_t > Edge
Definition: submodel2.hxx:48
GM::IndexType IndexType
Definition: submodel2.hxx:35
std::vector< double > DoubleVector
Definition: submodel2.hxx:39
void toc()
Definition: timer.hxx:109
SubmodelCGC(const GM &gm, const IndexType maxBruteForceSize2, const IndexType maxBruteForceSize4, const bool useBfs)
Definition: submodel2.hxx:638
ValueType inferBruteForce2()
Definition: submodel2.hxx:839
Platform-independent runtime measurements.
Definition: timer.hxx:29
GM::ValueType ValueType
Definition: submodel2.hxx:34
void cleanInsideAndBorder()
Definition: submodel2.hxx:199
std::vector< IndexType > IndexVector
Definition: submodel2.hxx:40
detail_types::UInt64Type UInt64Type
uint64
Definition: config.hxx:300
ValueType inferPlanarMaxCut()
Definition: submodel2.hxx:810
std::vector< bool > BoolVector
Definition: submodel2.hxx:42
GM::LabelType LabelType
Definition: submodel2.hxx:36
boost::unordered_map< Edge, size_t > EdgeMap
Definition: submodel2.hxx:50
std::pair< Edge, size_t > EdgeMapEntry
Definition: submodel2.hxx:49
double elapsedTime() const
Definition: timer.hxx:130
ValueType inferQPBOI(Mode mode)
Definition: submodel2.hxx:764
void tic()
Definition: timer.hxx:96
void updateDirtyness(std::vector< unsigned char > &dirtyFactors, const bool changes)
Definition: submodel2.hxx:124
IVPairType inferSubset(ARG &globalArg, const LabelType colorCC, const IndexType viCC, IndexType offset, std::deque< IndexType > &deque, const bool planar, bool verbose=false)
#define OPENGM_CHECK_OP(A, OP, B, TXT)
Definition: submodel2.hxx:24
ValueType inferMulticut(Mode mode)
Definition: submodel2.hxx:715
Disjoint set data structure with path compression.
Definition: partition.hxx:13
std::pair< int, ValueType > IVPairType
Definition: submodel2.hxx:45
IVPairType infer2Subsets(ARG &globalArg, const LabelType colorCC0, const LabelType colorCC1, const IndexType viCC0, const IndexType viCC1, IndexType offset, const bool planar=true)
#define OPENGM_CHECK(B, TXT)
Definition: submodel2.hxx:28
ValueType inferBruteForce4()
Definition: submodel2.hxx:870
std::vector< LabelType > LabelVector
Definition: submodel2.hxx:41
std::vector< ValueType > ValueVector
Definition: submodel2.hxx:38
std::vector< unsigned char > PseudoBoolVector
Definition: submodel2.hxx:43
OpenGM runtime error.
Definition: opengm.hxx:100
void resize(ShapeIterator, ShapeIterator, const T &=T())
Resize (existing entries are preserved, new entries are initialized).
Definition: marray.hxx:3886