1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
3 * This file is a part of LEMON, a generic C++ optimization library.
5 * Copyright (C) 2003-2010
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
19 #ifndef LEMON_SMART_GRAPH_H
20 #define LEMON_SMART_GRAPH_H
24 ///\brief SmartDigraph and SmartGraph classes.
28 #include <lemon/core.h>
29 #include <lemon/error.h>
30 #include <lemon/bits/graph_extender.h>
36 class SmartDigraphBase {
41 int first_in, first_out;
46 int target, source, next_in, next_out;
50 std::vector<NodeT> nodes;
51 std::vector<ArcT> arcs;
55 typedef SmartDigraphBase Digraph;
62 SmartDigraphBase() : nodes(), arcs() { }
63 SmartDigraphBase(const SmartDigraphBase &_g)
64 : nodes(_g.nodes), arcs(_g.arcs) { }
66 typedef True NodeNumTag;
67 typedef True ArcNumTag;
69 int nodeNum() const { return nodes.size(); }
70 int arcNum() const { return arcs.size(); }
72 int maxNodeId() const { return nodes.size()-1; }
73 int maxArcId() const { return arcs.size()-1; }
77 nodes.push_back(NodeT());
78 nodes[n].first_in = -1;
79 nodes[n].first_out = -1;
83 Arc addArc(Node u, Node v) {
85 arcs.push_back(ArcT());
86 arcs[n].source = u._id;
87 arcs[n].target = v._id;
88 arcs[n].next_out = nodes[u._id].first_out;
89 arcs[n].next_in = nodes[v._id].first_in;
90 nodes[u._id].first_out = nodes[v._id].first_in = n;
100 Node source(Arc a) const { return Node(arcs[a._id].source); }
101 Node target(Arc a) const { return Node(arcs[a._id].target); }
103 static int id(Node v) { return v._id; }
104 static int id(Arc a) { return a._id; }
106 static Node nodeFromId(int id) { return Node(id);}
107 static Arc arcFromId(int id) { return Arc(id);}
109 bool valid(Node n) const {
110 return n._id >= 0 && n._id < static_cast<int>(nodes.size());
112 bool valid(Arc a) const {
113 return a._id >= 0 && a._id < static_cast<int>(arcs.size());
117 friend class SmartDigraphBase;
118 friend class SmartDigraph;
122 explicit Node(int id) : _id(id) {}
125 Node (Invalid) : _id(-1) {}
126 bool operator==(const Node i) const {return _id == i._id;}
127 bool operator!=(const Node i) const {return _id != i._id;}
128 bool operator<(const Node i) const {return _id < i._id;}
133 friend class SmartDigraphBase;
134 friend class SmartDigraph;
138 explicit Arc(int id) : _id(id) {}
141 Arc (Invalid) : _id(-1) {}
142 bool operator==(const Arc i) const {return _id == i._id;}
143 bool operator!=(const Arc i) const {return _id != i._id;}
144 bool operator<(const Arc i) const {return _id < i._id;}
147 void first(Node& node) const {
148 node._id = nodes.size() - 1;
151 static void next(Node& node) {
155 void first(Arc& arc) const {
156 arc._id = arcs.size() - 1;
159 static void next(Arc& arc) {
163 void firstOut(Arc& arc, const Node& node) const {
164 arc._id = nodes[node._id].first_out;
167 void nextOut(Arc& arc) const {
168 arc._id = arcs[arc._id].next_out;
171 void firstIn(Arc& arc, const Node& node) const {
172 arc._id = nodes[node._id].first_in;
175 void nextIn(Arc& arc) const {
176 arc._id = arcs[arc._id].next_in;
181 typedef DigraphExtender<SmartDigraphBase> ExtendedSmartDigraphBase;
185 ///\brief A smart directed graph class.
187 ///\ref SmartDigraph is a simple and fast digraph implementation.
188 ///It is also quite memory efficient but at the price
189 ///that it does not support node and arc deletion
190 ///(except for the Snapshot feature).
192 ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
193 ///and it also provides some additional functionalities.
194 ///Most of its member functions and nested classes are documented
195 ///only in the concept class.
197 ///This class provides constant time counting for nodes and arcs.
199 ///\sa concepts::Digraph
201 class SmartDigraph : public ExtendedSmartDigraphBase {
202 typedef ExtendedSmartDigraphBase Parent;
205 /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
206 SmartDigraph(const SmartDigraph &) : ExtendedSmartDigraphBase() {};
207 /// \brief Assignment of a digraph to another one is \e not allowed.
208 /// Use DigraphCopy instead.
209 void operator=(const SmartDigraph &) {}
219 ///Add a new node to the digraph.
221 ///This function adds a new node to the digraph.
222 ///\return The new node.
223 Node addNode() { return Parent::addNode(); }
225 ///Add a new arc to the digraph.
227 ///This function adds a new arc to the digraph with source node \c s
228 ///and target node \c t.
229 ///\return The new arc.
230 Arc addArc(Node s, Node t) {
231 return Parent::addArc(s, t);
234 /// \brief Node validity check
236 /// This function gives back \c true if the given node is valid,
237 /// i.e. it is a real node of the digraph.
239 /// \warning A removed node (using Snapshot) could become valid again
240 /// if new nodes are added to the digraph.
241 bool valid(Node n) const { return Parent::valid(n); }
243 /// \brief Arc validity check
245 /// This function gives back \c true if the given arc is valid,
246 /// i.e. it is a real arc of the digraph.
248 /// \warning A removed arc (using Snapshot) could become valid again
249 /// if new arcs are added to the graph.
250 bool valid(Arc a) const { return Parent::valid(a); }
254 ///This function splits the given node. First, a new node is added
255 ///to the digraph, then the source of each outgoing arc of node \c n
256 ///is moved to this new node.
257 ///If the second parameter \c connect is \c true (this is the default
258 ///value), then a new arc from node \c n to the newly created node
260 ///\return The newly created node.
262 ///\note All iterators remain valid.
264 ///\warning This functionality cannot be used together with the Snapshot
266 Node split(Node n, bool connect = true)
269 nodes[b._id].first_out=nodes[n._id].first_out;
270 nodes[n._id].first_out=-1;
271 for(int i=nodes[b._id].first_out; i!=-1; i=arcs[i].next_out) {
272 arcs[i].source=b._id;
274 if(connect) addArc(n,b);
278 ///Clear the digraph.
280 ///This function erases all nodes and arcs from the digraph.
286 /// Reserve memory for nodes.
288 /// Using this function, it is possible to avoid superfluous memory
289 /// allocation: if you know that the digraph you want to build will
290 /// be large (e.g. it will contain millions of nodes and/or arcs),
291 /// then it is worth reserving space for this amount before starting
292 /// to build the digraph.
294 void reserveNode(int n) { nodes.reserve(n); };
296 /// Reserve memory for arcs.
298 /// Using this function, it is possible to avoid superfluous memory
299 /// allocation: if you know that the digraph you want to build will
300 /// be large (e.g. it will contain millions of nodes and/or arcs),
301 /// then it is worth reserving space for this amount before starting
302 /// to build the digraph.
303 /// \sa reserveNode()
304 void reserveArc(int m) { arcs.reserve(m); };
312 void restoreSnapshot(const Snapshot &s)
314 while(s.arc_num<arcs.size()) {
315 Arc arc = arcFromId(arcs.size()-1);
316 Parent::notifier(Arc()).erase(arc);
317 nodes[arcs.back().source].first_out=arcs.back().next_out;
318 nodes[arcs.back().target].first_in=arcs.back().next_in;
321 while(s.node_num<nodes.size()) {
322 Node node = nodeFromId(nodes.size()-1);
323 Parent::notifier(Node()).erase(node);
330 ///Class to make a snapshot of the digraph and to restore it later.
332 ///Class to make a snapshot of the digraph and to restore it later.
334 ///The newly added nodes and arcs can be removed using the
335 ///restore() function. This is the only way for deleting nodes and/or
336 ///arcs from a SmartDigraph structure.
338 ///\note After a state is restored, you cannot restore a later state,
339 ///i.e. you cannot add the removed nodes and arcs again using
340 ///another Snapshot instance.
342 ///\warning Node splitting cannot be restored.
343 ///\warning The validity of the snapshot is not stored due to
344 ///performance reasons. If you do not use the snapshot correctly,
345 ///it can cause broken program, invalid or not restored state of
346 ///the digraph or no change.
349 SmartDigraph *_graph;
351 friend class SmartDigraph;
352 unsigned int node_num;
353 unsigned int arc_num;
355 ///Default constructor.
357 ///Default constructor.
358 ///You have to call save() to actually make a snapshot.
359 Snapshot() : _graph(0) {}
360 ///Constructor that immediately makes a snapshot
362 ///This constructor immediately makes a snapshot of the given digraph.
364 Snapshot(SmartDigraph &gr) : _graph(&gr) {
365 node_num=_graph->nodes.size();
366 arc_num=_graph->arcs.size();
371 ///This function makes a snapshot of the given digraph.
372 ///It can be called more than once. In case of a repeated
373 ///call, the previous snapshot gets lost.
374 void save(SmartDigraph &gr) {
376 node_num=_graph->nodes.size();
377 arc_num=_graph->arcs.size();
380 ///Undo the changes until a snapshot.
382 ///This function undos the changes until the last snapshot
383 ///created by save() or Snapshot(SmartDigraph&).
386 _graph->restoreSnapshot(*this);
392 class SmartGraphBase {
405 std::vector<NodeT> nodes;
406 std::vector<ArcT> arcs;
412 typedef SmartGraphBase Graph;
419 friend class SmartGraphBase;
423 explicit Node(int id) { _id = id;}
427 Node (Invalid) { _id = -1; }
428 bool operator==(const Node& node) const {return _id == node._id;}
429 bool operator!=(const Node& node) const {return _id != node._id;}
430 bool operator<(const Node& node) const {return _id < node._id;}
434 friend class SmartGraphBase;
438 explicit Edge(int id) { _id = id;}
442 Edge (Invalid) { _id = -1; }
443 bool operator==(const Edge& arc) const {return _id == arc._id;}
444 bool operator!=(const Edge& arc) const {return _id != arc._id;}
445 bool operator<(const Edge& arc) const {return _id < arc._id;}
449 friend class SmartGraphBase;
453 explicit Arc(int id) { _id = id;}
456 operator Edge() const {
457 return _id != -1 ? edgeFromId(_id / 2) : INVALID;
461 Arc (Invalid) { _id = -1; }
462 bool operator==(const Arc& arc) const {return _id == arc._id;}
463 bool operator!=(const Arc& arc) const {return _id != arc._id;}
464 bool operator<(const Arc& arc) const {return _id < arc._id;}
472 typedef True NodeNumTag;
473 typedef True EdgeNumTag;
474 typedef True ArcNumTag;
476 int nodeNum() const { return nodes.size(); }
477 int edgeNum() const { return arcs.size() / 2; }
478 int arcNum() const { return arcs.size(); }
480 int maxNodeId() const { return nodes.size()-1; }
481 int maxEdgeId() const { return arcs.size() / 2 - 1; }
482 int maxArcId() const { return arcs.size()-1; }
484 Node source(Arc e) const { return Node(arcs[e._id ^ 1].target); }
485 Node target(Arc e) const { return Node(arcs[e._id].target); }
487 Node u(Edge e) const { return Node(arcs[2 * e._id].target); }
488 Node v(Edge e) const { return Node(arcs[2 * e._id + 1].target); }
490 static bool direction(Arc e) {
491 return (e._id & 1) == 1;
494 static Arc direct(Edge e, bool d) {
495 return Arc(e._id * 2 + (d ? 1 : 0));
498 void first(Node& node) const {
499 node._id = nodes.size() - 1;
502 static void next(Node& node) {
506 void first(Arc& arc) const {
507 arc._id = arcs.size() - 1;
510 static void next(Arc& arc) {
514 void first(Edge& arc) const {
515 arc._id = arcs.size() / 2 - 1;
518 static void next(Edge& arc) {
522 void firstOut(Arc &arc, const Node& v) const {
523 arc._id = nodes[v._id].first_out;
525 void nextOut(Arc &arc) const {
526 arc._id = arcs[arc._id].next_out;
529 void firstIn(Arc &arc, const Node& v) const {
530 arc._id = ((nodes[v._id].first_out) ^ 1);
531 if (arc._id == -2) arc._id = -1;
533 void nextIn(Arc &arc) const {
534 arc._id = ((arcs[arc._id ^ 1].next_out) ^ 1);
535 if (arc._id == -2) arc._id = -1;
538 void firstInc(Edge &arc, bool& d, const Node& v) const {
539 int de = nodes[v._id].first_out;
548 void nextInc(Edge &arc, bool& d) const {
549 int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);
559 static int id(Node v) { return v._id; }
560 static int id(Arc e) { return e._id; }
561 static int id(Edge e) { return e._id; }
563 static Node nodeFromId(int id) { return Node(id);}
564 static Arc arcFromId(int id) { return Arc(id);}
565 static Edge edgeFromId(int id) { return Edge(id);}
567 bool valid(Node n) const {
568 return n._id >= 0 && n._id < static_cast<int>(nodes.size());
570 bool valid(Arc a) const {
571 return a._id >= 0 && a._id < static_cast<int>(arcs.size());
573 bool valid(Edge e) const {
574 return e._id >= 0 && 2 * e._id < static_cast<int>(arcs.size());
578 int n = nodes.size();
579 nodes.push_back(NodeT());
580 nodes[n].first_out = -1;
585 Edge addEdge(Node u, Node v) {
587 arcs.push_back(ArcT());
588 arcs.push_back(ArcT());
590 arcs[n].target = u._id;
591 arcs[n | 1].target = v._id;
593 arcs[n].next_out = nodes[v._id].first_out;
594 nodes[v._id].first_out = n;
596 arcs[n | 1].next_out = nodes[u._id].first_out;
597 nodes[u._id].first_out = (n | 1);
609 typedef GraphExtender<SmartGraphBase> ExtendedSmartGraphBase;
613 /// \brief A smart undirected graph class.
615 /// \ref SmartGraph is a simple and fast graph implementation.
616 /// It is also quite memory efficient but at the price
617 /// that it does not support node and edge deletion
618 /// (except for the Snapshot feature).
620 /// This type fully conforms to the \ref concepts::Graph "Graph concept"
621 /// and it also provides some additional functionalities.
622 /// Most of its member functions and nested classes are documented
623 /// only in the concept class.
625 /// This class provides constant time counting for nodes, edges and arcs.
627 /// \sa concepts::Graph
629 class SmartGraph : public ExtendedSmartGraphBase {
630 typedef ExtendedSmartGraphBase Parent;
633 /// Graphs are \e not copy constructible. Use GraphCopy instead.
634 SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {};
635 /// \brief Assignment of a graph to another one is \e not allowed.
636 /// Use GraphCopy instead.
637 void operator=(const SmartGraph &) {}
647 /// \brief Add a new node to the graph.
649 /// This function adds a new node to the graph.
650 /// \return The new node.
651 Node addNode() { return Parent::addNode(); }
653 /// \brief Add a new edge to the graph.
655 /// This function adds a new edge to the graph between nodes
656 /// \c u and \c v with inherent orientation from node \c u to
658 /// \return The new edge.
659 Edge addEdge(Node u, Node v) {
660 return Parent::addEdge(u, v);
663 /// \brief Node validity check
665 /// This function gives back \c true if the given node is valid,
666 /// i.e. it is a real node of the graph.
668 /// \warning A removed node (using Snapshot) could become valid again
669 /// if new nodes are added to the graph.
670 bool valid(Node n) const { return Parent::valid(n); }
672 /// \brief Edge validity check
674 /// This function gives back \c true if the given edge is valid,
675 /// i.e. it is a real edge of the graph.
677 /// \warning A removed edge (using Snapshot) could become valid again
678 /// if new edges are added to the graph.
679 bool valid(Edge e) const { return Parent::valid(e); }
681 /// \brief Arc validity check
683 /// This function gives back \c true if the given arc is valid,
684 /// i.e. it is a real arc of the graph.
686 /// \warning A removed arc (using Snapshot) could become valid again
687 /// if new edges are added to the graph.
688 bool valid(Arc a) const { return Parent::valid(a); }
692 ///This function erases all nodes and arcs from the graph.
698 /// Reserve memory for nodes.
700 /// Using this function, it is possible to avoid superfluous memory
701 /// allocation: if you know that the graph you want to build will
702 /// be large (e.g. it will contain millions of nodes and/or edges),
703 /// then it is worth reserving space for this amount before starting
704 /// to build the graph.
705 /// \sa reserveEdge()
706 void reserveNode(int n) { nodes.reserve(n); };
708 /// Reserve memory for edges.
710 /// Using this function, it is possible to avoid superfluous memory
711 /// allocation: if you know that the graph you want to build will
712 /// be large (e.g. it will contain millions of nodes and/or edges),
713 /// then it is worth reserving space for this amount before starting
714 /// to build the graph.
715 /// \sa reserveNode()
716 void reserveEdge(int m) { arcs.reserve(2 * m); };
724 void saveSnapshot(Snapshot &s)
727 s.node_num = nodes.size();
728 s.arc_num = arcs.size();
731 void restoreSnapshot(const Snapshot &s)
733 while(s.arc_num<arcs.size()) {
735 Edge arc=edgeFromId(n/2);
736 Parent::notifier(Edge()).erase(arc);
737 std::vector<Arc> dir;
738 dir.push_back(arcFromId(n));
739 dir.push_back(arcFromId(n-1));
740 Parent::notifier(Arc()).erase(dir);
741 nodes[arcs[n-1].target].first_out=arcs[n].next_out;
742 nodes[arcs[n].target].first_out=arcs[n-1].next_out;
746 while(s.node_num<nodes.size()) {
747 int n=nodes.size()-1;
748 Node node = nodeFromId(n);
749 Parent::notifier(Node()).erase(node);
756 ///Class to make a snapshot of the graph and to restore it later.
758 ///Class to make a snapshot of the graph and to restore it later.
760 ///The newly added nodes and edges can be removed using the
761 ///restore() function. This is the only way for deleting nodes and/or
762 ///edges from a SmartGraph structure.
764 ///\note After a state is restored, you cannot restore a later state,
765 ///i.e. you cannot add the removed nodes and edges again using
766 ///another Snapshot instance.
768 ///\warning The validity of the snapshot is not stored due to
769 ///performance reasons. If you do not use the snapshot correctly,
770 ///it can cause broken program, invalid or not restored state of
771 ///the graph or no change.
776 friend class SmartGraph;
777 unsigned int node_num;
778 unsigned int arc_num;
780 ///Default constructor.
782 ///Default constructor.
783 ///You have to call save() to actually make a snapshot.
784 Snapshot() : _graph(0) {}
785 ///Constructor that immediately makes a snapshot
787 /// This constructor immediately makes a snapshot of the given graph.
789 Snapshot(SmartGraph &gr) {
790 gr.saveSnapshot(*this);
795 ///This function makes a snapshot of the given graph.
796 ///It can be called more than once. In case of a repeated
797 ///call, the previous snapshot gets lost.
798 void save(SmartGraph &gr)
800 gr.saveSnapshot(*this);
803 ///Undo the changes until the last snapshot.
805 ///This function undos the changes until the last snapshot
806 ///created by save() or Snapshot(SmartGraph&).
809 _graph->restoreSnapshot(*this);
817 #endif //LEMON_SMART_GRAPH_H