79 : nodes(_g.nodes), edges(_g.edges) { } |
76 : nodes(_g.nodes), edges(_g.edges) { } |
80 |
77 |
81 typedef True NodeNumTag; |
78 typedef True NodeNumTag; |
82 typedef True EdgeNumTag; |
79 typedef True EdgeNumTag; |
83 |
80 |
84 ///Number of nodes. |
|
85 int nodeNum() const { return nodes.size(); } |
81 int nodeNum() const { return nodes.size(); } |
86 ///Number of edges. |
|
87 int edgeNum() const { return edges.size(); } |
82 int edgeNum() const { return edges.size(); } |
88 |
83 |
89 /// Maximum node ID. |
|
90 |
|
91 /// Maximum node ID. |
|
92 ///\sa id(Node) |
|
93 int maxNodeId() const { return nodes.size()-1; } |
84 int maxNodeId() const { return nodes.size()-1; } |
94 /// Maximum edge ID. |
|
95 |
|
96 /// Maximum edge ID. |
|
97 ///\sa id(Edge) |
|
98 int maxEdgeId() const { return edges.size()-1; } |
85 int maxEdgeId() const { return edges.size()-1; } |
99 |
86 |
100 Node addNode() { |
87 Node addNode() { |
101 Node n; n.n=nodes.size(); |
88 int n = nodes.size(); |
102 nodes.push_back(NodeT()); //FIXME: Hmmm... |
89 nodes.push_back(NodeT()); |
103 return n; |
90 nodes[n].first_in = -1; |
|
91 nodes[n].first_out = -1; |
|
92 return Node(n); |
104 } |
93 } |
105 |
94 |
106 Edge addEdge(Node u, Node v) { |
95 Edge addEdge(Node u, Node v) { |
107 Edge e; e.n=edges.size(); edges.push_back(EdgeT()); //FIXME: Hmmm... |
96 int n = edges.size(); |
108 edges[e.n].source=u.n; edges[e.n].target=v.n; |
97 edges.push_back(EdgeT()); |
109 edges[e.n].next_out=nodes[u.n].first_out; |
98 edges[n].source = u.id; |
110 edges[e.n].next_in=nodes[v.n].first_in; |
99 edges[n].target = v.id; |
111 nodes[u.n].first_out=nodes[v.n].first_in=e.n; |
100 edges[n].next_out = nodes[u.id].first_out; |
112 |
101 edges[n].next_in = nodes[v.id].first_in; |
113 return e; |
102 nodes[u.id].first_out = nodes[v.id].first_in = n; |
114 } |
103 |
115 |
104 return Edge(n); |
116 |
105 } |
117 Node source(Edge e) const { return edges[e.n].source; } |
106 |
118 Node target(Edge e) const { return edges[e.n].target; } |
107 void clear() { |
119 |
108 edges.clear(); |
120 /// Node ID. |
109 nodes.clear(); |
121 |
110 } |
122 /// The ID of a valid Node is a nonnegative integer not greater than |
111 |
123 /// \ref maxNodeId(). The range of the ID's is not surely continuous |
112 Node source(Edge e) const { return Node(edges[e.id].source); } |
124 /// and the greatest node ID can be actually less then \ref maxNodeId(). |
113 Node target(Edge e) const { return Node(edges[e.id].target); } |
125 /// |
114 |
126 /// The ID of the \ref INVALID node is -1. |
115 static int id(Node v) { return v.id; } |
127 ///\return The ID of the node \c v. |
116 static int id(Edge e) { return e.id; } |
128 static int id(Node v) { return v.n; } |
117 |
129 /// Edge ID. |
|
130 |
|
131 /// The ID of a valid Edge is a nonnegative integer not greater than |
|
132 /// \ref maxEdgeId(). The range of the ID's is not surely continuous |
|
133 /// and the greatest edge ID can be actually less then \ref maxEdgeId(). |
|
134 /// |
|
135 /// The ID of the \ref INVALID edge is -1. |
|
136 ///\return The ID of the edge \c e. |
|
137 static int id(Edge e) { return e.n; } |
|
138 |
|
139 /// \brief Returns the node from its \c id. |
|
140 /// |
|
141 /// Returns the node from its \c id. If there is not node |
|
142 /// with the given id the effect of the function is undefinied. |
|
143 static Node nodeFromId(int id) { return Node(id);} |
118 static Node nodeFromId(int id) { return Node(id);} |
144 |
|
145 /// \brief Returns the edge from its \c id. |
|
146 /// |
|
147 /// Returns the edge from its \c id. If there is not edge |
|
148 /// with the given id the effect of the function is undefinied. |
|
149 static Edge edgeFromId(int id) { return Edge(id);} |
119 static Edge edgeFromId(int id) { return Edge(id);} |
150 |
120 |
151 class Node { |
121 class Node { |
152 friend class SmartGraphBase; |
122 friend class SmartGraphBase; |
153 friend class SmartGraph; |
123 friend class SmartGraph; |
154 |
124 |
155 protected: |
125 protected: |
156 int n; |
126 int id; |
157 Node(int nn) {n=nn;} |
127 explicit Node(int _id) : id(_id) {} |
158 public: |
128 public: |
159 Node() {} |
129 Node() {} |
160 Node (Invalid) { n=-1; } |
130 Node (Invalid) : id(-1) {} |
161 bool operator==(const Node i) const {return n==i.n;} |
131 bool operator==(const Node i) const {return id == i.id;} |
162 bool operator!=(const Node i) const {return n!=i.n;} |
132 bool operator!=(const Node i) const {return id != i.id;} |
163 bool operator<(const Node i) const {return n<i.n;} |
133 bool operator<(const Node i) const {return id < i.id;} |
164 }; |
134 }; |
165 |
135 |
166 |
136 |
167 class Edge { |
137 class Edge { |
168 friend class SmartGraphBase; |
138 friend class SmartGraphBase; |
169 friend class SmartGraph; |
139 friend class SmartGraph; |
170 |
140 |
171 protected: |
141 protected: |
172 int n; |
142 int id; |
173 Edge(int nn) {n=nn;} |
143 explicit Edge(int _id) : id(_id) {} |
174 public: |
144 public: |
175 Edge() { } |
145 Edge() { } |
176 Edge (Invalid) { n=-1; } |
146 Edge (Invalid) : id(-1) {} |
177 bool operator==(const Edge i) const {return n==i.n;} |
147 bool operator==(const Edge i) const {return id == i.id;} |
178 bool operator!=(const Edge i) const {return n!=i.n;} |
148 bool operator!=(const Edge i) const {return id != i.id;} |
179 bool operator<(const Edge i) const {return n<i.n;} |
149 bool operator<(const Edge i) const {return id < i.id;} |
180 }; |
150 }; |
181 |
151 |
182 void first(Node& node) const { |
152 void first(Node& node) const { |
183 node.n = nodes.size() - 1; |
153 node.id = nodes.size() - 1; |
184 } |
154 } |
185 |
155 |
186 static void next(Node& node) { |
156 static void next(Node& node) { |
187 --node.n; |
157 --node.id; |
188 } |
158 } |
189 |
159 |
190 void first(Edge& edge) const { |
160 void first(Edge& edge) const { |
191 edge.n = edges.size() - 1; |
161 edge.id = edges.size() - 1; |
192 } |
162 } |
193 |
163 |
194 static void next(Edge& edge) { |
164 static void next(Edge& edge) { |
195 --edge.n; |
165 --edge.id; |
196 } |
166 } |
197 |
167 |
198 void firstOut(Edge& edge, const Node& node) const { |
168 void firstOut(Edge& edge, const Node& node) const { |
199 edge.n = nodes[node.n].first_out; |
169 edge.id = nodes[node.id].first_out; |
200 } |
170 } |
201 |
171 |
202 void nextOut(Edge& edge) const { |
172 void nextOut(Edge& edge) const { |
203 edge.n = edges[edge.n].next_out; |
173 edge.id = edges[edge.id].next_out; |
204 } |
174 } |
205 |
175 |
206 void firstIn(Edge& edge, const Node& node) const { |
176 void firstIn(Edge& edge, const Node& node) const { |
207 edge.n = nodes[node.n].first_in; |
177 edge.id = nodes[node.id].first_in; |
208 } |
178 } |
209 |
179 |
210 void nextIn(Edge& edge) const { |
180 void nextIn(Edge& edge) const { |
211 edge.n = edges[edge.n].next_in; |
181 edge.id = edges[edge.id].next_in; |
212 } |
182 } |
213 |
183 |
214 }; |
184 }; |
215 |
185 |
216 typedef GraphExtender<SmartGraphBase> ExtendedSmartGraphBase; |
186 typedef GraphExtender<SmartGraphBase> ExtendedSmartGraphBase; |
231 class SmartGraph : public ExtendedSmartGraphBase { |
201 class SmartGraph : public ExtendedSmartGraphBase { |
232 public: |
202 public: |
233 |
203 |
234 typedef ExtendedSmartGraphBase Parent; |
204 typedef ExtendedSmartGraphBase Parent; |
235 |
205 |
236 class Snapshot; |
|
237 friend class Snapshot; |
|
238 |
|
239 private: |
206 private: |
|
207 |
240 ///SmartGraph is \e not copy constructible. Use GraphCopy() instead. |
208 ///SmartGraph is \e not copy constructible. Use GraphCopy() instead. |
241 |
209 |
242 ///SmartGraph is \e not copy constructible. Use GraphCopy() instead. |
210 ///SmartGraph is \e not copy constructible. Use GraphCopy() instead. |
243 /// |
211 /// |
244 SmartGraph(const SmartGraph &) :ExtendedSmartGraphBase() {}; |
212 SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {}; |
245 ///\brief Assignment of SmartGraph to another one is \e not allowed. |
213 ///\brief Assignment of SmartGraph to another one is \e not allowed. |
246 ///Use GraphCopy() instead. |
214 ///Use GraphCopy() instead. |
247 |
215 |
248 ///Assignment of SmartGraph to another one is \e not allowed. |
216 ///Assignment of SmartGraph to another one is \e not allowed. |
249 ///Use GraphCopy() instead. |
217 ///Use GraphCopy() instead. |
250 void operator=(const SmartGraph &) {} |
218 void operator=(const SmartGraph &) {} |
251 protected: |
|
252 void restoreSnapshot(const Snapshot &s) |
|
253 { |
|
254 while(s.edge_num<edges.size()) { |
|
255 Parent::getNotifier(Edge()).erase(Edge(edges.size()-1)); |
|
256 nodes[edges.back().target].first_in=edges.back().next_in; |
|
257 nodes[edges.back().source].first_out=edges.back().next_out; |
|
258 edges.pop_back(); |
|
259 } |
|
260 //nodes.resize(s.nodes_num); |
|
261 while(s.node_num<nodes.size()) { |
|
262 Parent::getNotifier(Node()).erase(Node(nodes.size()-1)); |
|
263 nodes.pop_back(); |
|
264 } |
|
265 } |
|
266 |
219 |
267 public: |
220 public: |
268 |
221 |
269 /// Constructor |
222 /// Constructor |
270 |
223 |
312 ///feature. |
264 ///feature. |
313 ///\todo It could be implemented in a bit faster way. |
265 ///\todo It could be implemented in a bit faster way. |
314 Node split(Node n, bool connect = true) |
266 Node split(Node n, bool connect = true) |
315 { |
267 { |
316 Node b = addNode(); |
268 Node b = addNode(); |
317 nodes[b.n].first_out=nodes[n.n].first_out; |
269 nodes[b.id].first_out=nodes[n.id].first_out; |
318 nodes[n.n].first_out=-1; |
270 nodes[n.id].first_out=-1; |
319 for(int i=nodes[b.n].first_out;i!=-1;i++) edges[i].source=b.n; |
271 for(int i=nodes[b.id].first_out;i!=-1;i++) edges[i].source=b.id; |
320 if(connect) addEdge(n,b); |
272 if(connect) addEdge(n,b); |
321 return b; |
273 return b; |
322 } |
274 } |
|
275 |
|
276 public: |
|
277 |
|
278 class Snapshot; |
|
279 |
|
280 protected: |
|
281 |
|
282 void restoreSnapshot(const Snapshot &s) |
|
283 { |
|
284 while(s.edge_num<edges.size()) { |
|
285 Edge edge = edgeFromId(edges.size()-1); |
|
286 Parent::getNotifier(Edge()).erase(edge); |
|
287 nodes[edges.back().source].first_out=edges.back().next_out; |
|
288 nodes[edges.back().target].first_in=edges.back().next_in; |
|
289 edges.pop_back(); |
|
290 } |
|
291 while(s.node_num<nodes.size()) { |
|
292 Node node = nodeFromId(nodes.size()-1); |
|
293 Parent::getNotifier(Node()).erase(node); |
|
294 nodes.pop_back(); |
|
295 } |
|
296 } |
|
297 |
|
298 public: |
323 |
299 |
324 ///Class to make a snapshot of the graph and to restrore to it later. |
300 ///Class to make a snapshot of the graph and to restrore to it later. |
325 |
301 |
326 ///Class to make a snapshot of the graph and to restrore to it later. |
302 ///Class to make a snapshot of the graph and to restrore to it later. |
327 /// |
303 /// |
405 /// |
382 /// |
406 /// \todo Snapshot hasn't been implemented yet. |
383 /// \todo Snapshot hasn't been implemented yet. |
407 /// |
384 /// |
408 class SmartUGraph : public ExtendedSmartUGraphBase { |
385 class SmartUGraph : public ExtendedSmartUGraphBase { |
409 private: |
386 private: |
|
387 |
410 ///SmartUGraph is \e not copy constructible. Use UGraphCopy() instead. |
388 ///SmartUGraph is \e not copy constructible. Use UGraphCopy() instead. |
411 |
389 |
412 ///SmartUGraph is \e not copy constructible. Use UGraphCopy() instead. |
390 ///SmartUGraph is \e not copy constructible. Use UGraphCopy() instead. |
413 /// |
391 /// |
414 SmartUGraph(const SmartUGraph &) : ExtendedSmartUGraphBase() {}; |
392 SmartUGraph(const SmartUGraph &) : ExtendedSmartUGraphBase() {}; |
|
393 |
415 ///\brief Assignment of SmartUGraph to another one is \e not allowed. |
394 ///\brief Assignment of SmartUGraph to another one is \e not allowed. |
416 ///Use UGraphCopy() instead. |
395 ///Use UGraphCopy() instead. |
417 |
396 |
418 ///Assignment of SmartUGraph to another one is \e not allowed. |
397 ///Assignment of SmartUGraph to another one is \e not allowed. |
419 ///Use UGraphCopy() instead. |
398 ///Use UGraphCopy() instead. |
420 void operator=(const SmartUGraph &) {} |
399 void operator=(const SmartUGraph &) {} |
421 public: |
400 |
|
401 public: |
|
402 |
|
403 typedef ExtendedSmartUGraphBase Parent; |
|
404 |
422 /// Constructor |
405 /// Constructor |
423 |
406 |
424 /// Constructor. |
407 /// Constructor. |
425 /// |
408 /// |
426 SmartUGraph() {} |
409 SmartUGraph() {} |
|
410 |
|
411 ///Add a new node to the graph. |
|
412 |
|
413 /// \return the new node. |
|
414 /// |
|
415 Node addNode() { return Parent::addNode(); } |
|
416 |
|
417 ///Add a new undirected edge to the graph. |
|
418 |
|
419 ///Add a new undirected edge to the graph with node \c s |
|
420 ///and \c t. |
|
421 ///\return the new undirected edge. |
|
422 UEdge addEdge(const Node& s, const Node& t) { |
|
423 return Parent::addEdge(s, t); |
|
424 } |
|
425 |
|
426 ///Clear the graph. |
|
427 |
|
428 ///Erase all the nodes and edges from the graph. |
|
429 /// |
|
430 void clear() { |
|
431 Parent::clear(); |
|
432 } |
|
433 |
|
434 public: |
|
435 |
|
436 class Snapshot; |
|
437 |
|
438 protected: |
|
439 |
|
440 |
|
441 void restoreSnapshot(const Snapshot &s) |
|
442 { |
|
443 while(s.edge_num<edges.size()) { |
|
444 UEdge edge = uEdgeFromId(edges.size()-1); |
|
445 Parent::getNotifier(UEdge()).erase(edge); |
|
446 std::vector<Edge> dir; |
|
447 dir.push_back(Parent::direct(edge, true)); |
|
448 dir.push_back(Parent::direct(edge, false)); |
|
449 Parent::getNotifier(Edge()).erase(dir); |
|
450 nodes[edges.back().source].first_out=edges.back().next_out; |
|
451 nodes[edges.back().target].first_in=edges.back().next_in; |
|
452 edges.pop_back(); |
|
453 } |
|
454 while(s.node_num<nodes.size()) { |
|
455 Node node = nodeFromId(nodes.size()-1); |
|
456 Parent::getNotifier(Node()).erase(node); |
|
457 nodes.pop_back(); |
|
458 } |
|
459 } |
|
460 |
|
461 public: |
|
462 |
|
463 ///Class to make a snapshot of the graph and to restrore to it later. |
|
464 |
|
465 ///Class to make a snapshot of the graph and to restrore to it later. |
|
466 /// |
|
467 ///The newly added nodes and edges can be removed using the |
|
468 ///restore() function. |
|
469 /// |
|
470 ///\note After you restore a state, you cannot restore |
|
471 ///a later state, in other word you cannot add again the edges deleted |
|
472 ///by restore() using another one Snapshot instance. |
|
473 /// |
|
474 ///\warning If you do not use correctly the snapshot that can cause |
|
475 ///either broken program, invalid state of the graph, valid but |
|
476 ///not the restored graph or no change. Because the runtime performance |
|
477 ///the validity of the snapshot is not stored. |
|
478 class Snapshot |
|
479 { |
|
480 SmartUGraph *g; |
|
481 protected: |
|
482 friend class SmartUGraph; |
|
483 unsigned int node_num; |
|
484 unsigned int edge_num; |
|
485 public: |
|
486 ///Default constructor. |
|
487 |
|
488 ///Default constructor. |
|
489 ///To actually make a snapshot you must call save(). |
|
490 /// |
|
491 Snapshot() : g(0) {} |
|
492 ///Constructor that immediately makes a snapshot |
|
493 |
|
494 ///This constructor immediately makes a snapshot of the graph. |
|
495 ///\param _g The graph we make a snapshot of. |
|
496 Snapshot(SmartUGraph &_g) :g(&_g) { |
|
497 node_num=g->nodes.size(); |
|
498 edge_num=g->edges.size(); |
|
499 } |
|
500 |
|
501 ///Make a snapshot. |
|
502 |
|
503 ///Make a snapshot of the graph. |
|
504 /// |
|
505 ///This function can be called more than once. In case of a repeated |
|
506 ///call, the previous snapshot gets lost. |
|
507 ///\param _g The graph we make the snapshot of. |
|
508 void save(SmartUGraph &_g) |
|
509 { |
|
510 g=&_g; |
|
511 node_num=g->nodes.size(); |
|
512 edge_num=g->edges.size(); |
|
513 } |
|
514 |
|
515 ///Undo the changes until a snapshot. |
|
516 |
|
517 ///Undo the changes until a snapshot created by save(). |
|
518 /// |
|
519 ///\note After you restored a state, you cannot restore |
|
520 ///a later state, in other word you cannot add again the edges deleted |
|
521 ///by restore(). |
|
522 void restore() |
|
523 { |
|
524 g->restoreSnapshot(*this); |
|
525 } |
|
526 }; |
427 }; |
527 }; |
428 |
528 |
429 |
529 |
430 class SmartBpUGraphBase { |
530 class SmartBpUGraphBase { |
431 public: |
531 public: |
654 /// that <b> it does not support node and edge deletions</b>. |
754 /// that <b> it does not support node and edge deletions</b>. |
655 /// Except from this it conforms to |
755 /// Except from this it conforms to |
656 /// the \ref concept::BpUGraph "BpUGraph concept". |
756 /// the \ref concept::BpUGraph "BpUGraph concept". |
657 /// \sa concept::BpUGraph. |
757 /// \sa concept::BpUGraph. |
658 /// |
758 /// |
659 class SmartBpUGraph : public ExtendedSmartBpUGraphBase {}; |
759 class SmartBpUGraph : public ExtendedSmartBpUGraphBase { |
|
760 private: |
|
761 |
|
762 /// \brief SmartBpUGraph is \e not copy constructible. |
|
763 /// |
|
764 ///SmartBpUGraph is \e not copy constructible. |
|
765 SmartBpUGraph(const SmartBpUGraph &) : ExtendedSmartBpUGraphBase() {}; |
|
766 |
|
767 /// \brief Assignment of SmartBpUGraph to another one is \e not |
|
768 /// allowed. |
|
769 /// |
|
770 /// Assignment of SmartBpUGraph to another one is \e not allowed. |
|
771 void operator=(const SmartBpUGraph &) {} |
|
772 |
|
773 public: |
|
774 |
|
775 typedef ExtendedSmartBpUGraphBase Parent; |
|
776 |
|
777 ///Constructor |
|
778 |
|
779 ///Constructor. |
|
780 /// |
|
781 SmartBpUGraph() : ExtendedSmartBpUGraphBase() {} |
|
782 |
|
783 ///Add a new ANode to the graph. |
|
784 |
|
785 /// \return the new node. |
|
786 /// |
|
787 Node addANode() { return Parent::addANode(); } |
|
788 |
|
789 ///Add a new BNode to the graph. |
|
790 |
|
791 /// \return the new node. |
|
792 /// |
|
793 Node addBNode() { return Parent::addBNode(); } |
|
794 |
|
795 ///Add a new undirected edge to the graph. |
|
796 |
|
797 ///Add a new undirected edge to the graph with node \c s |
|
798 ///and \c t. |
|
799 ///\return the new undirected edge. |
|
800 UEdge addEdge(const Node& s, const Node& t) { |
|
801 return Parent::addEdge(s, t); |
|
802 } |
|
803 |
|
804 ///Clear the graph. |
|
805 |
|
806 ///Erase all the nodes and edges from the graph. |
|
807 /// |
|
808 void clear() { |
|
809 Parent::clear(); |
|
810 } |
|
811 |
|
812 public: |
|
813 |
|
814 class Snapshot; |
|
815 |
|
816 protected: |
|
817 |
|
818 void restoreSnapshot(const Snapshot &s) |
|
819 { |
|
820 while(s.edge_num<edges.size()) { |
|
821 UEdge edge = uEdgeFromId(edges.size()-1); |
|
822 Parent::getNotifier(UEdge()).erase(edge); |
|
823 std::vector<Edge> dir; |
|
824 dir.push_back(Parent::direct(edge, true)); |
|
825 dir.push_back(Parent::direct(edge, false)); |
|
826 Parent::getNotifier(Edge()).erase(dir); |
|
827 aNodes[edges.back().aNode >> 1].first=edges.back().next_out; |
|
828 bNodes[edges.back().bNode >> 1].first=edges.back().next_in; |
|
829 edges.pop_back(); |
|
830 } |
|
831 while(s.anode_num<aNodes.size()) { |
|
832 Node node = fromANodeId(aNodes.size() - 1); |
|
833 Parent::getNotifier(ANode()).erase(node); |
|
834 Parent::getNotifier(Node()).erase(node); |
|
835 aNodes.pop_back(); |
|
836 } |
|
837 while(s.bnode_num<bNodes.size()) { |
|
838 Node node = fromBNodeId(bNodes.size() - 1); |
|
839 Parent::getNotifier(BNode()).erase(node); |
|
840 Parent::getNotifier(Node()).erase(node); |
|
841 bNodes.pop_back(); |
|
842 } |
|
843 } |
|
844 |
|
845 public: |
|
846 |
|
847 ///Class to make a snapshot of the graph and to restrore to it later. |
|
848 |
|
849 ///Class to make a snapshot of the graph and to restrore to it later. |
|
850 /// |
|
851 ///The newly added nodes and edges can be removed using the |
|
852 ///restore() function. |
|
853 /// |
|
854 ///\note After you restore a state, you cannot restore |
|
855 ///a later state, in other word you cannot add again the edges deleted |
|
856 ///by restore() using another one Snapshot instance. |
|
857 /// |
|
858 ///\warning If you do not use correctly the snapshot that can cause |
|
859 ///either broken program, invalid state of the graph, valid but |
|
860 ///not the restored graph or no change. Because the runtime performance |
|
861 ///the validity of the snapshot is not stored. |
|
862 class Snapshot |
|
863 { |
|
864 SmartBpUGraph *g; |
|
865 protected: |
|
866 friend class SmartBpUGraph; |
|
867 unsigned int anode_num; |
|
868 unsigned int bnode_num; |
|
869 unsigned int edge_num; |
|
870 public: |
|
871 ///Default constructor. |
|
872 |
|
873 ///Default constructor. |
|
874 ///To actually make a snapshot you must call save(). |
|
875 /// |
|
876 Snapshot() : g(0) {} |
|
877 |
|
878 ///Constructor that immediately makes a snapshot |
|
879 |
|
880 ///This constructor immediately makes a snapshot of the graph. |
|
881 ///\param _g The graph we make a snapshot of. |
|
882 Snapshot(SmartBpUGraph &_g) : g(&_g) { |
|
883 anode_num=g->aNodes.size(); |
|
884 bnode_num=g->bNodes.size(); |
|
885 edge_num=g->edges.size(); |
|
886 } |
|
887 |
|
888 ///Make a snapshot. |
|
889 |
|
890 ///Make a snapshot of the graph. |
|
891 /// |
|
892 ///This function can be called more than once. In case of a repeated |
|
893 ///call, the previous snapshot gets lost. |
|
894 ///\param _g The graph we make the snapshot of. |
|
895 void save(SmartBpUGraph &_g) |
|
896 { |
|
897 g=&_g; |
|
898 anode_num=g->aNodes.size(); |
|
899 bnode_num=g->bNodes.size(); |
|
900 edge_num=g->edges.size(); |
|
901 } |
|
902 |
|
903 ///Undo the changes until a snapshot. |
|
904 |
|
905 ///Undo the changes until a snapshot created by save(). |
|
906 /// |
|
907 ///\note After you restored a state, you cannot restore |
|
908 ///a later state, in other word you cannot add again the edges deleted |
|
909 ///by restore(). |
|
910 void restore() |
|
911 { |
|
912 g->restoreSnapshot(*this); |
|
913 } |
|
914 }; |
|
915 }; |
660 |
916 |
661 |
917 |
662 /// @} |
918 /// @} |
663 } //namespace lemon |
919 } //namespace lemon |
664 |
920 |