57 template < GUM_Numeric GUM_SCALAR >
61 for (
const auto& elt:
_data_) {
69 template < GUM_Numeric GUM_SCALAR >
74 for (
const auto& edge:
_graph_->edges(&label)) {
75 bool u_first = (edge->l_u->id < edge->l_v->id);
76 Idx u_idx = (u_first) ? edge->l_u->id : edge->l_v->id;
77 Idx v_idx = (!u_first) ? edge->l_u->id : edge->l_v->id;
81 for (
const auto& elt:
roots)
82 if ((elt.second.first == u_idx) && (elt.second.second == v_idx)) {
83 roots_edges[elt.first]->
insert(edge);
91 roots.insert(p, std::make_pair(u_idx, v_idx));
93 roots_edges[p]->
insert(edge);
105 for (
const auto& elt: roots_edges) {
112 template < GUM_Numeric GUM_SCALAR >
117 std::vector< NodeId > degree_list;
119 for (
auto iter = edge_seq.begin(); iter != edge_seq.end(); ++iter) {
120 const auto& edge = *iter;
125 bool u_first = (edge->l_u->id < edge->l_v->id);
126 seq->
insert((u_first) ? edge->u : edge->v);
127 seq->
insert((!u_first) ? edge->u : edge->v);
130 data->iso_map.insert(an_id, seq);
131 degree_list.push_back(an_id);
135 for (
const auto& elt:
data->iso_map)
136 if (elt.first != an_id)
137 for (
auto iter = elt.second->begin(); iter != elt.second->end(); ++iter)
139 data->iso_graph.addEdge(an_id, elt.first);
146 std::sort(degree_list.begin(), degree_list.end(), my_operator);
149 for (
const auto node: degree_list) {
150 if (!removed.
exists(node)) {
153 for (
const auto neighbor:
data->iso_graph.neighbours(node))
156 data->max_indep_set.insert(node);
161 template < GUM_Numeric GUM_SCALAR >
165 for (
const auto& elt:
iso_map) {
168 for (
const auto& inst: seq)
169 if (!(elt.second->exists(inst))) {
174 if (!found) {
return false; }
180 template < GUM_Numeric GUM_SCALAR >
195 for (std::list< NodeId >::iterator iter =
children.begin(); iter !=
children.end();
207 template < GUM_Numeric GUM_SCALAR >
216 child->
addArc(edge_growth.
u, v, *(edge_growth.
edge));
221 if (edge < *(child->
code().
codes.front())) {
223 "added edge code is lesser than the first "
224 "one in the pattern's DFSCode");
228 for (
auto iter = child->
code().
codes.begin(); (iter + 1) != child->
code().
codes.end();
230 if ((((**iter).i == v) || ((**iter).j == v)) && edge < (**iter)) {
232 "added backward edge is lesser than an existing edge on v");
243 template < GUM_Numeric GUM_SCALAR >
258 std::vector< NodeId > degree_list;
265 for (
const auto& elt: p_iso_map) {
266 auto match = edge_growth.
matches.begin();
268 for (; match != edge_growth.
matches.end(); ++match) {
270 if (child->code().codes.back()->isForward()) {
271 if (elt.second->exists(match.val().first)
272 && !(elt.second->exists(match.val().second))) {
275 new_seq->
insert(match.val().second);
278 id =
data->iso_graph.addNode();
279 data->iso_map.insert(
id, new_seq);
287 if (elt.second->exists(match.val().first) && elt.second->exists(match.val().second)) {
292 id =
data->iso_graph.addNode();
293 data->iso_map.insert(
id, new_seq);
303 if (match != edge_growth.
matches.end()) {
305 for (
const auto node:
data->iso_graph.nodes())
307 for (
const auto m: *
data->iso_map[
id])
308 if (
data->iso_map[node]->exists(m)) {
309 data->iso_graph.addEdge(node,
id);
313 degree_list.push_back(
id);
314 edge_growth.
matches.erase(match.key());
318 if (
data->iso_graph.size() < min_freq) {
326 std::sort(degree_list.begin(), degree_list.end(), my_operator);
329 for (
const auto node: degree_list) {
330 if (!removed.
exists(node)) {
333 for (
const auto neighbor:
data->iso_graph.neighbours(node))
336 data->max_indep_set.insert(node);
342 if (!
_strategy_->accept_growth(&p, child, edge_growth)) {
353 template < GUM_Numeric GUM_SCALAR >
357 for (
const auto& elt: x) {
358 if (
auto p = y.tryGet(elt.first); !p || *p != elt.second)
return false;
365 template < GUM_Numeric GUM_SCALAR >
371 for (
const auto& elt: from.
iso_map)
375 template < GUM_Numeric GUM_SCALAR >
383 template < GUM_Numeric GUM_SCALAR >
394 template < GUM_Numeric GUM_SCALAR >
399 template < GUM_Numeric GUM_SCALAR >
404 template < GUM_Numeric GUM_SCALAR >
415 template < GUM_Numeric GUM_SCALAR >
426 template < GUM_Numeric GUM_SCALAR >
430 return (*pd)->children;
433 template < GUM_Numeric GUM_SCALAR >
437 return (*pd)->children;
440 template < GUM_Numeric GUM_SCALAR >
446 template < GUM_Numeric GUM_SCALAR >
452 template < GUM_Numeric GUM_SCALAR >
456 return (*pd)->iso_graph;
459 template < GUM_Numeric GUM_SCALAR >
464 auto p_iso = (*pd)->iso_map.tryGet(node);
469 template < GUM_Numeric GUM_SCALAR >
473 return (*pd)->max_indep_set;
476 template < GUM_Numeric GUM_SCALAR >
481 template < GUM_Numeric GUM_SCALAR >
483 out << edge.
u <<
", " << *(edge.
edge) <<
", " << *(edge.
l_v) <<
", " << edge.
v;
487 template < GUM_Numeric GUM_SCALAR >
492 template < GUM_Numeric GUM_SCALAR >
497 template < GUM_Numeric GUM_SCALAR >
503 template < GUM_Numeric GUM_SCALAR >
508 template < GUM_Numeric GUM_SCALAR >
515 template < GUM_Numeric GUM_SCALAR >
520 template < GUM_Numeric GUM_SCALAR >
526 template < GUM_Numeric GUM_SCALAR >
531 template < GUM_Numeric GUM_SCALAR >
533 return g.neighbours(i).size() <
g.neighbours(j).size();
538 template < GUM_Numeric GUM_SCALAR >
Headers of the DFSTree class.
const NodeSet & parents(NodeId id) const
returns the set of nodes with arc ingoing to a given node
The class for generic Hash Tables.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
Size size() const
alias for sizeNodes
virtual NodeId addNode()
insert a new node and return its id
Exception : the element we looked for cannot be found.
Exception : operation not allowed.
void insert(const Key &k)
Insert an element at the end of the sequence.
bool exists(const Key &k) const
Check the existence of k in the sequence.
The generic class for storing (ordered) sequences of objects.
bool exists(const Key &k) const
Indicates whether a given elements belong to the set.
void insert(const Key &k)
Inserts a new element into the set.
Base class for undirected graphs.
Abstract class representing an element of PRM class.
An PRMInstance is a Bayesian network fragment defined by a Class and used in a PRMSystem.
std::vector< EdgeCode * > codes
The vector containing the EdgeCode composing this DFSCode.
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...
SearchStrategy< GUM_SCALAR > * _strategy_
The strategy used to prune the search tree.
void _checkGrowth_(Pattern &p, Pattern *child, EdgeGrowth< GUM_SCALAR > &edge_growth)
Raise different exceptions if child is invalid or illegal.
std::list< NodeId > & children(const Pattern &p)
Returns the list of p children in this DFSTree.
bool _test_equality_(HashTable< PRMClassElement< GUM_SCALAR > *, Size > &x, HashTable< PRMClassElement< GUM_SCALAR > *, Size > &y)
SearchStrategy< GUM_SCALAR > & strategy()
strategy getter
double frequency(const Pattern &p) const
Returns the frequency of p respecting it's maximal independent set.
Pattern & parent(const Pattern &p)
Returns the parent of p in this DFSTree.
void addRoot(LabelData &data)
Add a one edge Pattern in this DFSTree.
UndiGraph & iso_graph(const Pattern &p)
Returns the isomorphism graph of p in the interface graph.
DFSTree(const InterfaceGraph< GUM_SCALAR > &graph, SearchStrategy< GUM_SCALAR > *strategy=0)
Default constructor.
Pattern & growPattern(Pattern &p, EdgeGrowth< GUM_SCALAR > &edge_growth, Size min_freq)
Add a one edge growth of p as one of its child.
void _addChild_(Pattern &p, Pattern *child, EdgeGrowth< GUM_SCALAR > &edge_growth)
Add a child to this DFSTree.
PatternData & data(const Pattern &p)
void _initialiaze_root_(Pattern *p, Sequence< EdgeData< GUM_SCALAR > * > &seq)
This initialize the DSFTree with a new root.
std::list< NodeId > & roots()
Returns the list of root patterns in this DFSTree.
HashTable< Pattern *, PatternData * > _data_
Data about patterns in this DFSTree.
bool _is_new_seq_(Sequence< PRMInstance< GUM_SCALAR > * > &seq, NodeProperty< Sequence< PRMInstance< GUM_SCALAR > * > * > &iso_map)
Check if an instance match is redundant.
Pattern & pattern(NodeId id)
Returns the pattern represented by id in this DFSTree.
const InterfaceGraph< GUM_SCALAR > & internalGraph() const
Returns the list of root patterns in this DFSTree.
~DFSTree() override
Destructor.
Bijection< NodeId, Pattern * > _node_map_
The mapping between nodes in this DFSTree and the patterns they represents.
const InterfaceGraph< GUM_SCALAR > * _graph_
The interface graph on which this DFSTree applies.
Set< NodeId > & max_indep_set(const Pattern &p)
Returns the maximal independent set of p isomorphism graph.
std::list< NodeId > _roots_
The list of root patterns in this DFSTree.
Inner class to handle data about edges in graph.
This class is used to define an edge growth of a pattern in this DFSTree.
NodeId u
The id of the node from which we grow an edge.
NodeProperty< std::pair< PRMInstance< GUM_SCALAR > *, PRMInstance< GUM_SCALAR > * > > matches
The mapping between the u and v for each match in the interface graph.
NodeId v
If the growth is backward you must assigned the subscript of v, otherwise 0 is assigned (recall that ...
LabelData * edge
The LabelData over the edge of this edge growth.
LabelData * l_v
The LabelData over the node of this edge growth.
This is class is an implementation of a simple serach strategy for the gspan algorithm: it accept a g...
This class represent the interface graph of a given gum::prm::PRMSystem<GUM_SCALAR>.
This contains all the information we want for a node in a DFSTree.
bool isMinimal()
Returns the DFSCode of this Pattern.
NodeId addNodeWithLabel(LabelData &l)
Insert a node with the given LabelData.
DFSCode & code()
Returns the DFSCode of this Pattern.
void addArc(NodeId i, NodeId j, LabelData &l)
Add an arc to this Pattern.
EdgeCode & edgeCode(NodeId tail, NodeId head)
Returns the EdgeCode of an edge of this Pattern.
This is an abstract class used to tune search strategies in the gspan algorithm.
Headers of the DFSTree class.
#define GUM_ERROR(type, msg)
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Size Idx
Type for indexes.
Size NodeId
Type for node ids.
HashTable< NodeId, VAL > NodeProperty
Property on graph elements.
std::ostream & operator<<(std::ostream &out, const DFSCode &code)
Print code in out.
namespace for all probabilistic relational models entities
gum is the global namespace for all aGrUM entities
This is used to generate the max_indep_set of a Pattern.
NeighborDegreeSort(UndiGraph &graph)
Constructor.
~NeighborDegreeSort()
Destructor.
bool operator()(NodeId i, NodeId j)
The operator used to sort stuff.
UndiGraph & g
The isomorphism graph.
~PatternData()
Destructor.
Pattern * pattern
The pattern.
PatternData(Pattern *p)
Constructor.
Size cost
The cost of this Pattern.
Size gain
The gain of this Pattern.
NodeProperty< Sequence< PRMInstance< GUM_SCALAR > * > * > iso_map
The instances matching p in the interface graph.
UndiGraph iso_graph
The isomorphism graph of the pattern.
Set< NodeId > max_indep_set
The maximal independent set of p.
std::list< NodeId > children
The list of the pattern's children, sorted lexicographically.
represent a DFS code used by gspan.
bool isBackward() const
Returns true if this EdgeCode is a backward edge.
Inner class to handle data about labels in this interface graph.