aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
incrementalTriangulation.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 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() {
103  GUM_ERROR(OperationNotAllowed, "Not implemented yet");
104  };
105 
106  /// returns an elimination ordering compatible with the triangulated graph
107  const std::vector< NodeId >& eliminationOrder();
108 
109  /** @brief returns the number of a given node in the elimination order
110  * (0 = first node eliminated) */
111  Idx eliminationOrder(const NodeId);
112 
113  /// returns the triangulated graph
114  const UndiGraph& triangulatedGraph() {
115  GUM_ERROR(OperationNotAllowed, "Not implemented yet");
116  };
117 
118  /// returns the current graph (that which is incrementally triangulated)
119  const UndiGraph& graph() const;
120 
121  /// returns the elimination tree of a compatible ordering
122  const CliqueGraph& eliminationTree() {
123  GUM_ERROR(OperationNotAllowed, "Not implemented yet");
124  };
125 
126  /// returns a junction tree corresponding to the current graph
127  const CliqueGraph& junctionTree();
128 
129  /** @brief returns the Id of the clique created by the
130  * elimination of a given node during the triangulation process */
131  NodeId createdJunctionTreeClique(const NodeId id);
132 
133  /** @brief returns the Ids of the cliques of the junction tree created by
134  * the elimination of the nodes */
135  const NodeProperty< NodeId >& createdJunctionTreeCliques();
136 
137  /// returns the junction tree of the maximal prime subgraphs
138  const CliqueGraph& maxPrimeSubgraphTree();
139 
140  /** @brief returns the Id of the maximal prime subgraph created by the
141  * elimination of a given node during the triangulation process */
142  NodeId createdMaxPrimeSubgraph(const NodeId id);
143 
144  /// sets the graph to the empty graph
145  void clear();
146 
147  /// changes the current graph
148  void setGraph(const UndiGraph* theGraph,
149  const NodeProperty< Size >* domain_sizes);
150 
151  /// returns the triangulation algorithm (useful for fine tuning it)
152  const UnconstrainedTriangulation& triangulationAlgo() const;
153 
154  /// @}
155 
156 
157  // ############################################################################
158  /// @name Operators
159  // ############################################################################
160  /// @{
161 
162  /// copy operator
163  IncrementalTriangulation& operator=(const IncrementalTriangulation& from);
164 
165  /// virtual clone constructor
166  virtual IncrementalTriangulation* newFactory() const final;
167 
168  /// virtual copy constructor
169  virtual IncrementalTriangulation* copyFactory() const final;
170 
171  /// @}
172 
173 
174  private:
175  /// the graph that needs be triangulated
176  UndiGraph graph__;
177 
178  /// the domain sizes of the nodes
179  NodeProperty< Size > domain_sizes__;
180 
181  /// the junction tree computed so far
182  CliqueGraph junction_tree__;
183 
184  /// the maximal prime subgraph tree
185  CliqueGraph T_mpd__;
186 
187  /// for each node in graph, store the MPS containing the node
188  NodeProperty< List< NodeId > > mps_of_node__;
189 
190  /// indicate for each MPS its set of cliques in the junction tree
191  NodeProperty< std::vector< NodeId > > cliques_of_mps__;
192 
193  /// indicate for each clique the MPS it belongs to
194  NodeProperty< NodeId > mps_of_clique__;
195 
196  /// the set of MPS affected by a new triangulation
197  NodeProperty< bool > mps_affected__;
198 
199  /// the triangulation algorithm that will be used incremantally
200  UnconstrainedTriangulation* triangulation__;
201 
202  /// a Boolean indicating whether the triangulation need be updated
203  bool require_update__{false};
204 
205  /// a Boolean indicating wether we should update the elimination order
206  bool require_elimination_order__{false};
207 
208  /// the current elimination ordering
209  std::vector< NodeId > elimination_order__;
210 
211  /// the elimination order (access by NodeId)
212  NodeProperty< Idx > reverse_elimination_order__;
213 
214  /// a Boolean indicating whether we should compute the createdJTCliques
215  bool require_created_JT_cliques__{false};
216 
217  /// For each node, a clique that contains it
218  NodeProperty< NodeId > created_JT_cliques__;
219 
220  /// mark the mps affected by the deletion of a given edge
221  void markAffectedMPSsByRemoveLink__(const NodeId My,
222  const NodeId Mz,
223  const Edge& edge);
224 
225  /// mark the mps affected by the insertion of a new edge
226  int markAffectedMPSsByAddLink__(const NodeId My,
227  const NodeId Mz,
228  const NodeId X,
229  const NodeId Y);
230 
231  /// remove a given node from the T_mpd structure
232  void performRemoveNode__(const NodeId node, const NodeId My, const NodeId Mz);
233 
234  /// adds a new node to T_mpd, the graph and the clique graph
235  void performAddNode__(const NodeId node);
236 
237  /// set-up the connected subgraph that needs be retriangulated
238  void setUpConnectedTriangulation__(
239  NodeId Mx,
240  NodeId Mfrom,
241  UndiGraph& theGraph,
242  std::vector< Edge >& notAffectedneighborClique,
243  HashTable< NodeId, bool >& cliques_affected);
244 
245  /// used for computing the junction tree of the maximal prime subgraphs
246  void computeMaxPrimeMergings__(
247  const NodeId node,
248  const NodeId from,
249  std::vector< std::pair< NodeId, NodeId > >& merged_cliques,
250  NodeProperty< bool >& mark,
251  const NodeSet& new_nodes_in_junction_tree) const;
252 
253  /// update the junction tree
254  void updateJunctionTree__(NodeProperty< bool >& all_cliques_affected,
255  NodeSet& new_nodes_in_junction_tree);
256 
257  /// update the max prime subgraph
258  void updateMaxPrimeSubgraph__(NodeProperty< bool >& cliques_affected,
259  const NodeSet& new_nodes_in_junction_tree);
260 
261  /// a collect algorithm to compute elimination orderings
262  void collectEliminationOrder__(const NodeId node,
263  const NodeId from,
264  NodeProperty< bool >& examined,
265  Idx& index);
266 
267  /// a collect algorithm to compute, for each node, one container JT's clique
268  void collectJTCliques__(const NodeId clique,
269  const NodeId from,
270  NodeProperty< bool >& examined);
271 
272  /// checks that the incremental triangulation works properly
273  bool check__();
274 
275  /// to enable testunits to use check__
276  friend class gum_tests::IncrementalTriangulationTestSuite;
277  };
278 
279 } /* namespace gum */
280 
281 #ifndef GUM_NO_INLINE
282 # include <agrum/tools/graphs/algorithms/triangulations/incrementalTriangulation_inl.h>
283 #endif // GUM_NO_INLINE
284 
285 #endif /* GUM_INCREMENTAL_TRIANGULATION_H */