aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
multiDimFunctionGraphManager.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 /**
23  * @file
24  * @brief Headers of MultiDimFunctionGraphManager.
25  *
26  * @author Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
27  * @author Pierre-Henri WUILLEMIN(@LIP6) and Jean-Christophe MAGNAN and Christophe
28  * GONZALES(@AMU)
29  *
30  */
31 #ifndef GUM_MULTI_DIM_FUNCTION_GRAPH_MANAGER_H
32 # define GUM_MULTI_DIM_FUNCTION_GRAPH_MANAGER_H
33 
34 # include <agrum/agrum.h>
35 # include <agrum/tools/graphs/parts/nodeGraphPart.h>
36 # include <agrum/tools/multidim/implementations/multiDimFunctionGraph.h>
37 # include <agrum/tools/multidim/utils/FunctionGraphUtilities/internalNode.h>
38 
39 namespace gum {
40 
41  template < typename GUM_SCALAR, template < typename > class TerminalNodePolicy >
43 
44  /**
45  * @class MultiDimFunctionGraphManager
46  * @ingroup multidim_group
47  *
48  * @brief Class implementingting a function graph manager.
49  *
50  * @warning Doxygen does not like spanning command on multiple line, so we
51  * could not configure it with the correct include directive. Use the
52  * following code snippet to include this file.
53  * @code
54  * #include <agrum/tools/multidim/implementations/multiDimFunctionGraphManager.h>
55  * @endcode
56  *
57  * This class provides methods to edit a Function Graph. Any modification on
58  * a MultiDimFunctionGraph graph must be done via this class.
59  *
60  * This class is a singleton and its unique instance ca be accessed using the
61  * MultiDimFunctionGraph::getManager() method.
62  *
63  * To do so :
64  *
65  * @code
66  * // You can also use getTreeInstance()
67  * auto * func_graph =
68  * MultiDimFunctionGraph<double>::getReducedAndOrderedInstance();
69  * auto manager = dg->manager();
70  * @endcode
71  *
72  * @tparam GUM_SCALAR The type of scalars stored in the multidimensional
73  * table.
74  * @tparam TerminalNodePolicy The terminal node policy to use.
75  */
76  template < typename GUM_SCALAR, template < typename > class TerminalNodePolicy >
78  // =========================================================================
79  /// @name Constructors / Destructors
80  // =========================================================================
81  /// @{
82 
83  /**
84  * @brief This friend methods from is the only way to get an instance of a
85  * manager.
86  *
87  * See class description for more info.
88  */
91 
92  /**
93  * @brief Default constructor.
94  *
95  * You have to call MultiDimFunctionGraph::getManager() to get the instance
96  * of MultiDimFunctionGraphManager bound to your function graph.
97  */
98  protected:
100  MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy >* master);
101 
102  public:
103  /**
104  * @brief Class destructor.
105  */
106  virtual ~MultiDimFunctionGraphManager();
107 
108  /// @}
109  // =========================================================================
110  /// @name Nodes manipulation methods.
111  // =========================================================================
112  /// @{
113 
114  /**
115  * @brief Sets root node of decision diagram.
116  * @param root The node to set as root.
117  */
118  void setRootNode(const NodeId& root);
119 
120  /**
121  * @brief Inserts a new non terminal node in graph.
122  *
123  * NodeId of this node is generated automatically.
124  *
125  * @param var Associated variable
126  * @return The id of the added non terminal node.
127  */
129 
130  /**
131  * @brief Inserts a new non terminal node in graph.
132  *
133  * NodeId of this node is generated automatically.
134  *
135  * @param var The associated variable.
136  * @param sons A table of size var->domainSize() containing nodeid of sons
137  * nodes.
138  * @return Returns the id of the added non terminal node.
139  *
140  * @throw OperationNotAllowed Raised if MultiDimFunctionGraph has no
141  * variable yet.
142  */
143  virtual NodeId addInternalNode(const DiscreteVariable* var, NodeId* sons) = 0;
144 
145  protected:
146  /**
147  * @brief Adds an internal node.
148  * @param var The node to add.
149  * @param sons The node sons.
150  * @return Returns the added node id.
151  */
153 
154  public:
155  /**
156  * @brief Inserts a new non terminal node in graph.
157  *
158  * NodeId of this node is generated automatically.
159  *
160  * @param var The ssociated variable.
161  * @param nid The desired id for that node.
162  * @return Returns the id of the added non terminal node.
163  *
164  * @throw OperationNotAllowed Raised if MultiDimFunctionGraph has no
165  * variable yet.
166  */
168 
169  /**
170  * @brief Adds a value to the MultiDimFunctionGraph.
171  *
172  * This will create a terminal node, which of id is returned. If a
173  * terminal node with such value already exists, its id will be return
174  * instead.
175  *
176  * @param value The value added by copy.
177  * @return Returns he id of the terminal node hence created.
178  */
180 
181  /**
182  * @brief Erases a node from the diagram.
183  *
184  * @param id The id of the variable to erase.
185  * @param replacingId Offers the possibility to reroute any parent to the
186  * given node.
187  * @param updateParents Indicates if such remapping has to be done.
188  *
189  * @throw NotFound Raised if node isn't in diagram.
190  */
191  void eraseNode(NodeId id, NodeId replacingId = 0, bool updateParents = true);
192 
193  /// @}
194  // =========================================================================
195  /// @name Manipulation methods.
196  // =========================================================================
197  /// @{
198 
199  /**
200  * @brief Sets nodes son for given modality to designated son node.
201  * @param node The node to which a node is added.
202  * @param modality The modality for which sonNode is added to node.
203  * @param sonNode The node to add as a son to node.
204  */
205  void setSon(const NodeId& node, const Idx& modality, const NodeId& sonNode);
206 
207 
208  /**
209  * @brief Performs a sifting in search of a(local) minimal size.
210  */
211  void minimizeSize();
212 
213  /**
214  * @brief Changes var position in variable sequence.
215  * @param x The varaible to change.
216  * @param desiredPos The new posiition.
217  */
218  void moveTo(const DiscreteVariable* x, Idx desiredPos);
219 
220  private:
221  /**
222  * @brief Swap two adjacent variable.
223  *
224  * Order is important here. X must precede Y before the swap (at the end Y
225  * will then precede X). Not respecting this constraint leads to
226  * unattended behaviour.
227  *
228  * @param x The first variable to swap.
229  * @param y The second variable to swap.
230  */
231  void _adjacentSwap_(const DiscreteVariable* x, const DiscreteVariable* y);
232 
233  protected:
234  /**
235  * @brief Remaps all arcs going to ou going from the first given node to
236  * the second node, then delete first node.
237  *
238  * @param x The variable from which all arcs are removed.
239  * @param y The variable for which all of x arcs are added.
240  */
241  void migrateNode_(const NodeId& x, const NodeId& y);
242 
243  /// @}
244  // =========================================================================
245  /// @name Redundancy methods.
246  // =========================================================================
247  /// @{
248 
249  protected:
250  /**
251  * @brief Check for redundancy.
252  *
253  * Checks if a similar node does not already exists in the graph or if it
254  * has the same child for every variable value. If no node is a match, this
255  * node is added to the graph.
256  *
257  * @warning : will free by itslef sonsMap if a match exists.
258  *
259  * @param var The node to add in the graph.
260  * @param sonsMap The node sons.
261  * @return Returns the nodes id in the graph.
262  */
264 
265  private:
266  /**
267  * @brief Checks if a similar node does not already exists in the graph.
268  *
269  * Tow nodes are similar if for every value assumed by the associated
270  * variable, these two nodes have the same children.
271  *
272  * @warning This will not free sons.
273  *
274  * @param var The node to check for.
275  * @param sons The node sons.
276  * @return Returns the node id if found, 0 otherwhise.
277  */
279 
280  /**
281  * @brief Checks if node has the same child for every variable value.
282  *
283  * @warning WON'T deallocate sons
284  *
285  * @param var The node to check for.
286  * @param sons The node sons.
287  * @return Returns true if the node is redundant.
288  */
289  bool _isRedundant_(const DiscreteVariable* var, NodeId* sons);
290 
291  public:
292  /**
293  * @brief Ensures that every isomorphic subgraphs are merged together.
294  */
295  virtual void reduce() = 0;
296 
297  protected:
298  /**
299  * @brief Ensures that every isomorphic subgraphs are merged together.
300  */
301  void reduce_();
302 
303  /// @}
304 
305  public:
306  /**
307  * @brief Removes var without nodes in the diagram
308  */
309  void clean();
310 
311  private:
312  /// The multidimdecisiongraph supposed to be edited.
314  };
315 
316  // ===========================================================================
317  // MultiDimFunctionGraphTreeManager
318  // ===========================================================================
319 
320  /**
321  * @class MultiDimFunctionGraphTreeManager
322  * @ingroup multidim_group
323  *
324  * @warning Doxygen does not like spanning command on multiple line, so we
325  * could not configure it with the correct include directive. Use the
326  * following code snippet to include this file.
327  * @code
328  * #include <agrum/tools/multidim/implementations/multiDimFunctionGraphManager.h>
329  * @endcode
330  *
331  * @tparam GUM_SCALAR The type of scalars stored in the multidimensional
332  * table.
333  * @tparam TerminalNodePolicy The terminal node policy to use.
334  */
335  template < typename GUM_SCALAR, template < typename > class TerminalNodePolicy >
338  /// This friend methods from is the only way to get an instance of a
339  /// manager.
342 
343  // ========================================================================
344  /// @name Constructor and destructor
345  // ========================================================================
346  /// @{
347  /**
348  * @brief Class constructor.
349  */
351  MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy >* master);
352 
353  public:
354  /**
355  * @brief Class destructor.
356  */
358 
359  /// @}
360  // ========================================================================
361  /// @name Inherited methods
362  // ========================================================================
363  /// @{
365 
366  virtual void reduce();
367  /// @}
368  };
369 
370  // ===========================================================================
371  // MultiDimFunctionGraphROManager
372  // ===========================================================================
373 
374  /**
375  * @class MultiDimFunctionGraphTreeManager
376  * @ingroup multidim_group
377  *
378  * @warning Doxygen does not like spanning command on multiple line, so we
379  * could not configure it with the correct include directive. Use the
380  * following code snippet to include this file.
381  * @code
382  * #include <agrum/tools/multidim/implementations/multiDimFunctionGraphManager.h>
383  * @endcode
384  *
385  * @tparam GUM_SCALAR The type of scalars stored in the multidimensional
386  * table.
387  * @tparam TerminalNodePolicy The terminal node policy to use.
388  */
389  template < typename GUM_SCALAR, template < typename > class TerminalNodePolicy >
392  /// This friend methods from is the only way to get an instance of a
393  /// manager.
396 
397  // ========================================================================
398  /// @name Constructor and destructor
399  // ========================================================================
400  /// @{
401  MultiDimFunctionGraphROManager(MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy >* master);
402 
403  public:
405 
406  /// @}
407  // ========================================================================
408  /// @name Inherited methods
409  // ========================================================================
410  /// @{
411 
413 
414  virtual void reduce();
415 
416  /// @}
417  };
418 
419 } // namespace gum
420 
421 // ============================================================================
422 # include <agrum/tools/multidim/implementations/multiDimFunctionGraphManager_tpl.h>
423 // ============================================================================
424 #endif // GUM_MULTI_DIM_FUNCTION_GRAPH_MANAGER_H
425 // ============================================================================
virtual void reduce()
Ensures that every isomorphic subgraphs are merged together.
NodeId _checkIsomorphism_(const DiscreteVariable *var, NodeId *sons)
Checks if a similar node does not already exists in the graph.
friend MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy > * MultiDimFunctionGraph()
This friend methods from is the only way to get an instance of a manager.
void setSon(const NodeId &node, const Idx &modality, const NodeId &sonNode)
Sets nodes son for given modality to designated son node.
void clean()
Removes var without nodes in the diagram.
MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > * _functionGraph_
The multidimdecisiongraph supposed to be edited.
void setRootNode(const NodeId &root)
Sets root node of decision diagram.
bool _isRedundant_(const DiscreteVariable *var, NodeId *sons)
Checks if node has the same child for every variable value.
HashTable< const DiscreteVariable *, LinkedList< NodeId > *> _var2NodeIdMap_
Mapping between var and node.
friend MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy > * MultiDimFunctionGraph()
This friend methods from is the only way to get an instance of a manager.
NodeId nodeRedundancyCheck_(const DiscreteVariable *var, NodeId *sonsMap)
Check for redundancy.
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
void reduce_()
Ensures that every isomorphic subgraphs are merged together.
friend MultiDimFunctionGraphManager< GUM_SCALAR, TerminalNodePolicy > * MultiDimFunctionGraph()
This friend methods from is the only way to get an instance of a manager.
NodeId addInternalNode(const DiscreteVariable *var)
Inserts a new non terminal node in graph.
void moveTo(const DiscreteVariable *x, Idx desiredPos)
Changes var position in variable sequence.
void eraseNode(NodeId id, NodeId replacingId=0, bool updateParents=true)
Erases a node from the diagram.
void _adjacentSwap_(const DiscreteVariable *x, const DiscreteVariable *y)
Swap two adjacent variable.
virtual NodeId addInternalNode(const DiscreteVariable *var, NodeId *sons)
Inserts a new non terminal node in graph.
NodeId addInternalNode_(const DiscreteVariable *var, NodeId *sons)
Adds an internal node.
void migrateNode_(const NodeId &x, const NodeId &y)
Remaps all arcs going to ou going from the first given node to the second node, then delete first nod...
void minimizeSize()
Performs a sifting in search of a(local) minimal size.
MultiDimFunctionGraphManager(MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *master)
Default constructor.
virtual void reduce()
Ensures that every isomorphic subgraphs are merged together.
NodeId addInternalNode(const DiscreteVariable *var, NodeId nid)
Inserts a new non terminal node in graph.
MultiDimFunctionGraphROManager(MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *master)
MultiDimFunctionGraphTreeManager(MultiDimFunctionGraph< GUM_SCALAR, TerminalNodePolicy > *master)
Class constructor.
NodeId addTerminalNode(const GUM_SCALAR &value)
Adds a value to the MultiDimFunctionGraph.
virtual NodeId addInternalNode(const DiscreteVariable *var, NodeId *sons)=0
Inserts a new non terminal node in graph.
virtual void reduce()=0
Ensures that every isomorphic subgraphs are merged together.
virtual ~MultiDimFunctionGraphManager()
Class destructor.
virtual NodeId addInternalNode(const DiscreteVariable *var, NodeId *sons)
Inserts a new non terminal node in graph.