aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
arcGraphPart.cpp
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /** @file
23  * @brief Source implementation of classes for directed edge sets
24  *
25  * @author Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
26  *
27  */
28 #include <agrum/tools/graphs/parts/arcGraphPart.h>
29 
30 #ifdef GUM_NO_INLINE
31 # include <agrum/tools/graphs/parts/arcGraphPart_inl.h>
32 #endif // GUM_NOINLINE
33 #include "agrum/tools/graphs/graphElements.h"
34 
35 namespace gum {
36 
37  ///////////////////// ArcGraphPart
41  }
42 
45 
46  // copy the sets of parents
47  const NodeProperty< NodeSet* >& pars = s._parents_;
49 
50  for (const auto& elt: pars) {
51  NodeSet* newpar = new NodeSet(*elt.second);
53  }
54 
55  // copy the sets of children
58 
59  for (const auto& elt: children) {
62  }
63 
64  // send signals to indicate that there are new arcs
65  if (onArcAdded.hasListener()) {
66  for (const auto& arc: _arcs_) {
68  }
69  }
70  }
71 
74  // be sure to deallocate all the parents and children sets
75  clearArcs();
76  }
77 
79  for (const auto& elt: _parents_)
80  delete elt.second;
81 
82  _parents_.clear();
83 
84  for (const auto& elt: _children_)
85  delete elt.second;
86 
87  _children_.clear();
88 
89  // we need this copy only if at least one onArcDeleted listener exists
90  if (onArcDeleted.hasListener()) {
91  ArcSet tmp = _arcs_;
92  _arcs_.clear();
93 
94  for (const auto& arc: tmp)
96  } else {
97  _arcs_.clear();
98  }
99  }
100 
102  // avoid self assignment
103  if (this != &s) {
104  // copy the arcs
105  clearArcs();
106  _arcs_ = s._arcs_;
107 
108  // copy the sets of parents
110 
111  for (const auto& elt: s._parents_) {
112  NodeSet* newpar = new NodeSet(*elt.second);
114  }
115 
116  // copy the sets of children
118 
119  for (const auto& elt: s._children_) {
122  }
123 
124  if (onArcAdded.hasListener()) {
125  for (const auto& arc: _arcs_) {
127  }
128  }
129  }
130 
131  return *this;
132  }
133 
135  std::stringstream s;
136  bool first = true;
137  s << "{";
138 
139  for (const auto& arc: _arcs_) {
140  if (first) {
141  first = false;
142  } else {
143  s << ",";
144  }
145 
146  s << arc;
147  }
148 
149  s << "}";
150 
151  return s.str();
152  }
153 
155  NodeSet res;
156  NodeSet tmp;
157  for (auto next: children(id))
158  tmp.insert(next);
159 
160  while (!tmp.empty()) {
161  auto current = *(tmp.begin());
162  tmp.erase(current);
163  res.insert(current);
164  for (auto next: children(current)) {
165  if (!tmp.contains(next) && !res.contains(next)) { tmp.insert(next); }
166  }
167  }
168  return res;
169  }
170 
171 
173  NodeSet res;
174  NodeSet tmp;
175  for (auto next: parents(id))
176  tmp.insert(next);
177 
178  while (!tmp.empty()) {
179  auto current = *(tmp.begin());
180  tmp.erase(current);
181  res.insert(current);
182  for (auto next: parents(current)) {
183  if (!tmp.contains(next) && !res.contains(next)) { tmp.insert(next); }
184  }
185  }
186  return res;
187  }
188 
189 
191  // not recursive version => use a FIFO for simulating the recursion
192  List< NodeId > nodeFIFO;
194 
195  // mark[node] = successor if visited, else mark[node] does not exist
197  mark.insert(n2, n2);
198 
199  NodeId current;
200 
201  while (!nodeFIFO.empty()) {
202  current = nodeFIFO.front();
203  nodeFIFO.popFront();
204 
205  // check the parents
206 
207  for (const auto new_one: parents(current)) {
208  if (mark.exists(new_one)) // if this node is already marked, do not
209  continue; // check it again
210 
212 
213  if (new_one == n1) {
214  std::vector< NodeId > v;
215 
216  for (current = n1; current != n2; current = mark[current])
218 
219  v.push_back(n2);
220 
221  return v;
222  }
223 
225  }
226  }
227 
228  GUM_ERROR(NotFound, "no path found")
229  }
230 
232  // not recursive version => use a FIFO for simulating the recursion
233  List< NodeId > nodeFIFO;
235 
236  // mark[node] = successor if visited, else mark[node] does not exist
238  mark.insert(n2, n2);
239 
240  NodeId current;
241 
242  while (!nodeFIFO.empty()) {
243  current = nodeFIFO.front();
244  nodeFIFO.popFront();
245 
246  // check the parents
247  for (const auto new_one: parents(current)) {
248  if (mark.exists(new_one)) // the node has already been visited
249  continue;
250 
252 
253  if (new_one == n1) {
254  std::vector< NodeId > v;
255 
256  for (current = n1; current != n2; current = mark[current])
258 
259  v.push_back(n2);
260 
261  return v;
262  }
263 
265  }
266 
267  // check the children
268  for (const auto new_one: children(current)) {
269  if (mark.exists(new_one)) // the node has already been visited
270  continue;
271 
273 
274  if (new_one == n1) {
275  std::vector< NodeId > v;
276 
277  for (current = n1; current != n2; current = mark[current])
279 
280  v.push_back(n2);
281 
282  return v;
283  }
284 
286  }
287  }
288 
289  GUM_ERROR(NotFound, "no path found")
290  }
291 
293  stream << set.toString();
294  return stream;
295  }
296 
297 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
std::ostream & operator<<(std::ostream &aStream, const Instantiation &i)
Print information of the instantiation in the stream.