36 template <
typename GUM_SCALAR >
40 for (
const auto& elt : __data) {
48 template <
typename GUM_SCALAR >
53 for (
const auto edge : __graph->edges(&label)) {
54 bool u_first = (edge->l_u->id < edge->l_v->id);
55 Idx u_idx = (u_first) ? edge->l_u->id : edge->l_v->id;
56 Idx v_idx = (!u_first) ? edge->l_u->id : edge->l_v->id;
60 for (
const auto& elt : roots)
61 if ((elt.second.first == u_idx) && (elt.second.second == v_idx)) {
62 roots_edges[elt.first]->
insert(edge);
70 roots.insert(p, std::make_pair(u_idx, v_idx));
72 roots_edges[p]->
insert(edge);
79 __data.insert(p, data);
80 __roots.push_back(__node_map.first(p));
85 for (
const auto& elt : roots_edges) {
86 __initialiaze_root(elt.first, *elt.second);
87 strategy().accept_root(elt.first);
92 template <
typename GUM_SCALAR >
96 std::vector< NodeId > degree_list;
98 for (
auto iter = edge_seq.begin(); iter != edge_seq.end(); ++iter) {
99 const auto& edge = *iter;
104 bool u_first = (edge->l_u->id < edge->l_v->id);
105 seq->
insert((u_first) ? edge->u : edge->v);
106 seq->
insert((!u_first) ? edge->u : edge->v);
109 data->
iso_map.insert(an_id, seq);
110 degree_list.push_back(an_id);
114 for (
const auto& elt : data->
iso_map)
115 if (elt.first != an_id)
116 for (
auto iter = elt.second->begin(); iter != elt.second->end();
126 std::sort(degree_list.begin(), degree_list.end(), my_operator);
129 for (
const auto node : degree_list) {
130 if (!removed.exists(node)) {
134 removed.insert(neighbor);
141 template <
typename GUM_SCALAR >
145 for (
const auto& elt : iso_map) {
148 for (
const auto& inst : seq)
149 if (!(elt.second->exists(inst))) {
154 if (!found) {
return false; }
160 template <
typename GUM_SCALAR >
165 __node_map.insert(node, child);
167 std::list< NodeId >& children = __data[&p]->children;
169 if (children.empty()) {
170 children.push_back(node);
172 size_t size = children.size();
174 for (std::list< NodeId >::iterator iter = children.begin();
175 iter != children.end();
177 if (child->
code() < pattern(*iter).code()) {
178 children.insert(iter, node);
183 if (size == children.size()) { children.push_back(node); }
187 template <
typename GUM_SCALAR >
195 child->
addArc(edge_growth.
u, v, *(edge_growth.
edge));
200 if (edge < *(child->
code().
codes.front())) {
202 "added edge code is lesser than the first " 203 "one in the pattern's DFSCode");
207 typedef std::vector< EdgeCode* >::iterator EdgeIter;
209 for (EdgeIter iter = child->
code().
codes.begin();
212 if ((((**iter).i == v) || ((**iter).j == v)) && edge < (**iter)) {
215 "added backward edge is lesser than an existing edge on v");
223 "the DFSCode for this growth is not minimal");
227 template <
typename GUM_SCALAR >
233 __checkGrowth(p, child, edge_growth);
242 std::vector< NodeId > degree_list;
246 std::pair< PRMInstance< GUM_SCALAR >*,
251 for (
const auto& elt : p_iso_map) {
252 auto match = edge_growth.
matches.begin();
254 for (; match != edge_growth.
matches.end(); ++match) {
256 if (child->
code().
codes.back()->isForward()) {
257 if (elt.second->exists(match.val().first)
258 && !(elt.second->exists(match.val().second))) {
262 new_seq->
insert(match.val().second);
264 if (__is_new_seq(*new_seq, data->
iso_map)) {
266 data->
iso_map.insert(
id, new_seq);
274 if (elt.second->exists(match.val().first)
275 && elt.second->exists(match.val().second)) {
279 if (__is_new_seq(*new_seq, data->
iso_map)) {
281 data->
iso_map.insert(
id, new_seq);
291 if (match != edge_growth.
matches.end()) {
295 for (
const auto m : *data->
iso_map[
id])
296 if (data->
iso_map[node]->exists(m)) {
301 degree_list.push_back(
id);
302 edge_growth.
matches.erase(match.key());
314 std::sort(degree_list.begin(), degree_list.end(), my_operator);
317 for (
const auto node : degree_list) {
318 if (!removed.exists(node)) {
322 removed.insert(neighbor);
328 __data.insert(child, data);
330 if (!__strategy->accept_growth(&p, child, edge_growth)) {
337 __addChild(p, child, edge_growth);
341 template <
typename GUM_SCALAR >
346 for (
const auto& elt : x)
347 if (y[elt.first] != elt.second)
return false;
348 }
catch (
NotFound&) {
return false; }
354 template <
typename GUM_SCALAR >
356 pattern(from.pattern), children(from.children),
357 iso_graph(from.iso_graph), max_indep_set(from.max_indep_set),
358 cost(from.cost), gain(from.gain) {
361 for (
const auto& elt : from.
iso_map)
366 template <
typename GUM_SCALAR >
370 for (
const auto& elt :
iso_map)
374 template <
typename GUM_SCALAR >
387 template <
typename GUM_SCALAR >
392 template <
typename GUM_SCALAR >
397 template <
typename GUM_SCALAR >
404 if (
__node_map.existsSecond(const_cast< Pattern* >(&p))) {
412 template <
typename GUM_SCALAR >
419 if (
__node_map.existsSecond(const_cast< Pattern* >(&p))) {
427 template <
typename GUM_SCALAR >
428 INLINE std::list< NodeId >&
437 template <
typename GUM_SCALAR >
438 INLINE
const std::list< NodeId >&
447 template <
typename GUM_SCALAR >
456 template <
typename GUM_SCALAR >
465 template <
typename GUM_SCALAR >
474 template <
typename GUM_SCALAR >
480 if (
__data.exists(const_cast< Pattern* >(&p))) {
488 template <
typename GUM_SCALAR >
498 template <
typename GUM_SCALAR >
504 template <
typename GUM_SCALAR >
507 out << edge.
u <<
", " << *(edge.
edge) <<
", " << *(edge.
l_v) <<
", " 512 template <
typename GUM_SCALAR >
517 template <
typename GUM_SCALAR >
523 template <
typename GUM_SCALAR >
529 template <
typename GUM_SCALAR >
534 template <
typename GUM_SCALAR >
542 template <
typename GUM_SCALAR >
549 template <
typename GUM_SCALAR >
556 template <
typename GUM_SCALAR >
561 template <
typename GUM_SCALAR >
569 template <
typename GUM_SCALAR >
PatternData(Pattern *p)
Constructor.
const InterfaceGraph< GUM_SCALAR > * __graph
The interface graph on which this DFSTree applies.
EdgeCode & edgeCode(NodeId tail, NodeId head)
Returns the EdgeCode of an edge of this Pattern.
UndiGraph & iso_graph(const Pattern &p)
Returns the isomorphism graph of p in the interface graph.
This class is used to define an edge growth of a pattern in this DFSTree.
LabelData * l_v
The LabelData over the node of this edge growth.
std::list< NodeId > & children(const Pattern &p)
Returns the list of p children in this DFSTree.
std::ostream & operator<<(std::ostream &out, const DFSCode &code)
Print code in out.
SearchStrategy< GUM_SCALAR > * __strategy
The strategy used to prune the search tree.
void __addChild(Pattern &p, Pattern *child, EdgeGrowth< GUM_SCALAR > &edge_growth)
Add a child to this DFSTree.
Inner class to handle data about labels in this interface graph.
bool operator()(NodeId i, NodeId j)
The operator used to sort stuff.
An PRMInstance is a Bayesian Network fragment defined by a Class and used in a PRMSystem.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
DFSCode & code()
Returns the DFSCode of this Pattern.
Size size() const
alias for sizeNodes
The generic class for storing (ordered) sequences of objects.
virtual void addEdge(const NodeId first, const NodeId second)
insert a new edge into the undirected graph
NodeId addNodeWithLabel(LabelData &l)
Insert a node with the given LabelData.
Pattern & growPattern(Pattern &p, EdgeGrowth< GUM_SCALAR > &edge_growth, Size min_freq)
Add a one edge growth of p as one of its child.
NodeProperty< std::pair< PRMInstance< GUM_SCALAR > *, PRMInstance< GUM_SCALAR > *> > matches
The mapping between the u and v for each match in the interface graph.
Abstract class representing an element of PRM class.
std::list< NodeId > __roots
The list of root patterns in this DFSTree.
UndiGraph & g
The isomorphism graph.
bool isMinimal()
Returns the DFSCode of this Pattern.
Inner class to handle data about edges in __graph.
NeighborDegreeSort(UndiGraph &graph)
Constructor.
This is used to generate the max_indep_set of a Pattern.
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.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
bool __is_new_seq(Sequence< PRMInstance< GUM_SCALAR > * > &seq, NodeProperty< Sequence< PRMInstance< GUM_SCALAR > * > * > &iso_map)
Check if an instance match is redundant.
LabelData * edge
The LabelData over the edge of this edge growth.
std::vector< EdgeCode *> codes
The vector containing the EdgeCode composing this DFSCode.
virtual NodeId addNode()
insert a new node and return its id
The class for generic Hash Tables.
~NeighborDegreeSort()
Destructor.
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.
const InterfaceGraph< GUM_SCALAR > & graph() const
Returns the list of root patterns in this DFSTree.
NodeId u
The id of the node from which we grow an edge.
A DFSTree is used by gspan to sort lexicographically patterns discovered in an interface graph...
represent a DFS code used by gspan.
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 ...
~PatternData()
Destructor.
bool isBackward() const
Returns true if this EdgeCode is a backward edge.
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...
const NodeGraphPart & nodes() const
return *this as a NodeGraphPart
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
bool exists(const Key &k) const
Check the existence of k in the sequence.
Set< NodeId > max_indep_set
The maximal independent set of p.
Pattern & pattern(NodeId id)
Returns the pattern represented by id in this DFSTree.
NodeProperty< Sequence< PRMInstance< GUM_SCALAR > *> *> iso_map
The instances matching p in the interface graph.
Set< NodeId > & max_indep_set(const Pattern &p)
Returns the maximal independent set of p isomorphism graph.
SearchStrategy< GUM_SCALAR > & strategy()
strategy getter
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.
Base class for undirected graphs.
Size Idx
Type for indexes.
PatternData & data(const Pattern &p)
void addArc(NodeId i, NodeId j, LabelData &l)
Add an arc to this Pattern.
HashTable< Pattern *, PatternData *> __data
Data about patterns in this DFSTree.
double frequency(const Pattern &p) const
Returns the frequency of p respecting it's maximal independent set.
bool __test_equality(HashTable< PRMClassElement< GUM_SCALAR > *, Size > &x, HashTable< PRMClassElement< GUM_SCALAR > *, Size > &y)
void __checkGrowth(Pattern &p, Pattern *child, EdgeGrowth< GUM_SCALAR > &edge_growth)
Raise different exceptions if child is invalid or illegal.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Pattern & parent(const Pattern &p)
Returns the parent of p in this DFSTree.
UndiGraph iso_graph
The isomorphism graph of the pattern.
Size size() const noexcept
Returns the number of elements in the set.
Bijection< NodeId, Pattern *> __node_map
The mapping between nodes in this DFSTree and the patterns they represents.
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.
DFSTree(const InterfaceGraph< GUM_SCALAR > &graph, SearchStrategy< GUM_SCALAR > *strategy=0)
Default constructor.
This is an abstract class used to tune search strategies in the gspan algorithm.
Size NodeId
Type for node ids.
void insert(const Key &k)
Inserts a new element into the set.
#define GUM_ERROR(type, msg)
void insert(const Key &k)
Insert an element at the end of the sequence.