OpenGM  2.3.x
Discrete Graphical Model Library
astar.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_ASTAR_HXX
3 #define OPENGM_ASTAR_HXX
4 
5 #include <cmath>
6 #include <vector>
7 #include <list>
8 #include <set>
9 #include <iostream>
10 #include <algorithm>
11 #include <iostream>
12 #include <functional>
13 
14 #include "opengm/opengm.hxx"
20 
21 namespace opengm {
22 
24 
25  // node of the search tree for the a-star search
26  template<class FactorType> struct AStarNode {
27  typename std::vector<typename FactorType::LabelType> conf;
28  typename FactorType::ValueType value;
29  };
30 /*
31  template<class AStar, bool Verbose=false>
32  class AStarVisitor {
33  public:
34  typedef AStar astar_type;
35  typedef typename astar_type::ValueType ValueType;
36  AStarVisitor();
37  void operator()(const astar_type&, const std::vector<size_t>& conf, const size_t heapsize, const ValueType& bound1, const ValueType& bound2, const double& runtime);
38  private:
39  size_t step_;
40  };
41 */
42 
44 
63  template<class GM,class ACC>
64  class AStar : public Inference<GM,ACC>
65  {
66  public:
68  typedef GM GraphicalModelType;
69  // -- obsolet -- typedef typename GraphicalModelType::template Rebind<true>::RebindType EditableGraphicalModelType;
71  typedef ACC AccumulationType;
74  typedef typename std::vector<LabelType> ConfVec ;
76  typedef typename ConfVec::iterator ConfVecIt;
81 
82  enum Heuristic{
86  };
87  struct Parameter {
89  {
90  maxHeapSize_ = 3000000;
91  numberOfOpt_ = 1;
92  objectiveBound_ = AccumulationType::template neutral<ValueType>();
94  };
96 
99  void addTreeFactorId(size_t id)
100  { treeFactorIds_.push_back(id); }
102  static const size_t DEFAULTHEURISTIC = 0;
104  static const size_t FASTHEURISTIC = 1;
106  static const size_t STANDARDHEURISTIC = 2;
108  size_t maxHeapSize_;
110  size_t numberOfOpt_;
118  size_t heuristic_;
119  std::vector<IndexType> nodeOrder_;
120  std::vector<size_t> treeFactorIds_;
121 
122  };
123  AStar(const GM& gm, Parameter para = Parameter());
124  virtual std::string name() const {return "AStar";}
125  const GraphicalModelType& graphicalModel() const;
126  virtual InferenceTermination infer();
127  virtual void reset();
128  template<class VisitorType> InferenceTermination infer(VisitorType& vistitor);
129  ValueType bound()const {return belowBound_;}
130  ValueType value()const;
131  virtual InferenceTermination marginal(const size_t,IndependentFactorType& out)const {return UNKNOWN;}
132  virtual InferenceTermination factorMarginal(const size_t, IndependentFactorType& out)const {return UNKNOWN;}
133  virtual InferenceTermination arg(std::vector<LabelType>& v, const size_t = 1)const;
134  virtual InferenceTermination args(std::vector< std::vector<LabelType> >& v)const;
135 
136  private:
137  const GM& gm_;
138  Parameter parameter_;
139  // remeber passed parameter in parameterInitial_
140  // to reset astar
141  Parameter parameterInitial_;
142  std::vector<AStarNode<IndependentFactorType> > array_;
143  std::vector<size_t> numStates_;
144  size_t numNodes_;
145  std::vector<IndependentFactorType> treeFactor_;
146  std::vector<IndependentFactorType> optimizedFactor_;
147  std::vector<ConfVec > optConf_;
148  std::vector<bool> isTreeFactor_;
149  ValueType aboveBound_;
150  ValueType belowBound_;
151  template<class VisitorType> void expand(VisitorType& vistitor);
152  std::vector<ValueType> fastHeuristic(ConfVec conf);
153  inline static bool comp1(const AStarNode<IndependentFactorType>& a, const AStarNode<IndependentFactorType>& b)
154  {return AccumulationType::ibop(a.value,b.value);};
155  inline static bool comp2(const AStarNode<IndependentFactorType>& a, const AStarNode<IndependentFactorType>& b)
156  { return AccumulationType::bop(a.value,b.value);};
157  inline static ValueType better(ValueType a, ValueType b) {return AccumulationType::op(a,b);};
158  inline static ValueType wrose(ValueType a, ValueType b) {return AccumulationType::iop(a,b);};
159  };
160 
161 
162 //*******************
163 //** Impelentation **
164 //*******************
165 
169  template<class GM, class ACC >
171  ::AStar
172  (
173  const GM& gm,
174  Parameter para
175  ):gm_(gm)
176  {
177  parameterInitial_=para;
178  parameter_ = para;
179  if( parameter_.heuristic_ == Parameter::DEFAULTHEURISTIC) {
180  if(gm_.factorOrder()<=2)
181  parameter_.heuristic_ = Parameter::FASTHEURISTIC;
182  else
183  parameter_.heuristic_ = Parameter::STANDARDHEURISTIC;
184  }
185  OPENGM_ASSERT(parameter_.heuristic_ == Parameter::FASTHEURISTIC || parameter_.heuristic_ == Parameter::STANDARDHEURISTIC);
186  ACC::ineutral(belowBound_);
187  ACC::neutral(aboveBound_);
188  //Set variables
189  isTreeFactor_.resize(gm_.numberOfFactors());
190  numStates_.resize(gm_.numberOfVariables());
191  numNodes_ = gm_.numberOfVariables();
192  for(size_t i=0; i<numNodes_;++i)
193  numStates_[i] = gm_.numberOfLabels(i);
194  //Check nodeOrder
195  if(parameter_.nodeOrder_.size()==0) {
196  parameter_.nodeOrder_.resize(numNodes_);
197  std::vector<std::pair<IndexType,IndexType> > tmp(numNodes_,std::pair<IndexType,IndexType>());
198  for(size_t i=0; i<numNodes_; ++i){
199  tmp[i].first = gm_.numberOfFactors(i);
200  tmp[i].second = i;
201  }
202  std::sort(tmp.begin(),tmp.end());
203  for(size_t i=0; i<numNodes_; ++i){
204  parameter_.nodeOrder_[i] = tmp[numNodes_-i-1].second;
205  //parameter_.nodeOrder_[i] = i;
206  }
207  }
208  if(parameter_.nodeOrder_.size()!=numNodes_)
209  throw RuntimeError("The node order does not fit to the model.");
210  OPENGM_ASSERT(std::set<size_t>(parameter_.nodeOrder_.begin(), parameter_.nodeOrder_.end()).size()==numNodes_);
211  for(size_t i=0;i<numNodes_; ++i) {
212  OPENGM_ASSERT(parameter_.nodeOrder_[i] < numNodes_);
213  OPENGM_ASSERT(parameter_.nodeOrder_[i] >= 0);
214  }
215  //Check FactorIds
216  if(parameter_.treeFactorIds_.size()==0) {
217  //Select tree factors
218  for(size_t i=0; i<gm_.numberOfFactors(); ++i) {
219  if((gm_[i].numberOfVariables()==2) &&
220  (gm_[i].variableIndex(0)==parameter_.nodeOrder_.back() || gm_[i].variableIndex(1)==parameter_.nodeOrder_.back())
221  )
222  parameter_.addTreeFactorId(i);
223  }
224  }
225  for(size_t i=0; i<parameter_.treeFactorIds_.size(); ++i)
226  OPENGM_ASSERT(gm_.numberOfFactors() > parameter_.treeFactorIds_[i]);
227  //compute optimized factors
228  optimizedFactor_.resize(gm_.numberOfFactors());
229  for(size_t i=0; i<gm_.numberOfFactors(); ++i) {
230  if(gm_[i].numberOfVariables()<=1) continue;
231  std::vector<size_t> index(gm_[i].numberOfVariables());
232  gm_[i].variableIndices(index.begin());
233  optimizedFactor_[i].assign(gm_ ,index.end()-1, index.end());
234  opengm::accumulate<ACC>(gm[i],index.begin()+1,index.end(),optimizedFactor_[i]);
235  //gm_[i].template accumulate<ACC>(index.begin()+1,index.end(),optimizedFactor_[i]);
236  OPENGM_ASSERT(optimizedFactor_[i].numberOfVariables() == 1);
237  OPENGM_ASSERT(optimizedFactor_[i].variableIndex(0) == index[0]);
238  }
239  //PUSH EMPTY CONFIGURATION TO HEAP
240  AStarNode<IndependentFactorType> a;
241  a.conf.resize(0);
242  a.value = 0;
243  array_.push_back(a);
244  make_heap(array_.begin(), array_.end(), comp1);
245  //Check if maximal order is smaller equal 2, otherwise fall back to naive computation of heuristic
246  if(parameter_.heuristic_ == parameter_.FASTHEURISTIC) {
247  for(size_t i=0; i<parameter_.treeFactorIds_.size(); ++i) {
248  if(gm_[parameter_.treeFactorIds_[i]].numberOfVariables() > 2) {
249  throw RuntimeError("The heuristic includes factor of order > 2.");
250  }
251  }
252  }
253  //Init treefactor structure
254  treeFactor_.clear();
255  for(size_t i=0; i<gm_.numberOfFactors(); ++i)
256  isTreeFactor_[i] = false;
257  for(size_t i=0; i<parameter_.treeFactorIds_.size(); ++i) {
258  int factorId = parameter_.treeFactorIds_[i];
259  isTreeFactor_[factorId] = true;
260  treeFactor_.push_back(gm_[factorId]);
261  }
262  }
263 
270  template<class GM, class ACC >
271  void
273  {
275  }
276 
277  template <class GM, class ACC>
280  {
281  EmptyVisitorType v;
282  return infer(v);
283  }
284 
287  template<class GM, class ACC>
288  template<class VisitorType>
290  {
291  size_t exitFlag=0;
292  optConf_.resize(0);
293  visitor.begin(*this);
294  while(array_.size()>0 && exitFlag==0) {
295  if(parameter_.numberOfOpt_ == optConf_.size()) {
296  visitor.end(*this);
297  return NORMAL;
298  }
299  while(array_.front().conf.size() < numNodes_ && exitFlag==0) {
300  expand(visitor);
301  belowBound_ = array_.front().value;
302  exitFlag = visitor(*this);
303  //visitor(*this, array_.front().conf, array_.size(), array_.front().value, globalBound_, time);
304  }
305  if(array_.front().conf.size()>=numNodes_){
306  ValueType value = array_.front().value;
307  belowBound_ = value;
308  std::vector<LabelType> conf(numNodes_);
309  for(size_t n=0; n<numNodes_; ++n) {
310  conf[parameter_.nodeOrder_[n]] = array_.front().conf[n];
311  }
312  optConf_.push_back(conf);
313  visitor(*this);
314  if(ACC::bop(parameter_.objectiveBound_, value)) {
315  visitor.end(*this);
316  return NORMAL;
317  }
318  }
319  pop_heap(array_.begin(), array_.end(), comp1); //greater<FactorType,Accumulation>);
320  array_.pop_back();
321  }
322  visitor.end(*this);
323  return UNKNOWN;
324  }
325 
326  template<class GM, class ACC>
327  typename GM::ValueType AStar<GM, ACC>::value() const
328  {
329  if(optConf_.size()>=1){
330  return gm_.evaluate(optConf_[0]);
331  }
332  else{
333  return ACC::template neutral<ValueType>();
334  }
335  }
336 
337  template<class GM, class ACC>
339  ::arg(ConfVec& conf, const size_t n)const
340  {
341  if(n>optConf_.size()) {
342  conf.resize(gm_.numberOfVariables(),0);
343  return UNKNOWN;
344  }
345  //conf.resize(opt_conf[n-1].size());
346  conf=optConf_[n-1];
347  return NORMAL;
348  }
349 
354  template<class GM, class ACC>
356  ::args(std::vector<std::vector<typename AStar<GM,ACC>::LabelType> >& conf)const
357  {
358  conf=optConf_;
359  return NORMAL;
360  }
361 
362  template<class GM, class ACC>
363  template<class VisitorType>
364  void AStar<GM, ACC>::expand(VisitorType& visitor)
365  {
366  //CHECK HEAP SIZE
367  if(array_.size()>parameter_.maxHeapSize_*0.99) {
368  partial_sort(array_.begin(), array_.begin()+(int)(parameter_.maxHeapSize_/2), array_.end(), comp2);
369  array_.resize((int)(parameter_.maxHeapSize_/2));
370  }
371  //GET HEAP HEAD
372  AStarNode<IndependentFactorType> a = array_.front();
373  size_t subconfsize = a.conf.size();
374  //REMOVE HEAD FROM HEAP
375  OPENGM_ASSERT(array_.size() > 0);
376  pop_heap(array_.begin(), array_.end(), comp1); //greater<FactorType,Accumulation>);
377  array_.pop_back();
378  if( parameter_.heuristic_ == parameter_.STANDARDHEURISTIC) {
379 
380  //BUILD GRAPHICAL MODEL FOR HEURISTC CALCULATION
381 
382  typedef typename opengm::DiscreteSpace<IndexType, LabelType> MSpaceType;
383  typedef typename meta::TypeListGenerator< ExplicitFunction<ValueType,IndexType,LabelType>, ViewFixVariablesFunction<GM>, ViewFunction<GM>, ConstantFunction<ValueType, IndexType, LabelType> >::type MFunctionTypeList;
384  typedef GraphicalModel<ValueType, typename GM::OperatorType, MFunctionTypeList, MSpaceType> MGM;
385 
386  IndexType numberOfVariables = 0;
387  std::vector<IndexType> varMap(gm_.numberOfVariables(),0);
388  std::vector<LabelType> fixVariableLabel(gm_.numberOfVariables(),0);
389  std::vector<bool> fixVariable(gm_.numberOfVariables(),false);
390  for(size_t i =0; i<subconfsize ; ++i) {
391  fixVariableLabel[parameter_.nodeOrder_[i]] = a.conf[i];
392  fixVariable[parameter_.nodeOrder_[i]] = true;
393  }
394 
395  for(IndexType var=0; var<gm_.numberOfVariables();++var){
396  if(fixVariable[var]==false){
397  varMap[var] = numberOfVariables++;
398  }
399  }
400  std::vector<LabelType> shape(numberOfVariables,0);
401  for(IndexType var=0; var<gm_.numberOfVariables();++var){
402  if(fixVariable[var]==false){
403  shape[varMap[var]] = gm_.numberOfLabels(var);
404  }
405  }
406  MSpaceType space(shape.begin(),shape.end());
407  MGM mgm(space);
408 
409  std::vector<PositionAndLabel<IndexType,LabelType> > fixedVars;
410  std::vector<IndexType> MVars;
411  ValueType constant;
412  GM::OperatorType::neutral(constant);
413 
414  for(IndexType f=0; f<gm_.numberOfFactors();++f){
415  fixedVars.resize(0);
416  MVars.resize(0);
417  for(IndexType i=0; i<gm_[f].numberOfVariables(); ++i){
418  const IndexType var = gm_[f].variableIndex(i);
419  if(fixVariable[var]){
420  fixedVars.push_back(PositionAndLabel<IndexType,LabelType>(i,fixVariableLabel[var]));
421  }else{
422  MVars.push_back(varMap[var]);
423  }
424  }
425  if(fixedVars.size()==gm_[f].numberOfVariables()){//all fixed
426  std::vector<LabelType> fixedStates(gm_[f].numberOfVariables(),0);
427  for(IndexType i=0; i<gm_[f].numberOfVariables(); ++i){
428  fixedStates[i]=fixVariableLabel[ gm_[f].variableIndex(i)];
429  }
430  GM::OperatorType::op(gm_[f](fixedStates.begin()),constant);
431  }else{
432  if(MVars.size()<2 || isTreeFactor_[f]){
433  const ViewFixVariablesFunction<GM> func(gm_[f], fixedVars);
434  mgm.addFactor(mgm.addFunction(func),MVars.begin(), MVars.end());
435  }else{
436  std::vector<IndexType> variablesIndices(optimizedFactor_[f].numberOfVariables());
437  for(size_t i=0; i<variablesIndices.size(); ++i)
438  variablesIndices[i] = varMap[optimizedFactor_[f].variableIndex(i)];
439  LabelType numberOfLabels = optimizedFactor_[f].numberOfLabels(0);
440  opengm::ExplicitFunction<ValueType,IndexType,LabelType> func(&numberOfLabels,&numberOfLabels+1,0);
441  for(LabelType i=0; i<numberOfLabels; ++i)
442  func(i) = optimizedFactor_[f](i);
443  mgm.addFactor(mgm.addFunction(func),variablesIndices.begin(),variablesIndices.end() );
444  OPENGM_ASSERT(mgm[mgm.numberOfFactors()-1].numberOfVariables()==1);
445  }
446  }
447  }
448  {
449  LabelType temp;
450  ConstantFunction<ValueType, IndexType, LabelType> func(&temp, &temp, constant);
451  mgm.addFactor(mgm.addFunction(func),MVars.begin(), MVars.begin());
452  }
453  typedef typename opengm::BeliefPropagationUpdateRules<MGM,ACC> UpdateRules;
454  typename MessagePassing<MGM, ACC, UpdateRules, opengm::MaxDistance>::Parameter bpPara;
455  bpPara.isAcyclic_ = opengm::Tribool::False;
456  bpPara.maximumNumberOfSteps_ = mgm.numberOfVariables();
457  OPENGM_ASSERT(mgm.isAcyclic());
458  MessagePassing<MGM, ACC, UpdateRules, opengm::MaxDistance> bp(mgm,bpPara);
459  try{
460  bp.infer();//Asynchronous();
461  }
462  catch(...) {
463  throw RuntimeError("bp failed in astar");
464  }
465  ACC::op(bp.value(),aboveBound_,aboveBound_);
466  std::vector<LabelType> conf(mgm.numberOfVariables());
467 
468  std::vector<IndexType> theVar(1, varMap[parameter_.nodeOrder_[subconfsize]]);
469 
470  std::vector<LabelType> theLabel(1,0);
471  a.conf.resize(subconfsize+1);
472  for(size_t i=0; i<numStates_[parameter_.nodeOrder_[subconfsize]]; ++i) {
473  a.conf[subconfsize] = i;
474  theLabel[0] =i;
475  bp.constrainedOptimum(theVar,theLabel,conf);
476  a.value = mgm.evaluate(conf);
477  array_.push_back(a);
478  push_heap(array_.begin(), array_.end(), comp1); //greater<FactorType,Accumulation>) ;
479  }
480  }
481  if( parameter_.heuristic_ == parameter_.FASTHEURISTIC) {
482  std::vector<LabelType> conf(subconfsize);
483  for(size_t i=0;i<subconfsize;++i)
484  conf[i] = a.conf[i];
485  std::vector<ValueType> bound = fastHeuristic(conf);
486  a.conf.resize(subconfsize+1);
487  for(size_t i=0; i<numStates_[parameter_.nodeOrder_[subconfsize]]; ++i) {
488  a.conf[subconfsize] = i;
489  a.value = bound[i];
490  //if(bound[i]<10) {
491  array_.push_back(a);
492  push_heap(array_.begin(), array_.end(), comp1); //greater<FactorType,Accumulation>) ;
493  //}
494  }
495  }
496  }
497 
498  template<class GM, class ACC>
499  std::vector<typename AStar<GM, ACC>::ValueType>
500  AStar<GM, ACC>::fastHeuristic(typename AStar<GM, ACC>::ConfVec conf)
501  {
502  std::list<size_t> factorList;
503  std::vector<size_t> nodeDegree(numNodes_,0);
504  std::vector<int> nodeLabel(numNodes_,-1);
505  std::vector<std::vector<ValueType > > nodeEnergy(numNodes_);
506  size_t nextNode = parameter_.nodeOrder_[conf.size()];
507  for(size_t i=0; i<numNodes_; ++i) {
508  nodeEnergy[i].resize(numStates_[i]); //the energy passed to node i
509  for(size_t j=0;j<numStates_[i];++j)
510  OperatorType::neutral(nodeEnergy[i][j]);
511  }
512  for(size_t i=0;i<conf.size();++i) {
513  nodeLabel[parameter_.nodeOrder_[i]] = conf[i];
514  }
515  //First run:
516  // * add unarry function
517  // * add pairwise functions with at least one observed node
518  // * add the approximation for pairwise none-tree edges
519  for(size_t i=0; i<gm_.numberOfFactors(); ++i) {
520  const FactorType & f = gm_[i];
521  size_t nvar = f.numberOfVariables();
522  //factors depending from 1 variable can be include
523  if(nvar==1) {
524  int index = f.variableIndex(0);
525  if(nodeLabel[index]>=0) {
526  nodeEnergy[index].resize(1);
527  //nodeEnergy[index][0] = operatipon(f(nodeLabel[index]), nodeEnergy[index][0]);
528  LabelType coordinates[]={static_cast<LabelType>(nodeLabel[index])};
529  OperatorType::op(f(coordinates), nodeEnergy[index][0]);
530  }
531  else{
532  OPENGM_ASSERT(numStates_[index] == nodeEnergy[index].size());
533  for(size_t j=0;j<numStates_[index];++j) {
534  //nodeEnergy[index][j] = operation(f(j),nodeEnergy[index][j]);
535  LabelType coordinates[]={j};
536  OperatorType::op(f(coordinates),nodeEnergy[index][j]);
537  }
538  }
539  }
540  if(nvar==2) {
541  size_t index1 = f.variableIndex(0);
542  size_t index2 = f.variableIndex(1);
543  if(nodeLabel[index1]>=0) {
544  if(nodeLabel[index2]>=0) {
545  nodeEnergy[index1].resize(1);
546  //nodeEnergy[index1][0] = operation(f(nodeLabel[index1],nodeLabel[index2]),nodeEnergy[index1][0]);
547  LabelType coordinates[]={
548  static_cast<LabelType>(nodeLabel[index1]),
549  static_cast<LabelType>(nodeLabel[index2])
550  };
551  OperatorType::op(f(coordinates),nodeEnergy[index1][0]);
552  }
553  else{
554  OPENGM_ASSERT(numStates_[index2] == nodeEnergy[index2].size());
555  for(size_t j=0;j<numStates_[index2];++j) {
556  //nodeEnergy[index2][j] = operation(f(nodeLabel[index1],j), nodeEnergy[index2][j]);
557  LabelType coordinates[]={
558  static_cast<LabelType>(nodeLabel[index1]),
559  static_cast<LabelType>(j)
560  };
561  OperatorType::op(f(coordinates), nodeEnergy[index2][j]);
562  }
563  }
564  }
565  else if(nodeLabel[index2]>=0) {
566  OPENGM_ASSERT(numStates_[index1] == nodeEnergy[index1].size());
567  for(size_t j=0;j<numStates_[index1];++j) {
568  //nodeEnergy[index1][j] = operation(f(j,nodeLabel[index2]),nodeEnergy[index1][j]);
569  LabelType coordinates[]={
570  static_cast<LabelType>(j),
571  static_cast<LabelType>(nodeLabel[index2])
572  };
573  OperatorType::op(f(coordinates),nodeEnergy[index1][j]);
574  }
575  }
576  else if(isTreeFactor_[i]) {
577  factorList.push_front(i);
578  ++nodeDegree[index1];
579  ++nodeDegree[index2];
580  continue;
581  }
582  else{
583  for(size_t j=0;j<numStates_[index1];++j) {
584  //nodeEnergy[index1][j] = operation(optimizedFactor_[i](j), nodeEnergy[index1][j]);
585  LabelType coordinates[]={j};
586  OperatorType::op(optimizedFactor_[i](coordinates), nodeEnergy[index1][j]);
587  }
588  }
589  }
590  if(nvar>2) {
591  bool covered = true;
592  std::vector<size_t> state(nvar);
593  for(size_t j=0; j<nvar; ++j) {
594  if(nodeLabel[f.variableIndex(j)]<0) {
595  state[j] = nodeLabel[f.variableIndex(j)];
596  covered = false;
597  }
598  }
599  if(covered)
600  nodeEnergy[f.variableIndex(0)][0] = f(state.begin());
601  else{
602  for(size_t j=0;j<numStates_[f.variableIndex(0)];++j) {
603  //nodeEnergy[f.variableIndex(0)][j] = operation(optimizedFactor_[i](j), nodeEnergy[f.variableIndex(0)][j]);
604  LabelType coordinates[]={j};
605  OperatorType::op(optimizedFactor_[i](coordinates), nodeEnergy[f.variableIndex(0)][j]);
606  }
607  }
608  }
609  }
610  nodeDegree[nextNode] += numNodes_;
611  // Start dynamic programming to solve the treestructured problem.
612  while(factorList.size()>0) {
613  size_t id = factorList.front();
614  factorList.pop_front();
615  const FactorType & f = gm_[id];
616  size_t index1 = f.variableIndex(0);
617  size_t index2 = f.variableIndex(1);
618  typename FactorType::ValueType temp;
619  OPENGM_ASSERT(index1 < numNodes_);
620  OPENGM_ASSERT(index2 < numNodes_);
621  OPENGM_ASSERT(gm_.numberOfLabels(index1) == numStates_[index1]);
622  OPENGM_ASSERT(gm_.numberOfLabels(index2) == numStates_[index2]);
623  if(nodeDegree[index1]==1) {
624  typename FactorType::ValueType min;
625  OPENGM_ASSERT(numStates_[index2] == nodeEnergy[index2].size());
626  for(size_t j2=0;j2<numStates_[index2];++j2) {
627  ACC::neutral(min);
628  OPENGM_ASSERT(numStates_[index1] == nodeEnergy[index1].size());
629  for(size_t j1=0;j1<numStates_[index1];++j1) {
630  LabelType coordinates[]={j1,j2};
631  OperatorType::op(f(coordinates),nodeEnergy[index1][j1],temp);
632  ACC::op(min,temp,min);
633  }
634  //nodeEnergy[index2][j2] = operation(min,nodeEnergy[index2][j2]);
635  OperatorType::op(min,nodeEnergy[index2][j2]);
636  }
637  --nodeDegree[index1];
638  --nodeDegree[index2];
639  nodeEnergy[index1].resize(1);
640  OperatorType::neutral(nodeEnergy[index1][0]);
641  }
642  else if(nodeDegree[index2]==1) {
643  typename FactorType::ValueType min;
644  OPENGM_ASSERT(numStates_[index1] == nodeEnergy[index1].size());
645  for(size_t j1=0;j1<numStates_[index1];++j1) {
646  ACC::neutral(min);
647  OPENGM_ASSERT(numStates_[index2] == nodeEnergy[index2].size());
648  for(size_t j2=0;j2<numStates_[index2];++j2) {
649  LabelType coordinates[]={j1,j2};
650  OperatorType::op(f(coordinates),nodeEnergy[index2][j2],temp);
651  ACC::op(min,temp,min);
652  //if(min>f(j1,j2)*node_energy[index2][j2]) min=f(j1,j2)*node_energy[index2][j2];
653  }
654  //nodeEnergy[index1][j1] = operation(min,nodeEnergy[index1][j1]);
655  OperatorType::op(min,nodeEnergy[index1][j1]);
656  }
657  --nodeDegree[index1];
658  --nodeDegree[index2];
659  nodeEnergy[index2].resize(1);
660  OperatorType::neutral(nodeEnergy[index2][0]);
661  }
662  else{
663  factorList.push_back(id);
664  }
665  }
666  //Evaluate
667  ValueType result;
668  ValueType min;
669  OperatorType::neutral(result);
670  std::vector<ValueType > bound;
671  for(size_t i=0;i<numNodes_;++i) {
672  if(i==nextNode) continue;
673  ACC::neutral(min);
674  for(size_t j=0; j<nodeEnergy[i].size();++j)
675  ACC::op(min,nodeEnergy[i][j],min);
676  //result = operation(result,min);
677  OperatorType::op(min,result);
678  }
679  bound.resize(nodeEnergy[nextNode].size());
680  for(size_t j=0; j<nodeEnergy[nextNode].size();++j) {
681  //bound[j] = operation(nodeEnergy[nextNode][j],result);
682  OperatorType::op(nodeEnergy[nextNode][j],result,bound[j]);
683  }
684  return bound;
685  }
686 
687  template<class GM, class ACC>
688  inline const typename AStar<GM, ACC>::GraphicalModelType&
690  {
691  return gm_;
692  }
693 
694 } // namespace opengm
695 
696 #endif // #ifndef OPENGM_ASTAR_HXX
697 
ValueType bound() const
return a bound on the solution
Definition: astar.hxx:129
Update rules for the MessagePassing framework.
opengm::visitors::EmptyVisitor< AStar< GM, ACC > > EmptyVisitorType
Definition: astar.hxx:80
The OpenGM namespace.
Definition: config.hxx:43
static const size_t DEFAULTHEURISTIC
DEFAULTHEURISTIC ;.
Definition: astar.hxx:102
opengm::visitors::VerboseVisitor< AStar< GM, ACC > > VerboseVisitorType
visitor
Definition: astar.hxx:78
OPENGM_GM_TYPE_TYPEDEFS
Definition: astar.hxx:72
Discrete space in which variables can have differently many labels.
virtual std::string name() const
Definition: astar.hxx:124
opengm::visitors::TimingVisitor< AStar< GM, ACC > > TimingVisitorType
Definition: astar.hxx:79
std::vector< LabelType > ConfVec
configuration vector type
Definition: astar.hxx:74
AStar(const GM &gm, Parameter para=Parameter())
constructor
Definition: astar.hxx:172
virtual InferenceTermination arg(std::vector< LabelType > &v, const size_t=1) const
output a solution
Definition: astar.hxx:339
size_t numberOfOpt_
number od N-best solutions that should be found
Definition: astar.hxx:110
virtual InferenceTermination args(std::vector< std::vector< LabelType > > &v) const
args
Definition: astar.hxx:356
#define OPENGM_ASSERT(expression)
Definition: opengm.hxx:77
static const size_t STANDARDHEURISTIC
STANDARDHEURISTIC.
Definition: astar.hxx:106
ValueType objectiveBound_
objective bound
Definition: astar.hxx:112
void addTreeFactorId(size_t id)
constuctor
Definition: astar.hxx:99
ACC AccumulationType
accumulation type
Definition: astar.hxx:71
ValueType value() const
return the solution (value)
Definition: astar.hxx:327
const GraphicalModelType & graphicalModel() const
Definition: astar.hxx:689
A star search algorithm.
Definition: astar.hxx:64
std::vector< size_t > treeFactorIds_
Definition: astar.hxx:120
size_t heuristic_
heuritstic
Definition: astar.hxx:118
GraphicalModelType::ValueType ValueType
Definition: inference.hxx:41
ConfVec::iterator ConfVecIt
configuration iterator
Definition: astar.hxx:76
virtual InferenceTermination marginal(const size_t, IndependentFactorType &out) const
output a solution for a marginal for a specific variable
Definition: astar.hxx:131
GM GraphicalModelType
graphical model type
Definition: astar.hxx:68
Inference algorithm interface.
Definition: inference.hxx:34
size_t maxHeapSize_
maxHeapSize_ maximum size of the heap
Definition: astar.hxx:108
virtual void reset()
reset
Definition: astar.hxx:272
static const size_t FASTHEURISTIC
FASTHEURISTIC.
Definition: astar.hxx:104
virtual InferenceTermination infer()
Definition: astar.hxx:279
std::vector< IndexType > nodeOrder_
Definition: astar.hxx:119
GraphicalModelType::LabelType LabelType
Definition: inference.hxx:39
OpenGM runtime error.
Definition: opengm.hxx:100
virtual InferenceTermination factorMarginal(const size_t, IndependentFactorType &out) const
output a solution for a marginal for all variables connected to a factor
Definition: astar.hxx:132
InferenceTermination
Definition: inference.hxx:24
GraphicalModelType::IndependentFactorType IndependentFactorType
Definition: inference.hxx:44