sat.hxx

Go to the documentation of this file.
00001 #pragma once
00002 #ifndef OPENGM_INFERENCE_SAT_HXX
00003 #define OPENGM_INFERENCE_SAT_HXX
00004 
00005 #include <iostream>
00006 #include <vector>
00007 
00008 #include <boost/config.hpp>
00009 #include <boost/graph/strong_components.hpp>
00010 #include <boost/graph/adjacency_list.hpp>
00011 #include <boost/foreach.hpp>
00012 
00013 #include "opengm/inference/inference.hxx"
00014 #include "opengm/operations/and.hxx"
00015 #include "opengm/operations/or.hxx"
00016 #include "opengm/inference/visitors/visitor.hxx"
00017 
00018 namespace opengm {
00019 
00023    template<class GM>
00024    class SAT : Inference<GM, opengm::Or> {
00025    public:
00026       typedef opengm::Or AccumulationType;
00027       typedef GM GraphicalModelType;
00028       OPENGM_GM_TYPE_TYPEDEFS;
00029 
00030       struct Parameter {};
00031 
00032       SAT(const GraphicalModelType&, const Parameter& = Parameter());
00033       std::string name() const;
00034       const GraphicalModelType& graphicalModel() const;
00035       InferenceTermination infer();
00036       template<class VISITOR>
00037       InferenceTermination infer(VISITOR &);
00038       virtual void reset();
00039       ValueType value() const;
00040       typedef VerboseVisitor<SAT<GM> >        VerboseVisitorType;
00041       typedef TimingVisitor<SAT<GM> >         TimingVisitorType;
00042       typedef EmptyVisitor<SAT<GM> >          EmptyVisitorType;
00043    private:
00044       const GraphicalModelType& gm_;
00045       std::vector<int> component_;
00046    };
00047 
00048    template<class GM>
00049    inline SAT<GM>::SAT
00050    (
00051       const GraphicalModelType& gm,
00052       const Parameter& para
00053    )
00054    :  gm_(gm)
00055    {
00056       if(!NO_DEBUG) {
00057          OPENGM_ASSERT(gm_.factorOrder() <= 2);
00058          OPENGM_ASSERT(typeid(OperatorType) == typeid(opengm::And));
00059          for(size_t i=0; i<gm_.numberOfVariables();++i) {
00060             OPENGM_ASSERT(gm_.numberOfLabels(i) == 2);
00061          }
00062       }
00063    }
00064    template<class GM>
00065    void
00066    inline SAT<GM>::reset()
00067    {
00068    }
00069 
00070    template<class GM>
00071    inline std::string
00072    SAT<GM>::name() const
00073    {
00074       return "2Sat";
00075    }
00076 
00077    template<class GM>
00078    inline const GM&
00079    SAT<GM>::graphicalModel() const
00080    {
00081       return gm_;
00082    }
00083    
00084    template<class GM>
00085    InferenceTermination
00086    SAT<GM>::infer() {
00087       EmptyVisitorType v;
00088       return infer(v);
00089    }
00090    
00091    template<class GM>
00092    template<class VISITOR>
00093    InferenceTermination
00094    SAT<GM>::infer
00095    (
00096       VISITOR & visitor
00097    ) {
00098       typedef std::pair<int, int> clause;
00099       typedef boost::adjacency_list<> Graph; // properties of our graph. by default: oriented graph
00100       // build graph
00101       Graph g(gm_.numberOfVariables() * 2);
00102       for(size_t f=0; f<gm_.numberOfFactors(); ++f) {
00103          if(gm_[f].numberOfVariables() != 2) {
00104             throw RuntimeError("This implementation of the 2-SAT solver supports only factors of order 2.");
00105          }
00106          std::vector<size_t> vec(2);
00107          for(vec[0]=0; vec[0]<2; ++vec[0]) {
00108             for(vec[1]=0; vec[1]<2; ++vec[1]) {
00109                if(!gm_[f](vec.begin())) {
00110                   const int  v1=gm_[f].variableIndex(0)+(1-vec[0])*gm_.numberOfVariables();
00111                   const int nv1=gm_[f].variableIndex(0)+(0+vec[0])*gm_.numberOfVariables();
00112                   const int  v2=gm_[f].variableIndex(1)+(1-vec[1])*gm_.numberOfVariables();
00113                   const int nv2=gm_[f].variableIndex(1)+(0+vec[1])*gm_.numberOfVariables();
00114                   boost::add_edge(nv1,v2,g);
00115                   boost::add_edge(nv2,v1,g);
00116                }
00117             }
00118          }
00119       }
00120       component_.resize(num_vertices(g));
00121       strong_components(g,&component_[0]);
00122       return NORMAL;
00123    }
00124 
00125    template<class GM>
00126    inline typename GM::ValueType
00127    SAT<GM>::value() const
00128    {
00129       bool satisfied = true;
00130       for(IndexType i=0; i<gm_.numberOfVariables(); i++) {
00131          if(component_[i] == component_[i+gm_.numberOfVariables()]) {
00132             satisfied = false;
00133          }
00134       }
00135       return satisfied;
00136    }
00137 
00138 } // namespace opengm
00139 
00140 #endif // #ifndef OPENGM_INFERENCE_SAT_HXX
00141 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:06 2013 for OpenGM by  doxygen 1.6.3