aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
incrementalTriangulation.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /** @file
23  * @brief Class for computing default triangulations of graphs
24  *
25  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
26  */
27 
28 #ifndef GUM_INCREMENTAL_TRIANGULATION_H
29 #define GUM_INCREMENTAL_TRIANGULATION_H
30 
31 #include <iostream>
32 #include <sstream>
33 #include <vector>
34 
35 #include <agrum/tools/graphs/algorithms/triangulations/unconstrainedTriangulation.h>
36 #include <agrum/tools/graphs/cliqueGraph.h>
37 #include <agrum/tools/graphs/graphElements.h>
38 
39 #ifndef DOXYGEN_SHOULD_SKIP_THIS
40 namespace gum_tests {
41  class IncrementalTriangulationTestSuite;
42 }
43 #endif
44 
45 namespace gum {
46 
47  /** @class IncrementalTriangulation
48  * @brief Class that performs incremental triangulations
49  */
50  class IncrementalTriangulation: public Triangulation {
51  public:
52  // ############################################################################
53  /// @name Constructors / Destructors
54  // ############################################################################
55  /// @{
56 
57  /// constructor
58  /** Note that, in the graph passed in argument, the type of the edges may
59  * differ from Edge. However, the junction trees and triangulated graphs
60  * produced by the triangulation algorithm will all have edges of type Edge.
61  */
62  IncrementalTriangulation(const UnconstrainedTriangulation& triang_algo,
63  const UndiGraph* theGraph,
64  const NodeProperty< Size >* modal);
65 
66  /// default constructor: initialize the triangulation with en empty graph
67  IncrementalTriangulation(const UnconstrainedTriangulation& triangAlgo);
68 
69  /// copy operator
70  IncrementalTriangulation(const IncrementalTriangulation& from);
71 
72  /// destructor
73  ~IncrementalTriangulation();
74 
75  /// @}
76 
77 
78  // ############################################################################
79  /// @name Accessors / Modifiers
80  // ############################################################################
81  /// @{
82 
83  /// updates the triangulated graph using the modif list
84  void updateTriangulation();
85 
86  /// adds a new node to the graph
87  void addNode(const NodeId node, Size modal);
88 
89  /** @brief removes a node from the graph (the join tree may need a
90  * triangulation update) */
91  void eraseNode(const NodeId node);
92 
93  /** @brief adds a new edge to the graph (the join tree may need a
94  * triangulation update) */
95  void addEdge(const NodeId X, const NodeId Y);
96 
97  /// removes an edge from the graph (the join tree may need a
98  /// retriangulation)
99  void eraseEdge(const Edge& edge);
100 
101  /// returns the fill-ins added by the triangulation algorithm
102  const EdgeSet& fillIns() { GUM_ERROR(OperationNotAllowed, "Not implemented yet") }
103 
104  /// returns an elimination ordering compatible with the triangulated graph
105  const std::vector< NodeId >& eliminationOrder();
106 
107  /** @brief returns the number of a given node in the elimination order
108  * (0 = first node eliminated) */
109  Idx eliminationOrder(const NodeId);
110 
111  /// returns the triangulated graph
112  const UndiGraph& triangulatedGraph() { GUM_ERROR(OperationNotAllowed, "Not implemented yet") }
113 
114  /// returns the current graph (that which is incrementally triangulated)
115  const UndiGraph& graph() const;
116 
117  /// returns the elimination tree of a compatible ordering
118  const CliqueGraph& eliminationTree() { GUM_ERROR(OperationNotAllowed, "Not implemented yet") }
119 
120  /// returns a junction tree corresponding to the current graph
121  const CliqueGraph& junctionTree();
122 
123  /** @brief returns the Id of the clique created by the
124  * elimination of a given node during the triangulation process */
125  NodeId createdJunctionTreeClique(const NodeId id);
126 
127  /** @brief returns the Ids of the cliques of the junction tree created by
128  * the elimination of the nodes */
129  const NodeProperty< NodeId >& createdJunctionTreeCliques();
130 
131  /// returns the junction tree of the maximal prime subgraphs
132  const CliqueGraph& maxPrimeSubgraphTree();
133 
134  /** @brief returns the Id of the maximal prime subgraph created by the
135  * elimination of a given node during the triangulation process */
136  NodeId createdMaxPrimeSubgraph(const NodeId id);
137 
138  /// sets the graph to the empty graph
139  void clear();
140 
141  /// changes the current graph
142  void setGraph(const UndiGraph* theGraph, const NodeProperty< Size >* domain_sizes);
143 
144  /// returns the triangulation algorithm (useful for fine tuning it)
145  const UnconstrainedTriangulation& triangulationAlgo() const;
146 
147  /// @}
148 
149 
150  // ############################################################################
151  /// @name Operators
152  // ############################################################################
153  /// @{
154 
155  /// copy operator
156  IncrementalTriangulation& operator=(const IncrementalTriangulation& from);
157 
158  /// virtual clone constructor
159  virtual IncrementalTriangulation* newFactory() const final;
160 
161  /// virtual copy constructor
162  virtual IncrementalTriangulation* copyFactory() const final;
163 
164  /// @}
165 
166 
167  private:
168  /// the graph that needs be triangulated
169  UndiGraph _graph_;
170 
171  /// the domain sizes of the nodes
172  NodeProperty< Size > _domain_sizes_;
173 
174  /// the junction tree computed so far
175  CliqueGraph _junction_tree_;
176 
177  /// the maximal prime subgraph tree
178  CliqueGraph _T_mpd_;
179 
180  /// for each node in graph, store the MPS containing the node
181  NodeProperty< List< NodeId > > _mps_of_node_;
182 
183  /// indicate for each MPS its set of cliques in the junction tree
184  NodeProperty< std::vector< NodeId > > _cliques_of_mps_;
185 
186  /// indicate for each clique the MPS it belongs to
187  NodeProperty< NodeId > _mps_of_clique_;
188 
189  /// the set of MPS affected by a new triangulation
190  NodeProperty< bool > _mps_affected_;
191 
192  /// the triangulation algorithm that will be used incremantally
193  UnconstrainedTriangulation* _triangulation_;
194 
195  /// a Boolean indicating whether the triangulation need be updated
196  bool _require_update_{false};
197 
198  /// a Boolean indicating wether we should update the elimination order
199  bool _require_elimination_order_{false};
200 
201  /// the current elimination ordering
202  std::vector< NodeId > _elimination_order_;
203 
204  /// the elimination order (access by NodeId)
205  NodeProperty< Idx > _reverse_elimination_order_;
206 
207  /// a Boolean indicating whether we should compute the createdJTCliques
208  bool _require_created_JT_cliques_{false};
209 
210  /// For each node, a clique that contains it
211  NodeProperty< NodeId > _created_JT_cliques_;
212 
213  /// mark the mps affected by the deletion of a given edge
214  void _markAffectedMPSsByRemoveLink_(const NodeId My, const NodeId Mz, const Edge& edge);
215 
216  /// mark the mps affected by the insertion of a new edge
217  int _markAffectedMPSsByAddLink_(const NodeId My,
218  const NodeId Mz,
219  const NodeId X,
220  const NodeId Y);
221 
222  /// remove a given node from the T_mpd structure
223  void _performRemoveNode_(const NodeId node, const NodeId My, const NodeId Mz);
224 
225  /// adds a new node to T_mpd, the graph and the clique graph
226  void _performAddNode_(const NodeId node);
227 
228  /// set-up the connected subgraph that needs be retriangulated
229  void _setUpConnectedTriangulation_(NodeId Mx,
230  NodeId Mfrom,
231  UndiGraph& theGraph,
232  std::vector< Edge >& notAffectedneighborClique,
233  HashTable< NodeId, bool >& cliques_affected);
234 
235  /// used for computing the junction tree of the maximal prime subgraphs
236  void _computeMaxPrimeMergings_(const NodeId node,
237  const NodeId from,
238  std::vector< std::pair< NodeId, NodeId > >& merged_cliques,
239  NodeProperty< bool >& mark,
240  const NodeSet& new_nodes_in_junction_tree) const;
241 
242  /// update the junction tree
243  void _updateJunctionTree_(NodeProperty< bool >& all_cliques_affected,
244  NodeSet& new_nodes_in_junction_tree);
245 
246  /// update the max prime subgraph
247  void _updateMaxPrimeSubgraph_(NodeProperty< bool >& cliques_affected,
248  const NodeSet& new_nodes_in_junction_tree);
249 
250  /// a collect algorithm to compute elimination orderings
251  void _collectEliminationOrder_(const NodeId node,
252  const NodeId from,
253  NodeProperty< bool >& examined,
254  Idx& index);
255 
256  /// a collect algorithm to compute, for each node, one container JT's clique
257  void _collectJTCliques_(const NodeId clique, const NodeId from, NodeProperty< bool >& examined);
258 
259  /// checks that the incremental triangulation works properly
260  bool _check_();
261 
262  /// to enable testunits to use _check_
263  friend class gum_tests::IncrementalTriangulationTestSuite;
264  };
265 
266 } /* namespace gum */
267 
268 #ifndef GUM_NO_INLINE
269 # include <agrum/tools/graphs/algorithms/triangulations/incrementalTriangulation_inl.h>
270 #endif // GUM_NO_INLINE
271 
272 #endif /* GUM_INCREMENTAL_TRIANGULATION_H */