aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
gum::StaticTriangulation Class Referenceabstract

base class for all non-incremental triangulation methods More...

#include <staticTriangulation.h>

+ Inheritance diagram for gum::StaticTriangulation:
+ Collaboration diagram for gum::StaticTriangulation:

Public Member Functions

Accessors / Modifiers
double maxLog10CliqueDomainSize ()
 returns the max of log10DomainSize of the cliques in the junction tree. More...
 
const NodeProperty< Size > * domainSizes () const
 returns the domain sizes of the variables of the graph to be triangulated More...
 

Protected Attributes

EliminationSequenceStrategyelimination_sequence_strategy_ {nullptr}
 the elimination sequence strategy used by the triangulation More...
 
JunctionTreeStrategyjunction_tree_strategy_ {nullptr}
 the junction tree strategy used by the triangulation More...
 
const NodeProperty< Size > * domain_sizes_ {nullptr}
 the domain sizes of the variables/nodes of the graph More...
 

Constructors / Destructors

virtual StaticTriangulationnewFactory () const =0
 returns a fresh triangulation of the same type as the current object but over an empty graph More...
 
virtual StaticTriangulationcopyFactory () const =0
 virtual copy constructor More...
 
virtual ~StaticTriangulation ()
 destructor More...
 
 StaticTriangulation (const EliminationSequenceStrategy &elimSeq, const JunctionTreeStrategy &JTStrategy, bool minimality=false)
 default constructor: without any graph More...
 
 StaticTriangulation (const UndiGraph *graph, const NodeProperty< Size > *dom_sizes, const EliminationSequenceStrategy &elimSeq, const JunctionTreeStrategy &JTStrategy, bool minimality=false)
 constructor with a given graph More...
 
 StaticTriangulation (const StaticTriangulation &)
 forbid copy constructor except in newfactory More...
 
 StaticTriangulation (StaticTriangulation &&)
 forbid move constructor except in children's constructors More...
 

Accessors / Modifiers

virtual void setGraph (const UndiGraph *graph, const NodeProperty< Size > *domsizes)
 initialize the triangulation data structures for a new graph More...
 
const EdgeSetfillIns ()
 returns the fill-ins added by the triangulation algorithm More...
 
const std::vector< NodeId > & eliminationOrder ()
 returns an elimination ordering compatible with the triangulated graph More...
 
Idx eliminationOrder (const NodeId)
 returns the index of a given node in the elimination order (0 = first node eliminated) More...
 
const NodeProperty< NodeId > & reverseEliminationOrder ()
 returns a table indicating, for each node, at which step it was deleted by the triangulation process More...
 
const UndiGraphtriangulatedGraph ()
 returns the triangulated graph More...
 
const CliqueGrapheliminationTree ()
 returns the elimination tree of a compatible ordering More...
 
const CliqueGraphjunctionTree ()
 returns a compatible junction tree More...
 
NodeId createdJunctionTreeClique (const NodeId id)
 returns the Id of the clique of the junction tree created by the elimination of a given node during the triangulation process More...
 
const NodeProperty< NodeId > & createdJunctionTreeCliques ()
 returns the Ids of the cliques of the junction tree created by the elimination of the nodes More...
 
const CliqueGraphmaxPrimeSubgraphTree ()
 returns a junction tree of maximal prime subgraphs More...
 
NodeId createdMaxPrimeSubgraph (const NodeId id)
 returns the Id of the maximal prime subgraph created by the elimination of a given node during the triangulation process More...
 
void clear ()
 reinitialize the graph to be triangulated to an empty graph More...
 
void setMinimalRequirement (bool)
 sets/unset the minimality requirement More...
 
virtual bool isMinimalityRequired () const final
 indicates wether minimality is required More...
 
void setFillIns (bool)
 sets/unsets the record of the fill-ins in the standard triangulation procedure More...
 
const UndiGraphoriginalGraph () const
 returns the graph to be triangulated More...
 
EliminationSequenceStrategyeliminationSequenceStrategy () const
 returns the elimination sequence strategy used by the triangulation More...
 
JunctionTreeStrategyjunctionTreeStrategy () const
 returns the junction tree strategy used by the triangulation More...
 
virtual void initTriangulation_ (UndiGraph &graph)
 the function called to initialize the triangulation process More...
 

Detailed Description

base class for all non-incremental triangulation methods

Definition at line 49 of file staticTriangulation.h.

Constructor & Destructor Documentation

◆ ~StaticTriangulation()

gum::StaticTriangulation::~StaticTriangulation ( )
virtual

destructor

Definition at line 152 of file staticTriangulation.cpp.

References gum::Set< Key, Alloc >::emplace().

152  {
153  // for debugging purposes
154  GUM_DESTRUCTOR(StaticTriangulation);
155 
158 
159  // no need to deallocate original_graph__ nor junction_tree__ because
160  // they are not owned by the static triangulation class
161  }
EliminationSequenceStrategy * elimination_sequence_strategy_
the elimination sequence strategy used by the triangulation
JunctionTreeStrategy * junction_tree_strategy_
the junction tree strategy used by the triangulation
StaticTriangulation(const EliminationSequenceStrategy &elimSeq, const JunctionTreeStrategy &JTStrategy, bool minimality=false)
default constructor: without any graph
+ Here is the call graph for this function:

◆ StaticTriangulation() [1/4]

gum::StaticTriangulation::StaticTriangulation ( const EliminationSequenceStrategy elimSeq,
const JunctionTreeStrategy JTStrategy,
bool  minimality = false 
)
protected

default constructor: without any graph

Parameters
elimSeqthe elimination sequence used to triangulate the graph
JTStrategythe junction tree strategy used to create junction trees from elimination trees
minimalitya Boolean indicating whether we should enforce that the triangulation is minimal w.r.t. inclusion

Definition at line 68 of file staticTriangulation.cpp.

References gum::Set< Key, Alloc >::emplace().

71  :
72  elimination_sequence_strategy_(elimSeq.newFactory()),
73  junction_tree_strategy_(JTStrategy.newFactory()),
74  minimality_required__(minimality) {
75  // for debugging purposes
76  GUM_CONSTRUCTOR(StaticTriangulation);
77 
78  // register the triangulation to its junction tree strategy
80  }
EliminationSequenceStrategy * elimination_sequence_strategy_
the elimination sequence strategy used by the triangulation
bool minimality_required__
indicates whether the triangulation must be minimal
virtual void setTriangulation(StaticTriangulation *triangulation)=0
assigns the triangulation to the junction tree strategy
JunctionTreeStrategy * junction_tree_strategy_
the junction tree strategy used by the triangulation
StaticTriangulation(const EliminationSequenceStrategy &elimSeq, const JunctionTreeStrategy &JTStrategy, bool minimality=false)
default constructor: without any graph
+ Here is the call graph for this function:

◆ StaticTriangulation() [2/4]

gum::StaticTriangulation::StaticTriangulation ( const UndiGraph graph,
const NodeProperty< Size > *  dom_sizes,
const EliminationSequenceStrategy elimSeq,
const JunctionTreeStrategy JTStrategy,
bool  minimality = false 
)
protected

constructor with a given graph

Parameters
graphthe graph to be triangulated, i.e., the nodes of which will be eliminated
dom_sizesthe domain sizes of the nodes to be eliminated
elimSeqthe elimination sequence used to triangulate the graph
JTStrategythe junction tree strategy used to create junction trees
Warning
Note that we allow dom_sizes to be defined over nodes/variables that do not belong to graph. These sizes will simply be ignored. However, it is compulsory that all the nodes of graph belong to dom_sizes
Parameters
minimalitya Boolean indicating whether we should enforce that the triangulation is minimal w.r.t. inclusion
Warning
note that, by aGrUM's rule, the graph is not copied but only referenced by the triangulation algorithm.

Definition at line 40 of file staticTriangulation.cpp.

References gum::Set< Key, Alloc >::emplace().

