JunctionTree now handles factor graphs with multiple connected components
authorJoris Mooij <joris.mooij@tuebingen.mpg.de>
Mon, 12 Apr 2010 19:27:21 +0000 (21:27 +0200)
committerJoris Mooij <joris.mooij@tuebingen.mpg.de>
Mon, 12 Apr 2010 19:27:21 +0000 (21:27 +0200)
include/dai/jtree.h
src/jtree.cpp
src/treeep.cpp

index 3c6d926..74bce1c 100644 (file)
@@ -110,10 +110,9 @@ class JTree : public DAIAlgRG {
         JTree() : DAIAlgRG(), _mes(), _logZ(), RTree(), Qa(), Qb(), props() {}
 
         /// Construct from FactorGraph \a fg and PropertySet \a opts
-        /** \param fg factor graph (which has to be connected);
+        /** \param fg factor graph
          ** \param opts Parameters @see Properties
          *  \param automatic if \c true, construct the junction tree automatically, using the heuristic in opts['heuristic'].
-         *  \throw FACTORGRAPH_NOT_CONNECTED if \a fg is not connected
          */
         JTree( const FactorGraph &fg, const PropertySet &opts, bool automatic=true );
     //@}
index e74aa85..850d65d 100644 (file)
@@ -64,9 +64,6 @@ string JTree::printProperties() const {
 JTree::JTree( const FactorGraph &fg, const PropertySet &opts, bool automatic ) : DAIAlgRG(), _mes(), _logZ(), RTree(), Qa(), Qb(), props() {
     setProperties( opts );
 
-    if( !fg.isConnected() )
-       DAI_THROW(FACTORGRAPH_NOT_CONNECTED);
-
     if( automatic ) {
         // Create ClusterGraph which contains factors as clusters
         vector<VarSet> cl;
@@ -118,12 +115,15 @@ void JTree::construct( const FactorGraph &fg, const std::vector<VarSet> &cl, boo
     // Construct a weighted graph (each edge is weighted with the cardinality
     // of the intersection of the nodes, where the nodes are the elements of cl).
     WeightedGraph<int> JuncGraph;
-    for( size_t i = 0; i < cl.size(); i++ )
+    for( size_t i = 0; i < cl.size(); i++ ) {
+        if( i )
+            JuncGraph[UEdge(i,0)] = 0; // for clusters that consist of a single variable
         for( size_t j = i+1; j < cl.size(); j++ ) {
             size_t w = (cl[i] & cl[j]).size();
             if( w )
                 JuncGraph[UEdge(i,j)] = w;
         }
+    }
 
     // Construct maximal spanning tree using Prim's algorithm
     RTree = MaxSpanningTree( JuncGraph, true );
index 37863eb..13a80a4 100644 (file)
@@ -100,8 +100,11 @@ TreeEP::TreeEP( const FactorGraph &fg, const PropertySet &opts ) : JTree(fg, opt
                                 piet = piet.marginal( ij );
                                 Factor pietf = piet.marginal(v_i) * piet.marginal(*j);
                                 wg[UEdge(i,fg.findVar(*j))] = dist( piet, pietf, DISTKL );
-                            } else
+                            } else {
+                                // this should never happen...
+                                DAI_ASSERT( 0 == 1 );
                                 wg[UEdge(i,fg.findVar(*j))] = 0;
+                            }
                         } else {
                             wg[UEdge(i,fg.findVar(*j))] = piet.strength(v_i, *j);
                         }