OpenGM  2.3.x
Discrete Graphical Model Library
intersection_based_inf.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_INTERSECTION_BASED_INF_HXX
3 #define OPENGM_INTERSECTION_BASED_INF_HXX
4 
5 #include <vector>
6 #include <string>
7 #include <iostream>
8 
9 #include <omp.h>
10 
11 #include "opengm/opengm.hxx"
15 
16 // Fusion Move Solver (they solve binary problems)
21 
22 #ifdef WITH_CPLEX
24 #endif
25 
26 #ifdef WITH_QPBO
27 #include <QPBO.h>
28 #endif
29 
30 #include <stdlib.h> /* srand, rand */
31 
32 
34 
35 
36 #include <fstream>
37 #include <iterator>
38 #include <string>
39 #include <vector>
40 
41 // FIXME
42 //using namespace std;
43 //#define Isinf Isinf2
44 #include <opengm/inference/cgc.hxx>
45 
46 
47 #include <vigra/adjacency_list_graph.hxx>
48 #include <vigra/merge_graph_adaptor.hxx>
49 #include <vigra/hierarchical_clustering.hxx>
50 #include <vigra/priority_queue.hxx>
51 #include <vigra/random.hxx>
52 #include <vigra/graph_algorithms.hxx>
53 
54 
55 
56 namespace opengm
57 {
58 
59 
60 
61 
62 template<class INFERENCE, class INTERSECTION_BASED, class INTERSECTION_BASED_VISITOR>
64 
65 public:
66 
67  CgcRedirectingVisitor(INTERSECTION_BASED & intersectionBased, INTERSECTION_BASED_VISITOR & otherVisitor)
68  : intersectionBased_(intersectionBased),
69  otherVisitor_(otherVisitor){
70 
71  }
72 
73 
74  void begin(INFERENCE & inf){
75 
76  }
77 
78  size_t operator()(INFERENCE & inf){
79  inf.arg(intersectionBased_._getArgRef());
80  intersectionBased_._setBestVal(inf.value());
81  return otherVisitor_(intersectionBased_);
82  }
83 
84  void end(INFERENCE & inf){
85 
86 
87  }
88 
89  void addLog(const std::string & logName){
90 
91 
92 
93  }
94 
95  void log(const std::string & logName,const double logValue){
96 
97 
98 
99  }
100 
101 private:
102  INTERSECTION_BASED & intersectionBased_;
103  INTERSECTION_BASED_VISITOR & otherVisitor_;
104 };
105 
106 
107 
108 
109 
110 
111 namespace proposal_gen{
112 
113  template<class G, class VEC>
115  public:
116  typedef typename G::Edge Key;
117  typedef typename VEC::value_type Value;
118  typedef typename VEC::reference Reference;
119  typedef typename VEC::const_reference ConstReference;
120 
121  VectorViewEdgeMap(const G & g, VEC & vec)
122  :
123  graph_(g),
124  vec_(vec){
125  }
126 
127  Reference operator[](const Key & key){
128  return vec_[graph_.id(key)];
129  }
130  ConstReference operator[](const Key & key)const{
131  return vec_[graph_.id(key)];
132  }
133  private:
134  const G & graph_;
135  VEC & vec_;
136  };
137 
138  template<class G, class VEC>
140  public:
141  typedef typename G::Node Key;
142  typedef typename VEC::value_type Value;
143  typedef typename VEC::reference Reference;
144  typedef typename VEC::const_reference ConstReference;
145 
146  VectorViewNodeMap(const G & g, VEC & vec)
147  :
148  graph_(g),
149  vec_(vec){
150  }
151 
152  Reference operator[](const Key & key){
153  return vec_[graph_.id(key)];
154  }
155  ConstReference operator[](const Key & key)const{
156  return vec_[graph_.id(key)];
157  }
158  private:
159  const G & graph_;
160  VEC & vec_;
161  };
162 
163 
164 
165 
166  template<class VALUE_TYPE>
168  public:
169  typedef VALUE_TYPE ValueType;
170 
171 
172 
173  struct Parameter{
174 
175  enum NoiseType{
176  NormalAdd = 0 ,
179  None = 3
180  };
181 
183  const NoiseType noiseType = NormalAdd,
184  const float noiseParam = 1.0,
185  const size_t seed = 42,
186  const bool ignoreSeed = true,
187  const bool autoScale = false,
188  const float permuteN = -1.0
189  )
190  :
191  noiseType_(noiseType),
192  noiseParam_(noiseParam),
193  seed_(seed),
194  ignoreSeed_(ignoreSeed),
195  autoScale_(autoScale),
196  permuteN_(permuteN)
197  {
198 
199  }
200 
202  float noiseParam_;
203  size_t seed_;
206  float permuteN_;
207  };
208 
209  WeightRandomization(const Parameter & param = Parameter())
210  :
211  param_(param),
212  randGen_(vigra::UInt32(param.seed_), param.ignoreSeed_),
213  calclulatedMinMax_(false){
214 
215  }
216 
217  void randomize(const std::vector<ValueType> & weights, std::vector<ValueType> & rweights){
218 
219  if(param_.autoScale_ && !calclulatedMinMax_){
220  // find the min max
221  ValueType wmin = std::numeric_limits<ValueType>::infinity();
222  ValueType wmax = static_cast<ValueType>(-1.0)*std::numeric_limits<ValueType>::infinity();
223  for(size_t i=0; i<rweights.size(); ++i){
224  wmin = std::min(weights[i], wmin);
225  wmax = std::max(weights[i], wmax);
226  }
227  ValueType range = wmax - wmin;
228  calclulatedMinMax_ = true;
229  param_.noiseParam_ *= range;
230  }
231 
232 
233  if (param_.noiseType_ == Parameter::NormalAdd){
234 
235 
236  for(size_t i=0; i<rweights.size(); ++i){
237  rweights[i] = weights[i] + randGen_.normal()*param_.noiseParam_;
238  }
239  }
240  else if(param_.noiseType_ == Parameter::UniformAdd){
241  for(size_t i=0; i<rweights.size(); ++i){
242  rweights[i] = weights[i] + randGen_.uniform(-1.0*param_.noiseParam_, param_.noiseParam_);
243  }
244  }
245  else if(param_.noiseType_ == Parameter::NormalMult){
246  for(size_t i=0; i<rweights.size(); ++i){
247  rweights[i] = weights[i]*randGen_.normal(1.0, param_.noiseParam_);
248  }
249  }
250  else if(param_.noiseType_ == Parameter::None){
251  std::copy(weights.begin(), weights.begin()+rweights.size(), rweights.begin());
252  }
253  else{
254  throw RuntimeError("wrong noise type");
255  }
256 
257 
258 
259  // DO PERMUTATION
260  if(param_.permuteN_ > 0.0){
261  size_t nP = param_.permuteN_ > 1.0 ?
262  size_t(param_.permuteN_) :
263  size_t(param_.permuteN_ * float(rweights.size()));
264 
265  for(size_t p=0; p< nP; ++p){
266  size_t fi0 = randGen_.uniformInt(rweights.size());
267  size_t fi1 = randGen_.uniformInt(rweights.size());
268  if(fi0!=fi1){
269  std::swap(rweights[fi0], rweights[fi1]);
270  }
271  }
272  }
273 
274  }
275  vigra::RandomNumberGenerator< > & randGen(){
276  return randGen_;
277  }
278 
279  private:
280  Parameter param_;
281  vigra::RandomNumberGenerator< > randGen_;
282 
283  bool calclulatedMinMax_;
284  };
285 
286 
287  #ifndef NOVIGRA
288  template<class GM, class ACC >
290  public:
291  typedef ACC AccumulationType;
292  typedef GM GraphicalModelType;
294 
295  typedef vigra::AdjacencyListGraph Graph;
296  typedef vigra::MergeGraphAdaptor< Graph > MergeGraph;
297 
298 
300  typedef typename WeightRand::Parameter WeightRandomizationParam;
301 
302  typedef typename MergeGraph::Edge Edge;
303  typedef ValueType WeightType;
304  typedef IndexType index_type;
305  struct Parameter
306  {
307 
308 
309 
311  const WeightRandomizationParam & randomizer = WeightRandomizationParam(),
312  const float stopWeight = 0.0,
313  const float nodeNum = -1.0,
314  const float ignoreNegativeWeights = false,
315  const bool setCutToZero = false
316  )
317  :
318  randomizer_(randomizer),
319  stopWeight_(stopWeight),
320  nodeStopNum_(nodeNum),
321  setCutToZero_(setCutToZero)
322  {
323 
324  }
325  WeightRandomizationParam randomizer_;
326  float stopWeight_;
330  };
331 
332 
333  RandMcClusterOp(const Graph & graph , MergeGraph & mergegraph,
334  const Parameter & param)
335  :
336  graph_(graph),
337  mergeGraph_(mergegraph),
338  pq_(graph.edgeNum()),
339  param_(param),
340  nodeStopNum_(0),
341  rWeights_(graph.edgeNum()),
342  wRandomizer_(param.randomizer_){
343 
344  if(param_.nodeStopNum_>0.000001 && param_.nodeStopNum_<=1.0 ){
345  float keep = param_.nodeStopNum_;
346  keep = std::max(0.0f, keep);
347  keep = std::min(1.0f, keep);
348  nodeStopNum_ = IndexType(float(graph_.nodeNum())*keep);
349  }
350  else if(param_.nodeStopNum_ >= 1.0){
352  }
353  else{
354  nodeStopNum_ = 2;
355  }
356 
357  }
358 
359 
360 
361 
362  void reset(){
363  pq_.reset();
364  }
365 
366 
367  void setWeights(const std::vector<ValueType> & weights,
368  const std::vector<LabelType> & labels){
369 
370  wRandomizer_.randomize(weights, rWeights_);
371 
372 
373  if(param_.setCutToZero_ == false){
374  for(size_t i=0; i<graph_.edgeNum(); ++i){
375  pq_.push(i, rWeights_[i]);
376  }
377  }
378  else{
379  for(size_t i=0; i<graph_.edgeNum(); ++i){
380  size_t u = graph_.id(graph_.u(graph_.edgeFromId(i)));
381  size_t v = graph_.id(graph_.v(graph_.edgeFromId(i)));
382  if(labels[u] == labels[v])
383  pq_.push(i, rWeights_[i]);
384  else
385  pq_.push(i, 0.0);
386  }
387  }
388  }
389 
391  index_type minLabel = pq_.top();
392  while(mergeGraph_.hasEdgeId(minLabel)==false){
393  pq_.deleteItem(minLabel);
394  minLabel = pq_.top();
395  }
396  return Edge(minLabel);
397  }
398 
400  WeightType contractionWeight(){
401  index_type minLabel = pq_.top();
402  while(mergeGraph_.hasEdgeId(minLabel)==false){
403  pq_.deleteItem(minLabel);
404  minLabel = pq_.top();
405  }
406  return pq_.topPriority();
407 
408  }
409 
411  MergeGraph & mergeGraph(){
412  return mergeGraph_;
413  }
414 
415  bool done()const{
416  const bool doneByWeight = pq_.topPriority()<=ValueType(param_.stopWeight_);
417  const bool doneByNodeNum = mergeGraph_.nodeNum()<nodeStopNum_;
418  return doneByWeight || doneByNodeNum;
419  }
420 
421  void mergeEdges(const Edge & a,const Edge & b){
422  rWeights_[a.id()]+=rWeights_[b.id()];
423  pq_.push(a.id(), rWeights_[a.id()]);
424  pq_.deleteItem(b.id());
425  }
426 
427  void eraseEdge(const Edge & edge){
428  pq_.deleteItem(edge.id());
429  }
430 
431  const Graph & graph_;
432  MergeGraph & mergeGraph_;
433  vigra::ChangeablePriorityQueue< ValueType ,std::greater<ValueType> > pq_;
435  size_t nodeStopNum_;
436  std::vector<ValueType> rWeights_;
437  WeightRand wRandomizer_;
438  };
439 
440  template<class GM, class ACC>
442  public:
443  typedef ACC AccumulationType;
444  typedef GM GraphicalModelType;
446 
447  typedef vigra::AdjacencyListGraph Graph;
448  typedef vigra::MergeGraphAdaptor< Graph > MGraph;
449 
451  typedef typename WeightRand::Parameter WeightRandomizationParam;
452 
454  typedef typename Cop::Parameter CopParam;
455  typedef vigra::HierarchicalClustering< Cop > HC;
456  typedef typename HC::Parameter HcParam;
457 
458 
459 
460  typedef typename Graph::Edge GraphEdge;
461 
462  struct Parameter : public CopParam
463  {
464 
465 
466 
468  const WeightRandomizationParam & randomizer = WeightRandomizationParam(),
469  const float stopWeight = 0.0,
470  const float nodeStopNum = -1.0,
471  const bool ignoreNegativeWeights = false,
472  const bool setCutToZero = true
473  )
474  : CopParam(randomizer, stopWeight, nodeStopNum,setCutToZero)
475  {
476 
477  }
478  };
479 
480 
481 
482 
483 
484  RandomizedHierarchicalClustering(const GM & gm, const Parameter & param = Parameter())
485  :
486  gm_(gm),
487  weights_(gm.numberOfFactors(),ValueType(0.0)),
488  param_(param),
489  graph_(),
490  mgraph_(NULL),
491  clusterOp_(NULL)
492  {
493 
494 
495  LabelType lAA[2]={0, 0};
496  LabelType lAB[2]={0, 1};
497 
498  //std::cout<<"add nodes\n";
499  for(size_t i=0; i<gm_.numberOfVariables();++i){
500  graph_.addNode(i);
501  }
502 
503  //std::cout<<"add edges\n";
504  for(size_t i=0; i<gm_.numberOfFactors(); ++i){
505  if(gm_[i].numberOfVariables()==2){
506  const ValueType val00 = gm_[i](lAA);
507  const ValueType val01 = gm_[i](lAB);
508  const ValueType weight = val01 - val00;
509  if(!param_.ignoreNegativeWeights_ || weight >= 0.0){
510  const GraphEdge gEdge = graph_.addEdge(gm_[i].variableIndex(0),gm_[i].variableIndex(1));
511  weights_[gEdge.id()]+=weight;
512  }
513  }
514  }
515 
516  }
517 
519  if(mgraph_ != NULL){
520  delete mgraph_;
521  delete clusterOp_;
522  }
523  }
524  size_t defaultNumStopIt() {return 100;}
525 
526  void reset(){
527 
528  }
529  void getProposal(const std::vector<LabelType> &current , std::vector<LabelType> &proposal){
530 
531 
532 
533 
534  if(mgraph_ == NULL){
535  mgraph_ = new MGraph(graph_);
536  clusterOp_ = new Cop(graph_, *mgraph_ , param_);
537  }
538  else{
539  mgraph_->reset();
540  clusterOp_->reset();
541  }
542 
543 
544  HcParam p;
545  p.verbose_=false;
546  p.buildMergeTreeEncoding_=false;
547 
548 
549 
550  //std::cout<<"alloc cluster op\n";
551 
552 
553  //std::cout<<"set weights \n";
554  clusterOp_->setWeights(weights_, current);
555 
556  //std::cout<<"alloc hc\n";
557  HC hc(*clusterOp_,p);
558 
559  //std::cout<<"start\n";
560  hc.cluster();
561 
562  //std::cout<<"get reps.\n";
563  for(size_t i=0; i< gm_.numberOfVariables(); ++i){
564  proposal[i] = hc.reprNodeId(i);
565  }
566  //std::cout<<"get reps.done \n";
567 
568  }
569  private:
570  const GM & gm_;
571  Parameter param_;
572  std::vector<ValueType> weights_;
573  vigra::AdjacencyListGraph graph_;
574  MGraph * mgraph_;
575  Cop * clusterOp_;
576  };
577 
578 
579  template<class GM, class ACC>
581  public:
582  typedef ACC AccumulationType;
583  typedef GM GraphicalModelType;
585 
586  typedef vigra::AdjacencyListGraph Graph;
587 
588 
589  typedef typename Graph::Edge GraphEdge;
590 
591  typedef typename Graph:: template EdgeMap<ValueType> WeightMap;
592  typedef typename Graph:: template EdgeMap<vigra::UInt32> LabelMap;
593 
595  typedef typename WeightRand::Parameter WeightRandomizationParam;
596 
597  struct Parameter
598  {
599 
600 
601 
603  const float seedFraction = 0.01,
604  const bool ignoreNegativeWeights = false,
605  const bool seedFromNegativeEdges = true,
606  const WeightRandomizationParam randomizer = WeightRandomizationParam()
607 
608  )
609  :
610  seedFraction_(seedFraction),
611  ignoreNegativeWeights_(ignoreNegativeWeights),
612  seedFromNegativeEdges_(seedFromNegativeEdges),
613  randomizer_(randomizer)
614  {
615 
616  }
617 
621  WeightRandomizationParam randomizer_;
622  };
623 
624 
625 
626 
627  RandomizedWatershed(const GM & gm, const Parameter & param = Parameter())
628  :
629  gm_(gm),
630  param_(param),
631  wRandomizer_(param.randomizer_),
632  graph_(),
633  weights_(gm_.numberOfFactors()),
634  rWeights_(),
635  seeds_(),
636  negativeFactors_()
637  {
638 
639  LabelType lAA[2]={0, 0};
640  LabelType lAB[2]={0, 1};
641 
642  //std::cout<<"add nodes\n";
643  for(size_t i=0; i<gm_.numberOfVariables();++i){
644  graph_.addNode(i);
645  }
646 
647  for(size_t i=0; i<gm_.numberOfFactors(); ++i){
648  if(gm_[i].numberOfVariables()==2){
649  ValueType val00 = gm_[i](lAA);
650  ValueType val01 = gm_[i](lAB);
651  ValueType weight = val01 - val00;
652  if(!param_.ignoreNegativeWeights_ || weight >= 0.0){
653  const GraphEdge gEdge = graph_.addEdge(gm_[i].variableIndex(0),gm_[i].variableIndex(1));
654  weights_[gEdge.id()]+=weight;
655  }
656  if(param_.seedFromNegativeEdges_ && weight < 0.0){
657  negativeFactors_.push_back(i);
658  }
659  }
660  }
661 
662  //weights_.resize(graph_.edgeNum());
663  rWeights_.resize(graph_.edgeNum());
664  seeds_.resize(graph_.maxNodeId()+1);
665  }
666 
667 
668  size_t defaultNumStopIt() {return 100;}
669 
670  void reset(){
671 
672  }
673  void getProposal(const std::vector<LabelType> &current , std::vector<LabelType> &proposal){
674 
675 
676  const size_t nSeeds = param_.seedFraction_ <=1.0 ?
677  size_t(float(graph_.nodeNum())*param_.seedFraction_+0.5f) :
678  size_t(param_.seedFraction_ + 0.5);
679  std::fill(seeds_.begin(), seeds_.end(), 0);
680 
681 
682  // randomize weights
683  wRandomizer_.randomize(weights_, rWeights_);
684 
685  // vectorViewEdgeMap
686  VectorViewEdgeMap<Graph, std::vector<ValueType> > wMap(graph_, rWeights_);
688  VectorViewNodeMap<Graph, std::vector<LabelType> > lMap(graph_, proposal);
689 
690 
691  if(!param_.seedFromNegativeEdges_){
692  for(size_t i=0; i<nSeeds; ++i){
693  const int randId = wRandomizer_.randGen().uniformInt(graph_.nodeNum());
694  seeds_[randId] = i+1;
695  }
696  }
697  else{
698  //std::cout<<"using n seeds = "<<nSeeds<<"\n";
699 
700 
701  for(size_t i=0; i<nSeeds/2; ++i){
702  const int randId = wRandomizer_.randGen().uniformInt(negativeFactors_.size());
703  const IndexType fi = negativeFactors_[randId];
704 
705  //std::cout<<" fi "<<fi<<" ";
706  const IndexType vi0 = gm_[fi].variableIndex(0);
707  const IndexType vi1 = gm_[fi].variableIndex(1);
708 
709  seeds_[vi0] = (2*i)+1;
710  seeds_[vi1] = (2*i+1)+1;
711  }
712  //std::cout<<"\n";
713  }
714 
715  // negate
716  for(size_t i=0; i<graph_.edgeNum(); ++i){
717  rWeights_[i] *= -1.0;
718  }
719 
720  vigra::edgeWeightedWatershedsSegmentation(graph_, wMap, sMap, lMap);
721  }
722  private:
723  const GM & gm_;
724  Parameter param_;
725  WeightRand wRandomizer_;
726  Graph graph_;
727  std::vector<ValueType> weights_;
728  std::vector<ValueType> rWeights_;
729  std::vector<LabelType> seeds_;
730  std::vector<IndexType> negativeFactors_;
731  };
732  #endif
733 
734 
735  #ifdef WITH_QPBO
736  template<class GM, class ACC>
737  class QpboBased{
738  public:
739  typedef ACC AccumulationType;
740  typedef GM GraphicalModelType;
742 
743  typedef WeightRandomization<ValueType> WeightRand;
744  typedef typename WeightRand::Parameter WeightRandomizationParam;
745 
746  class Parameter
747  {
748  public:
749  Parameter(
750  const WeightRandomizationParam & randomizer = WeightRandomizationParam()
751  )
752  : randomizer_(randomizer)
753  {
754 
755  }
756  WeightRandomizationParam randomizer_;
757  };
758 
759 
760 
761 
762  QpboBased(const GM & gm, const Parameter & param = Parameter())
763  :
764  gm_(gm),
765  param_(param),
766  qpbo_(NULL),
767  //qpbo_(int(gm.numberOfVariables()), int(gm.numberOfFactors()), NULL),
768  iteration_(0),
769  weights_(gm.numberOfFactors()),
770  rweights_(gm.numberOfFactors()),
771  wRandomizer_(param_.randomizer_)
772  {
773  //srand(42);
774  qpbo_ = new kolmogorov::qpbo::QPBO<ValueType>(int(gm.numberOfVariables()),
775  int(gm.numberOfFactors()), NULL);
776 
777  LabelType lAA[2]={0, 0};
778  LabelType lAB[2]={0, 1};
779 
780 
781  for(size_t i=0; i<gm_.numberOfFactors(); ++i){
782  if(gm_[i].numberOfVariables()==2){
783  ValueType val00 = gm_[i](lAA);
784  ValueType val01 = gm_[i](lAB);
785  ValueType weight = val01 - val00;
786  weights_[i]=weight;
787  }
788  }
789 
790  }
791 
792  ~QpboBased(){
793  delete qpbo_;
794  }
795 
796  size_t defaultNumStopIt() {
797  return 0;
798  }
799 
800  void reset(){
801 
802  }
803  void getProposal(const std::vector<LabelType> &current , std::vector<LabelType> &proposal){
804 
805  LabelType lAA[2]={0, 0};
806  LabelType lAB[2]={0, 1};
807 
808 
809  if(iteration_>0){
810  qpbo_->Reset();
811  }
812 
813  // randomize
814  // randomize weights
815  wRandomizer_.randomize(weights_, rweights_);
816 
817  // add nodes
818  qpbo_->AddNode(gm_.numberOfVariables());
819 
820  // add edges
821  for(size_t i=0; i<gm_.numberOfFactors(); ++i){
822  if(gm_[i].numberOfVariables()==2){
823 
824 
825  // check if current edge is cut
826 
827  const IndexType vi0 = gm_[i].variableIndex(0);
828  const IndexType vi1 = gm_[i].variableIndex(1);
829 
830  if(current[vi0] == current[vi1]){
831  const ValueType weight = rweights_[i];
832  qpbo_->AddPairwiseTerm( vi0, vi1, 0.0, weight, weight, 0.0);
833  }
834  else{
835  qpbo_->AddPairwiseTerm( vi0, vi1, 0.0, 0.0, 0.0, 0.0);
836  }
837  }
838  }
839 
840  // merge parallel edges
841  qpbo_->MergeParallelEdges();
842 
843  // set label for one variable
844  qpbo_->SetLabel(0, 0);
845 
846  // run optimization
847  qpbo_->Improve();
848 
849  for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
850  const int l = qpbo_->GetLabel(vi);
851  proposal[vi] = l ==-1 ? 0 : l ;
852  }
853 
854  ++iteration_;
855  }
856  private:
857  const GM & gm_;
858  Parameter param_;
859  kolmogorov::qpbo::QPBO<ValueType> * qpbo_;
860  size_t iteration_;
861  std::vector<ValueType> weights_;
862  std::vector<ValueType> rweights_;
863  WeightRand wRandomizer_;
864  };
865 
866  #endif
867 
868  /*
869  template<class GM, class ACC>
870  class BlockGen{
871  public:
872  typedef ACC AccumulationType;
873  typedef GM GraphicalModelType;
874  OPENGM_GM_TYPE_TYPEDEFS;
875 
876  typedef WeightRandomization<ValueType> WeightRand;
877  typedef typename WeightRand::Parameter WeightRandomizationParam;
878 
879  class Parameter
880  {
881  public:
882  Parameter(
883  const double numVar = 0.1,
884  const bool seedFromNegativeEdges = true,
885  const WeightRandomizationParam & randomizer = WeightRandomizationParam()
886  )
887  :
888  numVar_(numVar),
889  randomizer_(randomizer)
890  {
891 
892  }
893  WeightRandomizationParam randomizer_;
894  double numVar_;
895  };
896 
897 
898 
899 
900  BlockGen(const GM & gm, const Parameter & param = Parameter())
901  :
902  gm_(gm),
903  param_(param),
904  wRandomizer_(param_.randomizer_),
905  viAdjacency_(gm.numberOfVariables()),
906  vis_(gm.numberOfVariables()),
907  usedVi_(gm.numberOfVariables(), 0)
908  {
909 
910  // compute variable adjacency
911  gm.variableAdjacencyList(viAdjacency_);
912 
913  LabelType lAA[2]={0, 0};
914  LabelType lAB[2]={0, 1};
915 
916  if(param_.seedFromNegativeEdges_){
917  for(size_t i=0; i<gm_.numberOfFactors(); ++i){
918  if(gm_[i].numberOfVariables()==2){
919  ValueType val00 = gm_[i](lAA);
920  ValueType val01 = gm_[i](lAB);
921  ValueType weight = val01 - val00;
922  if(weight < 0.0){
923  negativeFactors_.push_back(i);
924  }
925  }
926  }
927  }
928 
929  }
930 
931  ~BlockGen(){
932 
933  }
934 
935  size_t defaultNumStopIt() {
936  return 0;
937  }
938 
939  void reset(){
940 
941  }
942  void getProposal(const std::vector<LabelType> &current , std::vector<LabelType> &proposal){
943 
944  std::fill(proposal.begin(), proposal.end(), LabelType(0));
945 
946  // how many variable should the subgraph contain
947  size_t sgSize = size_t( param_.numVar_ > 1.0f ?
948  param_.numVar_ :
949  float(gm_.numberOfVariables())*param_.numVar_);
950 
951  size_t rVar;
952  // get a random negative edge factor
953  if(param_.seedFromNegativeEdges_){
954  const size_t rFactor = wRandomizer_.uniformInt(negativeFactors_.size());
955  rVar = gm_[rFactor].variableIndex(wRandomizer_.uniformInt(2));
956  }
957  else{
958  rVar = wRandomizer_.uniformInt(gm_.numberOfVariables());
959  }
960 
961 
962  // grow subgraph SG until |SG| == param_.numVar_;
963  std::fill(usedVi_.begin(),usedVi_.end(),false);
964  vis.clear();
965  vis.push_back(startVi);
966  usedVi_[startVi]=true;
967  std::queue<size_t> viQueue;
968  viQueue.push(startVi);
969 
970  std::fill(distance_.begin(),distance_.begin()+gm_.numberOfVariables(),0);
971 
972  const size_t maxSgSize = (param_.maxBlockSize_==0? gm_.numberOfVariables() :param_.maxBlockSize_);
973  while(viQueue.size()!=0 && vis.size()<=maxSgSize) {
974  size_t cvi=viQueue.front();
975  viQueue.pop();
976  // for each neigbour of cvi
977  for(size_t vni=0;vni<viAdjacency_[cvi].size();++vni) {
978  // if neighbour has not been visited
979  const size_t vn=viAdjacency_[cvi][vni];
980  if(usedVi_[vn]==false) {
981  // set as visited
982  usedVi_[vn]=true;
983  // insert into the subgraph vis
984  distance_[vn]=distance_[cvi]+1;
985  if(distance_[vn]<=radius){
986  if(vis.size()<maxSgSize){
987  vis.push_back(vn);
988  viQueue.push(vn);
989  }
990  else{
991  break;
992  }
993  }
994  }
995  }
996  }
997 
998  }
999  private:
1000  const GM & gm_;
1001  Parameter param_;
1002  WeightRand wRandomizer_;
1003  std::vector<IndexType> negativeFactors_;
1004  std::vector< RandomAccessSet<IndexType> > viAdjacency_;
1005  std::vector<IndexType> sgVis_;
1006  std::vector<unsigned char> usedVi_;
1007  };
1008  */
1009 
1010 }
1011 
1012 
1013 template<class GM, class PROPOSAL_GEN>
1014 class IntersectionBasedInf : public Inference<GM, typename PROPOSAL_GEN::AccumulationType>
1015 {
1016 public:
1017 
1018 
1019 
1020  typedef PROPOSAL_GEN ProposalGen;
1021  typedef typename ProposalGen::AccumulationType AccumulationType;
1022  typedef AccumulationType ACC;
1025 
1029 
1031 
1032  typedef typename ProposalGen::Parameter ProposalParameter;
1034 
1035 
1036 
1038  {
1039  public:
1041  const ProposalParameter & proposalParam = ProposalParameter(),
1042  const FusionParameter & fusionParam = FusionParameter(),
1043  const size_t numIt=1000,
1044  const size_t numStopIt = 0,
1045  const size_t parallelProposals = 1,
1046  const bool cgcFinalization = false,
1047  const bool planar = false,
1048  const bool doCutMove = false,
1049  const bool acceptFirst = true,
1050  const bool warmStart = true,
1051  const std::vector<bool> & allowCutsWithin = std::vector<bool> ()
1052  )
1053  : proposalParam_(proposalParam),
1054  fusionParam_(fusionParam),
1055  numIt_(numIt),
1056  numStopIt_(numStopIt),
1057  parallelProposals_(parallelProposals),
1058  cgcFinalization_(cgcFinalization),
1059  planar_(planar),
1060  doCutMove_(doCutMove),
1061  acceptFirst_(acceptFirst),
1062  warmStart_(warmStart),
1063  allowCutsWithin_(allowCutsWithin)
1064  {
1065  storagePrefix_ = std::string("");
1066  }
1067  ProposalParameter proposalParam_;
1068  FusionParameter fusionParam_;
1069  size_t numIt_;
1070  size_t numStopIt_;
1073  bool planar_;
1076  std::vector<bool> allowCutsWithin_;
1078  std::string storagePrefix_;
1079 
1080  };
1081 
1082 
1083  IntersectionBasedInf(const GraphicalModelType &, const Parameter & = Parameter() );
1085  std::string name() const;
1086  const GraphicalModelType &graphicalModel() const;
1088  void reset();
1089  template<class VisitorType>
1090  InferenceTermination infer(VisitorType &);
1091  void setStartingPoint(typename std::vector<LabelType>::const_iterator);
1092  virtual InferenceTermination arg(std::vector<LabelType> &, const size_t = 1) const ;
1093  virtual ValueType value()const {return bestValue_;}
1094 
1095 
1096  std::vector<LabelType> & _getArgRef(){
1097  return bestArg_;
1098  }
1099 
1100  void _setBestVal(const ValueType value){
1101  bestValue_ = value;
1102  }
1103 private:
1104 
1105  template<class VisitorType>
1106  InferenceTermination inferIntersectionBased(VisitorType &);
1107 
1108 
1109  typedef FusionMoverType * FusionMoverTypePtr;
1110  typedef PROPOSAL_GEN * ProposalGenTypePtr;
1111 
1112  const GraphicalModelType &gm_;
1113  Parameter param_;
1114 
1115 
1116  FusionMoverType * fusionMover_;
1117  FusionMoverTypePtr * fusionMoverArray_;
1118 
1119 
1120  PROPOSAL_GEN * proposalGen_;
1121  ProposalGenTypePtr * proposalGenArray_;
1122 
1123  ValueType bestValue_;
1124  std::vector<LabelType> bestArg_;
1125  size_t maxOrder_;
1126 
1127  typedef CGC<GM, ACC> CgcInf;
1128  typedef typename CgcInf::Parameter CgcParam;
1129 
1130  CgcInf * cgcInf_;
1131 };
1132 
1133 
1134 
1135 
1136 template<class GM, class PROPOSAL_GEN>
1139  const GraphicalModelType &gm,
1140  const Parameter &parameter
1141 )
1142  : gm_(gm),
1143  param_(parameter),
1144  fusionMover_(NULL),
1145  fusionMoverArray_(NULL),
1146  proposalGen_(NULL),
1147  proposalGenArray_(NULL),
1148  //proposalGen_(gm_, parameter.proposalParam_),
1149  bestValue_(),
1150  bestArg_(gm_.numberOfVariables(), 0),
1151  maxOrder_(gm.factorOrder()),
1152  cgcInf_(NULL)
1153 {
1154  ACC::neutral(bestValue_);
1155 
1156 
1157  //param_.fusionParam_.allowCutsWithin_ = param_.allowCutsWithin_;
1158  //fusionMover_ =
1159 
1160 
1161  size_t nFuser = param_.parallelProposals_;
1162  fusionMoverArray_ = new FusionMoverTypePtr[nFuser];
1163  proposalGenArray_ = new ProposalGenTypePtr[nFuser];
1164 
1165  for(size_t f=0; f<nFuser; ++f){
1166  fusionMoverArray_[f] = new FusionMoverType(gm_,param_.fusionParam_);
1167  proposalGenArray_[f] = new PROPOSAL_GEN(gm_, param_.proposalParam_);
1168  }
1169 
1170  fusionMover_ = fusionMoverArray_[0];
1171  proposalGen_ = proposalGenArray_[0];
1172 
1173  if(!param_.warmStart_){
1174  //set default starting point
1175  std::vector<LabelType> conf(gm_.numberOfVariables(),0);
1176  setStartingPoint(conf.begin());
1177  }
1178  else{
1179 
1180  LabelType lAA[2]={0, 0};
1181  LabelType lAB[2]={0, 1};
1182  Partition<LabelType> ufd(gm_.numberOfVariables());
1183  for(size_t fi=0; fi< gm_.numberOfFactors(); ++fi){
1184  if(gm_[fi].numberOfVariables()==2){
1185 
1186  const ValueType val00 = gm_[fi](lAA);
1187  const ValueType val01 = gm_[fi](lAB);
1188  const ValueType weight = val01 - val00;
1189  if(weight>0.0){
1190  const size_t vi0 = gm_[fi].variableIndex(0);
1191  const size_t vi1 = gm_[fi].variableIndex(1);
1192  ufd.merge(vi0, vi1);
1193  }
1194  }
1195  else{
1196  throw RuntimeError("wrong factor order for multicut");
1197  }
1198  }
1199  std::vector<LabelType> conf(gm_.numberOfVariables(),0);
1200  for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
1201  conf[vi] = ufd.find(vi);
1202  }
1203  setStartingPoint(conf.begin());
1204  }
1205 
1206 
1207 
1208 
1209  if(param_.cgcFinalization_){
1210  CgcParam cgcParam;
1211  cgcParam.planar_ = param_.planar_;
1212  cgcParam.doCutMove_ = param_.doCutMove_;
1213  cgcParam.startFromThreshold_ = false;
1214  cgcInf_ = new CgcInf(gm_, cgcParam);
1215  }
1216 }
1217 
1218 
1219 template<class GM, class PROPOSAL_GEN>
1221 {
1222  for(size_t f=0; f<param_.parallelProposals_; ++f){
1223  delete fusionMoverArray_[f];// = new FusionMoverType(gm_,parameter.fusionParam_);
1224  delete proposalGenArray_[f];
1225  }
1226 
1227  delete[] fusionMoverArray_;
1228  delete[] proposalGenArray_;
1229 
1230  if(param_.cgcFinalization_){
1231  delete cgcInf_;
1232  }
1233 }
1234 
1235 
1236 template<class GM, class PROPOSAL_GEN>
1237 inline void
1239 {
1240  throw RuntimeError("not implemented yet");
1241 }
1242 
1243 template<class GM, class PROPOSAL_GEN>
1244 inline void
1247  typename std::vector<typename IntersectionBasedInf<GM, PROPOSAL_GEN>::LabelType>::const_iterator begin
1248 )
1249 {
1250  std::copy(begin, begin + gm_.numberOfVariables(), bestArg_.begin());
1251  bestValue_ = gm_.evaluate(bestArg_.begin());
1252 }
1253 
1254 template<class GM, class PROPOSAL_GEN>
1255 inline std::string
1257 {
1258  return "IntersectionBasedInf";
1259 }
1260 
1261 template<class GM, class PROPOSAL_GEN>
1264 {
1265  return gm_;
1266 }
1267 
1268 template<class GM, class PROPOSAL_GEN>
1269 inline InferenceTermination
1271 {
1272  EmptyVisitorType v;
1273  return infer(v);
1274 }
1275 template<class GM, class PROPOSAL_GEN>
1276 template<class VisitorType>
1279  VisitorType &visitor
1280 ){
1281  visitor.begin(*this);
1282  InferenceTermination infTerm = this->inferIntersectionBased(visitor);
1283  if(param_.cgcFinalization_){
1284 
1285 
1286  CgcRedirectingVisitor<CgcInf, IntersectionBasedInf<GM, PROPOSAL_GEN> , VisitorType> redirectingVisitor(*this, visitor);
1287 
1288  cgcInf_->setStartingPoint(bestArg_.begin());
1289  cgcInf_->infer(redirectingVisitor);
1290  cgcInf_->arg(bestArg_);
1291  bestValue_ = gm_.evaluate(bestArg_);
1292  }
1293  visitor.end(*this);
1294  return infTerm;
1295 }
1296 
1297 
1298 template<class GM, class PROPOSAL_GEN>
1299 template<class VisitorType>
1301 (
1302  VisitorType &visitor
1303 )
1304 {
1305  // evaluate the current best state
1306  bestValue_ = gm_.evaluate(bestArg_.begin());
1307 
1308 
1309 
1310 
1311  if(param_.numStopIt_ == 0){
1312  param_.numStopIt_ = proposalGen_->defaultNumStopIt();
1313  }
1314 
1315  std::vector<LabelType> proposedState(gm_.numberOfVariables());
1316  std::vector<LabelType> fusedState(gm_.numberOfVariables());
1317 
1318  size_t countRoundsWithNoImprovement = 0;
1319 
1320 
1321  size_t nFuser = param_.parallelProposals_;
1322 
1323  std::vector< std::vector<LabelType> > pVec;
1324  std::vector< std::vector<LabelType> > rVec;
1325 
1326  std::vector<ValueType> vVec;
1327  std::vector<bool> dVec;
1328  if(nFuser>1){
1329  pVec.resize(nFuser);
1330  rVec.resize(nFuser);
1331  vVec.resize(nFuser);
1332  dVec.resize(nFuser);
1333  for(size_t i=0; i<nFuser; ++i){
1334  pVec[i].resize(gm_.numberOfVariables());
1335  rVec[i].resize(gm_.numberOfVariables());
1336  dVec[i]=false;
1337  }
1338  }
1339 
1340  const bool mmcv = param_.allowCutsWithin_.size()>0;
1341 
1342  for(size_t iteration=0; iteration<param_.numIt_; ++iteration){
1343 
1344  if(mmcv && iteration == 0){
1345  ACC::neutral(bestValue_);
1346  continue;
1347  }
1348  else if(!mmcv && iteration == 0 && param_.acceptFirst_ && !param_.warmStart_){
1349  proposalGen_->getProposal(bestArg_,proposedState);
1350  std::copy(proposedState.begin(), proposedState.end(), bestArg_.begin());
1351  bestValue_ = gm_.evaluate(bestArg_);
1352  if(visitor(*this)!=0){
1353  break;
1354  }
1355  continue;
1356  }
1357 
1358  // store initial value before one proposal round
1359  const ValueType valueBeforeRound = bestValue_;
1360 
1361 
1362  bool anyVar=true;
1363 
1364  if(nFuser == 1){
1365  proposalGen_->getProposal(bestArg_,proposedState);
1366  ValueType proposalValue = gm_.evaluate(proposedState);
1367  if(mmcv)
1368  ACC::neutral(proposalValue);
1369  //std::cout<<"best val "<<bestValue_<<" pval "<<proposalValue<<"\n";
1370 
1371 
1372  if(!mmcv){
1373  anyVar = fusionMover_->fuse(bestArg_,proposedState, fusedState,
1374  bestValue_, proposalValue, bestValue_);
1375  }
1376  else{
1377  //std::cout<<"do cuts within\n";
1378  //anyVar = fusionMover_->fuseMmwc(bestArg_,proposedState, fusedState,
1379  // bestValue_, proposalValue, bestValue_);
1381  }
1382 
1383 
1384  if(!param_.storagePrefix_.empty()){
1385 
1386  {
1387  std::stringstream ss;
1388  ss<<param_.storagePrefix_<<iteration<<"proposal.txt";
1389  std::ofstream f(ss.str().c_str());
1390  for(size_t i=0; i<gm_.numberOfVariables(); ++i) {
1391  f << proposedState[i] << '\n';
1392  }
1393  }
1394  {
1395  std::stringstream ss;
1396  ss<<param_.storagePrefix_<<iteration<<"cbest.txt";
1397  std::ofstream f(ss.str().c_str());
1398  for(size_t i=0; i<gm_.numberOfVariables(); ++i) {
1399  f << bestArg_[i] << '\n';
1400  }
1401  }
1402  {
1403  std::stringstream ss;
1404  ss<<param_.storagePrefix_<<iteration<<"nbest.txt";
1405  std::ofstream f(ss.str().c_str());
1406  for(size_t i=0; i<gm_.numberOfVariables(); ++i) {
1407  f << fusedState[i] << '\n';
1408  }
1409  }
1410  }
1411  }
1412  else{
1413 
1414  // get proposals (so far not in parallel)
1415  //std::cout<<"generate proposas\n";
1416  //for(size_t i=0; i<nFuser; ++i){
1417  // dVec[i]=false;
1418  // proposalGen_.getProposal(bestArg_,pVec[i]);
1419  //}
1420 
1421  #pragma omp parallel for
1422  for(size_t i=0; i<nFuser; ++i){
1423  //#pragma omp critical(printstuff)
1424  //{
1425  //std::cout<<"fuse i"<<i<<"\n";
1426  //}
1427  proposalGenArray_[i]->getProposal(bestArg_,pVec[i]);
1428  bool tmp = fusionMoverArray_[i]->fuse(bestArg_,pVec[i], rVec[i],
1429  bestValue_, gm_.evaluate(pVec[i]), vVec[i]);
1430  if(bestValue_ < vVec[i]){
1431  dVec[i] = true;
1432  }
1433  }
1434  bool done = false;
1435  size_t total = nFuser;
1436  size_t c = 0;
1437  while(!done){
1438  //std::cout<<"TOTAL "<<total<<"\n";
1439  size_t left = 0;
1440  for(size_t i=0; i<total; ++i){
1441  if(dVec[i]==false){
1442  pVec[left] = rVec[i];
1443  ++left;
1444  }
1445  }
1446  if(left == 0 && c == 0){
1447  break;
1448  }
1449  else if(left==0 || left == 1){
1450  fusedState = rVec[0];
1451  bestValue_ = vVec[0];
1452  break;
1453  }
1454  ++c;
1455  // fuse all pairs
1456  #pragma omp parallel for
1457  for(size_t i=0; i<left; i+=2){
1458  if(i==left-1){
1459  continue;
1460  }
1461  //std::cout<<"fuse ii"<<i<<"\n";
1462  bool tmp = fusionMoverArray_[i]->fuse(
1463  pVec[i],pVec[i+1],rVec[i],
1464  gm_.evaluate(pVec[i]),
1465  gm_.evaluate(pVec[i+1]),
1466  vVec[i]
1467  );
1468  dVec[i+1] = true;
1469  --left;
1470  }
1471  total = left;
1472  }
1473  }
1474 
1475 
1476 
1477 
1478 
1479 
1480  if(anyVar){
1481  if( !ACC::bop(bestValue_, valueBeforeRound)){
1482  ++countRoundsWithNoImprovement;
1483  }
1484  else{
1485  // Improvement
1486  countRoundsWithNoImprovement = 0;
1487  bestArg_ = fusedState;
1488  }
1489  if(visitor(*this)!=0){
1490  break;
1491  }
1492  }
1493  else{
1494  if(visitor(*this)!=0){
1495  break;
1496  }
1497  ++countRoundsWithNoImprovement;
1498  }
1499  // check if converged or done
1500  if(countRoundsWithNoImprovement==param_.numStopIt_ && param_.numStopIt_ !=0 ){
1501  break;
1502  }
1503  }
1504  return NORMAL;
1505 }
1506 
1507 
1508 
1509 
1510 template<class GM, class PROPOSAL_GEN>
1511 inline InferenceTermination
1514  std::vector<LabelType> &x,
1515  const size_t N
1516 ) const
1517 {
1518  if (N == 1)
1519  {
1520  x.resize(gm_.numberOfVariables());
1521  for (size_t j = 0; j < x.size(); ++j)
1522  {
1523  x[j] = bestArg_[j];
1524  }
1525  return NORMAL;
1526  }
1527  else
1528  {
1529  return UNKNOWN;
1530  }
1531 }
1532 
1533 } // namespace opengm
1534 
1535 #endif // #ifndef OPENGM_INTERSECTION_BASED_INF_HXX
void addLog(const std::string &logName)
WeightRandomization(const Parameter &param=Parameter())
const GraphicalModelType & graphicalModel() const
Graph::template EdgeMap< ValueType > WeightMap
The OpenGM namespace.
Definition: config.hxx:43
RandomizedWatershed(const GM &gm, const Parameter &param=Parameter())
void getProposal(const std::vector< LabelType > &current, std::vector< LabelType > &proposal)
void merge(value_type, value_type)
Merge two sets.
Definition: partition.hxx:147
vigra::MergeGraphAdaptor< Graph > MergeGraph
MergeGraph & mergeGraph()
get a reference to the merge
Parameter(const ProposalParameter &proposalParam=ProposalParameter(), const FusionParameter &fusionParam=FusionParameter(), const size_t numIt=1000, const size_t numStopIt=0, const size_t parallelProposals=1, const bool cgcFinalization=false, const bool planar=false, const bool doCutMove=false, const bool acceptFirst=true, const bool warmStart=true, const std::vector< bool > &allowCutsWithin=std::vector< bool >())
vigra::RandomNumberGenerator< > & randGen()
void mergeEdges(const Edge &a, const Edge &b)
IntersectionBasedInf(const GraphicalModelType &, const Parameter &=Parameter())
WeightType contractionWeight()
get the edge weight of the edge which should be contracted next
opengm::visitors::VerboseVisitor< IntersectionBasedInf< GM, PROPOSAL_GEN > > VerboseVisitorType
void getProposal(const std::vector< LabelType > &current, std::vector< LabelType > &proposal)
vigra::ChangeablePriorityQueue< ValueType,std::greater< ValueType > > pq_
FusionMoverType::Parameter FusionParameter
opengm::visitors::EmptyVisitor< IntersectionBasedInf< GM, PROPOSAL_GEN > > EmptyVisitorType
Experimental Multicut.
Definition: cgc.hxx:121
ConstReference operator[](const Key &key) const
void randomize(const std::vector< ValueType > &weights, std::vector< ValueType > &rweights)
ProposalGen::Parameter ProposalParameter
Parameter(const WeightRandomizationParam &randomizer=WeightRandomizationParam(), const float stopWeight=0.0, const float nodeNum=-1.0, const float ignoreNegativeWeights=false, const bool setCutToZero=false)
RandMcClusterOp(const Graph &graph, MergeGraph &mergegraph, const Parameter &param)
ConstReference operator[](const Key &key) const
bool startFromThreshold_
Definition: cgc.hxx:161
PermutableLabelFusionMove< GraphicalModelType, AccumulationType > FusionMoverType
Inference algorithm interface.
Definition: inference.hxx:34
void setStartingPoint(typename std::vector< LabelType >::const_iterator)
set initial labeling
ProposalGen::AccumulationType AccumulationType
void log(const std::string &logName, const double logValue)
Graph::template EdgeMap< vigra::UInt32 > LabelMap
virtual InferenceTermination arg(std::vector< LabelType > &, const size_t=1) const
output a solution
virtual ValueType value() const
return the solution (value)
std::vector< LabelType > & _getArgRef()
Parameter(const WeightRandomizationParam &randomizer=WeightRandomizationParam(), const float stopWeight=0.0, const float nodeStopNum=-1.0, const bool ignoreNegativeWeights=false, const bool setCutToZero=true)
Disjoint set data structure with path compression.
Definition: partition.hxx:13
Parameter(const NoiseType noiseType=NormalAdd, const float noiseParam=1.0, const size_t seed=42, const bool ignoreSeed=true, const bool autoScale=false, const float permuteN=-1.0)
#define OPENGM_GM_TYPE_TYPEDEFS
Definition: inference.hxx:13
Parameter(const float seedFraction=0.01, const bool ignoreNegativeWeights=false, const bool seedFromNegativeEdges=true, const WeightRandomizationParam randomizer=WeightRandomizationParam())
void _setBestVal(const ValueType value)
OpenGM runtime error.
Definition: opengm.hxx:100
void setWeights(const std::vector< ValueType > &weights, const std::vector< LabelType > &labels)
RandomizedHierarchicalClustering(const GM &gm, const Parameter &param=Parameter())
opengm::visitors::TimingVisitor< IntersectionBasedInf< GM, PROPOSAL_GEN > > TimingVisitorType
CgcRedirectingVisitor(INTERSECTION_BASED &intersectionBased, INTERSECTION_BASED_VISITOR &otherVisitor)
InferenceTermination
Definition: inference.hxx:24
WeightRandomization< ValueType > WeightRand