00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00014
00015
00016 #ifndef __defined_libdai_clustergraph_h
00017 #define __defined_libdai_clustergraph_h
00018
00019
00020 #include <set>
00021 #include <vector>
00022 #include <dai/varset.h>
00023 #include <dai/bipgraph.h>
00024
00025
00026 namespace dai {
00027
00028
00030
00032 class ClusterGraph {
00033 public:
00035 BipartiteGraph G;
00036
00038 std::vector<Var> vars;
00039
00041 std::vector<VarSet> clusters;
00042
00044 typedef BipartiteGraph::Neighbor Neighbor;
00045
00047 typedef BipartiteGraph::Edge Edge;
00048
00049 public:
00051
00052
00053 ClusterGraph() : G(), vars(), clusters() {}
00054
00056 ClusterGraph( const std::vector<VarSet> & cls );
00058
00060
00061
00062 const std::vector<VarSet> & toVector() const { return clusters; }
00063
00065 size_t size() const {
00066 return G.nrNodes2();
00067 }
00068
00070 size_t findVar( const Var &n ) const {
00071 return find( vars.begin(), vars.end(), n ) - vars.begin();
00072 }
00073
00075 VarSet Delta( size_t i ) const {
00076 VarSet result;
00077 foreach( const Neighbor &I, G.nb1(i) )
00078 result |= clusters[I];
00079 return result;
00080 }
00081
00083 VarSet delta( size_t i ) const {
00084 return Delta( i ) / vars[i];
00085 }
00086
00088 bool adj( size_t i1, size_t i2 ) const {
00089 bool result = false;
00090 foreach( const Neighbor &I, G.nb1(i1) )
00091 if( find( G.nb2(I).begin(), G.nb2(I).end(), i2 ) != G.nb2(I).end() ) {
00092 result = true;
00093 break;
00094 }
00095 return result;
00096 }
00097
00099 bool isMaximal( size_t I ) const {
00100 DAI_DEBASSERT( I < G.nrNodes2() );
00101 const VarSet & clI = clusters[I];
00102 bool maximal = true;
00103
00104 foreach( const Neighbor &i, G.nb2(I) ) {
00105 foreach( const Neighbor &J, G.nb1(i) )
00106 if( (J != I) && (clI << clusters[J]) ) {
00107 maximal = false;
00108 break;
00109 }
00110 if( !maximal )
00111 break;
00112 }
00113 return maximal;
00114 }
00116
00118
00119
00120 void insert( const VarSet &cl ) {
00121 if( find( clusters.begin(), clusters.end(), cl ) == clusters.end() ) {
00122 clusters.push_back( cl );
00123
00124 std::vector<size_t> nbs;
00125 for( VarSet::const_iterator n = cl.begin(); n != cl.end(); n++ ) {
00126 size_t iter = find( vars.begin(), vars.end(), *n ) - vars.begin();
00127 nbs.push_back( iter );
00128 if( iter == vars.size() ) {
00129 G.addNode1();
00130 vars.push_back( *n );
00131 }
00132 }
00133 G.addNode2( nbs.begin(), nbs.end(), nbs.size() );
00134 }
00135 }
00136
00138 ClusterGraph& eraseNonMaximal() {
00139 for( size_t I = 0; I < G.nrNodes2(); ) {
00140 if( !isMaximal(I) ) {
00141 clusters.erase( clusters.begin() + I );
00142 G.eraseNode2(I);
00143 } else
00144 I++;
00145 }
00146 return *this;
00147 }
00148
00150 ClusterGraph& eraseSubsuming( size_t i ) {
00151 while( G.nb1(i).size() ) {
00152 clusters.erase( clusters.begin() + G.nb1(i)[0] );
00153 G.eraseNode2( G.nb1(i)[0] );
00154 }
00155 return *this;
00156 }
00158
00160
00161
00162 friend std::ostream & operator << ( std::ostream & os, const ClusterGraph & cl ) {
00163 os << cl.toVector();
00164 return os;
00165 }
00167
00169
00170
00171
00175 template<class EliminationChoice>
00176 ClusterGraph VarElim( EliminationChoice f ) const {
00177
00178 ClusterGraph cl(*this);
00179 cl.eraseNonMaximal();
00180
00181 ClusterGraph result;
00182
00183
00184 std::set<size_t> varindices;
00185 for( size_t i = 0; i < vars.size(); ++i )
00186 varindices.insert( i );
00187
00188
00189 while( !varindices.empty() ) {
00190 size_t i = f( cl, varindices );
00191 DAI_ASSERT( i < vars.size() );
00192 result.insert( cl.Delta( i ) );
00193 cl.insert( cl.delta( i ) );
00194 cl.eraseSubsuming( i );
00195 cl.eraseNonMaximal();
00196 varindices.erase( i );
00197 }
00198
00199 return result;
00200 }
00201
00203
00208 size_t eliminationCost( size_t i ) const;
00209
00211
00215 ClusterGraph VarElim( const std::vector<Var> &ElimSeq ) const;
00216
00218
00223 ClusterGraph VarElim_MinFill() const;
00225 };
00226
00227
00229
00231 class sequentialVariableElimination {
00232 private:
00234 std::vector<Var> seq;
00236 size_t i;
00237
00238 public:
00240 sequentialVariableElimination( const std::vector<Var> s ) : seq(s), i(0) {}
00241
00243 size_t operator()( const ClusterGraph &cl, const std::set<size_t> & );
00244 };
00245
00246
00248
00251 class greedyVariableElimination {
00252 public:
00254 typedef size_t (*eliminationCostFunction)(const ClusterGraph &, size_t);
00255
00256 private:
00258 eliminationCostFunction heuristic;
00259
00260 public:
00262
00264 greedyVariableElimination( eliminationCostFunction h ) : heuristic(h) {}
00265
00267
00269 size_t operator()( const ClusterGraph &cl, const std::set<size_t> &remainingVars );
00270 };
00271
00272
00274
00278 size_t eliminationCost_MinNeighbors( const ClusterGraph &cl, size_t i );
00279
00280
00282
00287 size_t eliminationCost_MinWeight( const ClusterGraph &cl, size_t i );
00288
00289
00291
00295 size_t eliminationCost_MinFill( const ClusterGraph &cl, size_t i );
00296
00297
00299
00304 size_t eliminationCost_WeightedMinFill( const ClusterGraph &cl, size_t i );
00305
00306
00307 }
00308
00309
00310 #endif