aGrUM  0.14.2
arcGraphPart.cpp
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  ***************************************************************************/
27 
28 #ifdef GUM_NO_INLINE
30 #endif // GUM_NOINLINE
32 
33 namespace gum {
34 
36  ArcGraphPart::ArcGraphPart(Size arcs_size, bool arcs_resize_policy) :
37  __arcs(arcs_size, arcs_resize_policy) {
38  GUM_CONSTRUCTOR(ArcGraphPart);
39  }
40 
42  GUM_CONS_CPY(ArcGraphPart);
43 
44  // copy the sets of parents
45  const NodeProperty< NodeSet* >& pars = s.__parents;
46  __parents.resize(pars.capacity());
47 
48  for (const auto& elt : pars) {
49  NodeSet* newpar = new NodeSet(*elt.second);
50  __parents.insert(elt.first, newpar);
51  }
52 
53  // copy the sets of children
55  __children.resize(children.capacity());
56 
57  for (const auto& elt : children) {
58  NodeSet* newchildren = new NodeSet(*elt.second);
59  __children.insert(elt.first, newchildren);
60  }
61 
62  // send signals to indicate that there are new arcs
63  if (onArcAdded.hasListener()) {
64  for (const auto& arc : __arcs) {
65  GUM_EMIT2(onArcAdded, arc.tail(), arc.head());
66  }
67  }
68  }
69 
71  GUM_DESTRUCTOR(ArcGraphPart);
72  // be sure to deallocate all the parents and children sets
73  clearArcs();
74  }
75 
77  for (const auto& elt : __parents)
78  delete elt.second;
79 
80  __parents.clear();
81 
82  for (const auto& elt : __children)
83  delete elt.second;
84 
85  __children.clear();
86 
87  // we need this copy only if at least one onArcDeleted listener exists
88  if (onArcDeleted.hasListener()) {
89  ArcSet tmp = __arcs;
90  __arcs.clear();
91 
92  for (const auto& arc : tmp)
93  GUM_EMIT2(onArcDeleted, arc.tail(), arc.head());
94  } else {
95  __arcs.clear();
96  }
97  }
98 
100  // avoid self assignment
101  if (this != &s) {
102  // copy the arcs
103  clearArcs();
104  __arcs = s.__arcs;
105 
106  // copy the sets of parents
107  __parents.resize(s.__parents.capacity());
108 
109  for (const auto& elt : s.__parents) {
110  NodeSet* newpar = new NodeSet(*elt.second);
111  __parents.insert(elt.first, newpar);
112  }
113 
114  // copy the sets of children
115  __children.resize(s.__children.capacity());
116 
117  for (const auto& elt : s.__children) {
118  NodeSet* newchildren = new NodeSet(*elt.second);
119  __children.insert(elt.first, newchildren);
120  }
121 
122  if (onArcAdded.hasListener()) {
123  for (const auto& arc : __arcs) {
124  GUM_EMIT2(onArcAdded, arc.tail(), arc.head());
125  }
126  }
127  }
128 
129  return *this;
130  }
131 
132  const std::string ArcGraphPart::toString() const {
133  std::stringstream s;
134  bool first = true;
135  s << "{";
136 
137  for (const auto& arc : __arcs) {
138  if (first) {
139  first = false;
140  } else {
141  s << ",";
142  }
143 
144  s << arc;
145  }
146 
147  s << "}";
148 
149  return s.str();
150  }
151 
152  const std::vector< NodeId > ArcGraphPart::directedPath(const NodeId n1,
153  const NodeId n2) const {
154  // not recursive version => use a FIFO for simulating the recursion
155  List< NodeId > nodeFIFO;
156  nodeFIFO.pushBack(n2);
157 
158  // mark[node] = successor if visited, else mark[node] does not exist
160  mark.insert(n2, n2);
161 
162  NodeId current;
163 
164  while (!nodeFIFO.empty()) {
165  current = nodeFIFO.front();
166  nodeFIFO.popFront();
167 
168  // check the parents
169 
170  for (const auto new_one : parents(current)) {
171  if (mark.exists(new_one)) // if this node is already marked, do not
172  continue; // check it again
173 
174  mark.insert(new_one, current);
175 
176  if (new_one == n1) {
177  std::vector< NodeId > v;
178 
179  for (current = n1; current != n2; current = mark[current])
180  v.push_back(current);
181 
182  v.push_back(n2);
183 
184  return v;
185  }
186 
187  nodeFIFO.pushBack(new_one);
188  }
189  }
190 
191  GUM_ERROR(NotFound, "no path found");
192  }
193 
194  const std::vector< NodeId >
196  // not recursive version => use a FIFO for simulating the recursion
197  List< NodeId > nodeFIFO;
198  nodeFIFO.pushBack(n2);
199 
200  // mark[node] = successor if visited, else mark[node] does not exist
202  mark.insert(n2, n2);
203 
204  NodeId current;
205 
206  while (!nodeFIFO.empty()) {
207  current = nodeFIFO.front();
208  nodeFIFO.popFront();
209 
210  // check the parents
211  for (const auto new_one : parents(current)) {
212  if (mark.exists(new_one)) // the node has already been visited
213  continue;
214 
215  mark.insert(new_one, current);
216 
217  if (new_one == n1) {
218  std::vector< NodeId > v;
219 
220  for (current = n1; current != n2; current = mark[current])
221  v.push_back(current);
222 
223  v.push_back(n2);
224 
225  return v;
226  }
227 
228  nodeFIFO.pushBack(new_one);
229  }
230 
231  // check the children
232  for (const auto new_one : children(current)) {
233  if (mark.exists(new_one)) // the node has already been visited
234  continue;
235 
236  mark.insert(new_one, current);
237 
238  if (new_one == n1) {
239  std::vector< NodeId > v;
240 
241  for (current = n1; current != n2; current = mark[current])
242  v.push_back(current);
243 
244  v.push_back(n2);
245 
246  return v;
247  }
248 
249  nodeFIFO.pushBack(new_one);
250  }
251  }
252 
253  GUM_ERROR(NotFound, "no path found");
254  }
255 
256  std::ostream& operator<<(std::ostream& stream, const ArcGraphPart& set) {
257  stream << set.toString();
258  return stream;
259  }
260 
261 } /* namespace gum */
bool empty() const noexcept
Returns a boolean indicating whether the chained list is empty.
Definition: list_tpl.h:1967
const std::vector< NodeId > directedUnorientedPath(const NodeId node1, const NodeId node2) const
returns an unoriented (directed) path from node1 to node2 in the arc set
const std::string toString() const
to friendly display the content of the ArcGraphPart
ArcGraphPart & operator=(const ArcGraphPart &s)
copy operator
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
void clearArcs()
removes all the arcs from the ArcGraphPart
Classes for directed edge sets.
Definition: arcGraphPart.h:76
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
Generic doubly linked lists.
Definition: list.h:369
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
void popFront()
Removes the first element of a List, if any.
Definition: list_tpl.h:1961
The class for generic Hash Tables.
Definition: hashTable.h:676
Representation of a setA Set is a structure that contains arbitrary elements.
Definition: set.h:162
Inline implementation of classes for directed edge sets.
std::ostream & operator<<(std::ostream &output, const BayesNet< GUM_SCALAR > &bn)
Prints map&#39;s DAG in output using the Graphviz-dot format.
Definition: BayesNet_tpl.h:583
#define GUM_EMIT2(signal, arg1, arg2)
Definition: signaler2.h:40
const NodeSet & parents(const NodeId id) const
returns the set of nodes with arc ingoing to a given node
Val & pushBack(const Val &val)
Inserts a new element (a copy) at the end of the chained list.
Definition: list_tpl.h:1589
const std::vector< NodeId > directedPath(const NodeId node1, const NodeId node2) const
returns a directed path from node1 to node2 belonging to the set of arcs
NodeProperty< NodeSet *> __parents
for each arc, the sets of its parents
Definition: arcGraphPart.h:269
Size capacity() const noexcept
Returns the number of slots in the &#39;nodes&#39; vector of the hashtable.
Val & front() const
Returns a reference to first element of a list, if any.
Definition: list_tpl.h:1828
const NodeSet & children(const NodeId id) const
returns the set of nodes with arc outgoing from a given node
Signaler2< NodeId, NodeId > onArcAdded
Definition: arcGraphPart.h:80
virtual ~ArcGraphPart()
destructor
NodeProperty< NodeSet *> __children
for each arc, the set of its children
Definition: arcGraphPart.h:272
Signaler2< NodeId, NodeId > onArcDeleted
Definition: arcGraphPart.h:81
void clear()
Removes all the elements, if any, from the set.
Definition: set_tpl.h:372
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:45
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
Set< Arc > __arcs
the set of all the arcs contained within the ArcGraphPart
Definition: arcGraphPart.h:266
ArcGraphPart(Size arcs_size=HashTableConst::default_size, bool arcs_resize_policy=true)
default constructor
Size NodeId
Type for node ids.
Definition: graphElements.h:97
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52
some utils for topology : NodeId, Edge, Arc and consorts ...