90 |
90 |
91 |
91 |
92 |
92 |
93 ListDigraphBase() |
93 ListDigraphBase() |
94 : nodes(), first_node(-1), |
94 : nodes(), first_node(-1), |
95 first_free_node(-1), arcs(), first_free_arc(-1) {} |
95 first_free_node(-1), arcs(), first_free_arc(-1) {} |
96 |
96 |
97 |
97 |
98 int maxNodeId() const { return nodes.size()-1; } |
98 int maxNodeId() const { return nodes.size()-1; } |
99 int maxArcId() const { return arcs.size()-1; } |
99 int maxArcId() const { return arcs.size()-1; } |
100 |
100 |
101 Node source(Arc e) const { return Node(arcs[e.id].source); } |
101 Node source(Arc e) const { return Node(arcs[e.id].source); } |
102 Node target(Arc e) const { return Node(arcs[e.id].target); } |
102 Node target(Arc e) const { return Node(arcs[e.id].target); } |
103 |
103 |
104 |
104 |
105 void first(Node& node) const { |
105 void first(Node& node) const { |
106 node.id = first_node; |
106 node.id = first_node; |
107 } |
107 } |
108 |
108 |
109 void next(Node& node) const { |
109 void next(Node& node) const { |
110 node.id = nodes[node.id].next; |
110 node.id = nodes[node.id].next; |
111 } |
111 } |
112 |
112 |
113 |
113 |
114 void first(Arc& arc) const { |
114 void first(Arc& arc) const { |
115 int n; |
115 int n; |
116 for(n = first_node; |
116 for(n = first_node; |
117 n!=-1 && nodes[n].first_in == -1; |
117 n!=-1 && nodes[n].first_in == -1; |
118 n = nodes[n].next) {} |
118 n = nodes[n].next) {} |
119 arc.id = (n == -1) ? -1 : nodes[n].first_in; |
119 arc.id = (n == -1) ? -1 : nodes[n].first_in; |
120 } |
120 } |
121 |
121 |
122 void next(Arc& arc) const { |
122 void next(Arc& arc) const { |
123 if (arcs[arc.id].next_in != -1) { |
123 if (arcs[arc.id].next_in != -1) { |
124 arc.id = arcs[arc.id].next_in; |
124 arc.id = arcs[arc.id].next_in; |
125 } else { |
125 } else { |
126 int n; |
126 int n; |
127 for(n = nodes[arcs[arc.id].target].next; |
127 for(n = nodes[arcs[arc.id].target].next; |
128 n!=-1 && nodes[n].first_in == -1; |
128 n!=-1 && nodes[n].first_in == -1; |
129 n = nodes[n].next) {} |
129 n = nodes[n].next) {} |
130 arc.id = (n == -1) ? -1 : nodes[n].first_in; |
130 arc.id = (n == -1) ? -1 : nodes[n].first_in; |
131 } |
131 } |
132 } |
132 } |
133 |
133 |
134 void firstOut(Arc &e, const Node& v) const { |
134 void firstOut(Arc &e, const Node& v) const { |
135 e.id = nodes[v.id].first_out; |
135 e.id = nodes[v.id].first_out; |
136 } |
136 } |
143 } |
143 } |
144 void nextIn(Arc &e) const { |
144 void nextIn(Arc &e) const { |
145 e.id=arcs[e.id].next_in; |
145 e.id=arcs[e.id].next_in; |
146 } |
146 } |
147 |
147 |
148 |
148 |
149 static int id(Node v) { return v.id; } |
149 static int id(Node v) { return v.id; } |
150 static int id(Arc e) { return e.id; } |
150 static int id(Arc e) { return e.id; } |
151 |
151 |
152 static Node nodeFromId(int id) { return Node(id);} |
152 static Node nodeFromId(int id) { return Node(id);} |
153 static Arc arcFromId(int id) { return Arc(id);} |
153 static Arc arcFromId(int id) { return Arc(id);} |
154 |
154 |
155 bool valid(Node n) const { |
155 bool valid(Node n) const { |
156 return n.id >= 0 && n.id < static_cast<int>(nodes.size()) && |
156 return n.id >= 0 && n.id < static_cast<int>(nodes.size()) && |
157 nodes[n.id].prev != -2; |
157 nodes[n.id].prev != -2; |
158 } |
158 } |
159 |
159 |
160 bool valid(Arc a) const { |
160 bool valid(Arc a) const { |
161 return a.id >= 0 && a.id < static_cast<int>(arcs.size()) && |
161 return a.id >= 0 && a.id < static_cast<int>(arcs.size()) && |
162 arcs[a.id].prev_in != -2; |
162 arcs[a.id].prev_in != -2; |
163 } |
163 } |
164 |
164 |
165 Node addNode() { |
165 Node addNode() { |
166 int n; |
166 int n; |
167 |
167 |
168 if(first_free_node==-1) { |
168 if(first_free_node==-1) { |
169 n = nodes.size(); |
169 n = nodes.size(); |
170 nodes.push_back(NodeT()); |
170 nodes.push_back(NodeT()); |
171 } else { |
171 } else { |
172 n = first_free_node; |
172 n = first_free_node; |
173 first_free_node = nodes[n].next; |
173 first_free_node = nodes[n].next; |
174 } |
174 } |
175 |
175 |
176 nodes[n].next = first_node; |
176 nodes[n].next = first_node; |
177 if(first_node != -1) nodes[first_node].prev = n; |
177 if(first_node != -1) nodes[first_node].prev = n; |
178 first_node = n; |
178 first_node = n; |
179 nodes[n].prev = -1; |
179 nodes[n].prev = -1; |
180 |
180 |
181 nodes[n].first_in = nodes[n].first_out = -1; |
181 nodes[n].first_in = nodes[n].first_out = -1; |
182 |
182 |
183 return Node(n); |
183 return Node(n); |
184 } |
184 } |
185 |
185 |
186 Arc addArc(Node u, Node v) { |
186 Arc addArc(Node u, Node v) { |
187 int n; |
187 int n; |
188 |
188 |
189 if (first_free_arc == -1) { |
189 if (first_free_arc == -1) { |
190 n = arcs.size(); |
190 n = arcs.size(); |
191 arcs.push_back(ArcT()); |
191 arcs.push_back(ArcT()); |
192 } else { |
192 } else { |
193 n = first_free_arc; |
193 n = first_free_arc; |
194 first_free_arc = arcs[n].next_in; |
194 first_free_arc = arcs[n].next_in; |
195 } |
195 } |
196 |
196 |
197 arcs[n].source = u.id; |
197 arcs[n].source = u.id; |
198 arcs[n].target = v.id; |
198 arcs[n].target = v.id; |
199 |
199 |
200 arcs[n].next_out = nodes[u.id].first_out; |
200 arcs[n].next_out = nodes[u.id].first_out; |
201 if(nodes[u.id].first_out != -1) { |
201 if(nodes[u.id].first_out != -1) { |
202 arcs[nodes[u.id].first_out].prev_out = n; |
202 arcs[nodes[u.id].first_out].prev_out = n; |
203 } |
203 } |
204 |
204 |
205 arcs[n].next_in = nodes[v.id].first_in; |
205 arcs[n].next_in = nodes[v.id].first_in; |
206 if(nodes[v.id].first_in != -1) { |
206 if(nodes[v.id].first_in != -1) { |
207 arcs[nodes[v.id].first_in].prev_in = n; |
207 arcs[nodes[v.id].first_in].prev_in = n; |
208 } |
208 } |
209 |
209 |
210 arcs[n].prev_in = arcs[n].prev_out = -1; |
210 arcs[n].prev_in = arcs[n].prev_out = -1; |
211 |
211 |
212 nodes[u.id].first_out = nodes[v.id].first_in = n; |
212 nodes[u.id].first_out = nodes[v.id].first_in = n; |
213 |
213 |
214 return Arc(n); |
214 return Arc(n); |
215 } |
215 } |
216 |
216 |
217 void erase(const Node& node) { |
217 void erase(const Node& node) { |
218 int n = node.id; |
218 int n = node.id; |
219 |
219 |
220 if(nodes[n].next != -1) { |
220 if(nodes[n].next != -1) { |
221 nodes[nodes[n].next].prev = nodes[n].prev; |
221 nodes[nodes[n].next].prev = nodes[n].prev; |
222 } |
222 } |
223 |
223 |
224 if(nodes[n].prev != -1) { |
224 if(nodes[n].prev != -1) { |
225 nodes[nodes[n].prev].next = nodes[n].next; |
225 nodes[nodes[n].prev].next = nodes[n].next; |
226 } else { |
226 } else { |
227 first_node = nodes[n].next; |
227 first_node = nodes[n].next; |
228 } |
228 } |
229 |
229 |
230 nodes[n].next = first_free_node; |
230 nodes[n].next = first_free_node; |
231 first_free_node = n; |
231 first_free_node = n; |
232 nodes[n].prev = -2; |
232 nodes[n].prev = -2; |
233 |
233 |
234 } |
234 } |
235 |
235 |
236 void erase(const Arc& arc) { |
236 void erase(const Arc& arc) { |
237 int n = arc.id; |
237 int n = arc.id; |
238 |
238 |
239 if(arcs[n].next_in!=-1) { |
239 if(arcs[n].next_in!=-1) { |
240 arcs[arcs[n].next_in].prev_in = arcs[n].prev_in; |
240 arcs[arcs[n].next_in].prev_in = arcs[n].prev_in; |
241 } |
241 } |
242 |
242 |
243 if(arcs[n].prev_in!=-1) { |
243 if(arcs[n].prev_in!=-1) { |
244 arcs[arcs[n].prev_in].next_in = arcs[n].next_in; |
244 arcs[arcs[n].prev_in].next_in = arcs[n].next_in; |
245 } else { |
245 } else { |
246 nodes[arcs[n].target].first_in = arcs[n].next_in; |
246 nodes[arcs[n].target].first_in = arcs[n].next_in; |
247 } |
247 } |
248 |
248 |
249 |
249 |
250 if(arcs[n].next_out!=-1) { |
250 if(arcs[n].next_out!=-1) { |
251 arcs[arcs[n].next_out].prev_out = arcs[n].prev_out; |
251 arcs[arcs[n].next_out].prev_out = arcs[n].prev_out; |
252 } |
252 } |
253 |
253 |
254 if(arcs[n].prev_out!=-1) { |
254 if(arcs[n].prev_out!=-1) { |
255 arcs[arcs[n].prev_out].next_out = arcs[n].next_out; |
255 arcs[arcs[n].prev_out].next_out = arcs[n].next_out; |
256 } else { |
256 } else { |
257 nodes[arcs[n].source].first_out = arcs[n].next_out; |
257 nodes[arcs[n].source].first_out = arcs[n].next_out; |
258 } |
258 } |
259 |
259 |
260 arcs[n].next_in = first_free_arc; |
260 arcs[n].next_in = first_free_arc; |
261 first_free_arc = n; |
261 first_free_arc = n; |
262 arcs[n].prev_in = -2; |
262 arcs[n].prev_in = -2; |
263 } |
263 } |
264 |
264 |
267 nodes.clear(); |
267 nodes.clear(); |
268 first_node = first_free_node = first_free_arc = -1; |
268 first_node = first_free_node = first_free_arc = -1; |
269 } |
269 } |
270 |
270 |
271 protected: |
271 protected: |
272 void changeTarget(Arc e, Node n) |
272 void changeTarget(Arc e, Node n) |
273 { |
273 { |
274 if(arcs[e.id].next_in != -1) |
274 if(arcs[e.id].next_in != -1) |
275 arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in; |
275 arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in; |
276 if(arcs[e.id].prev_in != -1) |
276 if(arcs[e.id].prev_in != -1) |
277 arcs[arcs[e.id].prev_in].next_in = arcs[e.id].next_in; |
277 arcs[arcs[e.id].prev_in].next_in = arcs[e.id].next_in; |
278 else nodes[arcs[e.id].target].first_in = arcs[e.id].next_in; |
278 else nodes[arcs[e.id].target].first_in = arcs[e.id].next_in; |
279 if (nodes[n.id].first_in != -1) { |
279 if (nodes[n.id].first_in != -1) { |
280 arcs[nodes[n.id].first_in].prev_in = e.id; |
280 arcs[nodes[n.id].first_in].prev_in = e.id; |
281 } |
281 } |
282 arcs[e.id].target = n.id; |
282 arcs[e.id].target = n.id; |
283 arcs[e.id].prev_in = -1; |
283 arcs[e.id].prev_in = -1; |
284 arcs[e.id].next_in = nodes[n.id].first_in; |
284 arcs[e.id].next_in = nodes[n.id].first_in; |
285 nodes[n.id].first_in = e.id; |
285 nodes[n.id].first_in = e.id; |
286 } |
286 } |
287 void changeSource(Arc e, Node n) |
287 void changeSource(Arc e, Node n) |
288 { |
288 { |
289 if(arcs[e.id].next_out != -1) |
289 if(arcs[e.id].next_out != -1) |
290 arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out; |
290 arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out; |
291 if(arcs[e.id].prev_out != -1) |
291 if(arcs[e.id].prev_out != -1) |
292 arcs[arcs[e.id].prev_out].next_out = arcs[e.id].next_out; |
292 arcs[arcs[e.id].prev_out].next_out = arcs[e.id].next_out; |
293 else nodes[arcs[e.id].source].first_out = arcs[e.id].next_out; |
293 else nodes[arcs[e.id].source].first_out = arcs[e.id].next_out; |
294 if (nodes[n.id].first_out != -1) { |
294 if (nodes[n.id].first_out != -1) { |
295 arcs[nodes[n.id].first_out].prev_out = e.id; |
295 arcs[nodes[n.id].first_out].prev_out = e.id; |
296 } |
296 } |
297 arcs[e.id].source = n.id; |
297 arcs[e.id].source = n.id; |
298 arcs[e.id].prev_out = -1; |
298 arcs[e.id].prev_out = -1; |
299 arcs[e.id].next_out = nodes[n.id].first_out; |
299 arcs[e.id].next_out = nodes[n.id].first_out; |
300 nodes[n.id].first_out = e.id; |
300 nodes[n.id].first_out = e.id; |
339 public: |
339 public: |
340 |
340 |
341 typedef ExtendedListDigraphBase Parent; |
341 typedef ExtendedListDigraphBase Parent; |
342 |
342 |
343 /// Constructor |
343 /// Constructor |
344 |
344 |
345 /// Constructor. |
345 /// Constructor. |
346 /// |
346 /// |
347 ListDigraph() {} |
347 ListDigraph() {} |
348 |
348 |
349 ///Add a new node to the digraph. |
349 ///Add a new node to the digraph. |
350 |
350 |
351 ///Add a new node to the digraph. |
351 ///Add a new node to the digraph. |
352 ///\return the new node. |
352 ///\return the new node. |
353 Node addNode() { return Parent::addNode(); } |
353 Node addNode() { return Parent::addNode(); } |
354 |
354 |
355 ///Add a new arc to the digraph. |
355 ///Add a new arc to the digraph. |
356 |
356 |
357 ///Add a new arc to the digraph with source node \c s |
357 ///Add a new arc to the digraph with source node \c s |
358 ///and target node \c t. |
358 ///and target node \c t. |
359 ///\return the new arc. |
359 ///\return the new arc. |
360 Arc addArc(const Node& s, const Node& t) { |
360 Arc addArc(const Node& s, const Node& t) { |
361 return Parent::addArc(s, t); |
361 return Parent::addArc(s, t); |
362 } |
362 } |
363 |
363 |
364 /// Node validity check |
364 /// Node validity check |
365 |
365 |
366 /// This function gives back true if the given node is valid, |
366 /// This function gives back true if the given node is valid, |
367 /// ie. it is a real node of the graph. |
367 /// ie. it is a real node of the graph. |
368 /// |
368 /// |
369 /// \warning A Node pointing to a removed item |
369 /// \warning A Node pointing to a removed item |
370 /// could become valid again later if new nodes are |
370 /// could become valid again later if new nodes are |
371 /// added to the graph. |
371 /// added to the graph. |
372 bool valid(Node n) const { return Parent::valid(n); } |
372 bool valid(Node n) const { return Parent::valid(n); } |
373 |
373 |
374 /// Arc validity check |
374 /// Arc validity check |
375 |
375 |
376 /// This function gives back true if the given arc is valid, |
376 /// This function gives back true if the given arc is valid, |
377 /// ie. it is a real arc of the graph. |
377 /// ie. it is a real arc of the graph. |
378 /// |
378 /// |
379 /// \warning An Arc pointing to a removed item |
379 /// \warning An Arc pointing to a removed item |
380 /// could become valid again later if new nodes are |
380 /// could become valid again later if new nodes are |
381 /// added to the graph. |
381 /// added to the graph. |
382 bool valid(Arc a) const { return Parent::valid(a); } |
382 bool valid(Arc a) const { return Parent::valid(a); } |
454 ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s |
454 ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s |
455 ///may be invalidated. |
455 ///may be invalidated. |
456 /// |
456 /// |
457 ///\warning This functionality cannot be used together with the Snapshot |
457 ///\warning This functionality cannot be used together with the Snapshot |
458 ///feature. |
458 ///feature. |
459 void contract(Node a, Node b, bool r = true) |
459 void contract(Node a, Node b, bool r = true) |
460 { |
460 { |
461 for(OutArcIt e(*this,b);e!=INVALID;) { |
461 for(OutArcIt e(*this,b);e!=INVALID;) { |
462 OutArcIt f=e; |
462 OutArcIt f=e; |
463 ++f; |
463 ++f; |
464 if(r && target(e)==a) erase(e); |
464 if(r && target(e)==a) erase(e); |
465 else changeSource(e,a); |
465 else changeSource(e,a); |
466 e=f; |
466 e=f; |
467 } |
467 } |
468 for(InArcIt e(*this,b);e!=INVALID;) { |
468 for(InArcIt e(*this,b);e!=INVALID;) { |
469 InArcIt f=e; |
469 InArcIt f=e; |
470 ++f; |
470 ++f; |
471 if(r && source(e)==a) erase(e); |
471 if(r && source(e)==a) erase(e); |
472 else changeTarget(e,a); |
472 else changeTarget(e,a); |
473 e=f; |
473 e=f; |
474 } |
474 } |
475 erase(b); |
475 erase(b); |
476 } |
476 } |
477 |
477 |
478 ///Split a node. |
478 ///Split a node. |
483 ///from \c n to the newly created node is also added. |
483 ///from \c n to the newly created node is also added. |
484 ///\return The newly created node. |
484 ///\return The newly created node. |
485 /// |
485 /// |
486 ///\note The <tt>ArcIt</tt>s referencing a moved arc remain |
486 ///\note The <tt>ArcIt</tt>s referencing a moved arc remain |
487 ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may |
487 ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may |
488 ///be invalidated. |
488 ///be invalidated. |
489 /// |
489 /// |
490 ///\warning This functionality cannot be used together with the |
490 ///\warning This functionality cannot be used together with the |
491 ///Snapshot feature. |
491 ///Snapshot feature. |
492 /// |
492 /// |
493 ///\todo It could be implemented in a bit faster way. |
493 ///\todo It could be implemented in a bit faster way. |
494 Node split(Node n, bool connect = true) { |
494 Node split(Node n, bool connect = true) { |
495 Node b = addNode(); |
495 Node b = addNode(); |
496 for(OutArcIt e(*this,n);e!=INVALID;) { |
496 for(OutArcIt e(*this,n);e!=INVALID;) { |
497 OutArcIt f=e; |
497 OutArcIt f=e; |
498 ++f; |
498 ++f; |
499 changeSource(e,b); |
499 changeSource(e,b); |
500 e=f; |
500 e=f; |
501 } |
501 } |
502 if (connect) addArc(n,b); |
502 if (connect) addArc(n,b); |
503 return b; |
503 return b; |
504 } |
504 } |
505 |
505 |
506 ///Split an arc. |
506 ///Split an arc. |
507 |
507 |
508 ///This function splits an arc. First a new node \c b is added to |
508 ///This function splits an arc. First a new node \c b is added to |
509 ///the digraph, then the original arc is re-targeted to \c |
509 ///the digraph, then the original arc is re-targeted to \c |
510 ///b. Finally an arc from \c b to the original target is added. |
510 ///b. Finally an arc from \c b to the original target is added. |
615 } |
615 } |
616 } |
616 } |
617 virtual void build() { |
617 virtual void build() { |
618 Arc arc; |
618 Arc arc; |
619 std::vector<Arc> arcs; |
619 std::vector<Arc> arcs; |
620 for (notifier()->first(arc); arc != INVALID; |
620 for (notifier()->first(arc); arc != INVALID; |
621 notifier()->next(arc)) { |
621 notifier()->next(arc)) { |
622 arcs.push_back(arc); |
622 arcs.push_back(arc); |
623 } |
623 } |
624 for (int i = arcs.size() - 1; i >= 0; --i) { |
624 for (int i = arcs.size() - 1; i >= 0; --i) { |
625 snapshot.addArc(arcs[i]); |
625 snapshot.addArc(arcs[i]); |
626 } |
626 } |
627 } |
627 } |
628 virtual void clear() { |
628 virtual void clear() { |
629 Arc arc; |
629 Arc arc; |
630 for (notifier()->first(arc); arc != INVALID; |
630 for (notifier()->first(arc); arc != INVALID; |
631 notifier()->next(arc)) { |
631 notifier()->next(arc)) { |
632 snapshot.eraseArc(arc); |
632 snapshot.eraseArc(arc); |
633 } |
633 } |
634 } |
634 } |
635 |
635 |
636 Snapshot& snapshot; |
636 Snapshot& snapshot; |
637 }; |
637 }; |
638 |
638 |
639 ListDigraph *digraph; |
639 ListDigraph *digraph; |
640 |
640 |
641 NodeObserverProxy node_observer_proxy; |
641 NodeObserverProxy node_observer_proxy; |
642 ArcObserverProxy arc_observer_proxy; |
642 ArcObserverProxy arc_observer_proxy; |
643 |
643 |
644 std::list<Node> added_nodes; |
644 std::list<Node> added_nodes; |
645 std::list<Arc> added_arcs; |
645 std::list<Arc> added_arcs; |
646 |
646 |
647 |
647 |
648 void addNode(const Node& node) { |
648 void addNode(const Node& node) { |
649 added_nodes.push_front(node); |
649 added_nodes.push_front(node); |
650 } |
650 } |
651 void eraseNode(const Node& node) { |
651 void eraseNode(const Node& node) { |
652 std::list<Node>::iterator it = |
652 std::list<Node>::iterator it = |
653 std::find(added_nodes.begin(), added_nodes.end(), node); |
653 std::find(added_nodes.begin(), added_nodes.end(), node); |
654 if (it == added_nodes.end()) { |
654 if (it == added_nodes.end()) { |
655 clear(); |
655 clear(); |
656 arc_observer_proxy.detach(); |
656 arc_observer_proxy.detach(); |
657 throw NodeNotifier::ImmediateDetach(); |
657 throw NodeNotifier::ImmediateDetach(); |
659 added_nodes.erase(it); |
659 added_nodes.erase(it); |
660 } |
660 } |
661 } |
661 } |
662 |
662 |
663 void addArc(const Arc& arc) { |
663 void addArc(const Arc& arc) { |
664 added_arcs.push_front(arc); |
664 added_arcs.push_front(arc); |
665 } |
665 } |
666 void eraseArc(const Arc& arc) { |
666 void eraseArc(const Arc& arc) { |
667 std::list<Arc>::iterator it = |
667 std::list<Arc>::iterator it = |
668 std::find(added_arcs.begin(), added_arcs.end(), arc); |
668 std::find(added_arcs.begin(), added_arcs.end(), arc); |
669 if (it == added_arcs.end()) { |
669 if (it == added_arcs.end()) { |
670 clear(); |
670 clear(); |
671 node_observer_proxy.detach(); |
671 node_observer_proxy.detach(); |
672 throw ArcNotifier::ImmediateDetach(); |
672 throw ArcNotifier::ImmediateDetach(); |
673 } else { |
673 } else { |
674 added_arcs.erase(it); |
674 added_arcs.erase(it); |
675 } |
675 } |
676 } |
676 } |
677 |
677 |
678 void attach(ListDigraph &_digraph) { |
678 void attach(ListDigraph &_digraph) { |
679 digraph = &_digraph; |
679 digraph = &_digraph; |
680 node_observer_proxy.attach(digraph->notifier(Node())); |
680 node_observer_proxy.attach(digraph->notifier(Node())); |
681 arc_observer_proxy.attach(digraph->notifier(Arc())); |
681 arc_observer_proxy.attach(digraph->notifier(Arc())); |
682 } |
682 } |
683 |
683 |
684 void detach() { |
684 void detach() { |
685 node_observer_proxy.detach(); |
685 node_observer_proxy.detach(); |
686 arc_observer_proxy.detach(); |
686 arc_observer_proxy.detach(); |
687 } |
687 } |
688 |
688 |
689 bool attached() const { |
689 bool attached() const { |
690 return node_observer_proxy.attached(); |
690 return node_observer_proxy.attached(); |
691 } |
691 } |
692 |
692 |
693 void clear() { |
693 void clear() { |
694 added_nodes.clear(); |
694 added_nodes.clear(); |
695 added_arcs.clear(); |
695 added_arcs.clear(); |
696 } |
696 } |
697 |
697 |
698 public: |
698 public: |
699 |
699 |
700 /// \brief Default constructor. |
700 /// \brief Default constructor. |
701 /// |
701 /// |
702 /// Default constructor. |
702 /// Default constructor. |
703 /// To actually make a snapshot you must call save(). |
703 /// To actually make a snapshot you must call save(). |
704 Snapshot() |
704 Snapshot() |
705 : digraph(0), node_observer_proxy(*this), |
705 : digraph(0), node_observer_proxy(*this), |
706 arc_observer_proxy(*this) {} |
706 arc_observer_proxy(*this) {} |
707 |
707 |
708 /// \brief Constructor that immediately makes a snapshot. |
708 /// \brief Constructor that immediately makes a snapshot. |
709 /// |
709 /// |
710 /// This constructor immediately makes a snapshot of the digraph. |
710 /// This constructor immediately makes a snapshot of the digraph. |
711 /// \param _digraph The digraph we make a snapshot of. |
711 /// \param _digraph The digraph we make a snapshot of. |
712 Snapshot(ListDigraph &_digraph) |
712 Snapshot(ListDigraph &_digraph) |
713 : node_observer_proxy(*this), |
713 : node_observer_proxy(*this), |
714 arc_observer_proxy(*this) { |
714 arc_observer_proxy(*this) { |
715 attach(_digraph); |
715 attach(_digraph); |
716 } |
716 } |
717 |
717 |
718 /// \brief Make a snapshot. |
718 /// \brief Make a snapshot. |
719 /// |
719 /// |
720 /// Make a snapshot of the digraph. |
720 /// Make a snapshot of the digraph. |
721 /// |
721 /// |
722 /// This function can be called more than once. In case of a repeated |
722 /// This function can be called more than once. In case of a repeated |
860 |
860 |
861 static Arc direct(Edge e, bool d) { |
861 static Arc direct(Edge e, bool d) { |
862 return Arc(e.id * 2 + (d ? 1 : 0)); |
862 return Arc(e.id * 2 + (d ? 1 : 0)); |
863 } |
863 } |
864 |
864 |
865 void first(Node& node) const { |
865 void first(Node& node) const { |
866 node.id = first_node; |
866 node.id = first_node; |
867 } |
867 } |
868 |
868 |
869 void next(Node& node) const { |
869 void next(Node& node) const { |
870 node.id = nodes[node.id].next; |
870 node.id = nodes[node.id].next; |
871 } |
871 } |
872 |
872 |
873 void first(Arc& e) const { |
873 void first(Arc& e) const { |
874 int n = first_node; |
874 int n = first_node; |
875 while (n != -1 && nodes[n].first_out == -1) { |
875 while (n != -1 && nodes[n].first_out == -1) { |
876 n = nodes[n].next; |
876 n = nodes[n].next; |
877 } |
877 } |
878 e.id = (n == -1) ? -1 : nodes[n].first_out; |
878 e.id = (n == -1) ? -1 : nodes[n].first_out; |
879 } |
879 } |
880 |
880 |
881 void next(Arc& e) const { |
881 void next(Arc& e) const { |
882 if (arcs[e.id].next_out != -1) { |
882 if (arcs[e.id].next_out != -1) { |
883 e.id = arcs[e.id].next_out; |
883 e.id = arcs[e.id].next_out; |
884 } else { |
884 } else { |
885 int n = nodes[arcs[e.id ^ 1].target].next; |
885 int n = nodes[arcs[e.id ^ 1].target].next; |
886 while(n != -1 && nodes[n].first_out == -1) { |
886 while(n != -1 && nodes[n].first_out == -1) { |
887 n = nodes[n].next; |
887 n = nodes[n].next; |
888 } |
888 } |
889 e.id = (n == -1) ? -1 : nodes[n].first_out; |
889 e.id = (n == -1) ? -1 : nodes[n].first_out; |
890 } |
890 } |
891 } |
891 } |
892 |
892 |
893 void first(Edge& e) const { |
893 void first(Edge& e) const { |
894 int n = first_node; |
894 int n = first_node; |
895 while (n != -1) { |
895 while (n != -1) { |
896 e.id = nodes[n].first_out; |
896 e.id = nodes[n].first_out; |
897 while ((e.id & 1) != 1) { |
897 while ((e.id & 1) != 1) { |
898 e.id = arcs[e.id].next_out; |
898 e.id = arcs[e.id].next_out; |
899 } |
899 } |
900 if (e.id != -1) { |
900 if (e.id != -1) { |
901 e.id /= 2; |
901 e.id /= 2; |
902 return; |
902 return; |
903 } |
903 } |
904 n = nodes[n].next; |
904 n = nodes[n].next; |
905 } |
905 } |
906 e.id = -1; |
906 e.id = -1; |
907 } |
907 } |
908 |
908 |
965 } else { |
965 } else { |
966 e.id = -1; |
966 e.id = -1; |
967 d = true; |
967 d = true; |
968 } |
968 } |
969 } |
969 } |
970 |
970 |
971 static int id(Node v) { return v.id; } |
971 static int id(Node v) { return v.id; } |
972 static int id(Arc e) { return e.id; } |
972 static int id(Arc e) { return e.id; } |
973 static int id(Edge e) { return e.id; } |
973 static int id(Edge e) { return e.id; } |
974 |
974 |
975 static Node nodeFromId(int id) { return Node(id);} |
975 static Node nodeFromId(int id) { return Node(id);} |
976 static Arc arcFromId(int id) { return Arc(id);} |
976 static Arc arcFromId(int id) { return Arc(id);} |
977 static Edge edgeFromId(int id) { return Edge(id);} |
977 static Edge edgeFromId(int id) { return Edge(id);} |
978 |
978 |
979 bool valid(Node n) const { |
979 bool valid(Node n) const { |
980 return n.id >= 0 && n.id < static_cast<int>(nodes.size()) && |
980 return n.id >= 0 && n.id < static_cast<int>(nodes.size()) && |
981 nodes[n.id].prev != -2; |
981 nodes[n.id].prev != -2; |
982 } |
982 } |
983 |
983 |
984 bool valid(Arc a) const { |
984 bool valid(Arc a) const { |
985 return a.id >= 0 && a.id < static_cast<int>(arcs.size()) && |
985 return a.id >= 0 && a.id < static_cast<int>(arcs.size()) && |
986 arcs[a.id].prev_out != -2; |
986 arcs[a.id].prev_out != -2; |
987 } |
987 } |
988 |
988 |
989 bool valid(Edge e) const { |
989 bool valid(Edge e) const { |
990 return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) && |
990 return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) && |
991 arcs[2 * e.id].prev_out != -2; |
991 arcs[2 * e.id].prev_out != -2; |
992 } |
992 } |
993 |
993 |
994 Node addNode() { |
994 Node addNode() { |
995 int n; |
995 int n; |
996 |
996 |
997 if(first_free_node==-1) { |
997 if(first_free_node==-1) { |
998 n = nodes.size(); |
998 n = nodes.size(); |
999 nodes.push_back(NodeT()); |
999 nodes.push_back(NodeT()); |
1000 } else { |
1000 } else { |
1001 n = first_free_node; |
1001 n = first_free_node; |
1002 first_free_node = nodes[n].next; |
1002 first_free_node = nodes[n].next; |
1003 } |
1003 } |
1004 |
1004 |
1005 nodes[n].next = first_node; |
1005 nodes[n].next = first_node; |
1006 if (first_node != -1) nodes[first_node].prev = n; |
1006 if (first_node != -1) nodes[first_node].prev = n; |
1007 first_node = n; |
1007 first_node = n; |
1008 nodes[n].prev = -1; |
1008 nodes[n].prev = -1; |
1009 |
1009 |
1010 nodes[n].first_out = -1; |
1010 nodes[n].first_out = -1; |
1011 |
1011 |
1012 return Node(n); |
1012 return Node(n); |
1013 } |
1013 } |
1014 |
1014 |
1015 Edge addEdge(Node u, Node v) { |
1015 Edge addEdge(Node u, Node v) { |
1016 int n; |
1016 int n; |
1017 |
1017 |
1018 if (first_free_arc == -1) { |
1018 if (first_free_arc == -1) { |
1019 n = arcs.size(); |
1019 n = arcs.size(); |
1020 arcs.push_back(ArcT()); |
1020 arcs.push_back(ArcT()); |
1021 arcs.push_back(ArcT()); |
1021 arcs.push_back(ArcT()); |
1022 } else { |
1022 } else { |
1023 n = first_free_arc; |
1023 n = first_free_arc; |
1024 first_free_arc = arcs[n].next_out; |
1024 first_free_arc = arcs[n].next_out; |
1025 } |
1025 } |
1026 |
1026 |
1027 arcs[n].target = u.id; |
1027 arcs[n].target = u.id; |
1028 arcs[n | 1].target = v.id; |
1028 arcs[n | 1].target = v.id; |
1029 |
1029 |
1030 arcs[n].next_out = nodes[v.id].first_out; |
1030 arcs[n].next_out = nodes[v.id].first_out; |
1031 if (nodes[v.id].first_out != -1) { |
1031 if (nodes[v.id].first_out != -1) { |
1032 arcs[nodes[v.id].first_out].prev_out = n; |
1032 arcs[nodes[v.id].first_out].prev_out = n; |
1033 } |
1033 } |
1034 arcs[n].prev_out = -1; |
1034 arcs[n].prev_out = -1; |
1035 nodes[v.id].first_out = n; |
1035 nodes[v.id].first_out = n; |
1036 |
1036 |
1037 arcs[n | 1].next_out = nodes[u.id].first_out; |
1037 arcs[n | 1].next_out = nodes[u.id].first_out; |
1038 if (nodes[u.id].first_out != -1) { |
1038 if (nodes[u.id].first_out != -1) { |
1039 arcs[nodes[u.id].first_out].prev_out = (n | 1); |
1039 arcs[nodes[u.id].first_out].prev_out = (n | 1); |
1040 } |
1040 } |
1041 arcs[n | 1].prev_out = -1; |
1041 arcs[n | 1].prev_out = -1; |
1042 nodes[u.id].first_out = (n | 1); |
1042 nodes[u.id].first_out = (n | 1); |
1043 |
1043 |
1044 return Edge(n / 2); |
1044 return Edge(n / 2); |
1045 } |
1045 } |
1046 |
1046 |
1047 void erase(const Node& node) { |
1047 void erase(const Node& node) { |
1048 int n = node.id; |
1048 int n = node.id; |
1049 |
1049 |
1050 if(nodes[n].next != -1) { |
1050 if(nodes[n].next != -1) { |
1051 nodes[nodes[n].next].prev = nodes[n].prev; |
1051 nodes[nodes[n].next].prev = nodes[n].prev; |
1052 } |
1052 } |
1053 |
1053 |
1054 if(nodes[n].prev != -1) { |
1054 if(nodes[n].prev != -1) { |
1055 nodes[nodes[n].prev].next = nodes[n].next; |
1055 nodes[nodes[n].prev].next = nodes[n].next; |
1056 } else { |
1056 } else { |
1057 first_node = nodes[n].next; |
1057 first_node = nodes[n].next; |
1058 } |
1058 } |
1059 |
1059 |
1060 nodes[n].next = first_free_node; |
1060 nodes[n].next = first_free_node; |
1061 first_free_node = n; |
1061 first_free_node = n; |
1062 nodes[n].prev = -2; |
1062 nodes[n].prev = -2; |
1063 } |
1063 } |
1064 |
1064 |
1065 void erase(const Edge& edge) { |
1065 void erase(const Edge& edge) { |
1066 int n = edge.id * 2; |
1066 int n = edge.id * 2; |
1067 |
1067 |
1068 if (arcs[n].next_out != -1) { |
1068 if (arcs[n].next_out != -1) { |
1069 arcs[arcs[n].next_out].prev_out = arcs[n].prev_out; |
1069 arcs[arcs[n].next_out].prev_out = arcs[n].prev_out; |
1070 } |
1070 } |
1071 |
1071 |
1072 if (arcs[n].prev_out != -1) { |
1072 if (arcs[n].prev_out != -1) { |
1073 arcs[arcs[n].prev_out].next_out = arcs[n].next_out; |
1073 arcs[arcs[n].prev_out].next_out = arcs[n].next_out; |
1074 } else { |
1074 } else { |
1075 nodes[arcs[n | 1].target].first_out = arcs[n].next_out; |
1075 nodes[arcs[n | 1].target].first_out = arcs[n].next_out; |
1076 } |
1076 } |
1077 |
1077 |
1078 if (arcs[n | 1].next_out != -1) { |
1078 if (arcs[n | 1].next_out != -1) { |
1079 arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out; |
1079 arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out; |
1080 } |
1080 } |
1081 |
1081 |
1082 if (arcs[n | 1].prev_out != -1) { |
1082 if (arcs[n | 1].prev_out != -1) { |
1083 arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out; |
1083 arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out; |
1084 } else { |
1084 } else { |
1085 nodes[arcs[n].target].first_out = arcs[n | 1].next_out; |
1085 nodes[arcs[n].target].first_out = arcs[n | 1].next_out; |
1086 } |
1086 } |
1087 |
1087 |
1088 arcs[n].next_out = first_free_arc; |
1088 arcs[n].next_out = first_free_arc; |
1089 first_free_arc = n; |
1089 first_free_arc = n; |
1090 arcs[n].prev_out = -2; |
1090 arcs[n].prev_out = -2; |
1091 arcs[n | 1].prev_out = -2; |
1091 arcs[n | 1].prev_out = -2; |
1092 |
1092 |
1093 } |
1093 } |
1094 |
1094 |
1100 |
1100 |
1101 protected: |
1101 protected: |
1102 |
1102 |
1103 void changeTarget(Edge e, Node n) { |
1103 void changeTarget(Edge e, Node n) { |
1104 if(arcs[2 * e.id].next_out != -1) { |
1104 if(arcs[2 * e.id].next_out != -1) { |
1105 arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out; |
1105 arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out; |
1106 } |
1106 } |
1107 if(arcs[2 * e.id].prev_out != -1) { |
1107 if(arcs[2 * e.id].prev_out != -1) { |
1108 arcs[arcs[2 * e.id].prev_out].next_out = |
1108 arcs[arcs[2 * e.id].prev_out].next_out = |
1109 arcs[2 * e.id].next_out; |
1109 arcs[2 * e.id].next_out; |
1110 } else { |
1110 } else { |
1111 nodes[arcs[(2 * e.id) | 1].target].first_out = |
1111 nodes[arcs[(2 * e.id) | 1].target].first_out = |
1112 arcs[2 * e.id].next_out; |
1112 arcs[2 * e.id].next_out; |
1113 } |
1113 } |
1114 |
1114 |
1115 if (nodes[n.id].first_out != -1) { |
1115 if (nodes[n.id].first_out != -1) { |
1116 arcs[nodes[n.id].first_out].prev_out = 2 * e.id; |
1116 arcs[nodes[n.id].first_out].prev_out = 2 * e.id; |
1117 } |
1117 } |
1118 arcs[(2 * e.id) | 1].target = n.id; |
1118 arcs[(2 * e.id) | 1].target = n.id; |
1119 arcs[2 * e.id].prev_out = -1; |
1119 arcs[2 * e.id].prev_out = -1; |
1120 arcs[2 * e.id].next_out = nodes[n.id].first_out; |
1120 arcs[2 * e.id].next_out = nodes[n.id].first_out; |
1121 nodes[n.id].first_out = 2 * e.id; |
1121 nodes[n.id].first_out = 2 * e.id; |
1122 } |
1122 } |
1123 |
1123 |
1124 void changeSource(Edge e, Node n) { |
1124 void changeSource(Edge e, Node n) { |
1125 if(arcs[(2 * e.id) | 1].next_out != -1) { |
1125 if(arcs[(2 * e.id) | 1].next_out != -1) { |
1126 arcs[arcs[(2 * e.id) | 1].next_out].prev_out = |
1126 arcs[arcs[(2 * e.id) | 1].next_out].prev_out = |
1127 arcs[(2 * e.id) | 1].prev_out; |
1127 arcs[(2 * e.id) | 1].prev_out; |
1128 } |
1128 } |
1129 if(arcs[(2 * e.id) | 1].prev_out != -1) { |
1129 if(arcs[(2 * e.id) | 1].prev_out != -1) { |
1130 arcs[arcs[(2 * e.id) | 1].prev_out].next_out = |
1130 arcs[arcs[(2 * e.id) | 1].prev_out].next_out = |
1131 arcs[(2 * e.id) | 1].next_out; |
1131 arcs[(2 * e.id) | 1].next_out; |
1132 } else { |
1132 } else { |
1133 nodes[arcs[2 * e.id].target].first_out = |
1133 nodes[arcs[2 * e.id].target].first_out = |
1134 arcs[(2 * e.id) | 1].next_out; |
1134 arcs[(2 * e.id) | 1].next_out; |
1135 } |
1135 } |
1136 |
1136 |
1137 if (nodes[n.id].first_out != -1) { |
1137 if (nodes[n.id].first_out != -1) { |
1138 arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1); |
1138 arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1); |
1139 } |
1139 } |
1140 arcs[2 * e.id].target = n.id; |
1140 arcs[2 * e.id].target = n.id; |
1141 arcs[(2 * e.id) | 1].prev_out = -1; |
1141 arcs[(2 * e.id) | 1].prev_out = -1; |
1142 arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out; |
1142 arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out; |
1143 nodes[n.id].first_out = ((2 * e.id) | 1); |
1143 nodes[n.id].first_out = ((2 * e.id) | 1); |
1200 /// \brief Add a new edge to the graph. |
1200 /// \brief Add a new edge to the graph. |
1201 /// |
1201 /// |
1202 /// Add a new edge to the graph with source node \c s |
1202 /// Add a new edge to the graph with source node \c s |
1203 /// and target node \c t. |
1203 /// and target node \c t. |
1204 /// \return the new edge. |
1204 /// \return the new edge. |
1205 Edge addEdge(const Node& s, const Node& t) { |
1205 Edge addEdge(const Node& s, const Node& t) { |
1206 return Parent::addEdge(s, t); |
1206 return Parent::addEdge(s, t); |
1207 } |
1207 } |
1208 /// Node validity check |
1208 /// Node validity check |
1209 |
1209 |
1210 /// This function gives back true if the given node is valid, |
1210 /// This function gives back true if the given node is valid, |
1211 /// ie. it is a real node of the graph. |
1211 /// ie. it is a real node of the graph. |
1212 /// |
1212 /// |
1213 /// \warning A Node pointing to a removed item |
1213 /// \warning A Node pointing to a removed item |
1214 /// could become valid again later if new nodes are |
1214 /// could become valid again later if new nodes are |
1215 /// added to the graph. |
1215 /// added to the graph. |
1216 bool valid(Node n) const { return Parent::valid(n); } |
1216 bool valid(Node n) const { return Parent::valid(n); } |
1217 /// Arc validity check |
1217 /// Arc validity check |
1218 |
1218 |
1219 /// This function gives back true if the given arc is valid, |
1219 /// This function gives back true if the given arc is valid, |
1220 /// ie. it is a real arc of the graph. |
1220 /// ie. it is a real arc of the graph. |
1221 /// |
1221 /// |
1222 /// \warning An Arc pointing to a removed item |
1222 /// \warning An Arc pointing to a removed item |
1223 /// could become valid again later if new edges are |
1223 /// could become valid again later if new edges are |
1224 /// added to the graph. |
1224 /// added to the graph. |
1225 bool valid(Arc a) const { return Parent::valid(a); } |
1225 bool valid(Arc a) const { return Parent::valid(a); } |
1226 /// Edge validity check |
1226 /// Edge validity check |
1227 |
1227 |
1228 /// This function gives back true if the given edge is valid, |
1228 /// This function gives back true if the given edge is valid, |
1229 /// ie. it is a real arc of the graph. |
1229 /// ie. it is a real arc of the graph. |
1230 /// |
1230 /// |
1231 /// \warning A Edge pointing to a removed item |
1231 /// \warning A Edge pointing to a removed item |
1232 /// could become valid again later if new edges are |
1232 /// could become valid again later if new edges are |
1233 /// added to the graph. |
1233 /// added to the graph. |
1234 bool valid(Edge e) const { return Parent::valid(e); } |
1234 bool valid(Edge e) const { return Parent::valid(e); } |
1240 ///referencing the changed arc remain |
1240 ///referencing the changed arc remain |
1241 ///valid. However <tt>OutArcIt</tt>s are invalidated. |
1241 ///valid. However <tt>OutArcIt</tt>s are invalidated. |
1242 /// |
1242 /// |
1243 ///\warning This functionality cannot be used together with the |
1243 ///\warning This functionality cannot be used together with the |
1244 ///Snapshot feature. |
1244 ///Snapshot feature. |
1245 void changeSource(Edge e, Node n) { |
1245 void changeSource(Edge e, Node n) { |
1246 Parent::changeSource(e,n); |
1246 Parent::changeSource(e,n); |
1247 } |
1247 } |
1248 /// \brief Change the target of \c e to \c n |
1248 /// \brief Change the target of \c e to \c n |
1249 /// |
1249 /// |
1250 /// This function changes the target of \c e to \c n. |
1250 /// This function changes the target of \c e to \c n. |
1251 /// |
1251 /// |
1252 /// \note The <tt>ArcIt</tt>s referencing the changed arc remain |
1252 /// \note The <tt>ArcIt</tt>s referencing the changed arc remain |
1253 /// valid. However the other iterators may be invalidated. |
1253 /// valid. However the other iterators may be invalidated. |
1254 /// |
1254 /// |
1255 ///\warning This functionality cannot be used together with the |
1255 ///\warning This functionality cannot be used together with the |
1256 ///Snapshot feature. |
1256 ///Snapshot feature. |
1257 void changeTarget(Edge e, Node n) { |
1257 void changeTarget(Edge e, Node n) { |
1258 Parent::changeTarget(e,n); |
1258 Parent::changeTarget(e,n); |
1259 } |
1259 } |
1260 /// \brief Change the source of \c e to \c n |
1260 /// \brief Change the source of \c e to \c n |
1261 /// |
1261 /// |
1262 /// This function changes the source of \c e to \c n. |
1262 /// This function changes the source of \c e to \c n. |
1263 /// It also changes the proper node of the represented edge. |
1263 /// It also changes the proper node of the represented edge. |
1264 /// |
1264 /// |
1265 ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s |
1265 ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s |
1266 ///referencing the changed arc remain |
1266 ///referencing the changed arc remain |
1267 ///valid. However <tt>OutArcIt</tt>s are invalidated. |
1267 ///valid. However <tt>OutArcIt</tt>s are invalidated. |
1268 /// |
1268 /// |
1269 ///\warning This functionality cannot be used together with the |
1269 ///\warning This functionality cannot be used together with the |
1270 ///Snapshot feature. |
1270 ///Snapshot feature. |
1271 void changeSource(Arc e, Node n) { |
1271 void changeSource(Arc e, Node n) { |
1272 if (Parent::direction(e)) { |
1272 if (Parent::direction(e)) { |
1273 Parent::changeSource(e,n); |
1273 Parent::changeSource(e,n); |
1274 } else { |
1274 } else { |
1275 Parent::changeTarget(e,n); |
1275 Parent::changeTarget(e,n); |
1276 } |
1276 } |
1277 } |
1277 } |
1278 /// \brief Change the target of \c e to \c n |
1278 /// \brief Change the target of \c e to \c n |
1279 /// |
1279 /// |
1280 /// This function changes the target of \c e to \c n. |
1280 /// This function changes the target of \c e to \c n. |
1281 /// It also changes the proper node of the represented edge. |
1281 /// It also changes the proper node of the represented edge. |
1282 /// |
1282 /// |
1283 ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s |
1283 ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s |
1284 ///referencing the changed arc remain |
1284 ///referencing the changed arc remain |
1285 ///valid. However <tt>InArcIt</tt>s are invalidated. |
1285 ///valid. However <tt>InArcIt</tt>s are invalidated. |
1286 /// |
1286 /// |
1287 ///\warning This functionality cannot be used together with the |
1287 ///\warning This functionality cannot be used together with the |
1288 ///Snapshot feature. |
1288 ///Snapshot feature. |
1289 void changeTarget(Arc e, Node n) { |
1289 void changeTarget(Arc e, Node n) { |
1290 if (Parent::direction(e)) { |
1290 if (Parent::direction(e)) { |
1291 Parent::changeTarget(e,n); |
1291 Parent::changeTarget(e,n); |
1292 } else { |
1292 } else { |
1293 Parent::changeSource(e,n); |
1293 Parent::changeSource(e,n); |
1294 } |
1294 } |
1295 } |
1295 } |
1296 /// \brief Contract two nodes. |
1296 /// \brief Contract two nodes. |
1297 /// |
1297 /// |
1298 /// This function contracts two nodes. |
1298 /// This function contracts two nodes. |
1299 /// Node \p b will be removed but instead of deleting |
1299 /// Node \p b will be removed but instead of deleting |
1476 added_edges.erase(it); |
1476 added_edges.erase(it); |
1477 } |
1477 } |
1478 } |
1478 } |
1479 |
1479 |
1480 void attach(ListGraph &_graph) { |
1480 void attach(ListGraph &_graph) { |
1481 graph = &_graph; |
1481 graph = &_graph; |
1482 node_observer_proxy.attach(graph->notifier(Node())); |
1482 node_observer_proxy.attach(graph->notifier(Node())); |
1483 edge_observer_proxy.attach(graph->notifier(Edge())); |
1483 edge_observer_proxy.attach(graph->notifier(Edge())); |
1484 } |
1484 } |
1485 |
1485 |
1486 void detach() { |
1486 void detach() { |
1487 node_observer_proxy.detach(); |
1487 node_observer_proxy.detach(); |
1488 edge_observer_proxy.detach(); |
1488 edge_observer_proxy.detach(); |
1489 } |
1489 } |
1490 |
1490 |
1491 bool attached() const { |
1491 bool attached() const { |
1492 return node_observer_proxy.attached(); |
1492 return node_observer_proxy.attached(); |
1493 } |
1493 } |
1494 |
1494 |
1495 void clear() { |
1495 void clear() { |
1496 added_nodes.clear(); |
1496 added_nodes.clear(); |
1497 added_edges.clear(); |
1497 added_edges.clear(); |
1498 } |
1498 } |
1499 |
1499 |
1500 public: |
1500 public: |
1501 |
1501 |
1502 /// \brief Default constructor. |
1502 /// \brief Default constructor. |
1503 /// |
1503 /// |
1504 /// Default constructor. |
1504 /// Default constructor. |
1505 /// To actually make a snapshot you must call save(). |
1505 /// To actually make a snapshot you must call save(). |
1506 Snapshot() |
1506 Snapshot() |
1507 : graph(0), node_observer_proxy(*this), |
1507 : graph(0), node_observer_proxy(*this), |
1508 edge_observer_proxy(*this) {} |
1508 edge_observer_proxy(*this) {} |
1509 |
1509 |
1510 /// \brief Constructor that immediately makes a snapshot. |
1510 /// \brief Constructor that immediately makes a snapshot. |
1511 /// |
1511 /// |
1512 /// This constructor immediately makes a snapshot of the graph. |
1512 /// This constructor immediately makes a snapshot of the graph. |
1513 /// \param _graph The graph we make a snapshot of. |
1513 /// \param _graph The graph we make a snapshot of. |
1514 Snapshot(ListGraph &_graph) |
1514 Snapshot(ListGraph &_graph) |
1515 : node_observer_proxy(*this), |
1515 : node_observer_proxy(*this), |
1516 edge_observer_proxy(*this) { |
1516 edge_observer_proxy(*this) { |
1517 attach(_graph); |
1517 attach(_graph); |
1518 } |
1518 } |
1519 |
1519 |
1520 /// \brief Make a snapshot. |
1520 /// \brief Make a snapshot. |
1521 /// |
1521 /// |
1522 /// Make a snapshot of the graph. |
1522 /// Make a snapshot of the graph. |
1523 /// |
1523 /// |
1524 /// This function can be called more than once. In case of a repeated |
1524 /// This function can be called more than once. In case of a repeated |