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;
410 typedef SmartGraphBase Graph;
417 friend class SmartGraphBase;
421 explicit Node(int id) { _id = id;}
425 Node (Invalid) { _id = -1; }
426 bool operator==(const Node& node) const {return _id == node._id;}
427 bool operator!=(const Node& node) const {return _id != node._id;}
428 bool operator<(const Node& node) const {return _id < node._id;}
432 friend class SmartGraphBase;
436 explicit Edge(int id) { _id = id;}
440 Edge (Invalid) { _id = -1; }
441 bool operator==(const Edge& arc) const {return _id == arc._id;}
442 bool operator!=(const Edge& arc) const {return _id != arc._id;}
443 bool operator<(const Edge& arc) const {return _id < arc._id;}
447 friend class SmartGraphBase;
451 explicit Arc(int id) { _id = id;}
454 operator Edge() const {
455 return _id != -1 ? edgeFromId(_id / 2) : INVALID;
459 Arc (Invalid) { _id = -1; }
460 bool operator==(const Arc& arc) const {return _id == arc._id;}
461 bool operator!=(const Arc& arc) const {return _id != arc._id;}
462 bool operator<(const Arc& arc) const {return _id < arc._id;}
470 typedef True NodeNumTag;
471 typedef True EdgeNumTag;
472 typedef True ArcNumTag;
474 int nodeNum() const { return nodes.size(); }
475 int edgeNum() const { return arcs.size() / 2; }
476 int arcNum() const { return arcs.size(); }
478 int maxNodeId() const { return nodes.size()-1; }
479 int maxEdgeId() const { return arcs.size() / 2 - 1; }
480 int maxArcId() const { return arcs.size()-1; }
482 Node source(Arc e) const { return Node(arcs[e._id ^ 1].target); }
483 Node target(Arc e) const { return Node(arcs[e._id].target); }
485 Node u(Edge e) const { return Node(arcs[2 * e._id].target); }
486 Node v(Edge e) const { return Node(arcs[2 * e._id + 1].target); }
488 static bool direction(Arc e) {
489 return (e._id & 1) == 1;
492 static Arc direct(Edge e, bool d) {
493 return Arc(e._id * 2 + (d ? 1 : 0));
496 void first(Node& node) const {
497 node._id = nodes.size() - 1;
500 static void next(Node& node) {
504 void first(Arc& arc) const {
505 arc._id = arcs.size() - 1;
508 static void next(Arc& arc) {
512 void first(Edge& arc) const {
513 arc._id = arcs.size() / 2 - 1;
516 static void next(Edge& arc) {
520 void firstOut(Arc &arc, const Node& v) const {
521 arc._id = nodes[v._id].first_out;
523 void nextOut(Arc &arc) const {
524 arc._id = arcs[arc._id].next_out;
527 void firstIn(Arc &arc, const Node& v) const {
528 arc._id = ((nodes[v._id].first_out) ^ 1);
529 if (arc._id == -2) arc._id = -1;
531 void nextIn(Arc &arc) const {
532 arc._id = ((arcs[arc._id ^ 1].next_out) ^ 1);
533 if (arc._id == -2) arc._id = -1;
536 void firstInc(Edge &arc, bool& d, const Node& v) const {
537 int de = nodes[v._id].first_out;
546 void nextInc(Edge &arc, bool& d) const {
547 int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);
557 static int id(Node v) { return v._id; }
558 static int id(Arc e) { return e._id; }
559 static int id(Edge e) { return e._id; }
561 static Node nodeFromId(int id) { return Node(id);}
562 static Arc arcFromId(int id) { return Arc(id);}
563 static Edge edgeFromId(int id) { return Edge(id);}
565 bool valid(Node n) const {
566 return n._id >= 0 && n._id < static_cast<int>(nodes.size());
568 bool valid(Arc a) const {
569 return a._id >= 0 && a._id < static_cast<int>(arcs.size());
571 bool valid(Edge e) const {
572 return e._id >= 0 && 2 * e._id < static_cast<int>(arcs.size());
576 int n = nodes.size();
577 nodes.push_back(NodeT());
578 nodes[n].first_out = -1;
583 Edge addEdge(Node u, Node v) {
585 arcs.push_back(ArcT());
586 arcs.push_back(ArcT());
588 arcs[n].target = u._id;
589 arcs[n | 1].target = v._id;
591 arcs[n].next_out = nodes[v._id].first_out;
592 nodes[v._id].first_out = n;
594 arcs[n | 1].next_out = nodes[u._id].first_out;
595 nodes[u._id].first_out = (n | 1);
607 typedef GraphExtender<SmartGraphBase> ExtendedSmartGraphBase;
611 /// \brief A smart undirected graph class.
613 /// \ref SmartGraph is a simple and fast graph implementation.
614 /// It is also quite memory efficient but at the price
615 /// that it does not support node and edge deletion
616 /// (except for the Snapshot feature).
618 /// This type fully conforms to the \ref concepts::Graph "Graph concept"
619 /// and it also provides some additional functionalities.
620 /// Most of its member functions and nested classes are documented
621 /// only in the concept class.
623 /// This class provides constant time counting for nodes, edges and arcs.
625 /// \sa concepts::Graph
627 class SmartGraph : public ExtendedSmartGraphBase {
628 typedef ExtendedSmartGraphBase Parent;
631 /// Graphs are \e not copy constructible. Use GraphCopy instead.
632 SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {};
633 /// \brief Assignment of a graph to another one is \e not allowed.
634 /// Use GraphCopy instead.
635 void operator=(const SmartGraph &) {}
645 /// \brief Add a new node to the graph.
647 /// This function adds a new node to the graph.
648 /// \return The new node.
649 Node addNode() { return Parent::addNode(); }
651 /// \brief Add a new edge to the graph.
653 /// This function adds a new edge to the graph between nodes
654 /// \c u and \c v with inherent orientation from node \c u to
656 /// \return The new edge.
657 Edge addEdge(Node u, Node v) {
658 return Parent::addEdge(u, v);
661 /// \brief Node validity check
663 /// This function gives back \c true if the given node is valid,
664 /// i.e. it is a real node of the graph.
666 /// \warning A removed node (using Snapshot) could become valid again
667 /// if new nodes are added to the graph.
668 bool valid(Node n) const { return Parent::valid(n); }
670 /// \brief Edge validity check
672 /// This function gives back \c true if the given edge is valid,
673 /// i.e. it is a real edge of the graph.
675 /// \warning A removed edge (using Snapshot) could become valid again
676 /// if new edges are added to the graph.
677 bool valid(Edge e) const { return Parent::valid(e); }
679 /// \brief Arc validity check
681 /// This function gives back \c true if the given arc is valid,
682 /// i.e. it is a real arc of the graph.
684 /// \warning A removed arc (using Snapshot) could become valid again
685 /// if new edges are added to the graph.
686 bool valid(Arc a) const { return Parent::valid(a); }
690 ///This function erases all nodes and arcs from the graph.
696 /// Reserve memory for nodes.
698 /// Using this function, it is possible to avoid superfluous memory
699 /// allocation: if you know that the graph you want to build will
700 /// be large (e.g. it will contain millions of nodes and/or edges),
701 /// then it is worth reserving space for this amount before starting
702 /// to build the graph.
703 /// \sa reserveEdge()
704 void reserveNode(int n) { nodes.reserve(n); };
706 /// Reserve memory for edges.
708 /// Using this function, it is possible to avoid superfluous memory
709 /// allocation: if you know that the graph you want to build will
710 /// be large (e.g. it will contain millions of nodes and/or edges),
711 /// then it is worth reserving space for this amount before starting
712 /// to build the graph.
713 /// \sa reserveNode()
714 void reserveEdge(int m) { arcs.reserve(2 * m); };
722 void saveSnapshot(Snapshot &s)
725 s.node_num = nodes.size();
726 s.arc_num = arcs.size();
729 void restoreSnapshot(const Snapshot &s)
731 while(s.arc_num<arcs.size()) {
733 Edge arc=edgeFromId(n/2);
734 Parent::notifier(Edge()).erase(arc);
735 std::vector<Arc> dir;
736 dir.push_back(arcFromId(n));
737 dir.push_back(arcFromId(n-1));
738 Parent::notifier(Arc()).erase(dir);
739 nodes[arcs[n-1].target].first_out=arcs[n].next_out;
740 nodes[arcs[n].target].first_out=arcs[n-1].next_out;
744 while(s.node_num<nodes.size()) {
745 int n=nodes.size()-1;
746 Node node = nodeFromId(n);
747 Parent::notifier(Node()).erase(node);
754 ///Class to make a snapshot of the graph and to restore it later.
756 ///Class to make a snapshot of the graph and to restore it later.
758 ///The newly added nodes and edges can be removed using the
759 ///restore() function. This is the only way for deleting nodes and/or
760 ///edges from a SmartGraph structure.
762 ///\note After a state is restored, you cannot restore a later state,
763 ///i.e. you cannot add the removed nodes and edges again using
764 ///another Snapshot instance.
766 ///\warning The validity of the snapshot is not stored due to
767 ///performance reasons. If you do not use the snapshot correctly,
768 ///it can cause broken program, invalid or not restored state of
769 ///the graph or no change.
774 friend class SmartGraph;
775 unsigned int node_num;
776 unsigned int arc_num;
778 ///Default constructor.
780 ///Default constructor.
781 ///You have to call save() to actually make a snapshot.
782 Snapshot() : _graph(0) {}
783 ///Constructor that immediately makes a snapshot
785 /// This constructor immediately makes a snapshot of the given graph.
787 Snapshot(SmartGraph &gr) {
788 gr.saveSnapshot(*this);
793 ///This function makes a snapshot of the given graph.
794 ///It can be called more than once. In case of a repeated
795 ///call, the previous snapshot gets lost.
796 void save(SmartGraph &gr)
798 gr.saveSnapshot(*this);
801 ///Undo the changes until the last snapshot.
803 ///This function undos the changes until the last snapshot
804 ///created by save() or Snapshot(SmartGraph&).
807 _graph->restoreSnapshot(*this);
812 class SmartBpGraphBase {
828 std::vector<NodeT> nodes;
829 std::vector<ArcT> arcs;
831 int first_red, first_blue;
832 int max_red, max_blue;
836 typedef SmartBpGraphBase Graph;
843 friend class SmartBpGraphBase;
847 explicit Node(int id) { _id = id;}
851 Node (Invalid) { _id = -1; }
852 bool operator==(const Node& node) const {return _id == node._id;}
853 bool operator!=(const Node& node) const {return _id != node._id;}
854 bool operator<(const Node& node) const {return _id < node._id;}
857 class RedNode : public Node {
858 friend class SmartBpGraphBase;
861 explicit RedNode(int pid) : Node(pid) {}
865 RedNode(const RedNode& node) : Node(node) {}
866 RedNode(Invalid) : Node(INVALID){}
869 class BlueNode : public Node {
870 friend class SmartBpGraphBase;
873 explicit BlueNode(int pid) : Node(pid) {}
877 BlueNode(const BlueNode& node) : Node(node) {}
878 BlueNode(Invalid) : Node(INVALID){}
882 friend class SmartBpGraphBase;
886 explicit Edge(int id) { _id = id;}
890 Edge (Invalid) { _id = -1; }
891 bool operator==(const Edge& arc) const {return _id == arc._id;}
892 bool operator!=(const Edge& arc) const {return _id != arc._id;}
893 bool operator<(const Edge& arc) const {return _id < arc._id;}
897 friend class SmartBpGraphBase;
901 explicit Arc(int id) { _id = id;}
904 operator Edge() const {
905 return _id != -1 ? edgeFromId(_id / 2) : INVALID;
909 Arc (Invalid) { _id = -1; }
910 bool operator==(const Arc& arc) const {return _id == arc._id;}
911 bool operator!=(const Arc& arc) const {return _id != arc._id;}
912 bool operator<(const Arc& arc) const {return _id < arc._id;}
918 : nodes(), arcs(), first_red(-1), first_blue(-1),
919 max_red(-1), max_blue(-1) {}
921 typedef True NodeNumTag;
922 typedef True EdgeNumTag;
923 typedef True ArcNumTag;
925 int nodeNum() const { return nodes.size(); }
926 int redNum() const { return max_red + 1; }
927 int blueNum() const { return max_blue + 1; }
928 int edgeNum() const { return arcs.size() / 2; }
929 int arcNum() const { return arcs.size(); }
931 int maxNodeId() const { return nodes.size()-1; }
932 int maxRedId() const { return max_red; }
933 int maxBlueId() const { return max_blue; }
934 int maxEdgeId() const { return arcs.size() / 2 - 1; }
935 int maxArcId() const { return arcs.size()-1; }
937 bool red(Node n) const { return nodes[n._id].red; }
938 bool blue(Node n) const { return !nodes[n._id].red; }
940 static RedNode asRedNodeUnsafe(Node n) { return RedNode(n._id); }
941 static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n._id); }
943 Node source(Arc a) const { return Node(arcs[a._id ^ 1].target); }
944 Node target(Arc a) const { return Node(arcs[a._id].target); }
946 RedNode redNode(Edge e) const {
947 return RedNode(arcs[2 * e._id].target);
949 BlueNode blueNode(Edge e) const {
950 return BlueNode(arcs[2 * e._id + 1].target);
953 static bool direction(Arc a) {
954 return (a._id & 1) == 1;
957 static Arc direct(Edge e, bool d) {
958 return Arc(e._id * 2 + (d ? 1 : 0));
961 void first(Node& node) const {
962 node._id = nodes.size() - 1;
965 static void next(Node& node) {
969 void first(RedNode& node) const {
970 node._id = first_red;
973 void next(RedNode& node) const {
974 node._id = nodes[node._id].partition_next;
977 void first(BlueNode& node) const {
978 node._id = first_blue;
981 void next(BlueNode& node) const {
982 node._id = nodes[node._id].partition_next;
985 void first(Arc& arc) const {
986 arc._id = arcs.size() - 1;
989 static void next(Arc& arc) {
993 void first(Edge& arc) const {
994 arc._id = arcs.size() / 2 - 1;
997 static void next(Edge& arc) {
1001 void firstOut(Arc &arc, const Node& v) const {
1002 arc._id = nodes[v._id].first_out;
1004 void nextOut(Arc &arc) const {
1005 arc._id = arcs[arc._id].next_out;
1008 void firstIn(Arc &arc, const Node& v) const {
1009 arc._id = ((nodes[v._id].first_out) ^ 1);
1010 if (arc._id == -2) arc._id = -1;
1012 void nextIn(Arc &arc) const {
1013 arc._id = ((arcs[arc._id ^ 1].next_out) ^ 1);
1014 if (arc._id == -2) arc._id = -1;
1017 void firstInc(Edge &arc, bool& d, const Node& v) const {
1018 int de = nodes[v._id].first_out;
1021 d = ((de & 1) == 1);
1027 void nextInc(Edge &arc, bool& d) const {
1028 int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);
1031 d = ((de & 1) == 1);
1038 static int id(Node v) { return v._id; }
1039 int id(RedNode v) const { return nodes[v._id].partition_index; }
1040 int id(BlueNode v) const { return nodes[v._id].partition_index; }
1041 static int id(Arc e) { return e._id; }
1042 static int id(Edge e) { return e._id; }
1044 static Node nodeFromId(int id) { return Node(id);}
1045 static Arc arcFromId(int id) { return Arc(id);}
1046 static Edge edgeFromId(int id) { return Edge(id);}
1048 bool valid(Node n) const {
1049 return n._id >= 0 && n._id < static_cast<int>(nodes.size());
1051 bool valid(Arc a) const {
1052 return a._id >= 0 && a._id < static_cast<int>(arcs.size());
1054 bool valid(Edge e) const {
1055 return e._id >= 0 && 2 * e._id < static_cast<int>(arcs.size());
1058 RedNode addRedNode() {
1059 int n = nodes.size();
1060 nodes.push_back(NodeT());
1061 nodes[n].first_out = -1;
1062 nodes[n].red = true;
1063 nodes[n].partition_index = ++max_red;
1064 nodes[n].partition_next = first_red;
1070 BlueNode addBlueNode() {
1071 int n = nodes.size();
1072 nodes.push_back(NodeT());
1073 nodes[n].first_out = -1;
1074 nodes[n].red = false;
1075 nodes[n].partition_index = ++max_blue;
1076 nodes[n].partition_next = first_blue;
1082 Edge addEdge(RedNode u, BlueNode v) {
1083 int n = arcs.size();
1084 arcs.push_back(ArcT());
1085 arcs.push_back(ArcT());
1087 arcs[n].target = u._id;
1088 arcs[n | 1].target = v._id;
1090 arcs[n].next_out = nodes[v._id].first_out;
1091 nodes[v._id].first_out = n;
1093 arcs[n | 1].next_out = nodes[u._id].first_out;
1094 nodes[u._id].first_out = (n | 1);
1110 typedef BpGraphExtender<SmartBpGraphBase> ExtendedSmartBpGraphBase;
1114 /// \brief A smart undirected bipartite graph class.
1116 /// \ref SmartBpGraph is a simple and fast bipartite graph implementation.
1117 /// It is also quite memory efficient but at the price
1118 /// that it does not support node and edge deletion
1119 /// (except for the Snapshot feature).
1121 /// This type fully conforms to the \ref concepts::BpGraph "BpGraph concept"
1122 /// and it also provides some additional functionalities.
1123 /// Most of its member functions and nested classes are documented
1124 /// only in the concept class.
1126 /// This class provides constant time counting for nodes, edges and arcs.
1128 /// \sa concepts::BpGraph
1130 class SmartBpGraph : public ExtendedSmartBpGraphBase {
1131 typedef ExtendedSmartBpGraphBase Parent;
1134 /// Graphs are \e not copy constructible. Use GraphCopy instead.
1135 SmartBpGraph(const SmartBpGraph &) : ExtendedSmartBpGraphBase() {};
1136 /// \brief Assignment of a graph to another one is \e not allowed.
1137 /// Use GraphCopy instead.
1138 void operator=(const SmartBpGraph &) {}
1148 /// \brief Add a new red node to the graph.
1150 /// This function adds a red new node to the graph.
1151 /// \return The new node.
1152 RedNode addRedNode() { return Parent::addRedNode(); }
1154 /// \brief Add a new blue node to the graph.
1156 /// This function adds a blue new node to the graph.
1157 /// \return The new node.
1158 BlueNode addBlueNode() { return Parent::addBlueNode(); }
1160 /// \brief Add a new edge to the graph.
1162 /// This function adds a new edge to the graph between nodes
1163 /// \c u and \c v with inherent orientation from node \c u to
1165 /// \return The new edge.
1166 Edge addEdge(RedNode u, BlueNode v) {
1167 return Parent::addEdge(u, v);
1169 Edge addEdge(BlueNode v, RedNode u) {
1170 return Parent::addEdge(u, v);
1173 /// \brief Node validity check
1175 /// This function gives back \c true if the given node is valid,
1176 /// i.e. it is a real node of the graph.
1178 /// \warning A removed node (using Snapshot) could become valid again
1179 /// if new nodes are added to the graph.
1180 bool valid(Node n) const { return Parent::valid(n); }
1182 /// \brief Edge validity check
1184 /// This function gives back \c true if the given edge is valid,
1185 /// i.e. it is a real edge of the graph.
1187 /// \warning A removed edge (using Snapshot) could become valid again
1188 /// if new edges are added to the graph.
1189 bool valid(Edge e) const { return Parent::valid(e); }
1191 /// \brief Arc validity check
1193 /// This function gives back \c true if the given arc is valid,
1194 /// i.e. it is a real arc of the graph.
1196 /// \warning A removed arc (using Snapshot) could become valid again
1197 /// if new edges are added to the graph.
1198 bool valid(Arc a) const { return Parent::valid(a); }
1202 ///This function erases all nodes and arcs from the graph.
1208 /// Reserve memory for nodes.
1210 /// Using this function, it is possible to avoid superfluous memory
1211 /// allocation: if you know that the graph you want to build will
1212 /// be large (e.g. it will contain millions of nodes and/or edges),
1213 /// then it is worth reserving space for this amount before starting
1214 /// to build the graph.
1215 /// \sa reserveEdge()
1216 void reserveNode(int n) { nodes.reserve(n); };
1218 /// Reserve memory for edges.
1220 /// Using this function, it is possible to avoid superfluous memory
1221 /// allocation: if you know that the graph you want to build will
1222 /// be large (e.g. it will contain millions of nodes and/or edges),
1223 /// then it is worth reserving space for this amount before starting
1224 /// to build the graph.
1225 /// \sa reserveNode()
1226 void reserveEdge(int m) { arcs.reserve(2 * m); };
1234 void saveSnapshot(Snapshot &s)
1237 s.node_num = nodes.size();
1238 s.arc_num = arcs.size();
1241 void restoreSnapshot(const Snapshot &s)
1243 while(s.arc_num<arcs.size()) {
1244 int n=arcs.size()-1;
1245 Edge arc=edgeFromId(n/2);
1246 Parent::notifier(Edge()).erase(arc);
1247 std::vector<Arc> dir;
1248 dir.push_back(arcFromId(n));
1249 dir.push_back(arcFromId(n-1));
1250 Parent::notifier(Arc()).erase(dir);
1251 nodes[arcs[n-1].target].first_out=arcs[n].next_out;
1252 nodes[arcs[n].target].first_out=arcs[n-1].next_out;
1256 while(s.node_num<nodes.size()) {
1257 int n=nodes.size()-1;
1258 Node node = nodeFromId(n);
1259 if (Parent::red(node)) {
1260 first_red = nodes[n].partition_next;
1261 if (first_red != -1) {
1262 max_red = nodes[first_red].partition_index;
1266 Parent::notifier(RedNode()).erase(asRedNodeUnsafe(node));
1268 first_blue = nodes[n].partition_next;
1269 if (first_blue != -1) {
1270 max_blue = nodes[first_blue].partition_index;
1274 Parent::notifier(BlueNode()).erase(asBlueNodeUnsafe(node));
1276 Parent::notifier(Node()).erase(node);
1283 ///Class to make a snapshot of the graph and to restore it later.
1285 ///Class to make a snapshot of the graph and to restore it later.
1287 ///The newly added nodes and edges can be removed using the
1288 ///restore() function. This is the only way for deleting nodes and/or
1289 ///edges from a SmartBpGraph structure.
1291 ///\note After a state is restored, you cannot restore a later state,
1292 ///i.e. you cannot add the removed nodes and edges again using
1293 ///another Snapshot instance.
1295 ///\warning The validity of the snapshot is not stored due to
1296 ///performance reasons. If you do not use the snapshot correctly,
1297 ///it can cause broken program, invalid or not restored state of
1298 ///the graph or no change.
1301 SmartBpGraph *_graph;
1303 friend class SmartBpGraph;
1304 unsigned int node_num;
1305 unsigned int arc_num;
1307 ///Default constructor.
1309 ///Default constructor.
1310 ///You have to call save() to actually make a snapshot.
1311 Snapshot() : _graph(0) {}
1312 ///Constructor that immediately makes a snapshot
1314 /// This constructor immediately makes a snapshot of the given graph.
1316 Snapshot(SmartBpGraph &gr) {
1317 gr.saveSnapshot(*this);
1322 ///This function makes a snapshot of the given graph.
1323 ///It can be called more than once. In case of a repeated
1324 ///call, the previous snapshot gets lost.
1325 void save(SmartBpGraph &gr)
1327 gr.saveSnapshot(*this);
1330 ///Undo the changes until the last snapshot.
1332 ///This function undos the changes until the last snapshot
1333 ///created by save() or Snapshot(SmartBpGraph&).
1336 _graph->restoreSnapshot(*this);
1344 #endif //LEMON_SMART_GRAPH_H