loc.hxx

Go to the documentation of this file.
00001 #pragma once
00002 #ifndef OPENGM_LOC_HXX
00003 #define OPENGM_LOC_HXX
00004 
00005 #include <vector>
00006 #include <algorithm>
00007 #include <string>
00008 #include <iostream>
00009 #include <iomanip>
00010 #include <cstdlib>
00011 #include <cmath>
00012 #include <queue>
00013 
00014 #include "opengm/opengm.hxx"
00015 #include "opengm/utilities/random.hxx"
00016 #include "opengm/inference/inference.hxx"
00017 #include "opengm/inference/movemaker.hxx"
00018 #include "opengm/inference/astar.hxx"
00019 #include "opengm/inference/visitors/visitor.hxx"
00020 
00021 namespace opengm {
00031 template<class GM, class ACC>
00032 class LOC : public Inference<GM, ACC> {
00033 public:
00034    typedef ACC AccumulationType;
00035    typedef GM GraphicalModelType;
00036    OPENGM_GM_TYPE_TYPEDEFS;
00037    typedef Movemaker<GraphicalModelType> MovemakerType;
00038    typedef VerboseVisitor<LOC<GM, ACC> > VerboseVisitorType;
00039    typedef TimingVisitor<LOC<GM, ACC> > TimingVisitorType;
00040    typedef EmptyVisitor<LOC<GM, ACC> > EmptyVisitorType;
00041 
00042    class Parameter {
00043    public:
00050       Parameter
00051       (
00052          double phi = 0.5,
00053          size_t maxRadius = 10,
00054          size_t maxIterations = 0,
00055          size_t aStarThreshold = 10,
00056          const std::vector<LabelType>& startPoint = std::vector<LabelType>()
00057       )
00058       :  phi_(phi),
00059          maxRadius_(maxRadius),
00060          maxIterations_(maxIterations),
00061          aStarThreshold_(aStarThreshold),
00062          startPoint_(startPoint)
00063       {}
00065       double phi_;
00067       size_t maxRadius_;
00069       size_t maxIterations_;
00071       size_t aStarThreshold_;
00073       std::vector<LabelType> startPoint_;
00074    };
00075 
00076    LOC(const GraphicalModelType&, const Parameter& param = Parameter());
00077    std::string name() const;
00078    const GraphicalModelType& graphicalModel() const;
00079    InferenceTermination infer();
00080    void reset();
00081    template<class VisitorType>
00082       InferenceTermination infer(VisitorType&);
00083    void setStartingPoint(typename std::vector<LabelType>::const_iterator);
00084    InferenceTermination arg(std::vector<LabelType>&, const size_t = 1) const;
00085    ValueType value() const;
00086 
00087 private:
00088    void getSubgraphVis(const size_t, const size_t, std::vector<size_t>&);
00089    void inline initializeProbabilities(std::vector<double>&);
00090    const GraphicalModelType& gm_;
00091    MovemakerType movemaker_;
00092    Parameter param_;
00093    std::vector<std::vector<size_t> > viAdjacency_;
00094    std::vector<bool> usedVi_;
00095 };
00096 
00097 template<class GM, class ACC>
00098 LOC<GM, ACC>::LOC
00099 (
00100    const GraphicalModelType& gm,
00101    const Parameter& parameter
00102 )
00103 :  gm_(gm),
00104    movemaker_(gm),
00105    param_(parameter),
00106    viAdjacency_(gm.numberOfVariables()),
00107    usedVi_(gm.numberOfVariables(), false)
00108 {
00109    if(parameter.startPoint_.size() == gm.numberOfVariables())
00110       movemaker_.initialize(parameter.startPoint_.begin());
00111    else if(parameter.startPoint_.size() != 0)
00112       throw RuntimeError("Unsuitable starting point.");
00113    // compute variable adjacency
00114    for(size_t f=0;f<gm_.numberOfFactors();++f) {
00115       if(gm_[f].numberOfVariables()>1) {
00116          //connect all vi from factor f with each other
00117          for(size_t va=0;va<gm_[f].numberOfVariables();++va) {
00118          for(size_t vb=0;vb<gm_[f].numberOfVariables();++vb)
00119             if(va!=vb) { //connect
00120                viAdjacency_[ gm_[f].variableIndex(va)].push_back(gm_[f].variableIndex(vb));
00121                viAdjacency_[ gm_[f].variableIndex(vb)].push_back(gm_[f].variableIndex(va));
00122             }
00123          }
00124       }
00125    }
00126    if(this->param_.maxIterations_==0)
00127       param_.maxIterations_ = gm_.numberOfVariables() * 
00128          log(double(gm_.numberOfVariables()))*log(double(gm_.numberOfVariables()));
00129 }
00130 
00131 template<class GM, class ACC>
00132 void
00133 LOC<GM, ACC>::reset()
00134 {
00135    if(param_.startPoint_.size() == gm_.numberOfVariables()) {
00136       movemaker_.initialize(param_.startPoint_.begin());
00137    }
00138    else if(param_.startPoint_.size() != 0) {
00139       throw RuntimeError("Unsuitable starting point.");
00140    }
00141    else{
00142       movemaker_.reset();
00143    }
00144    std::fill(usedVi_.begin(),usedVi_.end(),false);
00145    // compute variable adjacency is not nessesary
00146    // since reset assumes that the structure of
00147    // the graphical model has not changed
00148    if(this->param_.maxIterations_==0)
00149       param_.maxIterations_ = gm_.numberOfVariables() * 
00150          log(double(gm_.numberOfVariables()))*log(double(gm_.numberOfVariables()));
00151 }
00152    
00153 template<class GM, class ACC>
00154 inline void 
00155 LOC<GM,ACC>::setStartingPoint
00156 (
00157    typename std::vector<typename LOC<GM,ACC>::LabelType>::const_iterator begin
00158 ) {
00159    try{
00160       movemaker_.initialize(begin);
00161    }
00162    catch(...) {
00163       throw RuntimeError("unsuitable starting point");
00164    }
00165 }
00166    
00167 template<class GM, class ACC>
00168 inline typename LOC<GM, ACC>::ValueType
00169 LOC<GM, ACC>::value()const
00170 {
00171    return this->movemaker_.value();
00172 }
00173 
00174 template<class GM, class ACC>
00175 void inline
00176 LOC<GM, ACC>::initializeProbabilities
00177 (
00178    std::vector<double>& prob
00179 )
00180 {
00181    const double phi = param_.phi_;
00182    if(param_.maxRadius_ < 2) {
00183       param_.maxRadius_ = 2;
00184    }
00185    size_t maxRadius = param_.maxRadius_;
00186    prob.resize(param_.maxRadius_);
00187    for(size_t i=0;i<param_.maxRadius_-1;++i) {
00188       prob[i] = phi * pow((1.0-phi), static_cast<double>(i));
00189    }
00190    prob[maxRadius-1]= pow((1.0-phi), static_cast<double>(param_.maxRadius_));
00191 }
00192 
00193 template<class GM, class ACC>
00194 inline std::string
00195 LOC<GM, ACC>::name() const {
00196    return "LOC";
00197 }
00198 
00199 template<class GM, class ACC>
00200 inline const typename LOC<GM, ACC>::GraphicalModelType&
00201 LOC<GM, ACC>::graphicalModel() const {
00202    return gm_;
00203 }
00204 
00205 template<class GM, class ACC>
00206 void LOC<GM, ACC>::getSubgraphVis
00207 (
00208    const size_t startVi,
00209    const size_t radius,
00210    std::vector<size_t>& vis
00211 ) {
00212    std::fill(usedVi_.begin(),usedVi_.end(),false);
00213    vis.clear();
00214    vis.push_back(startVi);
00215    usedVi_[startVi]=true;
00216    std::queue<size_t> viQueue;
00217    viQueue.push(startVi);
00218    size_t r=0;
00219    while(viQueue.size()!=0 && r<radius) {
00220       size_t cvi=viQueue.front();
00221       viQueue.pop();
00222       // for each neigbour of cvi
00223       for(size_t vni=0;vni<viAdjacency_[cvi].size();++vni) {
00224          // if neighbour has not been visited
00225          const size_t vn=viAdjacency_[cvi][vni];
00226          if(usedVi_[vn]==false) {
00227             // set as visited
00228             usedVi_[vn]=true;
00229             // insert into queue
00230             viQueue.push(vn);
00231             // insert into the subgraph vis
00232             vis.push_back(vn);
00233          }
00234       }
00235       ++r;
00236    }
00237 }
00238 
00239 template<class GM, class ACC>
00240 inline InferenceTermination
00241 LOC<GM, ACC>::infer() {
00242    EmptyVisitorType v;
00243    return infer(v);
00244 }
00245 
00246 template<class GM, class ACC>
00247 template<class VisitorType>
00248 InferenceTermination 
00249 LOC<GM, ACC>::infer
00250 (
00251    VisitorType& visitor
00252 ) {
00253    visitor.begin(*this,this->value(),this->bound());
00254    // create random generators
00255    opengm::RandomUniform<size_t> randomVariable(0, gm_.numberOfVariables());
00256    std::vector<double> prob;
00257    this->initializeProbabilities(prob);
00258    opengm::RandomDiscreteWeighted<size_t, double> randomRadius(prob.begin(), prob.end());
00259    std::vector<size_t> subgGraphVi;
00260    // all iterations, usualy n*log(n)
00261    for(size_t i=0;i<param_.maxIterations_;++i) {
00262       // select random variable
00263       size_t viStart = randomVariable();
00264       // select random radius
00265       size_t radius=randomRadius()+1;
00266       // grow subgraph from beginning from viStart with r=Radius
00267       this->getSubgraphVis(viStart, radius, subgGraphVi);
00268       // find the optimal configuration for all variables in subgGraphVi
00269       if(subgGraphVi.size()>param_.aStarThreshold_) {
00270           std::sort(subgGraphVi.begin(), subgGraphVi.end());
00271          typedef typename MovemakerType::SubGmType SubGmType;
00272          typedef opengm::AStar<SubGmType, ACC> SubGmInferenceType;
00273          typedef typename SubGmInferenceType::Parameter SubGmInferenceParameterType;
00274          SubGmInferenceParameterType para;
00275          para.heuristic_ = para.STANDARDHEURISTIC;
00276          std::vector<LabelType> states(std::distance(subgGraphVi.begin(), subgGraphVi.end()));
00277          movemaker_. template proposeMoveAccordingToInference< 
00278             SubGmInferenceType, 
00279             SubGmInferenceParameterType,
00280             typename std::vector<size_t>::const_iterator,
00281             typename std::vector<LabelType>::iterator 
00282          > (para, subgGraphVi.begin(), subgGraphVi.end(), states);
00283          movemaker_.move(subgGraphVi.begin(), subgGraphVi.end(), states.begin());
00284 
00285         
00286          //movemaker_.template moveAstarOptimally<AccumulationType>(subgGraphVi.begin(), subgGraphVi.end());
00287       }
00288       else
00289          movemaker_.template moveOptimally<AccumulationType>(subgGraphVi.begin(), subgGraphVi.end());
00290       visitor(*this,this->value(),this->bound(),radius);
00291    }
00292    visitor.end(*this,this->value(),this->bound());
00293    return NORMAL;
00294 }
00295 
00296 template<class GM, class ACC>
00297 inline InferenceTermination
00298 LOC<GM, ACC>::arg
00299 (
00300    std::vector<LabelType>& x,
00301    const size_t N
00302 ) const {
00303    if(N == 1) {
00304       x.resize(gm_.numberOfVariables());
00305       for(size_t j = 0; j < x.size(); ++j) {
00306          x[j] = movemaker_.state(j);
00307       }
00308       return NORMAL;
00309    }
00310    else 
00311       return UNKNOWN;
00312 }
00313 
00314 } // namespace opengm
00315 
00316 #endif // #ifndef OPENGM_LOC_HXX
00317 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:03 2013 for OpenGM by  doxygen 1.6.3