45  :
46  Triangulation(domsizes),
47  elimination_sequence_strategy_(elimSeq.newFactory()),
48  junction_tree_strategy_(JTStrategy.newFactory()), original_graph__(theGraph),
49  minimality_required__(minimality) {
50  // for debugging purposes
51  GUM_CONSTRUCTOR(StaticTriangulation);
52 
53  // if the graph is not empty, resize several structures in order to speed-up
54  // their fillings.
55  if (theGraph != nullptr) {
56  elim_order__.resize(theGraph->size());
57  reverse_elim_order__.resize(theGraph->size());
58  elim_cliques__.resize(theGraph->size());
59  node_2_max_prime_clique__.resize(theGraph->size());
60  added_fill_ins__.resize(theGraph->size());
61  }
62 
63  // register the triangulation to its junction tree strategy
65  }
EliminationSequenceStrategy * elimination_sequence_strategy_
the elimination sequence strategy used by the triangulation
std::vector< NodeId > elim_order__
the order in which nodes are eliminated by the algorithm
bool minimality_required__
indicates whether the triangulation must be minimal
const UndiGraph * original_graph__
a pointer to the (external) original graph (which will be triangulated)
NodeProperty< NodeId > node_2_max_prime_clique__
indicates which clique of the max prime junction tree was created by the elmination of a given node (...
NodeProperty< NodeId > reverse_elim_order__
the elimination order (access by NodeId)
virtual void setTriangulation(StaticTriangulation *triangulation)=0
assigns the triangulation to the junction tree strategy
NodeProperty< NodeSet > elim_cliques__
the cliques formed by the elimination of the nodes
Triangulation()
default constructor
std::vector< EdgeSet > added_fill_ins__
a vector containing the set of fill-ins added after each node elimination (used by recursive thinning...
JunctionTreeStrategy * junction_tree_strategy_
the junction tree strategy used by the triangulation
StaticTriangulation(const EliminationSequenceStrategy &elimSeq, const JunctionTreeStrategy &JTStrategy, bool minimality=false)
default constructor: without any graph
+ Here is the call graph for this function:

◆ StaticTriangulation() [3/4]

gum::StaticTriangulation::StaticTriangulation ( const StaticTriangulation from)
protected

forbid copy constructor except in newfactory

Definition at line 83 of file staticTriangulation.cpp.

References gum::Set< Key, Alloc >::emplace().

83  :
84  Triangulation(from), original_graph__(from.original_graph__),
85  triangulated_graph__(from.triangulated_graph__), fill_ins__(from.fill_ins__),
86  elim_order__(from.elim_order__),
87  reverse_elim_order__(from.reverse_elim_order__),
88  elim_cliques__(from.elim_cliques__), elim_tree__(from.elim_tree__),
89  max_prime_junction_tree__(from.max_prime_junction_tree__),
90  node_2_max_prime_clique__(from.node_2_max_prime_clique__),
91  has_triangulation__(from.has_triangulation__),
92  has_triangulated_graph__(from.has_triangulated_graph__),
93  has_elimination_tree__(from.has_elimination_tree__),
94  has_junction_tree__(from.has_junction_tree__),
95  has_max_prime_junction_tree__(from.has_max_prime_junction_tree__),
96  has_fill_ins__(from.has_fill_ins__),
97  minimality_required__(from.minimality_required__),
98  added_fill_ins__(from.added_fill_ins__),
99  we_want_fill_ins__(from.we_want_fill_ins__) {
100  // copy the strategies
102  = from.elimination_sequence_strategy_->copyFactory();
103  junction_tree_strategy_ = from.junction_tree_strategy_->copyFactory(this);
104 
105  // if from has a junction tree, copy it
106  if (from.junction_tree__ != nullptr) {
108  }
109 
110  // for debugging purposes
111  GUM_CONS_CPY(StaticTriangulation);
112  }
bool has_max_prime_junction_tree__
indicates whether a maximal prime subgraph junction tree has been constructed
bool has_elimination_tree__
a boolean indicating whether the elimination tree has been computed
EdgeSet fill_ins__
the fill-ins added during the whole triangulation process
virtual EliminationSequenceStrategy * copyFactory() const =0
virtual copy constructor
const CliqueGraph * junction_tree__
the junction tree computed by the algorithm
EliminationSequenceStrategy * elimination_sequence_strategy_
the elimination sequence strategy used by the triangulation
std::vector< NodeId > elim_order__
the order in which nodes are eliminated by the algorithm
bool minimality_required__
indicates whether the triangulation must be minimal
bool has_junction_tree__
a boolean indicating whether the junction tree has been constructed
CliqueGraph max_prime_junction_tree__
the maximal prime subgraph junction tree computed from the junction tree
bool has_triangulation__
a boolean indicating whether we have parformed a triangulation
bool has_triangulated_graph__
a boolean indicating whether we have constructed the triangulated graph
CliqueGraph elim_tree__
the elimination tree computed by the algorithm
const UndiGraph * original_graph__
a pointer to the (external) original graph (which will be triangulated)
bool has_fill_ins__
indicates whether we actually computed fill-ins
NodeProperty< NodeId > node_2_max_prime_clique__
indicates which clique of the max prime junction tree was created by the elmination of a given node (...
bool we_want_fill_ins__
a boolean indicating if we want fill-ins list with the standard triangulation method ...
virtual JunctionTreeStrategy * copyFactory(StaticTriangulation *triangulation=nullptr) const =0
virtual copy constructor
NodeProperty< NodeId > reverse_elim_order__
the elimination order (access by NodeId)
NodeProperty< NodeSet > elim_cliques__
the cliques formed by the elimination of the nodes
Triangulation()
default constructor
std::vector< EdgeSet > added_fill_ins__
a vector containing the set of fill-ins added after each node elimination (used by recursive thinning...
JunctionTreeStrategy * junction_tree_strategy_
the junction tree strategy used by the triangulation
UndiGraph triangulated_graph__
the triangulated graph
virtual const CliqueGraph & junctionTree()=0
returns the junction tree computed
StaticTriangulation(const EliminationSequenceStrategy &elimSeq, const JunctionTreeStrategy &JTStrategy, bool minimality=false)
default constructor: without any graph
+ Here is the call graph for this function:

◆ StaticTriangulation() [4/4]

gum::StaticTriangulation::StaticTriangulation ( StaticTriangulation &&  from)
protected

forbid move constructor except in children's constructors

Definition at line 115 of file staticTriangulation.cpp.

References gum::Set< Key, Alloc >::emplace().

115  :
116  Triangulation(std::move(from)),
117  elimination_sequence_strategy_(from.elimination_sequence_strategy_),
118  junction_tree_strategy_(from.junction_tree_strategy_),
119  original_graph__(from.original_graph__),
120  triangulated_graph__(std::move(from.triangulated_graph__)),
121  fill_ins__(std::move(from.fill_ins__)),
122  elim_order__(std::move(from.elim_order__)),
123  reverse_elim_order__(std::move(from.reverse_elim_order__)),
124  elim_cliques__(std::move(from.elim_cliques__)),
125  elim_tree__(std::move(from.elim_tree__)),
126  max_prime_junction_tree__(std::move(from.max_prime_junction_tree__)),
127  node_2_max_prime_clique__(std::move(from.node_2_max_prime_clique__)),
128  has_triangulation__(from.has_triangulation__),
129  has_triangulated_graph__(from.has_triangulated_graph__),
130  has_elimination_tree__(from.has_elimination_tree__),
131  has_junction_tree__(from.has_junction_tree__),
132  has_max_prime_junction_tree__(from.has_max_prime_junction_tree__),
133  has_fill_ins__(from.has_fill_ins__),
134  minimality_required__(from.minimality_required__),
135  added_fill_ins__(std::move(from.added_fill_ins__)),
136  we_want_fill_ins__(from.we_want_fill_ins__) {
137  // move the factories contained in from
138  from.elimination_sequence_strategy_ = new DefaultEliminationSequenceStrategy;
139  from.junction_tree_strategy_ = new DefaultJunctionTreeStrategy;
141 
142  // if from has a junction tree, copy it
143  if (from.junction_tree__ != nullptr) {
145  }
146 
147  // for debugging purposes
148  GUM_CONS_MOV(StaticTriangulation);
149  }
bool has_max_prime_junction_tree__
indicates whether a maximal prime subgraph junction tree has been constructed
bool has_elimination_tree__
a boolean indicating whether the elimination tree has been computed
EdgeSet fill_ins__
the fill-ins added during the whole triangulation process
const CliqueGraph * junction_tree__
the junction tree computed by the algorithm
EliminationSequenceStrategy * elimination_sequence_strategy_
the elimination sequence strategy used by the triangulation
std::vector< NodeId > elim_order__
the order in which nodes are eliminated by the algorithm
bool minimality_required__
indicates whether the triangulation must be minimal
bool has_junction_tree__
a boolean indicating whether the junction tree has been constructed
CliqueGraph max_prime_junction_tree__
the maximal prime subgraph junction tree computed from the junction tree
bool has_triangulation__
a boolean indicating whether we have parformed a triangulation
bool has_triangulated_graph__
a boolean indicating whether we have constructed the triangulated graph
CliqueGraph elim_tree__
the elimination tree computed by the algorithm
const UndiGraph * original_graph__
a pointer to the (external) original graph (which will be triangulated)
bool has_fill_ins__
indicates whether we actually computed fill-ins
NodeProperty< NodeId > node_2_max_prime_clique__
indicates which clique of the max prime junction tree was created by the elmination of a given node (...
bool we_want_fill_ins__
a boolean indicating if we want fill-ins list with the standard triangulation method ...
NodeProperty< NodeId > reverse_elim_order__
the elimination order (access by NodeId)
NodeProperty< NodeSet > elim_cliques__
the cliques formed by the elimination of the nodes
Triangulation()
default constructor
std::vector< EdgeSet > added_fill_ins__
a vector containing the set of fill-ins added after each node elimination (used by recursive thinning...
JunctionTreeStrategy * junction_tree_strategy_
the junction tree strategy used by the triangulation
UndiGraph triangulated_graph__
the triangulated graph
virtual const CliqueGraph & junctionTree()=0
returns the junction tree computed
virtual void moveTriangulation(StaticTriangulation *triangulation)
assigns a new triangulation to the junction tree strategy during a move construction ...
StaticTriangulation(const EliminationSequenceStrategy &elimSeq, const JunctionTreeStrategy &JTStrategy, bool minimality=false)
default constructor: without any graph
+ Here is the call graph for this function:

Member Function Documentation

◆ clear()

void gum::StaticTriangulation::clear ( )
virtual

reinitialize the graph to be triangulated to an empty graph

Implements gum::Triangulation.

Definition at line 164 of file staticTriangulation.cpp.

References gum::Set< Key, Alloc >::emplace().

164  {
165  // clear the factories
168 
169  // remove the current graphs
170  original_graph__ = nullptr;
171  junction_tree__ = nullptr;
173  elim_tree__.clear();
175  elim_cliques__.clear();
177 
178  // remove all fill-ins and orderings
179  fill_ins__.clear();
180  added_fill_ins__.clear();
181  elim_order__.clear();
182  reverse_elim_order__.clear();
183 
184  // indicates that the junction tree, the max prime tree, etc, are updated
185  has_triangulation__ = true;
187  has_elimination_tree__ = true;
188  has_junction_tree__ = true;
190  has_fill_ins__ = true;
191  }
bool has_max_prime_junction_tree__
indicates whether a maximal prime subgraph junction tree has been constructed
virtual void clear()
clears the sequence (to prepare, for instance, a new elimination sequence)
bool has_elimination_tree__
a boolean indicating whether the elimination tree has been computed
EdgeSet fill_ins__
the fill-ins added during the whole triangulation process
const CliqueGraph * junction_tree__
the junction tree computed by the algorithm
EliminationSequenceStrategy * elimination_sequence_strategy_
the elimination sequence strategy used by the triangulation
void clear() override
removes all the nodes and edges from the graph
Definition: undiGraph_inl.h:46
std::vector< NodeId > elim_order__
the order in which nodes are eliminated by the algorithm
bool has_junction_tree__
a boolean indicating whether the junction tree has been constructed
CliqueGraph max_prime_junction_tree__
the maximal prime subgraph junction tree computed from the junction tree
bool has_triangulation__
a boolean indicating whether we have parformed a triangulation
bool has_triangulated_graph__
a boolean indicating whether we have constructed the triangulated graph
CliqueGraph elim_tree__
the elimination tree computed by the algorithm
const UndiGraph * original_graph__
a pointer to the (external) original graph (which will be triangulated)
virtual void clear()
removes all the cliques and separators from the graph (as well as their adjacent edges) ...
bool has_fill_ins__
indicates whether we actually computed fill-ins
NodeProperty< NodeId > node_2_max_prime_clique__
indicates which clique of the max prime junction tree was created by the elmination of a given node (...
virtual void clear()=0
resets the current junction tree strategy data structures
NodeProperty< NodeId > reverse_elim_order__
the elimination order (access by NodeId)
NodeProperty< NodeSet > elim_cliques__
the cliques formed by the elimination of the nodes
std::vector< EdgeSet > added_fill_ins__
a vector containing the set of fill-ins added after each node elimination (used by recursive thinning...
JunctionTreeStrategy * junction_tree_strategy_
the junction tree strategy used by the triangulation
void clear()
Removes all the elements, if any, from the set.
Definition: set_tpl.h:374
UndiGraph triangulated_graph__
the triangulated graph
+ Here is the call graph for this function:

◆ computeEliminationTree__()

void gum::StaticTriangulation::computeEliminationTree__ ( )
private

returns an elimination tree from a triangulated graph

Definition at line 337 of file staticTriangulation.cpp.

References gum::Set< Key, Alloc >::emplace().

337  {
338  // if there already exists an elimination tree, no need to compute it again
339  if (has_elimination_tree__) return;
340 
341  // if the graph is not triangulated, triangulate it
343 
344  // create the nodes of the elimination tree
345  elim_tree__.clear();
346 
347  Size size = Size(elim_order__.size());
348  for (NodeId i = NodeId(0); i < size; ++i)
350 
351  // create the edges of the elimination tree: join a node to the one in
352  // its clique that is eliminated first
353  for (NodeId i = NodeId(0); i < size; ++i) {
354  NodeId clique_i_creator = elim_order__[i];
355  const NodeSet& list_of_nodes = elim_cliques__[clique_i_creator];
356  Idx child = original_graph__->bound() + 1;
357 
358  for (const auto node: list_of_nodes) {
359  Idx it_elim_step = reverse_elim_order__[node];
360 
361  if ((node != clique_i_creator) && (child > it_elim_step))
362  child = it_elim_step;
363  }
364 
365  if (child <= original_graph__->bound()) {
366  // WARNING: here, we assume that the nodes of the elimination tree are
367  // indexed from 0 to n-1
368  elim_tree__.addEdge(i, child);
369  }
370  }
371 
372  has_elimination_tree__ = true;
373  }
bool has_elimination_tree__
a boolean indicating whether the elimination tree has been computed
NodeId addNode(const NodeSet &clique)
adds a new clique to the graph
std::vector< NodeId > elim_order__
the order in which nodes are eliminated by the algorithm
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
void triangulate__()
the function that performs the triangulation
bool has_triangulation__
a boolean indicating whether we have parformed a triangulation
CliqueGraph elim_tree__
the elimination tree computed by the algorithm
const UndiGraph * original_graph__
a pointer to the (external) original graph (which will be triangulated)
virtual void clear()
removes all the cliques and separators from the graph (as well as their adjacent edges) ...
NodeProperty< NodeId > reverse_elim_order__
the elimination order (access by NodeId)
NodeProperty< NodeSet > elim_cliques__
the cliques formed by the elimination of the nodes
virtual void addEdge(const NodeId first, const NodeId second)
inserts a new edge between two cliques
NodeId bound() const
returns a number n such that all node ids are strictly lower than n
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:47
Size NodeId
Type for node ids.
Definition: graphElements.h:97
+ Here is the call graph for this function:

◆ computeMaxPrimeJunctionTree__()

void gum::StaticTriangulation::computeMaxPrimeJunctionTree__ ( )
private

computes the junction tree of the maximal prime subgraphs

Definition at line 410 of file staticTriangulation.cpp.

References gum::Set< Key, Alloc >::emplace().

410  {
411  // if there already exists a max prime junction tree, no need
412  // to recompute it
413  if (has_max_prime_junction_tree__) return;
414 
415  // if there is no junction tree, create it
417 
418  // the maximal prime subgraph join tree is created by aggregation of some
419  // cliques. More precisely, when the separator between 2 cliques is not
420  // complete in the original graph, then the two cliques must be merged.
421  // Create a hashtable indicating which clique has been absorbed by some
422  // other
423  // clique.
424  NodeProperty< NodeId > T_mpd_cliques(junction_tree__->size());
425 
426  for (const auto clik: junction_tree__->nodes())
427  T_mpd_cliques.insert(clik, clik);
428 
429  // parse all the separators of the junction tree and test those that are not
430  // complete in the orginal graph
431  std::vector< Arc > merged_cliques;
432 
433  NodeSet mark;
434 
435  for (const auto clik: junction_tree__->nodes())
436  if (!mark.contains(clik))
437  computeMaxPrimeMergings__(clik, clik, merged_cliques, mark);
438 
439  // compute the transitive closure of merged_cliques. This one will contain
440  // pairs (X,Y) indicating that clique X must be merged with clique Y.
441  // Actually clique X will be inserted into clique Y.
442  for (unsigned int i = 0; i < merged_cliques.size(); ++i) {
443  T_mpd_cliques[merged_cliques[i].tail()]
444  = T_mpd_cliques[merged_cliques[i].head()];
445  }
446 
447  // now we can create the max prime junction tree. First, create the cliques
448  for (const auto& elt: T_mpd_cliques)
449  if (elt.first == elt.second)
451  junction_tree__->clique(elt.second));
452 
453  // add to the cliques previously created the nodes of the cliques that were
454  // merged into them
455  for (const auto& elt: T_mpd_cliques)
456  if (elt.first != elt.second)
457  for (const auto node: junction_tree__->clique(elt.first)) {
458  try {
459  max_prime_junction_tree__.addToClique(elt.second, node);
460  } catch (DuplicateElement&) {}
461  }
462 
463  // add the edges to the graph
464  for (const auto& edge: junction_tree__->edges()) {
465  NodeId node1 = T_mpd_cliques[edge.first()];
466  NodeId node2 = T_mpd_cliques[edge.second()];
467 
468  if (node1 != node2) {
469  try {
470  max_prime_junction_tree__.addEdge(node1, node2);
471  } catch (DuplicateElement&) {}
472  }
473  }
474 
475  // compute for each node which clique of the max prime junction tree was
476  // created by the elimination of the node
477  const NodeProperty< NodeId >& node_2_junction_clique
479 
480  for (const auto& elt: node_2_junction_clique)
481  node_2_max_prime_clique__.insert(elt.first, T_mpd_cliques[elt.second]);
482 
484  }
bool has_max_prime_junction_tree__
indicates whether a maximal prime subgraph junction tree has been constructed
const CliqueGraph & junctionTree()
returns a compatible junction tree
NodeId addNode(const NodeSet &clique)
adds a new clique to the graph
virtual const NodeProperty< NodeId > & createdCliques()=0
returns, for each node, the clique of the junction tree which was created by its deletion ...
void computeMaxPrimeMergings__(const NodeId node, const NodeId from, std::vector< Arc > &merged_cliques, NodeSet &mark) const
used for computing the junction tree of the maximal prime subgraphs
const CliqueGraph * junction_tree__
the junction tree computed by the algorithm
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
bool has_junction_tree__
a boolean indicating whether the junction tree has been constructed
Size size() const
alias for sizeNodes
CliqueGraph max_prime_junction_tree__
the maximal prime subgraph junction tree computed from the junction tree
NodeProperty< NodeId > node_2_max_prime_clique__
indicates which clique of the max prime junction tree was created by the elmination of a given node (...
const EdgeSet & edges() const
returns the set of edges stored within the EdgeGraphPart
virtual void addToClique(const NodeId clique_id, const NodeId node_id)
changes the set of nodes included into a given clique and returns the new set
const NodeGraphPart & nodes() const
return *this as a NodeGraphPart
virtual void addEdge(const NodeId first, const NodeId second)
inserts a new edge between two cliques
const NodeSet & clique(const NodeId idClique) const
returns the set of nodes included into a given clique
JunctionTreeStrategy * junction_tree_strategy_
the junction tree strategy used by the triangulation
Size NodeId
Type for node ids.
Definition: graphElements.h:97
+ Here is the call graph for this function:

◆ computeMaxPrimeMergings__()

void gum::StaticTriangulation::computeMaxPrimeMergings__ ( const NodeId  node,
const NodeId  from,
std::vector< Arc > &  merged_cliques,
NodeSet mark 
) const
private

used for computing the junction tree of the maximal prime subgraphs

Definition at line 376 of file staticTriangulation.cpp.

References gum::Set< Key, Alloc >::emplace().

380  {
381  mark << node;
382 
383  for (const auto other_node: junction_tree__->neighbours(node))
384  if (other_node != from) {
385  const NodeSet& separator = junction_tree__->separator(node, other_node);
386  // check that the separator between node and other_node is complete
387  bool complete = true;
388 
389  for (auto iter_sep1 = separator.begin();
390  iter_sep1 != separator.end() && complete;
391  ++iter_sep1) {
392  auto iter_sep2 = iter_sep1;
393 
394  for (++iter_sep2; iter_sep2 != separator.end(); ++iter_sep2) {
395  if (!original_graph__->existsEdge(*iter_sep1, *iter_sep2)) {
396  complete = false;
397  break;
398  }
399  }
400  }
401 
402  // here complete indicates whether the separator is complete or not
403  if (!complete) merged_cliques.push_back(Arc(other_node, node));
404 
405  computeMaxPrimeMergings__(other_node, node, merged_cliques, mark);
406  }
407  }
void computeMaxPrimeMergings__(const NodeId node, const NodeId from, std::vector< Arc > &merged_cliques, NodeSet &mark) const
used for computing the junction tree of the maximal prime subgraphs
const CliqueGraph * junction_tree__
the junction tree computed by the algorithm
const NodeSet & separator(const Edge &edge) const
returns the separator included in a given edge
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
const UndiGraph * original_graph__
a pointer to the (external) original graph (which will be triangulated)
const NodeSet & neighbours(const NodeId id) const
returns the set of edges adjacent to a given node
bool existsEdge(const Edge &edge) const
indicates whether a given edge exists
+ Here is the call graph for this function:

◆ computeRecursiveThinning__()

void gum::StaticTriangulation::computeRecursiveThinning__ ( )
private

removes redondant fill-ins and compute proper elimination cliques and order

Definition at line 194 of file staticTriangulation.cpp.

References gum::Set< Key, Alloc >::emplace().

194  {
195  // apply recursive thinning (fmint, see Kjaerulff (90), "triangulation of
196  // graphs - algorithms giving small total state space")
197  NodeId node1, node2;
198  bool incomplete;
199  std::vector< NodeId > adj;
200  EdgeSet T_prime;
201  NodeProperty< unsigned int > R(triangulated_graph__.size());
202 
203  for (const auto node: triangulated_graph__)
204  R.insert(node, 0);
205 
206  // the FMINT loop
207  if (added_fill_ins__.size() > 0) {
208  for (auto iter = added_fill_ins__.rbegin(); iter != added_fill_ins__.rend();
209  ++iter) {
210  if (iter->size()) {
211  // here apply MINT to T_i = added_fill_ins__[i]
212  EdgeSet& T = *iter;
213 
214  // compute R: by default, R is equal to all the nodes in the graph
215  // when R[...] >= j (see the j in the loop below), this means that the
216  // node belongs to an extremal edge in R
217  for (std::size_t k = 0; k < elim_order__.size(); ++k)
218  R[elim_order__[k]]
219  = 0; // WARNING: do not replace R[elim_order__[k]] by
220 
221  // R[k] because the node ids may not be
222  // consecutive numbers
223 
224  // apply MINT while some edges can possibly be deleted
225  bool require_mint = true;
226 
227  for (unsigned int j = 0; require_mint; ++j) {
228  // find T' (it is equal to the edges (v,w) of T such that
229  // the intersection of adj(v,G) and adj(w,G) is complete and such
230  // that
231  // v and/or w belongs to an extremal node in R
232  for (const auto& edge: T) {
233  node1 = edge.first();
234  node2 = edge.second();
235 
236  // check if at least one extremal node belongs to R
237  if ((R[node1] < j) && (R[node2] < j)) continue;
238 
239  // check if the intersection of adj(v,G) and adj(w,G) is a
240  // complete subgraph
241  if (triangulated_graph__.neighbours(node2).size()
242  < triangulated_graph__.neighbours(node1).size()) {
243  NodeId tmp = node1;
244  node1 = node2;
245  node2 = tmp;
246  }
247 
248  incomplete = false;
249 
250  // find the nodes belonging to the intersection of adj(v,G)
251  // and adj(w,G)
252  for (const auto adjnode: triangulated_graph__.neighbours(node1))
253  if (triangulated_graph__.existsEdge(node2, adjnode))
254  adj.push_back(adjnode);
255 
256  // check if the intersection is complete
257  for (unsigned int k = 0; k < adj.size() && !incomplete; ++k) {
258  for (unsigned int m = k + 1; m < adj.size(); ++m) {
259  if (!triangulated_graph__.existsEdge(adj[k], adj[m])) {
260  incomplete = true;
261  break;
262  }
263  }
264  }
265 
266  adj.clear();
267 
268  if (!incomplete) {
269  T_prime.insert(edge);
270  R[node1] = j + 1;
271  R[node2] = j + 1;
272  }
273  }
274 
275  // compute the new value of T (i.e. T\T') and update the
276  // triangulated graph
277  for (const auto& edge: T_prime) {
278  T.erase(edge);
279  triangulated_graph__.eraseEdge(edge);
280 
281  if (has_fill_ins__) fill_ins__.erase(edge);
282  }
283 
284  if (T_prime.size() == 0) require_mint = false;
285 
286  T_prime.clear();
287  }
288  }
289  }
290  }
291 
292  // here, the recursive thinning has removed all the superfluous edges.
293  // Hence some cliques have been split and, as a result, the elimination
294  // order has changed. We should thus compute a new perfect ordering. To
295  // do so, we use a Maximal Cardinality Search: it has indeed the nice
296  // property that, when the graph is already triangulated, it finds a
297  // compatible order of elimination that does not require any edge addition
298 
299  // a structure storing the number of neighbours previously processed
300  PriorityQueue< NodeId, unsigned int, std::greater< unsigned int > >
301  numbered_neighbours(std::greater< unsigned int >(),
302  triangulated_graph__.size());
303 
304  for (Size i = 0; i < elim_order__.size(); ++i)
305  numbered_neighbours.insert(elim_order__[i], 0);
306 
307  // perform the maximum cardinality search
308  if (elim_order__.size() > 0) {
309  for (Size i = Size(elim_order__.size()); i >= 1; --i) {
310  NodeId ni = NodeId(i - 1);
311  NodeId node = numbered_neighbours.pop();
312  elim_order__[ni] = node;
313  reverse_elim_order__[node] = ni;
314 
315  for (const auto neighbour: triangulated_graph__.neighbours(node)) {
316  try {
317  numbered_neighbours.setPriority(
318  neighbour,
319  1 + numbered_neighbours.priority(neighbour));
320  } catch (NotFound&) {}
321  }
322  }
323  }
324 
325  // here the elimination order is ok. We now need to update the
326  // elim_cliques__
327  for (Size i = 0; i < elim_order__.size(); ++i) {
328  NodeSet& cliques = elim_cliques__.insert(elim_order__[i], NodeSet()).second;
329  cliques << elim_order__[i];
330 
331  for (const auto neighbour: triangulated_graph__.neighbours(elim_order__[i]))
332  if (reverse_elim_order__[neighbour] > i) cliques << neighbour;
333  }
334  }
EdgeSet fill_ins__
the fill-ins added during the whole triangulation process
std::vector< NodeId > elim_order__
the order in which nodes are eliminated by the algorithm
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
Size size() const
alias for sizeNodes
bool has_fill_ins__
indicates whether we actually computed fill-ins
void erase(const Key &k)
Erases an element from the set.
Definition: set_tpl.h:675
Set< Edge > EdgeSet
Some typdefs and define for shortcuts ...
NodeProperty< NodeId > reverse_elim_order__
the elimination order (access by NodeId)
NodeProperty< NodeSet > elim_cliques__
the cliques formed by the elimination of the nodes
std::vector< EdgeSet > added_fill_ins__
a vector containing the set of fill-ins added after each node elimination (used by recursive thinning...
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:47
UndiGraph triangulated_graph__
the triangulated graph
Size NodeId
Type for node ids.
Definition: graphElements.h:97
void insert(const Key &k)
Inserts a new element into the set.
Definition: set_tpl.h:632
+ Here is the call graph for this function:

◆ copyFactory()

virtual StaticTriangulation* gum::StaticTriangulation::copyFactory ( ) const
pure virtual

virtual copy constructor

note that we return a pointer as it enables subclasses to return pointers to their types, not Triangulation pointers. See item 25 of the more effective C++.

Implements gum::Triangulation.

Implemented in gum::PartialOrderedTriangulation, gum::OrderedTriangulation, gum::DefaultTriangulation, and gum::UnconstrainedTriangulation.

◆ createdJunctionTreeClique()

NodeId gum::StaticTriangulation::createdJunctionTreeClique ( const NodeId  id)
virtual

returns the Id of the clique of the junction tree created by the elimination of a given node during the triangulation process

Implements gum::Triangulation.

◆ createdJunctionTreeCliques()

const NodeProperty< NodeId >& gum::StaticTriangulation::createdJunctionTreeCliques ( )
virtual

returns the Ids of the cliques of the junction tree created by the elimination of the nodes

Implements gum::Triangulation.

◆ createdMaxPrimeSubgraph()

NodeId gum::StaticTriangulation::createdMaxPrimeSubgraph ( const NodeId  id)
virtual

returns the Id of the maximal prime subgraph created by the elimination of a given node during the triangulation process

Implements gum::Triangulation.

◆ domainSizes()

const NodeProperty< Size >* gum::Triangulation::domainSizes ( ) const
inherited

returns the domain sizes of the variables of the graph to be triangulated

◆ eliminationOrder() [1/2]

const std::vector< NodeId >& gum::StaticTriangulation::eliminationOrder ( )
virtual

returns an elimination ordering compatible with the triangulated graph

Implements gum::Triangulation.

◆ eliminationOrder() [2/2]

Idx gum::StaticTriangulation::eliminationOrder ( const NodeId  )
virtual

returns the index of a given node in the elimination order (0 = first node eliminated)

Implements gum::Triangulation.

◆ eliminationSequenceStrategy()

EliminationSequenceStrategy& gum::StaticTriangulation::eliminationSequenceStrategy ( ) const

returns the elimination sequence strategy used by the triangulation

◆ eliminationTree()

const CliqueGraph& gum::StaticTriangulation::eliminationTree ( )
virtual

returns the elimination tree of a compatible ordering

Implements gum::Triangulation.

◆ fillIns()

const EdgeSet & gum::StaticTriangulation::fillIns ( )
virtual

returns the fill-ins added by the triangulation algorithm

Implements gum::Triangulation.

Definition at line 679 of file staticTriangulation.cpp.

References gum::Set< Key, Alloc >::emplace().

679  {
680  // if we did not compute the triangulation yet, do it and commpute
681  // the fill-ins at the same time
682  if (!has_triangulation__) {
683  bool want_fill_ins = we_want_fill_ins__;
684  we_want_fill_ins__ = true;
685  triangulate__();
686  we_want_fill_ins__ = want_fill_ins;
687  has_fill_ins__ = true;
688  }
689 
690  // here, we already computed a triangulation and we already computed
691  // the fill-ins, so return them
692  if (has_fill_ins__) {
695  else
696  return fill_ins__;
697  } else {
698  // ok, here, we shall compute the fill-ins as they were not precomputed
699  if (!original_graph__) return fill_ins__;
700 
701  // just in case, be sure that the junction tree has been constructed
703 
704  for (const auto clik_id: junction_tree__->nodes()) {
705  // for each clique, add the edges necessary to make it complete
706  const NodeSet& clique = junction_tree__->clique(clik_id);
707  std::vector< NodeId > clique_nodes(clique.size());
708  unsigned int i = 0;
709 
710  for (const auto node: clique) {
711  clique_nodes[i] = node;
712  i += 1;
713  }
714 
715  for (i = 0; i < clique_nodes.size(); ++i) {
716  for (unsigned int j = i + 1; j < clique_nodes.size(); ++j) {
717  Edge edge(clique_nodes[i], clique_nodes[j]);
718 
719  if (!original_graph__->existsEdge(edge)) {
720  try {
721  fill_ins__.insert(edge);
722  } catch (DuplicateElement&) {}
723  }
724  }
725  }
726  }
727 
728  return fill_ins__;
729  }
730  }
const CliqueGraph & junctionTree()
returns a compatible junction tree
virtual const EdgeSet & fillIns()
in case fill-ins are provided, this function returns the fill-ins due to all the nodes eliminated so ...
EdgeSet fill_ins__
the fill-ins added during the whole triangulation process
const CliqueGraph * junction_tree__
the junction tree computed by the algorithm
EliminationSequenceStrategy * elimination_sequence_strategy_
the elimination sequence strategy used by the triangulation
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
bool has_junction_tree__
a boolean indicating whether the junction tree has been constructed
void triangulate__()
the function that performs the triangulation
bool has_triangulation__
a boolean indicating whether we have parformed a triangulation
const UndiGraph * original_graph__
a pointer to the (external) original graph (which will be triangulated)
bool has_fill_ins__
indicates whether we actually computed fill-ins
bool we_want_fill_ins__
a boolean indicating if we want fill-ins list with the standard triangulation method ...
bool existsEdge(const Edge &edge) const
indicates whether a given edge exists
const NodeGraphPart & nodes() const
return *this as a NodeGraphPart
const NodeSet & clique(const NodeId idClique) const
returns the set of nodes included into a given clique
void insert(const Key &k)
Inserts a new element into the set.
Definition: set_tpl.h:632
virtual bool providesFillIns() const =0
indicates whether the fill-ins generated by the eliminated nodes, if needed, will be computed by the ...
+ Here is the call graph for this function:

◆ initTriangulation_()

void gum::StaticTriangulation::initTriangulation_ ( UndiGraph graph)
protectedvirtual

the function called to initialize the triangulation process

This function is called when the triangulation process starts and is used to initialize the elimination sequence strategy. Actually, the graph that is modified by the triangulation algorithm is a copy of the original graph, and this copy needs be known by the elimination sequence strategy. initTriangulation_ is used to transmit this knowledge to the elimination sequence (through method setGraph of the elimination sequence class).

Parameters
graphthe very graph that is triangulated (this is a copy of original_graph__)

Reimplemented in gum::PartialOrderedTriangulation, and gum::OrderedTriangulation.

Definition at line 733 of file staticTriangulation.cpp.

References gum::Set< Key, Alloc >::emplace().

733  {
735  }
EliminationSequenceStrategy * elimination_sequence_strategy_
the elimination sequence strategy used by the triangulation
const NodeProperty< Size > * domain_sizes_
the domain sizes of the variables/nodes of the graph
virtual bool setGraph(UndiGraph *graph, const NodeProperty< Size > *dom_sizes)
sets a new graph to be triangulated
+ Here is the call graph for this function:

◆ isMinimalityRequired()

virtual bool gum::StaticTriangulation::isMinimalityRequired ( ) const
finalvirtual

indicates wether minimality is required

◆ junctionTree()

const CliqueGraph& gum::StaticTriangulation::junctionTree ( )
virtual

returns a compatible junction tree

Implements gum::Triangulation.

◆ junctionTreeStrategy()

JunctionTreeStrategy& gum::StaticTriangulation::junctionTreeStrategy ( ) const

returns the junction tree strategy used by the triangulation

◆ maxLog10CliqueDomainSize()

double gum::Triangulation::maxLog10CliqueDomainSize ( )
inherited

returns the max of log10DomainSize of the cliques in the junction tree.

This is usefull for instance to estimate the complexity (both in space and in time) of the inference that will use the junction tree.

This method is not 'const' since it can be called before building any junction tree and hence it needs to build it...

Definition at line 69 of file triangulation.cpp.

References gum::Set< Key, Alloc >::emplace().

69  {
70  double res = 0.0;
71  double dSize;
72  const JunctionTree& jt = junctionTree(); // here, the fact that we get
73  // a junction tree ensures that domain_sizes_ is different from nullptr
74 
75  for (const NodeId cl: jt) {
76  dSize = 0.0;
77 
78  for (const auto node: jt.clique(cl))
79  dSize += std::log10((*domain_sizes_)[node]);
80 
81  if (res < dSize) res = dSize;
82  }
83 
84  return res;
85  }
const NodeProperty< Size > * domain_sizes_
the domain sizes of the variables/nodes of the graph
CliqueGraph JunctionTree
a junction tree is a clique graph satisfying the running intersection property and such that no cliqu...
Definition: cliqueGraph.h:301
virtual const CliqueGraph & junctionTree()=0
returns a compatible junction tree
Size NodeId
Type for node ids.
Definition: graphElements.h:97
+ Here is the call graph for this function:

◆ maxPrimeSubgraphTree()

const CliqueGraph& gum::StaticTriangulation::maxPrimeSubgraphTree ( )
virtual

returns a junction tree of maximal prime subgraphs

Warning
Actually, the cliques of the junction tree are guarranteed to be maximal prime subgraph of the original graph that was triangulated only if the triangulation performed is minimal (in the sense that removing any edge in the triangulated graph results in a nontriangulated graph). This can be ensured by requiring minimality of the triangulation.

Implements gum::Triangulation.

◆ newFactory()

virtual StaticTriangulation* gum::StaticTriangulation::newFactory ( ) const
pure virtual

returns a fresh triangulation of the same type as the current object but over an empty graph

note that we return a pointer as it enables subclasses to return pointers to their types, not Triangulation pointers. See item 25 of the more effective C++.

Implements gum::Triangulation.

Implemented in gum::PartialOrderedTriangulation, gum::OrderedTriangulation, gum::DefaultTriangulation, and gum::UnconstrainedTriangulation.

◆ operator=()

StaticTriangulation& gum::StaticTriangulation::operator= ( const StaticTriangulation )
private

forbid copy operator

◆ originalGraph()

const UndiGraph* gum::StaticTriangulation::originalGraph ( ) const

returns the graph to be triangulated

Warning
if we have not set yet a graph, then originalGraph () will return a nullptr.

◆ reverseEliminationOrder()

const NodeProperty< NodeId >& gum::StaticTriangulation::reverseEliminationOrder ( )

returns a table indicating, for each node, at which step it was deleted by the triangulation process

◆ setFillIns()

void gum::StaticTriangulation::setFillIns ( bool  )

sets/unsets the record of the fill-ins in the standard triangulation procedure

◆ setGraph()

void gum::StaticTriangulation::setGraph ( const UndiGraph graph,
const NodeProperty< Size > *  domsizes 
)
virtual

initialize the triangulation data structures for a new graph

Parameters
graphthe graph to be triangulated, i.e., the nodes of which will be eliminated
domsizesthe domain sizes of the nodes to be eliminated
Warning
Note that we allow domsizes to be defined over nodes/variables that do not belong to graph. These sizes will simply be ignored. However, it is compulsory that all the nodes of graph belong to dom_sizes
the graph is not copied but only referenced by the elimination sequence algorithm.

Implements gum::Triangulation.

Reimplemented in gum::PartialOrderedTriangulation, and gum::OrderedTriangulation.

Definition at line 526 of file staticTriangulation.cpp.

References gum::Set< Key, Alloc >::emplace().

527  {
528  // remove the old graph
529  clear();
530 
531  if (graph != nullptr) {
532  // prepare the size of the data for the new graph
533  elim_order__.resize(graph->size());
534  reverse_elim_order__.resize(graph->size());
535  elim_cliques__.resize(graph->size());
536  added_fill_ins__.resize(graph->size());
537  node_2_max_prime_clique__.resize(graph->size());
538  }
539 
540  // keep track of the variables passed in argument
541  original_graph__ = graph;
542  domain_sizes_ = domsizes;
543 
544  // indicate that no triangulation was performed for this graph
545  has_triangulation__ = false;
546  has_triangulated_graph__ = false;
547  has_elimination_tree__ = false;
548  has_junction_tree__ = false;
550  has_fill_ins__ = false;
551  }
bool has_max_prime_junction_tree__
indicates whether a maximal prime subgraph junction tree has been constructed
bool has_elimination_tree__
a boolean indicating whether the elimination tree has been computed
void clear()
reinitialize the graph to be triangulated to an empty graph
std::vector< NodeId > elim_order__
the order in which nodes are eliminated by the algorithm
bool has_junction_tree__
a boolean indicating whether the junction tree has been constructed
const NodeProperty< Size > * domain_sizes_
the domain sizes of the variables/nodes of the graph
bool has_triangulation__
a boolean indicating whether we have parformed a triangulation
bool has_triangulated_graph__
a boolean indicating whether we have constructed the triangulated graph
const UndiGraph * original_graph__
a pointer to the (external) original graph (which will be triangulated)
bool has_fill_ins__
indicates whether we actually computed fill-ins
NodeProperty< NodeId > node_2_max_prime_clique__
indicates which clique of the max prime junction tree was created by the elmination of a given node (...
NodeProperty< NodeId > reverse_elim_order__
the elimination order (access by NodeId)
NodeProperty< NodeSet > elim_cliques__
the cliques formed by the elimination of the nodes
std::vector< EdgeSet > added_fill_ins__
a vector containing the set of fill-ins added after each node elimination (used by recursive thinning...
+ Here is the call graph for this function:

◆ setMinimalRequirement()

void gum::StaticTriangulation::setMinimalRequirement ( bool  )

sets/unset the minimality requirement

◆ triangulate__()

void gum::StaticTriangulation::triangulate__ ( )
private

the function that performs the triangulation

Definition at line 554 of file staticTriangulation.cpp.

References gum::Set< Key, Alloc >::emplace().

554  {
555  // if the graph is already triangulated, no need to triangulate it again
556  if (has_triangulation__) return;
557 
558  // copy the graph to be triangulated, so that we can modify it
559  UndiGraph tmp_graph = *original_graph__;
560 
561  initTriangulation_(tmp_graph);
563 
564  // if we are to do recursive thinning, we will have to add fill-ins to the
565  // triangulated graph each time we eliminate a node. Hence, we shall
566  // initialize the triangulated graph by a copy of the original graph
567  if (minimality_required__) {
570  }
571 
572  // perform the triangulation
573  NodeId removable_node = 0;
574 
575  for (unsigned int nb_elim = 0; tmp_graph.size() != 0; ++nb_elim) {
577 
578  // when minimality is not required, i.e., we won't apply recursive
579  // thinning, the cliques sets can be computed
580  if (!minimality_required__) {
581  NodeSet& cliques = elim_cliques__.insert(removable_node, NodeSet()).second;
582  cliques.resize(tmp_graph.neighbours(removable_node).size() / 2);
583  cliques << removable_node;
584  for (const auto clik: tmp_graph.neighbours(removable_node))
585  cliques << clik;
586  } else {
587  // here recursive thinning will be applied, hence we need store the
588  // fill-ins added by the current node removal
589  EdgeSet& current_fill = added_fill_ins__[nb_elim];
590  NodeId node1, node2;
591 
592  const NodeSet& nei = tmp_graph.neighbours(removable_node);
593 
594  for (auto iter_edges1 = nei.begin(); iter_edges1 != nei.end();
595  ++iter_edges1) {
596  node1 = *iter_edges1;
597  auto iter_edges2 = iter_edges1;
598 
599  for (++iter_edges2; iter_edges2 != nei.end(); ++iter_edges2) {
600  node2 = *iter_edges2;
601  Edge edge(node1, node2);
602 
603  if (!tmp_graph.existsEdge(edge)) {
604  current_fill.insert(edge);
605  triangulated_graph__.addEdge(node1, node2);
606  }
607  }
608  }
609  }
610 
611  // if we want fill-ins but the elimination sequence strategy does not
612  // compute them, we shall compute them here
615  NodeId node1, node2;
616 
617  // add edges between removable_node's neighbours in order to create
618  // a clique
619  const NodeSet& nei = tmp_graph.neighbours(removable_node);
620 
621  for (auto iter_edges1 = nei.begin(); iter_edges1 != nei.end();
622  ++iter_edges1) {
623  node1 = *iter_edges1;
624  auto iter_edges2 = iter_edges1;
625 
626  for (++iter_edges2; iter_edges2 != nei.end(); ++iter_edges2) {
627  node2 = *iter_edges2;
628  Edge edge(node1, node2);
629 
630  if (!tmp_graph.existsEdge(edge)) { fill_ins__.insert(edge); }
631  }
632  }
633 
634  // delete removable_node and its adjacent edges
635  tmp_graph.eraseNode(removable_node);
636  }
637 
638  // inform the elimination sequence that we are actually removing
639  // removable_node (this enables, for instance, to update the weights of
640  // the nodes in the graph)
642 
644  NodeId node1, node2;
645 
646  const NodeSet& nei = tmp_graph.neighbours(removable_node);
647 
648  for (auto iter_edges1 = nei.begin(); iter_edges1 != nei.end();
649  ++iter_edges1) {
650  node1 = *iter_edges1;
651  auto iter_edges2 = iter_edges1;
652 
653  for (++iter_edges2; iter_edges2 != nei.end(); ++iter_edges2) {
654  node2 = *iter_edges2;
655  Edge edge(node1, node2);
656 
657  if (!tmp_graph.existsEdge(edge)) { tmp_graph.addEdge(node1, node2); }
658  }
659  }
660 
661  tmp_graph.eraseNode(removable_node);
662  }
663 
664  // update the elimination order
665  elim_order__[nb_elim] = removable_node;
666  reverse_elim_order__.insert(removable_node, nb_elim);
667  }
668 
669  // indicate whether we actually computed fill-ins
671 
672  // if minimality is required, remove the redondant edges
674 
675  has_triangulation__ = true;
676  }
virtual void eliminationUpdate(const NodeId node)
performs all the graph/fill-ins updates provided (if any)
EdgeSet fill_ins__
the fill-ins added during the whole triangulation process
EliminationSequenceStrategy * elimination_sequence_strategy_
the elimination sequence strategy used by the triangulation
std::vector< NodeId > elim_order__
the order in which nodes are eliminated by the algorithm
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
bool minimality_required__
indicates whether the triangulation must be minimal
bool has_triangulation__
a boolean indicating whether we have parformed a triangulation
bool has_triangulated_graph__
a boolean indicating whether we have constructed the triangulated graph
const UndiGraph * original_graph__
a pointer to the (external) original graph (which will be triangulated)
bool has_fill_ins__
indicates whether we actually computed fill-ins
Set< Edge > EdgeSet
Some typdefs and define for shortcuts ...
bool we_want_fill_ins__
a boolean indicating if we want fill-ins list with the standard triangulation method ...
NodeProperty< NodeId > reverse_elim_order__
the elimination order (access by NodeId)
NodeProperty< NodeSet > elim_cliques__
the cliques formed by the elimination of the nodes
virtual bool providesGraphUpdate() const =0
indicates whether the elimination sequence updates by itself the graph after a node has been eliminat...
virtual NodeId nextNodeToEliminate()=0
returns the new node to be eliminated within the triangulation algorithm
virtual void initTriangulation_(UndiGraph &graph)
the function called to initialize the triangulation process
std::vector< EdgeSet > added_fill_ins__
a vector containing the set of fill-ins added after each node elimination (used by recursive thinning...
void computeRecursiveThinning__()
removes redondant fill-ins and compute proper elimination cliques and order
UndiGraph triangulated_graph__
the triangulated graph
void addEdge(NodeId first, NodeId second) override
insert a new edge into the undirected graph
Definition: undiGraph_inl.h:34
Size NodeId
Type for node ids.
Definition: graphElements.h:97
void insert(const Key &k)
Inserts a new element into the set.
Definition: set_tpl.h:632
virtual bool providesFillIns() const =0
indicates whether the fill-ins generated by the eliminated nodes, if needed, will be computed by the ...
virtual void askFillIns(bool do_it)=0
if the elimination sequence is able to compute fill-ins, we indicate whether we want this feature to ...
+ Here is the call graph for this function:

◆ triangulatedGraph()

const UndiGraph & gum::StaticTriangulation::triangulatedGraph ( )
virtual

returns the triangulated graph

Implements gum::Triangulation.

Definition at line 487 of file staticTriangulation.cpp.

References gum::Set< Key, Alloc >::emplace().

487  {
489 
490  // if we did not construct the triangulated graph during the triangulation,
491  // that is, we just constructed the junction tree, we shall construct it now
493  // just in case, be sure that the junction tree has been constructed
495 
496  // copy the original graph
498 
499  for (const auto clik_id: *junction_tree__) {
500  // for each clique, add the edges necessary to make it complete
501  const NodeSet& clique = junction_tree__->clique(clik_id);
502  std::vector< NodeId > clique_nodes(clique.size());
503  unsigned int i = 0;
504 
505  for (const auto node: clique) {
506  clique_nodes[i] = node;
507  i += 1;
508  }
509 
510  for (i = 0; i < clique_nodes.size(); ++i) {
511  for (unsigned int j = i + 1; j < clique_nodes.size(); ++j) {
512  try {
513  triangulated_graph__.addEdge(clique_nodes[i], clique_nodes[j]);
514  } catch (DuplicateElement&) {}
515  }
516  }
517  }
518 
520  }
521 
522  return triangulated_graph__;
523  }
const CliqueGraph & junctionTree()
returns a compatible junction tree
const CliqueGraph * junction_tree__
the junction tree computed by the algorithm
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
bool has_junction_tree__
a boolean indicating whether the junction tree has been constructed
void triangulate__()
the function that performs the triangulation
bool has_triangulation__
a boolean indicating whether we have parformed a triangulation
bool has_triangulated_graph__
a boolean indicating whether we have constructed the triangulated graph
const UndiGraph * original_graph__
a pointer to the (external) original graph (which will be triangulated)
UndiGraph triangulated_graph__
the triangulated graph
void addEdge(NodeId first, NodeId second) override
insert a new edge into the undirected graph
Definition: undiGraph_inl.h:34
+ Here is the call graph for this function:

Member Data Documentation

◆ added_fill_ins__

std::vector< EdgeSet > gum::StaticTriangulation::added_fill_ins__
private

a vector containing the set of fill-ins added after each node elimination (used by recursive thinning)

Definition at line 295 of file staticTriangulation.h.

◆ domain_sizes_

const NodeProperty< Size >* gum::Triangulation::domain_sizes_ {nullptr}
protectedinherited

the domain sizes of the variables/nodes of the graph

Definition at line 152 of file triangulation.h.

◆ elim_cliques__

NodeProperty< NodeSet > gum::StaticTriangulation::elim_cliques__
private

the cliques formed by the elimination of the nodes

Definition at line 253 of file staticTriangulation.h.

◆ elim_order__

std::vector< NodeId > gum::StaticTriangulation::elim_order__
private

the order in which nodes are eliminated by the algorithm

Definition at line 247 of file staticTriangulation.h.

◆ elim_tree__

CliqueGraph gum::StaticTriangulation::elim_tree__
private

the elimination tree computed by the algorithm

Definition at line 256 of file staticTriangulation.h.

◆ elimination_sequence_strategy_

EliminationSequenceStrategy* gum::StaticTriangulation::elimination_sequence_strategy_ {nullptr}
protected

the elimination sequence strategy used by the triangulation

Definition at line 230 of file staticTriangulation.h.

◆ fill_ins__

EdgeSet gum::StaticTriangulation::fill_ins__
private

the fill-ins added during the whole triangulation process

Definition at line 244 of file staticTriangulation.h.

◆ has_elimination_tree__

bool gum::StaticTriangulation::has_elimination_tree__ {false}
private

a boolean indicating whether the elimination tree has been computed

Definition at line 278 of file staticTriangulation.h.

◆ has_fill_ins__

bool gum::StaticTriangulation::has_fill_ins__ {false}
private

indicates whether we actually computed fill-ins

Definition at line 288 of file staticTriangulation.h.

◆ has_junction_tree__

bool gum::StaticTriangulation::has_junction_tree__ {false}
private

a boolean indicating whether the junction tree has been constructed

Definition at line 281 of file staticTriangulation.h.

◆ has_max_prime_junction_tree__

bool gum::StaticTriangulation::has_max_prime_junction_tree__ {false}
private

indicates whether a maximal prime subgraph junction tree has been constructed

Definition at line 285 of file staticTriangulation.h.

◆ has_triangulated_graph__

bool gum::StaticTriangulation::has_triangulated_graph__ {false}
private

a boolean indicating whether we have constructed the triangulated graph

Definition at line 275 of file staticTriangulation.h.

◆ has_triangulation__

bool gum::StaticTriangulation::has_triangulation__ {false}
private

a boolean indicating whether we have parformed a triangulation

Definition at line 272 of file staticTriangulation.h.

◆ junction_tree__

const CliqueGraph* gum::StaticTriangulation::junction_tree__ {nullptr}
private

the junction tree computed by the algorithm

note that the junction tree is owned by the junctionTreeStrategy and, therefore, its deletion from memory is not handled by the static triangulation class.

Definition at line 262 of file staticTriangulation.h.

◆ junction_tree_strategy_

JunctionTreeStrategy* gum::StaticTriangulation::junction_tree_strategy_ {nullptr}
protected

the junction tree strategy used by the triangulation

Definition at line 233 of file staticTriangulation.h.

◆ max_prime_junction_tree__

CliqueGraph gum::StaticTriangulation::max_prime_junction_tree__
private

the maximal prime subgraph junction tree computed from the junction tree

Definition at line 265 of file staticTriangulation.h.

◆ minimality_required__

bool gum::StaticTriangulation::minimality_required__ {false}
private

indicates whether the triangulation must be minimal

Definition at line 291 of file staticTriangulation.h.

◆ node_2_max_prime_clique__

NodeProperty< NodeId > gum::StaticTriangulation::node_2_max_prime_clique__
private

indicates which clique of the max prime junction tree was created by the elmination of a given node (the key of the table)

Definition at line 269 of file staticTriangulation.h.

◆ original_graph__

const UndiGraph* gum::StaticTriangulation::original_graph__ {nullptr}
private

a pointer to the (external) original graph (which will be triangulated)

Definition at line 238 of file staticTriangulation.h.

◆ reverse_elim_order__

NodeProperty< NodeId > gum::StaticTriangulation::reverse_elim_order__
private

the elimination order (access by NodeId)

Definition at line 250 of file staticTriangulation.h.

◆ triangulated_graph__

UndiGraph gum::StaticTriangulation::triangulated_graph__
private

the triangulated graph

Definition at line 241 of file staticTriangulation.h.

◆ we_want_fill_ins__

bool gum::StaticTriangulation::we_want_fill_ins__ {false}
private

a boolean indicating if we want fill-ins list with the standard triangulation method

Definition at line 299 of file staticTriangulation.h.


The documentation for this class was generated from the following files: