aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
DFSTree.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 /**
23  * @file
24  * @brief Headers of the DFSTree class.
25  *
26  * @author Lionel TORTI and Pierre-Henri WUILLEMIN(@LIP6)
27  */
28 
29 #ifndef GUM_DFS_TREE_H
30 #define GUM_DFS_TREE_H
31 
32 #include <list>
33 #include <ostream>
34 #include <utility>
35 #include <vector>
36 
37 #include <agrum/tools/core/math/math_utils.h>
38 #include <agrum/tools/core/bijection.h>
39 #include <agrum/tools/core/sequence.h>
40 #include <agrum/tools/core/set.h>
41 
42 #include <agrum/tools/graphs/diGraph.h>
43 
44 #include <agrum/tools/graphs/algorithms/triangulations/partialOrderedTriangulation.h>
45 
46 #include <agrum/PRM/gspan/edgeGrowth.h>
47 #include <agrum/PRM/gspan/interfaceGraph.h>
48 #include <agrum/PRM/gspan/pattern.h>
49 
50 #include <agrum/PRM/gspan/searchStrategy.h>
51 
52 namespace gum {
53  namespace prm {
54 
55  template < typename GUM_SCALAR >
56  class GSpan;
57 
58  namespace gspan {
59  template < typename GUM_SCALAR >
60  class SearchStrategy;
61 
62  /**
63  * @class DFSTree
64  * @headerfile DFSTree.h <agrum/PRM/gspan/DFSTree.h>
65  *
66  * A DFSTree is used by gspan to sort lexicographically patterns
67  * discovered in an interface graph.
68  */
69  template < typename GUM_SCALAR >
70  class DFSTree: private DiGraph {
71  public:
72  // =========================================================================
73  /// @name Constructor and destructor.
74  // ==========================================================================
75  /// @{
76 
77  /// Default constructor.
78  // DFSTree(InterfaceGraph<GUM_SCALAR>* graph);
79  DFSTree(const InterfaceGraph< GUM_SCALAR >& graph,
80  SearchStrategy< GUM_SCALAR >* strategy = 0);
81 
82  /// Destructor.
83  ~DFSTree();
84 
85  /// @}
86  // =========================================================================
87  /// @name DFSTree getters and setters.
88  // ==========================================================================
89  /// @{
90 
91  const InterfaceGraph< GUM_SCALAR >& graph() const;
92 
93  struct PatternData {
94  /// Constructor.
95  explicit PatternData(Pattern* p);
96  /// Copy constructor.
97  PatternData(const PatternData& from);
98  /// Destructor.
99  ~PatternData();
100  /// The pattern.
101  Pattern* pattern;
102  /// The list of the pattern's children, sorted lexicographically.
103  std::list< NodeId > children;
104  /// The isomorphism graph of the pattern.
105  UndiGraph iso_graph;
106  /// The instances matching p in the interface graph.
107  NodeProperty< Sequence< PRMInstance< GUM_SCALAR >* >* > iso_map;
108  /// The maximal independent set of p.
109  Set< NodeId > max_indep_set;
110  /// The cost of this Pattern
111  Size cost;
112  /// The gain of this Pattern
113  Size gain;
114  };
115 
116  /// Returns the list of root patterns in this DFSTree.
117  std::list< NodeId >& roots();
118 
119  /// Returns the list of root patterns in this DFSTree.
120  const std::list< NodeId >& roots() const;
121 
122  /// Returns the parent of p in this DFSTree.
123  Pattern& parent(const Pattern& p);
124 
125  /// Returns the parent of p in this DFSTree.
126  const Pattern& parent(const Pattern& p) const;
127 
128  /// Returns the list of p children in this DFSTree.
129  std::list< NodeId >& children(const Pattern& p);
130 
131  /// Returns the list of p children in this DFSTree.
132  const std::list< NodeId >& children(const Pattern& p) const;
133 
134  /// Returns the pattern represented by id in this DFSTree.
135  Pattern& pattern(NodeId id);
136 
137  /// Returns the pattern represented by id in this DFSTree.
138  const Pattern& pattern(NodeId id) const;
139 
140  /**
141  * @brief Add a one edge Pattern in this DFSTree.
142  *
143  * @param data Data over the edge used to create a root of this DFSTree.
144  * @return Returns the Pattern added as a root of this DFSTree.
145  */
146  void addRoot(LabelData& data);
147 
148  /**
149  * @brief Add a one edge growth of p as one of its child.
150  *
151  * The child is inserted lexicographically among the children of p.
152  * However if the child is found to be not minimal an
153  * OperationNotAllowed is raised.
154  *
155  * @param p The Pattern from which a one edge growth is spawned.
156  * @param edge_growth The data about the edge growth of p.
157  * @param min_freq minimum number of occurrence to be used as a pattern
158  *
159  * @throw FatalError Raised if the grow is an illegal backedge growth.
160  * @throw OperationNotAllowed Raised if the grow is found to be not
161  *minimal.
162  */
163  Pattern& growPattern(Pattern& p,
164  EdgeGrowth< GUM_SCALAR >& edge_growth,
165  Size min_freq);
166 
167  /// @}
168  // =========================================================================
169  /// @name Isomorphisms for patterns in this DFSTree.
170  // ==========================================================================
171  /// @{
172 
173  /**
174  * @brief Returns the isomorphism graph of p in the interface graph.
175  *
176  * The isomorphism graph is a undirected graph in which each node
177  *represents
178  * a set of PRMInstance<GUM_SCALAR> matching p in the interface graph.
179  *
180  * If there exists an edge between two nodes in the isomorphism graph,
181  *then
182  * the two respective set of instances are not disjoint.
183  *
184  * @param p The pattern for which we want the isomorphism graph.
185  * @return The isomorphism graph of p.
186  *
187  * @throw NotFound Raised if p is not a node in this DFSTree.
188  */
189  UndiGraph& iso_graph(const Pattern& p);
190 
191  /**
192  * @brief Given a pattern and a node in its isomorphism graph, this
193  *methods
194  * returns the sequence of instance matching p in the interface
195  *graph.
196  *
197  * The sequence of instances respect DSF subscripting. Each node in the
198  * pattern's graph have a DSF subscript from 1 to n, where n is the
199  *number
200  * of nodes in the pattern's graph.
201  *
202  * If for a given match you want the k-th instance repecting p's DFS
203  *subscripting,
204  * then it will be the (k - 1)th element in the sequence.
205  *
206  * @param p The pattern for which we want a match in the interface
207  *graph.
208  * @param node The node in p isomorphism graph for which we want the
209  *matching
210  * set if instances.
211  * @return Returns the sequence of instances matching p and node.
212  *
213  * @throw NotFound Raised if p or node does not exists.
214  */
215  Sequence< PRMInstance< GUM_SCALAR >* >& iso_map(const Pattern& p,
216  NodeId node);
217 
218  /**
219  * @brief Returns the maximal independent set of p isomorphism graph.
220  *
221  * @param p The pattern for which we want its maximal independent set.
222  *
223  * @throw NotFound Raised if p is not a node in this DFSTree.
224  */
225  Set< NodeId >& max_indep_set(const Pattern& p);
226 
227  /// Returns the frequency of p respecting it's maximal independent set.
228  /// @param p The pattern
229  double frequency(const Pattern& p) const;
230 
231  /// @param p The pattern
232  PatternData& data(const Pattern& p);
233  /// @param p The pattern
234  const PatternData& data(const Pattern& p) const;
235 
236  /// strategy getter
237  SearchStrategy< GUM_SCALAR >& strategy();
238 
239  /// strategy getter
240  const SearchStrategy< GUM_SCALAR >& strategy() const;
241 
242  /** @class NeighborDegreeSort
243  * @headerfile DFSTree.h <agrum/PRM/gspan/DFSTree.h>
244  * @brief This is used to generate the max_indep_set of a Pattern.
245  */
246  struct NeighborDegreeSort {
247  /// Constructor
248  explicit NeighborDegreeSort(UndiGraph& graph);
249  /// Copy constructor.
250  NeighborDegreeSort(const NeighborDegreeSort& source);
251  /// Destructor.
252  ~NeighborDegreeSort();
253  /// The operator used to sort stuff.
254  bool operator()(NodeId i, NodeId j);
255  /// The isomorphism graph.
256  UndiGraph& g;
257  };
258 
259  /// @}
260 
261  private:
262  /// The interface graph on which this DFSTree applies.
263  const InterfaceGraph< GUM_SCALAR >* graph__;
264 
265  /// The list of root patterns in this DFSTree.
266  std::list< NodeId > roots__;
267 
268  /// The mapping between nodes in this DFSTree and the patterns they
269  /// represents.
270  Bijection< NodeId, Pattern* > node_map__;
271 
272  /// Data about patterns in this DFSTree.
273  HashTable< Pattern*, PatternData* > data__;
274 
275  /// The strategy used to prune the search tree.
276  SearchStrategy< GUM_SCALAR >* strategy__;
277 
278  /// Raise different exceptions if child is invalid or illegal
279  void checkGrowth__(Pattern& p,
280  Pattern* child,
281  EdgeGrowth< GUM_SCALAR >& edge_growth);
282 
283  /// Add a child to this DFSTree.
284  void addChild__(Pattern& p,
285  Pattern* child,
286  EdgeGrowth< GUM_SCALAR >& edge_growth);
287 
288  /// Check if an instance match is redundant.
289  bool is_new_seq__(
290  Sequence< PRMInstance< GUM_SCALAR >* >& seq,
291  NodeProperty< Sequence< PRMInstance< GUM_SCALAR >* >* >& iso_map);
292 
293  /// This initialize the DSFTree with a new root.
294  /// @param p A Pattern.
295  /// @param seq A sequence of EdgeData<GUM_SCALAR>.
296  void initialiaze_root__(Pattern* p,
297  Sequence< EdgeData< GUM_SCALAR >* >& seq);
298 
299  // Used by find_sub_pattern__.
300  bool test_equality__(HashTable< PRMClassElement< GUM_SCALAR >*, Size >& x,
301  HashTable< PRMClassElement< GUM_SCALAR >*, Size >& y);
302  };
303 
304 
305 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
306  extern template class DFSTree< double >;
307 #endif
308 
309 
310  } /* namespace gspan */
311  } /* namespace prm */
312 } /* namespace gum */
313 
314 #include <agrum/PRM/gspan/DFSTree_tpl.h>
315 
316 #endif /* GUM_DFS_TREE_H */