aGrUM  0.14.2
DFSTree_tpl.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005 by Christophe GONZALES and Pierre-Henri WUILLEMIN *
3  * {prenom.nom}_at_lip6.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
29 
30 namespace gum {
31  namespace prm {
32  namespace gspan {
33  template < typename GUM_SCALAR >
35  GUM_DESTRUCTOR(DFSTree);
36 
37  for (const auto& elt : __data) {
38  delete elt.first;
39  delete elt.second;
40  }
41 
42  delete __strategy;
43  }
44 
45  template < typename GUM_SCALAR >
49 
50  for (const auto edge : __graph->edges(&label)) {
51  bool u_first = (edge->l_u->id < edge->l_v->id);
52  Idx u_idx = (u_first) ? edge->l_u->id : edge->l_v->id;
53  Idx v_idx = (!u_first) ? edge->l_u->id : edge->l_v->id;
54 
55  bool found = false;
56 
57  for (const auto& elt : roots)
58  if ((elt.second.first == u_idx) && (elt.second.second == v_idx)) {
59  roots_edges[elt.first]->insert(edge);
60  found = true;
61  break;
62  }
63 
65  if (!found) {
66  Pattern* p = new Pattern();
67  roots.insert(p, std::make_pair(u_idx, v_idx));
68  roots_edges.insert(p, new Sequence< EdgeData< GUM_SCALAR >* >());
69  roots_edges[p]->insert(edge);
72  NodeId u = p->addNodeWithLabel((u_first) ? *edge->l_u : *edge->l_v);
73  NodeId v = p->addNodeWithLabel((!u_first) ? *edge->l_u : *edge->l_v);
74  p->addArc(u, v, label);
75  __node_map.insert(DiGraph::addNode(), p);
76  __data.insert(p, data);
77  __roots.push_back(__node_map.first(p));
78  }
79  }
80 
81  // This is used to compute the max independent set of p->max_indep_set
82  for (const auto& elt : roots_edges) {
83  __initialiaze_root(elt.first, *elt.second);
84  strategy().accept_root(elt.first);
85  delete elt.second;
86  }
87  }
88 
89  template < typename GUM_SCALAR >
91  Pattern* p, Sequence< EdgeData< GUM_SCALAR >* >& edge_seq) {
92  DFSTree< GUM_SCALAR >::PatternData* data = __data[p];
93  std::vector< NodeId > degree_list;
94 
95  for (auto iter = edge_seq.begin(); iter != edge_seq.end(); ++iter) {
96  const auto& edge = *iter;
99 
100  // Creating the multiset of instances matching p
101  bool u_first = (edge->l_u->id < edge->l_v->id);
102  seq->insert((u_first) ? edge->u : edge->v);
103  seq->insert((!u_first) ? edge->u : edge->v);
104 
105  NodeId an_id = data->iso_graph.addNode();
106  data->iso_map.insert(an_id, seq);
107  degree_list.push_back(an_id);
108 
109  // Adding edges between two isomorphisms of p sharing at least one
110  // instance
111  for (const auto& elt : data->iso_map)
112  if (elt.first != an_id)
113  for (auto iter = elt.second->begin(); iter != elt.second->end();
114  ++iter)
115  if (seq->exists(*iter)) {
116  data->iso_graph.addEdge(an_id, elt.first);
117  break;
118  }
119  }
120 
121  // Computing p->max_indep_set using a greedy algorithm
123  std::sort(degree_list.begin(), degree_list.end(), my_operator);
124  Set< NodeId > removed;
125 
126  for (const auto node : degree_list) {
127  if (!removed.exists(node)) {
128  removed.insert(node);
129 
130  for (const auto neighbor : data->iso_graph.neighbours(node))
131  removed.insert(neighbor);
132 
133  data->max_indep_set.insert(node);
134  }
135  }
136  }
137 
138  template < typename GUM_SCALAR >
142  for (const auto& elt : iso_map) {
143  bool found = false;
144 
145  for (const auto& inst : seq)
146  if (!(elt.second->exists(inst))) {
147  found = true;
148  break;
149  }
150 
151  if (!found) { return false; }
152  }
153 
154  return true;
155  }
156 
157  template < typename GUM_SCALAR >
159  Pattern& p, Pattern* child, EdgeGrowth< GUM_SCALAR >& edge_growth) {
160  // Adding child to the tree
161  NodeId node = DiGraph::addNode();
162  __node_map.insert(node, child);
163  // Adding child in p's children list
164  std::list< NodeId >& children = __data[&p]->children;
165 
166  if (children.empty()) {
167  children.push_back(node);
168  } else {
169  size_t size = children.size();
170 
171  for (std::list< NodeId >::iterator iter = children.begin();
172  iter != children.end();
173  ++iter) {
174  if (child->code() < pattern(*iter).code()) {
175  children.insert(iter, node);
176  break;
177  }
178  }
179 
180  if (size == children.size()) { children.push_back(node); }
181  }
182  }
183 
184  template < typename GUM_SCALAR >
186  Pattern& p, Pattern* child, EdgeGrowth< GUM_SCALAR >& edge_growth) {
187  NodeId v = edge_growth.v;
188 
189  // First we check if the edge is legal
190  if (v == 0) { v = child->addNodeWithLabel(*(edge_growth.l_v)); }
191 
192  child->addArc(edge_growth.u, v, *(edge_growth.edge));
193  // Neighborhood restriction is checked by the Pattern class
194  EdgeCode& edge = child->edgeCode(edge_growth.u, v);
195 
196  // Then we check if the edge we added is valid
197  if (edge < *(child->code().codes.front())) {
199  "added edge code is lesser than the first "
200  "one in the pattern's DFSCode");
201  }
202 
203  if (edge.isBackward()) {
204  typedef std::vector< EdgeCode* >::iterator EdgeIter;
205 
206  for (EdgeIter iter = child->code().codes.begin();
207  (iter + 1) != child->code().codes.end();
208  ++iter) {
209  if ((((**iter).i == v) || ((**iter).j == v)) && edge < (**iter)) {
210  GUM_ERROR(
212  "added backward edge is lesser than an existing edge on v");
213  }
214  }
215  }
216 
217  // Finally we check if child is minimal.
218  if (!child->isMinimal()) {
220  "the DFSCode for this growth is not minimal");
221  }
222  }
223 
224  template < typename GUM_SCALAR >
226  Pattern& p, EdgeGrowth< GUM_SCALAR >& edge_growth, Size min_freq) {
227  Pattern* child = new Pattern(p);
228 
229  try {
230  __checkGrowth(p, child, edge_growth);
231  } catch (OperationNotAllowed&) {
232  delete child;
233  throw;
234  }
235 
236  // Now we need to build the pattern data about child
239  std::vector< NodeId > degree_list;
241  __data[&p]->iso_map;
242  typename NodeProperty<
243  std::pair< PRMInstance< GUM_SCALAR >*,
244  PRMInstance< GUM_SCALAR >* > >::iterator_safe match;
245  // Using p information to build child's isomorphism graph
246  NodeId id = 0;
247 
248  for (const auto& elt : p_iso_map) {
249  auto match = edge_growth.matches.begin();
250 
251  for (; match != edge_growth.matches.end(); ++match) {
252  // Adding the isomorphism in the iso_graph and building the iso_map.
253  if (child->code().codes.back()->isForward()) {
254  if (elt.second->exists(match.val().first)
255  && !(elt.second->exists(match.val().second))) {
256  // Let's see if the new match is already matched
258  new Sequence< PRMInstance< GUM_SCALAR >* >(*elt.second);
259  new_seq->insert(match.val().second);
260 
261  if (__is_new_seq(*new_seq, data->iso_map)) {
262  id = data->iso_graph.addNode();
263  data->iso_map.insert(id, new_seq);
264  } else {
265  delete new_seq;
266  }
267 
268  break;
269  }
270  } else {
271  if (elt.second->exists(match.val().first)
272  && elt.second->exists(match.val().second)) {
274  new Sequence< PRMInstance< GUM_SCALAR >* >(*elt.second);
275 
276  if (__is_new_seq(*new_seq, data->iso_map)) {
277  id = data->iso_graph.addNode();
278  data->iso_map.insert(id, new_seq);
279  } else {
280  delete new_seq;
281  }
282 
283  break;
284  }
285  }
286  }
287 
288  if (match != edge_growth.matches.end()) {
289  // Adding edges in the iso_graph
290  for (const auto node : data->iso_graph.nodes())
291  if (node != id)
292  for (const auto m : *data->iso_map[id])
293  if (data->iso_map[node]->exists(m)) {
294  data->iso_graph.addEdge(node, id);
295  break;
296  }
297 
298  degree_list.push_back(id);
299  edge_growth.matches.erase(match.key());
300  }
301  }
302 
303  if (data->iso_graph.size() < min_freq) {
304  delete data;
305  delete child;
306  GUM_ERROR(OperationNotAllowed, "child is not frequent enough");
307  }
308 
309  // Now we can compute the maximal independent set of child
311  std::sort(degree_list.begin(), degree_list.end(), my_operator);
312  Set< NodeId > removed;
313 
314  for (const auto node : degree_list) {
315  if (!removed.exists(node)) {
316  removed.insert(node);
317 
318  for (const auto neighbor : data->iso_graph.neighbours(node))
319  removed.insert(neighbor);
320 
321  data->max_indep_set.insert(node);
322  }
323  }
324 
325  __data.insert(child, data);
326 
327  if (!__strategy->accept_growth(&p, child, edge_growth)) {
328  __data.erase(child);
329  delete data;
330  delete child;
331  GUM_ERROR(OperationNotAllowed, "child is not frequent enough");
332  }
333 
334  __addChild(p, child, edge_growth);
335  return *child;
336  }
337 
338  template < typename GUM_SCALAR >
342  try {
343  for (const auto& elt : x)
344  if (y[elt.first] != elt.second) return false;
345  } catch (NotFound&) { return false; }
346 
347  return true;
348  }
349 
350  // PatternData
351  template < typename GUM_SCALAR >
353  pattern(from.pattern), children(from.children),
354  iso_graph(from.iso_graph), max_indep_set(from.max_indep_set),
355  cost(from.cost), gain(from.gain) {
357 
358  for (const auto& elt : from.iso_map)
359  iso_map.insert(elt.first,
360  new Sequence< PRMInstance< GUM_SCALAR >* >(*elt.second));
361  }
362 
363  template < typename GUM_SCALAR >
365  GUM_DESTRUCTOR(DFSTree< GUM_SCALAR >::PatternData);
366 
367  for (const auto& elt : iso_map)
368  delete elt.second;
369  }
370 
371  template < typename GUM_SCALAR >
375  __graph(&graph),
376  __strategy(strategy) {
377  GUM_CONSTRUCTOR(DFSTree);
378 
380 
381  __strategy->setTree(this);
382  }
383 
384  template < typename GUM_SCALAR >
385  INLINE std::list< NodeId >& DFSTree< GUM_SCALAR >::roots() {
386  return __roots;
387  }
388 
389  template < typename GUM_SCALAR >
390  INLINE const std::list< NodeId >& DFSTree< GUM_SCALAR >::roots() const {
391  return __roots;
392  }
393 
394  template < typename GUM_SCALAR >
396  try {
397  return *(__node_map.second(
398  *(DiGraph::parents(__node_map.first(const_cast< Pattern* >(&p)))
399  .begin())));
400  } catch (NotFound&) {
401  if (__node_map.existsSecond(const_cast< Pattern* >(&p))) {
402  GUM_ERROR(NotFound, "the given pattern is a root node");
403  } else {
404  GUM_ERROR(NotFound, "pattern not found in this DFSTree");
405  }
406  }
407  }
408 
409  template < typename GUM_SCALAR >
410  INLINE const Pattern& DFSTree< GUM_SCALAR >::parent(const Pattern& p) const {
411  try {
412  return *(__node_map.second(
413  *(DiGraph::parents(__node_map.first(const_cast< Pattern* >(&p)))
414  .begin())));
415  } catch (NotFound&) {
416  if (__node_map.existsSecond(const_cast< Pattern* >(&p))) {
417  GUM_ERROR(NotFound, "the given pattern is a root node");
418  } else {
419  GUM_ERROR(NotFound, "pattern not found in this DFSTree");
420  }
421  }
422  }
423 
424  template < typename GUM_SCALAR >
425  INLINE std::list< NodeId >&
427  try {
428  return __data[const_cast< Pattern* >(&p)]->children;
429  } catch (NotFound&) {
430  GUM_ERROR(NotFound, "pattern not found in this DFSTree");
431  }
432  }
433 
434  template < typename GUM_SCALAR >
435  INLINE const std::list< NodeId >&
437  try {
438  return __data[const_cast< Pattern* >(&p)]->children;
439  } catch (NotFound&) {
440  GUM_ERROR(NotFound, "pattern not found in this DFSTree");
441  }
442  }
443 
444  template < typename GUM_SCALAR >
446  try {
447  return *(__node_map.second(id));
448  } catch (NotFound&) {
449  GUM_ERROR(NotFound, "no pattern matching the given id");
450  }
451  }
452 
453  template < typename GUM_SCALAR >
455  try {
456  return *(__node_map.second(id));
457  } catch (NotFound&) {
458  GUM_ERROR(NotFound, "no pattern matching the given id");
459  }
460  }
461 
462  template < typename GUM_SCALAR >
464  try {
465  return __data[const_cast< Pattern* >(&p)]->iso_graph;
466  } catch (NotFound&) {
467  GUM_ERROR(NotFound, "pattern not found in this DFSTree");
468  }
469  }
470 
471  template < typename GUM_SCALAR >
474  try {
475  return *(__data[const_cast< Pattern* >(&p)]->iso_map[node]);
476  } catch (NotFound&) {
477  if (__data.exists(const_cast< Pattern* >(&p))) {
478  GUM_ERROR(NotFound, "node not found in Pattern's isomorphism graph");
479  } else {
480  GUM_ERROR(NotFound, "pattern not found in this DFSTree");
481  }
482  }
483  }
484 
485  template < typename GUM_SCALAR >
486  INLINE Set< NodeId >&
488  try {
489  return __data[const_cast< Pattern* >(&p)]->max_indep_set;
490  } catch (NotFound&) {
491  GUM_ERROR(NotFound, "pattern not found in this DFSTree");
492  }
493  }
494 
495  template < typename GUM_SCALAR >
496  INLINE const InterfaceGraph< GUM_SCALAR >&
498  return *__graph;
499  }
500 
501  template < typename GUM_SCALAR >
502  INLINE std::ostream& operator<<(std::ostream& out,
503  const EdgeGrowth< GUM_SCALAR >& edge) {
504  out << edge.u << ", " << *(edge.edge) << ", " << *(edge.l_v) << ", "
505  << edge.v;
506  return out;
507  }
508 
509  template < typename GUM_SCALAR >
510  INLINE double DFSTree< GUM_SCALAR >::frequency(const Pattern& p) const {
511  return (double)__data[const_cast< Pattern* >(&p)]->max_indep_set.size();
512  }
513 
514  template < typename GUM_SCALAR >
515  INLINE typename DFSTree< GUM_SCALAR >::PatternData&
517  return *(__data[const_cast< Pattern* >(&p)]);
518  }
519 
520  template < typename GUM_SCALAR >
521  INLINE const typename DFSTree< GUM_SCALAR >::PatternData&
523  return *(__data[const_cast< Pattern* >(&p)]);
524  }
525 
526  template < typename GUM_SCALAR >
528  return *__strategy;
529  }
530 
531  template < typename GUM_SCALAR >
532  INLINE const SearchStrategy< GUM_SCALAR >&
534  return *__strategy;
535  }
536 
537  // NeighborDegreeSort
538 
539  template < typename GUM_SCALAR >
541  UndiGraph& graph) :
542  g(graph) {
544  }
545 
546  template < typename GUM_SCALAR >
548  const NeighborDegreeSort& source) :
549  g(source.g) {
551  }
552 
553  template < typename GUM_SCALAR >
556  }
557 
558  template < typename GUM_SCALAR >
560  NodeId j) {
561  return g.neighbours(i).size() < g.neighbours(j).size();
562  }
563 
564  // PatternData
565 
566  template < typename GUM_SCALAR >
568  pattern(p), cost(0), gain(0) {
569  GUM_CONSTRUCTOR(DFSTree< GUM_SCALAR >::PatternData);
570  }
571 
572  } /* namespace gspan */
573  } /* namespace prm */
574 } /* namespace gum */
PatternData(Pattern *p)
Constructor.
Definition: DFSTree_tpl.h:567
const InterfaceGraph< GUM_SCALAR > * __graph
The interface graph on which this DFSTree applies.
Definition: DFSTree.h:261
~DFSTree()
Destructor.
Definition: DFSTree_tpl.h:34
EdgeCode & edgeCode(NodeId tail, NodeId head)
Returns the EdgeCode of an edge of this Pattern.
Definition: pattern_inl.h:176
UndiGraph & iso_graph(const Pattern &p)
Returns the isomorphism graph of p in the interface graph.
Definition: DFSTree_tpl.h:463
This class is used to define an edge growth of a pattern in this DFSTree.
Definition: edgeGrowth.h:60
LabelData * l_v
The LabelData over the node of this edge growth.
Definition: edgeGrowth.h:77
std::list< NodeId > & children(const Pattern &p)
Returns the list of p children in this DFSTree.
Definition: DFSTree_tpl.h:426
std::ostream & operator<<(std::ostream &out, const DFSCode &code)
Print code in out.
Definition: DFSCode.cpp:37
SearchStrategy< GUM_SCALAR > * __strategy
The strategy used to prune the search tree.
Definition: DFSTree.h:274
void __addChild(Pattern &p, Pattern *child, EdgeGrowth< GUM_SCALAR > &edge_growth)
Add a child to this DFSTree.
Definition: DFSTree_tpl.h:158
Inner class to handle data about labels in this interface graph.
bool operator()(NodeId i, NodeId j)
The operator used to sort stuff.
Definition: DFSTree_tpl.h:559
An PRMInstance is a Bayesian Network fragment defined by a Class and used in a PRMSystem.
Definition: PRMInstance.h:60
Headers of the DFSTree class.
DFSCode & code()
Returns the DFSCode of this Pattern.
Definition: pattern_inl.h:170
Size size() const
alias for sizeNodes
The generic class for storing (ordered) sequences of objects.
Definition: sequence.h:1019
virtual void addEdge(const NodeId first, const NodeId second)
insert a new edge into the undirected graph
Definition: undiGraph_inl.h:32
NodeId addNodeWithLabel(LabelData &l)
Insert a node with the given LabelData.
Definition: pattern_inl.h:38
Pattern & growPattern(Pattern &p, EdgeGrowth< GUM_SCALAR > &edge_growth, Size min_freq)
Add a one edge growth of p as one of its child.
Definition: DFSTree_tpl.h:225
NodeProperty< std::pair< PRMInstance< GUM_SCALAR > *, PRMInstance< GUM_SCALAR > *> > matches
The mapping between the u and v for each match in the interface graph.
Definition: edgeGrowth.h:87
Abstract class representing an element of PRM class.
std::list< NodeId > __roots
The list of root patterns in this DFSTree.
Definition: DFSTree.h:264
UndiGraph & g
The isomorphism graph.
Definition: DFSTree.h:254
bool isMinimal()
Returns the DFSCode of this Pattern.
Definition: pattern.cpp:53
Inner class to handle data about edges in __graph.
NeighborDegreeSort(UndiGraph &graph)
Constructor.
Definition: DFSTree_tpl.h:540
This is used to generate the max_indep_set of a Pattern.
Definition: DFSTree.h:244
This class represent the interface graph of a given gum::prm::PRMSystem<GUM_SCALAR>.
void addRoot(LabelData &data)
Add a one edge Pattern in this DFSTree.
Definition: DFSTree_tpl.h:46
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
bool __is_new_seq(Sequence< PRMInstance< GUM_SCALAR > * > &seq, NodeProperty< Sequence< PRMInstance< GUM_SCALAR > * > * > &iso_map)
Check if an instance match is redundant.
Definition: DFSTree_tpl.h:139
LabelData * edge
The LabelData over the edge of this edge growth.
Definition: edgeGrowth.h:75
std::vector< EdgeCode *> codes
The vector containing the EdgeCode composing this DFSCode.
Definition: DFSCode.h:87
virtual NodeId addNode()
insert a new node and return its id
The class for generic Hash Tables.
Definition: hashTable.h:676
const NodeSet & neighbours(const NodeId id) const
returns the set of edges adjacent to a given node
std::list< NodeId > & roots()
Returns the list of root patterns in this DFSTree.
Definition: DFSTree_tpl.h:385
const InterfaceGraph< GUM_SCALAR > & graph() const
Returns the list of root patterns in this DFSTree.
Definition: DFSTree_tpl.h:497
NodeId u
The id of the node from which we grow an edge.
Definition: edgeGrowth.h:73
A DFSTree is used by gspan to sort lexicographically patterns discovered in an interface graph...
Definition: DFSTree.h:68
represent a DFS code used by gspan.
Definition: edgeCode.h:49
node_iterator begin() const noexcept
a begin iterator to parse the set of nodes contained in the NodeGraphPart
NodeId v
If the growth is backward you must assigned the subscript of v, otherwise 0 is assigned (recall that ...
Definition: edgeGrowth.h:80
bool isBackward() const
Returns true if this EdgeCode is a backward edge.
Definition: edgeCode_inl.h:56
const NodeSet & parents(const NodeId id) const
returns the set of nodes with arc ingoing to a given node
Sequence< PRMInstance< GUM_SCALAR > *> & iso_map(const Pattern &p, NodeId node)
Given a pattern and a node in its isomorphism graph, this methods returns the sequence of instance ma...
Definition: DFSTree_tpl.h:473
const NodeGraphPart & nodes() const
return *this as a NodeGraphPart
Headers of the DFSTree class.
bool exists(const Key &k) const
Check the existence of k in the sequence.
Definition: sequence_tpl.h:399
Set< NodeId > max_indep_set
The maximal independent set of p.
Definition: DFSTree.h:107
Pattern & pattern(NodeId id)
Returns the pattern represented by id in this DFSTree.
Definition: DFSTree_tpl.h:445
NodeProperty< Sequence< PRMInstance< GUM_SCALAR > *> *> iso_map
The instances matching p in the interface graph.
Definition: DFSTree.h:105
Set< NodeId > & max_indep_set(const Pattern &p)
Returns the maximal independent set of p isomorphism graph.
Definition: DFSTree_tpl.h:487
SearchStrategy< GUM_SCALAR > & strategy()
strategy getter
Definition: DFSTree_tpl.h:527
This is class is an implementation of a simple serach strategy for the gspan algorithm: it accept a g...
void __initialiaze_root(Pattern *p, Sequence< EdgeData< GUM_SCALAR > * > &seq)
This initialize the DSFTree with a new root.
Definition: DFSTree_tpl.h:90
Base class for undirected graphs.
Definition: undiGraph.h:106
Size Idx
Type for indexes.
Definition: types.h:50
PatternData & data(const Pattern &p)
Definition: DFSTree_tpl.h:516
void addArc(NodeId i, NodeId j, LabelData &l)
Add an arc to this Pattern.
Definition: pattern_inl.h:115
HashTable< Pattern *, PatternData *> __data
Data about patterns in this DFSTree.
Definition: DFSTree.h:271
double frequency(const Pattern &p) const
Returns the frequency of p respecting it&#39;s maximal independent set.
Definition: DFSTree_tpl.h:510
bool __test_equality(HashTable< PRMClassElement< GUM_SCALAR > *, Size > &x, HashTable< PRMClassElement< GUM_SCALAR > *, Size > &y)
Definition: DFSTree_tpl.h:339
void __checkGrowth(Pattern &p, Pattern *child, EdgeGrowth< GUM_SCALAR > &edge_growth)
Raise different exceptions if child is invalid or illegal.
Definition: DFSTree_tpl.h:185
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:45
Pattern & parent(const Pattern &p)
Returns the parent of p in this DFSTree.
Definition: DFSTree_tpl.h:395
UndiGraph iso_graph
The isomorphism graph of the pattern.
Definition: DFSTree.h:103
Size size() const noexcept
Returns the number of elements in the set.
Definition: set_tpl.h:698
Bijection< NodeId, Pattern *> __node_map
The mapping between nodes in this DFSTree and the patterns they represents.
Definition: DFSTree.h:268
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
This contains all the information we want for a node in a DFSTree.
Definition: pattern.h:70
DFSTree(const InterfaceGraph< GUM_SCALAR > &graph, SearchStrategy< GUM_SCALAR > *strategy=0)
Default constructor.
Definition: DFSTree_tpl.h:372
This is an abstract class used to tune search strategies in the gspan algorithm.
Definition: DFSTree.h:58
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:610
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52
void insert(const Key &k)
Insert an element at the end of the sequence.
Definition: sequence_tpl.h:405