00001 #pragma once
00002 #ifndef OPENGM_INF_AND_FLIP_HXX
00003 #define OPENGM_INF_AND_FLIP_HXX
00004
00005 #include <vector>
00006 #include <set>
00007 #include <string>
00008 #include <iostream>
00009 #include <stdexcept>
00010 #include <list>
00011
00012 #include "opengm/opengm.hxx"
00013 #include "opengm/inference/inference.hxx"
00014 #include "opengm/inference/lazyflipper.hxx"
00015 #include "opengm/inference/visitors/visitor.hxx"
00016 #include "opengm/operations/minimizer.hxx"
00017 #include "opengm/utilities/tribool.hxx"
00018
00019 namespace opengm {
00020
00021
00022
00026 template<class GM, class ACC, class INF>
00027 class InfAndFlip : public Inference<GM, ACC> {
00028 public:
00029 typedef ACC AccumulationType;
00030 typedef GM GraphicalModelType;
00031 OPENGM_GM_TYPE_TYPEDEFS;
00032 typedef VerboseVisitor<InfAndFlip<GM, ACC, INF> > VerboseVisitorType;
00033 typedef EmptyVisitor<InfAndFlip<GM, ACC, INF> > EmptyVisitorType;
00034 typedef TimingVisitor<InfAndFlip<GM, ACC, INF> > TimingVisitorType;
00035
00036 struct Parameter
00037 {
00038 Parameter() : maxSubgraphSize_(2){}
00039 Parameter(const size_t maxSubgraphSize): maxSubgraphSize_(maxSubgraphSize){}
00040
00041 size_t maxSubgraphSize_;
00042 typename INF::Parameter subPara_;
00043 };
00044
00045 InfAndFlip(const GraphicalModelType&, typename InfAndFlip::Parameter param);
00046 std::string name() const;
00047 const GraphicalModelType& graphicalModel() const;
00048 ValueType value() const;
00049 ValueType bound() const;
00050 void reset();
00051 InferenceTermination infer();
00052 template<class VisitorType>
00053 InferenceTermination infer(VisitorType&);
00054 InferenceTermination arg(std::vector<LabelType>&, const size_t = 1)const;
00055
00056 private:
00057 const GraphicalModelType& gm_;
00058 Parameter para_;
00059 std::vector<LabelType> state_;
00060 ValueType value_;
00061 ValueType bound_;
00062 };
00063
00064
00065
00066
00067
00068 template<class GM, class ACC, class INF>
00069 inline
00070 InfAndFlip<GM, ACC, INF>::InfAndFlip(
00071 const GraphicalModelType& gm,
00072 typename InfAndFlip<GM, ACC, INF>::Parameter param
00073 )
00074 : gm_(gm), para_(param)
00075 {
00076 if(gm_.numberOfVariables() == 0) {
00077 throw RuntimeError("The graphical model has no variables.");
00078 }
00079 value_ = ACC::template neutral<ValueType>();
00080 bound_ = ACC::template ineutral<ValueType>();
00081 }
00082
00083 template<class GM, class ACC, class INF>
00084 inline void
00085 InfAndFlip<GM, ACC, INF>::reset()
00086 {}
00087
00088
00089 template<class GM, class ACC, class INF>
00090 inline std::string
00091 InfAndFlip<GM, ACC, INF>::name() const
00092 {
00093 return "InfAndFlip";
00094 }
00095
00096 template<class GM, class ACC, class INF>
00097 inline const typename InfAndFlip<GM, ACC, INF>::GraphicalModelType&
00098 InfAndFlip<GM, ACC, INF>::graphicalModel() const
00099 {
00100 return gm_;
00101 }
00102
00103
00105 template<class GM, class ACC, class INF>
00106 template<class VisitorType>
00107 inline InferenceTermination
00108 InfAndFlip<GM, ACC, INF>::infer(
00109 VisitorType& visitor
00110 )
00111 {
00112 INF inf(gm_,para_.subPara_);
00113 LazyFlipper<GM,ACC> lf(gm_);
00114
00115 visitor.begin(*this);
00116 inf.infer();
00117 inf.arg(state_);
00118 value_=inf.value();
00119 bound_=inf.bound();
00120 visitor.visit(*this);
00121 lf.setStartingPoint(state_.begin());
00122 lf.setMaxSubgraphSize(para_.maxSubgraphSize_);
00123 lf.infer();
00124 lf.arg(state_);
00125 value_=lf.value();
00126 visitor.end(*this);
00127
00128 return NORMAL;
00129 }
00130
00132 template<class GM, class ACC, class INF>
00133 inline InferenceTermination
00134 InfAndFlip<GM, ACC, INF>::infer()
00135 {
00136 EmptyVisitorType visitor;
00137 return this->infer(visitor);
00138 }
00139
00140
00141 template<class GM, class ACC, class INF>
00142 inline InferenceTermination
00143 InfAndFlip<GM, ACC, INF>::arg(
00144 std::vector<LabelType>& arg,
00145 const size_t N
00146 ) const
00147 {
00148 if(N==1) {
00149 arg.resize(gm_.numberOfVariables());
00150 for(size_t j=0; j<arg.size(); ++j) {
00151 arg[j] = state_[j];
00152 }
00153 return NORMAL;
00154 }
00155 else {
00156 return UNKNOWN;
00157 }
00158 }
00159
00160 template<class GM, class ACC, class INF>
00161 inline typename InfAndFlip<GM, ACC, INF>::ValueType
00162 InfAndFlip<GM, ACC, INF>::value() const
00163 {
00164 return value_;
00165 }
00166 template<class GM, class ACC, class INF>
00167 inline typename InfAndFlip<GM, ACC, INF>::ValueType
00168 InfAndFlip<GM, ACC, INF>::bound() const
00169 {
00170 return bound_;
00171 }
00172 }
00173
00174 #endif // #ifndef OPENGM_INFANDFLIP_HXX