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