astar.hxx

Go to the documentation of this file.
00001 #pragma once
00002 #ifndef OPENGM_ASTAR_HXX
00003 #define OPENGM_ASTAR_HXX
00004 
00005 #include <cmath>
00006 #include <vector>
00007 #include <list>
00008 #include <set>
00009 #include <iostream>
00010 #include <algorithm>
00011 #include <iostream>
00012 #include <functional>
00013 
00014 #include "opengm/opengm.hxx"
00015 #include "opengm/graphicalmodel/graphicalmodel.hxx"
00016 #include "opengm/inference/inference.hxx"
00017 #include "opengm/inference/messagepassing/messagepassing.hxx"
00018 #include "opengm/inference/visitors/visitor.hxx"
00019 
00020 namespace opengm {
00021 
00023 
00024    // node of the search tree for the a-star search
00025    template<class FactorType> struct AStarNode {
00026       typename std::vector<typename FactorType::LabelType>    conf;
00027       typename FactorType::ValueType     value;
00028    };
00029 /*
00030    template<class AStar, bool Verbose=false>
00031    class AStarVisitor {
00032    public:
00033       typedef AStar astar_type;
00034       typedef typename astar_type::ValueType ValueType;
00035       AStarVisitor();
00036       void operator()(const astar_type&, const std::vector<size_t>& conf, const size_t heapsize, const ValueType& bound1, const ValueType& bound2, const double& runtime);
00037    private:
00038       size_t step_;
00039    };
00040 */
00041 
00043 
00062    template<class GM,class ACC>
00063    class AStar : public Inference<GM,ACC>
00064    {
00065    public:
00067       typedef GM                                          GraphicalModelType;
00068       typedef typename GraphicalModelType::template Rebind<true>::RebindType EditableGraphicalModelType;
00070       typedef ACC                                         AccumulationType;
00071       OPENGM_GM_TYPE_TYPEDEFS;
00073       typedef typename std::vector<LabelType>             ConfVec ;
00075       typedef typename ConfVec::iterator                  ConfVecIt;
00077       typedef VerboseVisitor<AStar<GM, ACC> > VerboseVisitorType;
00078       typedef TimingVisitor<AStar<GM, ACC> > TimingVisitorType;
00079       typedef EmptyVisitor<AStar<GM, ACC> > EmptyVisitorType;
00080       
00081       enum Heuristic{
00082          DEFAULT_HEURISTIC = 0,
00083          FAST_HEURISTIC = 1,
00084          STANDARD_HEURISTIC = 2
00085       };
00086       struct Parameter {
00087          Parameter()
00088             {
00089                maxHeapSize_    = 3000000;
00090                numberOfOpt_    = 1;
00091                objectiveBound_ = AccumulationType::template neutral<ValueType>();
00092                heuristic_      = Parameter::DEFAULTHEURISTIC;
00093             };
00095 
00098          void addTreeFactorId(size_t id)
00099             { treeFactorIds_.push_back(id); }
00101          static const size_t DEFAULTHEURISTIC = 0;
00103          static const size_t FASTHEURISTIC = 1;
00105          static const size_t STANDARDHEURISTIC = 2;
00107          size_t maxHeapSize_;
00109          size_t              numberOfOpt_;
00111          ValueType          objectiveBound_;
00117          size_t heuristic_;  
00118          std::vector<IndexType> nodeOrder_;
00119          std::vector<size_t> treeFactorIds_;
00120        
00121       };
00122       AStar(const GM& gm, Parameter para = Parameter());
00123       virtual std::string name() const {return "AStar";}
00124       const GraphicalModelType& graphicalModel() const;
00125       virtual InferenceTermination infer();
00126       virtual void reset();
00127       template<class VisitorType> InferenceTermination infer(VisitorType& vistitor);
00128       ValueType bound()const {return belowBound_;}
00129       virtual InferenceTermination marginal(const size_t,IndependentFactorType& out)const        {return UNKNOWN;}
00130       virtual InferenceTermination factorMarginal(const size_t, IndependentFactorType& out)const {return UNKNOWN;}
00131       virtual InferenceTermination arg(std::vector<LabelType>& v, const size_t = 1)const;
00132       virtual InferenceTermination args(std::vector< std::vector<LabelType> >& v)const;
00133 
00134    private:
00135       const GM&                                   gm_;
00136       Parameter                                   parameter_;
00137       // remeber passed parameter in  parameterInitial_
00138       // to reset astar
00139       Parameter                                   parameterInitial_;
00140       std::vector<AStarNode<IndependentFactorType> >  array_;
00141       std::vector<size_t>                         numStates_;
00142       size_t                                      numNodes_;
00143       std::vector<IndependentFactorType>          treeFactor_;
00144       std::vector<IndependentFactorType>          optimizedFactor_;
00145       std::vector<ConfVec >                       optConf_;
00146       std::vector<bool>                           isTreeFactor_;
00147       ValueType                                   aboveBound_;
00148       ValueType                                   belowBound_;
00149       template<class VisitorType> void  expand(VisitorType& vistitor);
00150       std::vector<ValueType>           fastHeuristic(ConfVec conf);
00151       inline static bool                comp1(const AStarNode<IndependentFactorType>& a, const AStarNode<IndependentFactorType>& b)
00152          {return  AccumulationType::ibop(a.value,b.value);};
00153       inline static bool                comp2(const AStarNode<IndependentFactorType>& a, const AStarNode<IndependentFactorType>& b)
00154          { return  AccumulationType::bop(a.value,b.value);};
00155       inline static ValueType          better(ValueType a, ValueType b)   {return AccumulationType::op(a,b);};
00156       inline static ValueType          wrose(ValueType a,  ValueType b)   {return AccumulationType::iop(a,b);};
00157    };
00158 
00159 
00160 //*******************
00161 //** Impelentation **
00162 //*******************
00163 
00167    template<class GM, class ACC >
00168    AStar<GM,ACC>
00169    ::AStar
00170    (
00171       const GM& gm,
00172       Parameter para
00173    ):gm_(gm)
00174    {
00175       parameterInitial_=para;
00176       parameter_ = para;
00177       if( parameter_.heuristic_ == Parameter::DEFAULTHEURISTIC) {
00178          if(gm_.factorOrder()<=2)
00179             parameter_.heuristic_ = Parameter::FASTHEURISTIC;
00180          else
00181             parameter_.heuristic_ = Parameter::STANDARDHEURISTIC;
00182       }
00183       OPENGM_ASSERT(parameter_.heuristic_ == Parameter::FASTHEURISTIC || parameter_.heuristic_ == Parameter::STANDARDHEURISTIC);
00184       ACC::ineutral(belowBound_);
00185       ACC::neutral(aboveBound_);
00186       //Set variables
00187       isTreeFactor_.resize(gm_.numberOfFactors());
00188       numStates_.resize(gm_.numberOfVariables());
00189       numNodes_ = gm_.numberOfVariables();
00190       for(size_t i=0; i<numNodes_;++i)
00191          numStates_[i] = gm_.numberOfLabels(i);
00192       //Check nodeOrder
00193       if(parameter_.nodeOrder_.size()==0) {
00194          parameter_.nodeOrder_.resize(numNodes_);
00195          for(size_t i=0; i<numNodes_; ++i)
00196             parameter_.nodeOrder_[i]=i;
00197       }
00198       if(parameter_.nodeOrder_.size()!=numNodes_)
00199          throw RuntimeError("The node order does not fit to the model.");
00200       OPENGM_ASSERT(std::set<size_t>(parameter_.nodeOrder_.begin(), parameter_.nodeOrder_.end()).size()==numNodes_);
00201       for(size_t i=0;i<numNodes_; ++i) {
00202          OPENGM_ASSERT(parameter_.nodeOrder_[i] < numNodes_);
00203          OPENGM_ASSERT(parameter_.nodeOrder_[i] >= 0);
00204       }
00205       //Check FactorIds
00206       if(parameter_.treeFactorIds_.size()==0) {
00207          //Select tree factors
00208          for(size_t i=0; i<gm_.numberOfFactors(); ++i) {
00209             if((gm_[i].numberOfVariables()==2) &&
00210                (gm_[i].variableIndex(0)==parameter_.nodeOrder_.back() || gm_[i].variableIndex(1)==parameter_.nodeOrder_.back())
00211                )
00212                parameter_.addTreeFactorId(i);
00213          }
00214       }
00215       for(size_t i=0; i<parameter_.treeFactorIds_.size(); ++i)
00216          OPENGM_ASSERT(gm_.numberOfFactors() > parameter_.treeFactorIds_[i]);
00217       //compute optimized factors
00218       optimizedFactor_.resize(gm_.numberOfFactors());
00219       for(size_t i=0; i<gm_.numberOfFactors(); ++i) {
00220          if(gm_[i].numberOfVariables()<=1) continue;
00221          std::vector<size_t> index(gm_[i].numberOfVariables());
00222          gm_[i].variableIndices(index.begin());
00223          optimizedFactor_[i].assign(gm_ ,index.end()-1, index.end());
00224          opengm::accumulate<ACC>(gm[i],index.begin()+1,index.end(),optimizedFactor_[i]);
00225          //gm_[i].template accumulate<ACC>(index.begin()+1,index.end(),optimizedFactor_[i]);
00226          OPENGM_ASSERT(optimizedFactor_[i].numberOfVariables() == 1);
00227          OPENGM_ASSERT(optimizedFactor_[i].variableIndex(0) == index[0]);
00228       }
00229       //PUSH EMPTY CONFIGURATION TO HEAP
00230       AStarNode<IndependentFactorType> a;
00231       a.conf.resize(0);
00232       a.value = 0;
00233       array_.push_back(a);
00234       make_heap(array_.begin(), array_.end(), comp1);
00235       //Check if maximal order is smaller equal 2, otherwise fall back to naive computation of heuristic
00236       if(parameter_.heuristic_ == parameter_.FASTHEURISTIC) {
00237          for(size_t i=0; i<parameter_.treeFactorIds_.size(); ++i) {
00238             if(gm_[parameter_.treeFactorIds_[i]].numberOfVariables() > 2) {
00239                throw RuntimeError("The heuristic includes factor of order > 2.");
00240             }
00241          }
00242       }
00243       //Init treefactor structure
00244       treeFactor_.clear();
00245       for(size_t i=0; i<gm_.numberOfFactors(); ++i)
00246          isTreeFactor_[i] = false;
00247       for(size_t i=0; i<parameter_.treeFactorIds_.size(); ++i) {
00248          int factorId = parameter_.treeFactorIds_[i];
00249          isTreeFactor_[factorId] = true;
00250          treeFactor_.push_back(gm_[factorId]);
00251       }
00252    }
00253   
00260    template<class GM, class ACC >
00261    void
00262    AStar<GM,ACC>::reset()
00263    {
00265    }
00266 
00267    template <class GM, class ACC>
00268    InferenceTermination
00269    AStar<GM,ACC>::infer()
00270    { 
00271       EmptyVisitorType v;
00272       return infer(v);
00273    }
00274 
00277    template<class GM, class ACC>
00278    template<class VisitorType>
00279    InferenceTermination AStar<GM,ACC>::infer(VisitorType& visitor)
00280    {
00281       visitor.begin(*this, ACC::template neutral<ValueType>(),ACC::template ineutral<ValueType>());    
00282       optConf_.resize(0);
00283       while(array_.size()>0) {
00284          if(parameter_.numberOfOpt_ == optConf_.size()) {
00285             visitor.end(*this);
00286             return NORMAL;
00287          }
00288          while(array_.front().conf.size() < numNodes_) {
00289             expand(visitor);
00290             visitor(*this,  ACC::template neutral<ValueType>(),array_.front().value); 
00291             //visitor(*this, array_.front().conf, array_.size(), array_.front().value, globalBound_, time);
00292          }
00293          ValueType  value = array_.front().value;
00294          belowBound_ = value;
00295          std::vector<LabelType> conf(numNodes_);
00296          for(size_t n=0; n<numNodes_; ++n) {
00297             conf[parameter_.nodeOrder_[n]] = array_.front().conf[n];
00298          } 
00299          visitor(*this,gm_.evaluate(conf),this->bound());
00300          if(ACC::bop(parameter_.objectiveBound_, value)) {
00301             visitor.end(*this,value,this->bound());
00302             return NORMAL;
00303          }
00304          optConf_.push_back(conf);
00305          pop_heap(array_.begin(), array_.end(),  comp1); //greater<FactorType,Accumulation>);
00306          array_.pop_back();
00307       }
00308       visitor.end(*this);     
00309       return UNKNOWN;
00310    }
00311 
00312    template<class GM, class ACC>
00313    InferenceTermination AStar<GM, ACC>
00314    ::arg(ConfVec& conf, const size_t n)const
00315    {
00316       if(n>optConf_.size()) {
00317          conf.resize(0);
00318          return UNKNOWN;
00319       }
00320       //conf.resize(opt_conf[n-1].size());
00321       conf=optConf_[n-1];
00322       return NORMAL;
00323    }
00324 
00329    template<class GM, class ACC>
00330    InferenceTermination AStar<GM,ACC>
00331    ::args(std::vector<std::vector<typename AStar<GM,ACC>::LabelType> >& conf)const
00332    {
00333       conf=optConf_;
00334       return NORMAL;
00335    }
00336 
00337    template<class GM, class ACC>
00338    template<class VisitorType>
00339    void AStar<GM, ACC>::expand(VisitorType& visitor)
00340    {
00341       //CHECK HEAP SIZE
00342       if(array_.size()>parameter_.maxHeapSize_*0.99) {
00343          partial_sort(array_.begin(), array_.begin()+(int)(parameter_.maxHeapSize_/2), array_.end(),  comp2);
00344          array_.resize((int)(parameter_.maxHeapSize_/2));
00345       }
00346       //GET HEAP HEAD
00347       AStarNode<IndependentFactorType> a           = array_.front();
00348       size_t            subconfsize = a.conf.size();
00349       //REMOVE HEAD FROM HEAP
00350       OPENGM_ASSERT(array_.size() > 0);
00351       pop_heap(array_.begin(), array_.end(),  comp1); //greater<FactorType,Accumulation>);
00352       array_.pop_back();
00353       if( parameter_.heuristic_ == parameter_.STANDARDHEURISTIC) {
00354          //BUILD GRAPHICAL MODEL FOR HEURISTC CALCULATION
00355          EditableGraphicalModelType tgm = gm_;
00356          std::vector<size_t> variableIndices(subconfsize);
00357          std::vector<size_t> values(subconfsize);
00358          for(size_t i =0; i<subconfsize ; ++i) {
00359             variableIndices[i] = parameter_.nodeOrder_[i];
00360             values[i]          = a.conf[i];
00361          }
00362          tgm.introduceEvidence(variableIndices.begin(), variableIndices.end(),values.begin());
00363          //test begin
00364          //for(size_t f=0;f<tgm.numberOfFactor();++f) {
00365             
00366          //}
00367          //test end
00368          std::vector<IndexType> varInd;
00369          for(size_t i=0; i<tgm.numberOfFactors(); ++i) {
00370             //treefactors will not be modyfied
00371             if(isTreeFactor_[i]) {
00372                continue;
00373             }else{
00374                varInd.clear();
00375                size_t nvar = tgm[i].numberOfVariables();
00376                //factors depending from 1 variable can be include to the tree
00377                if(nvar<=1) {
00378                   continue;
00379                }
00380                else{
00381                   typename GraphicalModelType::FunctionIdentifier id=tgm.addFunction(optimizedFactor_[i].function());
00382                   std::vector<IndexType> variablesIndices(optimizedFactor_[i].numberOfVariables());
00383                   optimizedFactor_[i].variableIndices(variablesIndices.begin());
00384                   OPENGM_ASSERT(variablesIndices.size()==optimizedFactor_[i].numberOfVariables());
00385                   tgm.replaceFactor(i,id.functionIndex,variablesIndices.begin(),variablesIndices.end());
00386                   OPENGM_ASSERT(tgm[i].numberOfVariables()==1);
00387                   OPENGM_ASSERT(tgm[i].variableIndex(0)==variablesIndices[0]);
00388                }
00389             }
00390          }
00391          typedef typename opengm::BeliefPropagationUpdateRules<EditableGraphicalModelType,ACC> UpdateRules;
00392          typename MessagePassing<EditableGraphicalModelType, ACC, UpdateRules, opengm::MaxDistance>::Parameter bpPara;
00393          bpPara.isAcyclic_ = opengm::Tribool::True;
00394          //std::cout<<"test if acyclic \n"<<std::flush;
00395          OPENGM_ASSERT(tgm.isAcyclic());
00396          //std::cout<<"done \n"<<std::flush;
00397          MessagePassing<EditableGraphicalModelType, ACC, UpdateRules, opengm::MaxDistance> bp(tgm,bpPara);  
00398          //typedef typename opengm::BeliefPropagationUpdateRules<EditableGraphicalModelType,ACC> UpdateRules;
00399          //typename MessagePassing<EditableGraphicalModelType, ACC, UpdateRules, opengm::MaxDistance>::Parameter bpPara;
00400          //bpPara.isAcyclic_ = opengm::Tribool::True;
00401          //MessagePassing<EditableGraphicalModelType, ACC, UpdateRules, opengm::MaxDistance> bp(tgm,bpPara);
00402          try{
00403          bp.infer();//Asynchronous();
00404          }
00405          catch(...) {
00406             throw RuntimeError("bp failed in astar");
00407          }
00408 
00409          if(true) {
00410             std::vector<LabelType> conf(numNodes_);
00411             bp.arg(conf);
00412             for(size_t i =0; i<subconfsize ; ++i) {
00413                conf[i] = a.conf[i];
00414             }
00415             // globalBound_= ACC::template op<ValueType>(gm_.evaluate(conf),globalBound_);
00416             ACC::op(gm_.evaluate(conf),aboveBound_,aboveBound_);
00417          }
00418          std::vector<LabelType> conf(numNodes_);
00419          a.conf.resize(subconfsize+1);
00420          for(size_t i=0; i<numStates_[subconfsize]; ++i) {
00421             a.conf[subconfsize] = i;
00422             bp.constrainedOptimum(parameter_.nodeOrder_,a.conf,conf);
00423             a.value   = tgm.evaluate(conf);
00424             array_.push_back(a);
00425             push_heap(array_.begin(), array_.end(),  comp1); //greater<FactorType,Accumulation>) ;
00426          }
00427       }
00428       if( parameter_.heuristic_ == parameter_.FASTHEURISTIC) {
00429          std::vector<LabelType> conf(subconfsize);
00430          for(size_t i=0;i<subconfsize;++i)
00431             conf[i] = a.conf[i];
00432          std::vector<ValueType> bound = fastHeuristic(conf);
00433          a.conf.resize(subconfsize+1);
00434          for(size_t i=0; i<numStates_[parameter_.nodeOrder_[subconfsize]]; ++i) {
00435             a.conf[subconfsize] = i;
00436             a.value             = bound[i];
00437             //if(bound[i]<10) {
00438             array_.push_back(a);
00439             push_heap(array_.begin(), array_.end(),  comp1); //greater<FactorType,Accumulation>) ;
00440             //}
00441          }
00442       }
00443    }
00444 
00445    template<class GM, class ACC>
00446    std::vector<typename AStar<GM, ACC>::ValueType>
00447    AStar<GM, ACC>::fastHeuristic(typename AStar<GM, ACC>::ConfVec conf)
00448    {
00449       std::list<size_t>                 factorList;
00450       std::vector<size_t>               nodeDegree(numNodes_,0);
00451       std::vector<int>                  nodeLabel(numNodes_,-1);
00452       std::vector<std::vector<ValueType > > nodeEnergy(numNodes_);
00453       size_t                            nextNode = parameter_.nodeOrder_[conf.size()];
00454       for(size_t i=0; i<numNodes_; ++i) {
00455          nodeEnergy[i].resize(numStates_[i]); //the energy passed to node i
00456          for(size_t j=0;j<numStates_[i];++j)
00457             OperatorType::neutral(nodeEnergy[i][j]);
00458       }
00459       for(size_t i=0;i<conf.size();++i) {
00460          nodeLabel[parameter_.nodeOrder_[i]] = conf[i];
00461       }
00462       //First run:
00463       // * add unarry function
00464       // * add pairwise functions with at least one observed node
00465       // * add the approximation for pairwise none-tree edges
00466       for(size_t i=0; i<gm_.numberOfFactors(); ++i) {
00467          const FactorType & f    = gm_[i];
00468          size_t nvar = f.numberOfVariables();
00469          //factors depending from 1 variable can be include
00470          if(nvar==1) {
00471             int index = f.variableIndex(0);
00472             if(nodeLabel[index]>=0) {
00473                nodeEnergy[index].resize(1);
00474                //nodeEnergy[index][0] = operatipon(f(nodeLabel[index]), nodeEnergy[index][0]);
00475                LabelType coordinates[]={static_cast<LabelType>(nodeLabel[index])};
00476                OperatorType::op(f(coordinates), nodeEnergy[index][0]);
00477             }
00478             else{
00479                OPENGM_ASSERT(numStates_[index] == nodeEnergy[index].size());
00480                for(size_t j=0;j<numStates_[index];++j) {
00481                   //nodeEnergy[index][j] = operation(f(j),nodeEnergy[index][j]);
00482                   LabelType coordinates[]={j};
00483                   OperatorType::op(f(coordinates),nodeEnergy[index][j]);
00484                }
00485             }
00486          }
00487          if(nvar==2) {
00488             size_t index1 = f.variableIndex(0);
00489             size_t index2 = f.variableIndex(1);
00490             if(nodeLabel[index1]>=0) {
00491                if(nodeLabel[index2]>=0) {
00492                   nodeEnergy[index1].resize(1);
00493                   //nodeEnergy[index1][0] = operation(f(nodeLabel[index1],nodeLabel[index2]),nodeEnergy[index1][0]);
00494                   LabelType coordinates[]={
00495                      static_cast<LabelType>(nodeLabel[index1]),
00496                      static_cast<LabelType>(nodeLabel[index2])
00497                   };
00498                   OperatorType::op(f(coordinates),nodeEnergy[index1][0]);
00499                }
00500                else{
00501                   OPENGM_ASSERT(numStates_[index2] == nodeEnergy[index2].size());
00502                   for(size_t j=0;j<numStates_[index2];++j) {
00503                      //nodeEnergy[index2][j] = operation(f(nodeLabel[index1],j), nodeEnergy[index2][j]);
00504                      LabelType coordinates[]={
00505                         static_cast<LabelType>(nodeLabel[index1]),
00506                         static_cast<LabelType>(j)
00507                      };
00508                      OperatorType::op(f(coordinates), nodeEnergy[index2][j]);
00509                   }
00510                }
00511             }
00512             else if(nodeLabel[index2]>=0) {
00513                OPENGM_ASSERT(numStates_[index1] == nodeEnergy[index1].size());
00514                for(size_t j=0;j<numStates_[index1];++j) {
00515                   //nodeEnergy[index1][j] = operation(f(j,nodeLabel[index2]),nodeEnergy[index1][j]);
00516                   LabelType coordinates[]={
00517                      static_cast<LabelType>(j),
00518                      static_cast<LabelType>(nodeLabel[index2])
00519                   };
00520                   OperatorType::op(f(coordinates),nodeEnergy[index1][j]);
00521                }
00522             }
00523             else if(isTreeFactor_[i]) {
00524                factorList.push_front(i);
00525                ++nodeDegree[index1];
00526                ++nodeDegree[index2];
00527                continue;
00528             }
00529             else{
00530                for(size_t j=0;j<numStates_[index1];++j) {
00531                   //nodeEnergy[index1][j] = operation(optimizedFactor_[i](j), nodeEnergy[index1][j]);
00532                   LabelType coordinates[]={j};
00533                   OperatorType::op(optimizedFactor_[i](coordinates), nodeEnergy[index1][j]);
00534                }
00535             }
00536          }
00537          if(nvar>2) {
00538             bool covered = true;
00539             std::vector<size_t> state(nvar);
00540             for(size_t j=0; j<nvar; ++j) {
00541                if(nodeLabel[f.variableIndex(j)]<0) {
00542                   state[j] = nodeLabel[f.variableIndex(j)];
00543                   covered = false;
00544                }
00545             }
00546             if(covered)
00547                nodeEnergy[f.variableIndex(0)][0] = f(state.begin());
00548             else{
00549                for(size_t j=0;j<numStates_[f.variableIndex(0)];++j) {
00550                   //nodeEnergy[f.variableIndex(0)][j] = operation(optimizedFactor_[i](j), nodeEnergy[f.variableIndex(0)][j]);
00551                   LabelType coordinates[]={j};
00552                   OperatorType::op(optimizedFactor_[i](coordinates), nodeEnergy[f.variableIndex(0)][j]);
00553                }
00554             }
00555          }
00556       }
00557       nodeDegree[nextNode] += numNodes_;
00558       // Start dynamic programming to solve the treestructured problem.
00559       while(factorList.size()>0) {
00560          size_t    id  = factorList.front();
00561          factorList.pop_front();
00562          const FactorType &  f      = gm_[id];
00563          size_t    index1 = f.variableIndex(0);
00564          size_t    index2 = f.variableIndex(1);
00565          typename FactorType::ValueType temp;
00566          OPENGM_ASSERT(index1 < numNodes_);
00567          OPENGM_ASSERT(index2 < numNodes_);
00568          OPENGM_ASSERT(gm_.numberOfLabels(index1) == numStates_[index1]);
00569          OPENGM_ASSERT(gm_.numberOfLabels(index2) == numStates_[index2]);
00570          if(nodeDegree[index1]==1) {
00571             typename FactorType::ValueType min;
00572             OPENGM_ASSERT(numStates_[index2] == nodeEnergy[index2].size());
00573             for(size_t j2=0;j2<numStates_[index2];++j2) {
00574                ACC::neutral(min);
00575                OPENGM_ASSERT(numStates_[index1] == nodeEnergy[index1].size());
00576                for(size_t j1=0;j1<numStates_[index1];++j1) {
00577                   LabelType coordinates[]={j1,j2};
00578                   OperatorType::op(f(coordinates),nodeEnergy[index1][j1],temp);
00579                   ACC::op(min,temp,min);
00580                }
00581                //nodeEnergy[index2][j2] = operation(min,nodeEnergy[index2][j2]);
00582                OperatorType::op(min,nodeEnergy[index2][j2]);
00583             }
00584             --nodeDegree[index1];
00585             --nodeDegree[index2];
00586             nodeEnergy[index1].resize(1);
00587             OperatorType::neutral(nodeEnergy[index1][0]);
00588          }
00589          else if(nodeDegree[index2]==1) {
00590             typename FactorType::ValueType min;
00591             OPENGM_ASSERT(numStates_[index1] == nodeEnergy[index1].size());
00592             for(size_t j1=0;j1<numStates_[index1];++j1) {
00593                ACC::neutral(min);
00594                OPENGM_ASSERT(numStates_[index2] == nodeEnergy[index2].size());
00595                for(size_t j2=0;j2<numStates_[index2];++j2) {
00596                   LabelType coordinates[]={j1,j2};
00597                   OperatorType::op(f(coordinates),nodeEnergy[index2][j2],temp);
00598                   ACC::op(min,temp,min);
00599                   //if(min>f(j1,j2)*node_energy[index2][j2]) min=f(j1,j2)*node_energy[index2][j2];
00600                }
00601                //nodeEnergy[index1][j1] = operation(min,nodeEnergy[index1][j1]);
00602                OperatorType::op(min,nodeEnergy[index1][j1]);
00603             }
00604             --nodeDegree[index1];
00605             --nodeDegree[index2];
00606             nodeEnergy[index2].resize(1);
00607             OperatorType::neutral(nodeEnergy[index2][0]);
00608          }
00609          else{
00610             factorList.push_back(id);
00611          }
00612       }
00613       //Evaluate
00614       ValueType result;
00615       ValueType min;
00616       OperatorType::neutral(result);
00617       std::vector<ValueType > bound;
00618       for(size_t i=0;i<numNodes_;++i) {
00619          if(i==nextNode) continue;
00620          ACC::neutral(min);
00621          for(size_t j=0; j<nodeEnergy[i].size();++j)
00622             ACC::op(min,nodeEnergy[i][j],min);
00623          //result = operation(result,min);
00624          OperatorType::op(min,result);
00625       }
00626       bound.resize(nodeEnergy[nextNode].size());
00627       for(size_t j=0; j<nodeEnergy[nextNode].size();++j) {
00628          //bound[j] = operation(nodeEnergy[nextNode][j],result);
00629          OperatorType::op(nodeEnergy[nextNode][j],result,bound[j]);
00630       }
00631       return bound;
00632    }
00633 
00634    template<class GM, class ACC>
00635    inline const typename AStar<GM, ACC>::GraphicalModelType&
00636    AStar<GM, ACC>::graphicalModel() const
00637    {
00638       return gm_;
00639    }
00640 
00641 /*
00642    template<class AStar, bool Verbose>
00643    inline AStarVisitor<AStar,Verbose>::AStarVisitor()
00644    : step_(0)
00645    {}
00646    template<class AStar, bool Verbose>
00647    inline void
00648    AStarVisitor<AStar,Verbose>::operator()
00649    (
00650       const typename AStarVisitor<AStar,Verbose>::astar_type& astar,
00651       const std::vector<size_t>& conf,
00652       const size_t heapsize,
00653       const typename AStarVisitor<AStar,Verbose>::ValueType& bound1,
00654       const typename AStarVisitor<AStar,Verbose>::ValueType& bound2,
00655       const double& runtime
00656    )
00657    {
00658       if(Verbose) {
00659          ++step_;
00660          std::cout << "step :" << step_
00661                    << "    time = " << runtime/1000.0 << "s"
00662                    << "    heapsize = "<< heapsize
00663                    << "    " << bound1 << " <= E(x) <= " << bound2
00664                    << std::endl;
00665       }
00666    }
00667 */
00668 
00669 } // namespace opengm
00670 
00671 #endif // #ifndef OPENGM_ASTAR_HXX
00672 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:01 2013 for OpenGM by  doxygen 1.6.3