aGrUM  0.16.0
DAGCycleDetector_inl.h
Go to the documentation of this file.
1 
30 namespace gum {
31 
32  /* ===========================================================================
33  */
34  // CHANGES
35  /* ===========================================================================
36  */
37 
38  // default constructor
40  NodeId tail,
41  NodeId head) noexcept :
42  __type{type},
43  __tail{tail}, __head{head} {
44  GUM_CONSTRUCTOR(DAGCycleDetector::Change);
45  }
46 
47  // copy constructor
48  INLINE
50  __type{from.__type}, __tail{from.__tail}, __head{from.__head} {
51  GUM_CONS_CPY(DAGCycleDetector::Change);
52  }
53 
54  // move constructor
55  INLINE
57  __type{from.__type}, __tail{from.__tail}, __head{from.__head} {
58  GUM_CONS_MOV(DAGCycleDetector::Change);
59  }
60 
61  // destructor
63  GUM_DESTRUCTOR(DAGCycleDetector::Change);
64  }
65 
66  // copy operator
68  operator=(const DAGCycleDetector::Change& from) noexcept {
69  __type = from.__type;
70  __tail = from.__tail;
71  __head = from.__head;
72  return *this;
73  }
74 
75  // move operator
78  __type = from.__type;
79  __tail = from.__tail;
80  __head = from.__head;
81  return *this;
82  }
83 
86  noexcept {
87  return __type;
88  }
89 
91  INLINE NodeId DAGCycleDetector::Change::tail() const noexcept { return __tail; }
92 
94  INLINE NodeId DAGCycleDetector::Change::head() const noexcept { return __head; }
95 
96  /* ===========================================================================
97  */
98  // ArcAdd
99  /* ===========================================================================
100  */
101 
106  GUM_CONSTRUCTOR(DAGCycleDetector::ArcAdd);
107  }
108 
110  INLINE
112  DAGCycleDetector::Change(from.type(), from.tail(), from.head()) {
113  GUM_CONS_CPY(DAGCycleDetector::ArcAdd);
114  }
115 
117  INLINE
120  std::move(from.type()), std::move(from.tail()), std::move(from.head())) {
121  GUM_CONS_MOV(DAGCycleDetector::ArcAdd);
122  }
123 
126  GUM_DESTRUCTOR(DAGCycleDetector::ArcAdd);
127  }
128 
131  operator=(const DAGCycleDetector::ArcAdd& from) noexcept {
133  return *this;
134  }
135 
139  DAGCycleDetector::Change::operator=(std::move(from));
140  return *this;
141  }
142 
143  /* ===========================================================================
144  */
145  // ArcDel
146  /* ===========================================================================
147  */
148 
153  GUM_CONSTRUCTOR(DAGCycleDetector::ArcDel);
154  }
155 
157  INLINE
159  DAGCycleDetector::Change(from.type(), from.tail(), from.head()) {
160  GUM_CONS_CPY(DAGCycleDetector::ArcDel);
161  }
162 
164  INLINE
167  std::move(from.type()), std::move(from.tail()), std::move(from.head())) {
168  GUM_CONS_MOV(DAGCycleDetector::ArcDel);
169  }
170 
173  GUM_DESTRUCTOR(DAGCycleDetector::ArcDel);
174  }
175 
178  operator=(const DAGCycleDetector::ArcDel& from) noexcept {
180  return *this;
181  }
182 
186  DAGCycleDetector::Change::operator=(std::move(from));
187  return *this;
188  }
189 
190  /* ===========================================================================
191  */
192  // ArcReverse
193  /* ===========================================================================
194  */
195 
198  NodeId head) noexcept :
201  GUM_CONSTRUCTOR(DAGCycleDetector::ArcReverse);
202  }
203 
206  const DAGCycleDetector::ArcReverse& from) noexcept :
207  DAGCycleDetector::Change(from.type(), from.tail(), from.head()) {
208  GUM_CONS_CPY(DAGCycleDetector::ArcReverse);
209  }
210 
213  DAGCycleDetector::ArcReverse&& from) noexcept :
215  std::move(from.type()), std::move(from.tail()), std::move(from.head())) {
216  GUM_CONS_MOV(DAGCycleDetector::ArcReverse);
217  }
218 
221  GUM_DESTRUCTOR(DAGCycleDetector::ArcReverse);
222  }
223 
228  return *this;
229  }
230 
234  DAGCycleDetector::Change::operator=(std::move(from));
235  return *this;
236  }
237 
238  /* ===========================================================================
239  */
240  // DAGCycleDetector
241  /* ===========================================================================
242  */
243 
246  GUM_CONSTRUCTOR(DAGCycleDetector);
247  }
248 
251  __dag(from.__dag), __ancestors(from.__ancestors),
253  GUM_CONS_CPY(DAGCycleDetector);
254  }
255 
258  __dag(std::move(from.__dag)), __ancestors(std::move(from.__ancestors)),
259  __descendants(std::move(from.__descendants)) {
260  GUM_CONS_MOV(DAGCycleDetector);
261  }
262 
265  GUM_DESTRUCTOR(DAGCycleDetector);
266  }
267 
271  if (this != &from) {
272  __dag = from.__dag;
273  __ancestors = from.__ancestors;
275  }
276 
277  return *this;
278  }
279 
282  if (this != &from) {
283  __dag = std::move(from.__dag);
284  __ancestors = std::move(from.__ancestors);
285  __descendants = std::move(from.__descendants);
286  }
287 
288  return *this;
289  }
290 
293  noexcept {
294  return __descendants[y].exists(x);
295  }
296 
299  noexcept {
300  return (__ancestors[y][x] > 1);
301  }
302 
305  noexcept {
306  return false;
307  }
308 
310  INLINE
312  const NodeProperty< Size >& set_to_add,
313  Size multiplier) const {
314  for (auto iter = set_to_add.cbegin(); iter != set_to_add.cend(); ++iter) {
315  if (nodeset.exists(iter.key())) {
316  nodeset[iter.key()] += iter.val() * multiplier;
317  } else {
318  nodeset.insert(iter.key(), iter.val() * multiplier);
319  }
320  }
321  }
322 
324  INLINE
326  const NodeProperty< Size >& set_to_del,
327  Size multiplier) const {
328  for (auto iter = set_to_del.cbegin(); iter != set_to_del.cend(); ++iter) {
329  if (nodeset.exists(iter.key())) {
330  Size& weight = nodeset[iter.key()];
331  weight -= iter.val() * multiplier;
332 
333  if (!weight) { nodeset.erase(iter.key()); }
334  }
335  }
336  }
337 
340  INLINE
342  NodeProperty< Size >& result_set,
343  const NodeProperty< Size >& set_to_restrict,
344  const NodeSet& extremities) const {
345  for (auto iter = set_to_restrict.cbegin(); iter != set_to_restrict.cend();
346  ++iter) {
347  if (extremities.exists(iter.key())) {
348  result_set.insert(iter.key(), iter.val());
349  }
350  }
351  }
352 
354  INLINE void DAGCycleDetector::reverseArc(NodeId tail, NodeId head) {
355  if (hasCycleFromReversal(tail, head)) {
357  "the arc would create a directed into a DAG");
358  }
359 
360  eraseArc(tail, head);
361  addArc(head, tail);
362  }
363 
365  INLINE bool DAGCycleDetector::operator==(const DAGCycleDetector& from) const {
366  return ( //( __dagmodel == from.__dagmodel ) &&
367  (__ancestors == from.__ancestors) && (__descendants == from.__descendants));
368  }
369 
371  INLINE bool DAGCycleDetector::operator!=(const DAGCycleDetector& from) const {
372  return !operator==(from);
373  }
374 
375 } /* namespace gum */
A class for detecting directed cycles in DAGs when trying to apply many changes to the graph...
DiGraph __dag
the initial dag from which modifications are applied
the base class indicating the possible changes
NodeId tail() const noexcept
indicates the tail of the arc involved in the modification
ArcAdd & operator=(const ArcAdd &from) noexcept
copy operator
void erase(const Key &key)
Removes a given element from the hash table.
void eraseArc(NodeId x, NodeId y)
removes an arc from the current DAG
void __addWeightedSet(NodeProperty< Size > &nodeset, const NodeProperty< Size > &set_to_add, Size multiplier) const
adds a weighted nodeset to another (weights are added)
ArcDel(NodeId tail, NodeId head) noexcept
default constructor
STL namespace.
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
void addArc(NodeId x, NodeId y)
adds a new arc to the current DAG
void __delWeightedSet(NodeProperty< Size > &nodeset, const NodeProperty< Size > &set_to_del, Size multiplier) const
removes a weighted nodeset from another (weights are subtracted)
ChangeType type() const noexcept
returns the type of the operation
void __restrictWeightedSet(NodeProperty< Size > &result_set, const NodeProperty< Size > &set_to_restrict, const NodeSet &extrmities) const
put into a weighted nodeset the nodes of another weighted set that belong to a set of arc extremities...
ArcReverse(NodeId tail, NodeId head) noexcept
default constructor
ChangeType __type
the type of modification
the class to indicate that we wish to reverse an arc
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
Change & operator=(const Change &from) noexcept
The class for generic Hash Tables.
Definition: hashTable.h:679
DAGCycleDetector & operator=(const DAGCycleDetector &from)
copy operator
bool exists(const Key &k) const
Indicates whether a given elements belong to the set.
Definition: set_tpl.h:607
NodeId head() const noexcept
indicates the head of the arc involved in the modification
const const_iterator & cend() const noexcept
Returns the unsafe const_iterator pointing to the end of the hashtable.
the class to indicate that we wish to add a new arc
Change(ChangeType type, NodeId tail, NodeId head) noexcept
const_iterator cbegin() const
Returns an unsafe const_iterator pointing to the beginning of the hashtable.
ArcReverse & operator=(const ArcReverse &from) noexcept
copy operator
NodeId __head
the head of the arc to be modified
bool operator!=(const DAGCycleDetector &from) const
check the inequality between two DAGCycleDetectors
bool hasCycleFromAddition(NodeId x, NodeId y) const noexcept
indicates whether an arc addition would create a cycle
NodeId __tail
the tail of the arc to be modified
NodeProperty< NodeProperty< Size > > __descendants
the set of descendants of each node in the dag
NodeProperty< NodeProperty< Size > > __ancestors
the set of ancestors of each node in the dag
bool hasCycleFromReversal(NodeId x, NodeId y) const noexcept
indicates wether an arc reversal would create a cycle
bool hasCycleFromDeletion(NodeId x, NodeId y) const noexcept
indicates whether an arc deletion would create a cycle
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:48
ArcDel & operator=(const ArcDel &from) noexcept
copy operator
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
DAGCycleDetector() noexcept
default constructor
the class to indicate that we wish to remove an arc
bool operator==(const DAGCycleDetector &from) const
check the equality between two DAGCycleDetectors
Size NodeId
Type for node ids.
Definition: graphElements.h:98
ArcAdd(NodeId tail, NodeId head) noexcept
default constructor
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55
void reverseArc(NodeId x, NodeId y)
reverses an arc from the DAG