1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
 
     3  * This file is a part of LEMON, a generic C++ optimization library.
 
     5  * Copyright (C) 2003-2008
 
     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>
 
    35   ///Base of SmartDigraph
 
    37   ///Base of SmartDigraph
 
    39   class SmartDigraphBase {
 
    44       int first_in, first_out;
 
    49       int target, source, next_in, next_out;
 
    53     std::vector<NodeT> nodes;
 
    54     std::vector<ArcT> arcs;
 
    58     typedef SmartDigraphBase Graph;
 
    65     SmartDigraphBase() : nodes(), arcs() { }
 
    66     SmartDigraphBase(const SmartDigraphBase &_g)
 
    67       : nodes(_g.nodes), arcs(_g.arcs) { }
 
    69     typedef True NodeNumTag;
 
    70     typedef True ArcNumTag;
 
    72     int nodeNum() const { return nodes.size(); }
 
    73     int arcNum() const { return arcs.size(); }
 
    75     int maxNodeId() const { return nodes.size()-1; }
 
    76     int maxArcId() const { return arcs.size()-1; }
 
    80       nodes.push_back(NodeT());
 
    81       nodes[n].first_in = -1;
 
    82       nodes[n].first_out = -1;
 
    86     Arc addArc(Node u, Node v) {
 
    88       arcs.push_back(ArcT());
 
    89       arcs[n].source = u._id;
 
    90       arcs[n].target = v._id;
 
    91       arcs[n].next_out = nodes[u._id].first_out;
 
    92       arcs[n].next_in = nodes[v._id].first_in;
 
    93       nodes[u._id].first_out = nodes[v._id].first_in = n;
 
   103     Node source(Arc a) const { return Node(arcs[a._id].source); }
 
   104     Node target(Arc a) const { return Node(arcs[a._id].target); }
 
   106     static int id(Node v) { return v._id; }
 
   107     static int id(Arc a) { return a._id; }
 
   109     static Node nodeFromId(int id) { return Node(id);}
 
   110     static Arc arcFromId(int id) { return Arc(id);}
 
   112     bool valid(Node n) const {
 
   113       return n._id >= 0 && n._id < static_cast<int>(nodes.size());
 
   115     bool valid(Arc a) const {
 
   116       return a._id >= 0 && a._id < static_cast<int>(arcs.size());
 
   120       friend class SmartDigraphBase;
 
   121       friend class SmartDigraph;
 
   125       explicit Node(int id) : _id(id) {}
 
   128       Node (Invalid) : _id(-1) {}
 
   129       bool operator==(const Node i) const {return _id == i._id;}
 
   130       bool operator!=(const Node i) const {return _id != i._id;}
 
   131       bool operator<(const Node i) const {return _id < i._id;}
 
   136       friend class SmartDigraphBase;
 
   137       friend class SmartDigraph;
 
   141       explicit Arc(int id) : _id(id) {}
 
   144       Arc (Invalid) : _id(-1) {}
 
   145       bool operator==(const Arc i) const {return _id == i._id;}
 
   146       bool operator!=(const Arc i) const {return _id != i._id;}
 
   147       bool operator<(const Arc i) const {return _id < i._id;}
 
   150     void first(Node& node) const {
 
   151       node._id = nodes.size() - 1;
 
   154     static void next(Node& node) {
 
   158     void first(Arc& arc) const {
 
   159       arc._id = arcs.size() - 1;
 
   162     static void next(Arc& arc) {
 
   166     void firstOut(Arc& arc, const Node& node) const {
 
   167       arc._id = nodes[node._id].first_out;
 
   170     void nextOut(Arc& arc) const {
 
   171       arc._id = arcs[arc._id].next_out;
 
   174     void firstIn(Arc& arc, const Node& node) const {
 
   175       arc._id = nodes[node._id].first_in;
 
   178     void nextIn(Arc& arc) const {
 
   179       arc._id = arcs[arc._id].next_in;
 
   184   typedef DigraphExtender<SmartDigraphBase> ExtendedSmartDigraphBase;
 
   188   ///\brief A smart directed graph class.
 
   190   ///This is a simple and fast digraph implementation.
 
   191   ///It is also quite memory efficient, but at the price
 
   192   ///that <b> it does support only limited (only stack-like)
 
   193   ///node and arc deletions</b>.
 
   194   ///It conforms to the \ref concepts::Digraph "Digraph concept" with
 
   195   ///an important extra feature that its maps are real \ref
 
   196   ///concepts::ReferenceMap "reference map"s.
 
   198   ///\sa concepts::Digraph.
 
   199   class SmartDigraph : public ExtendedSmartDigraphBase {
 
   202     typedef ExtendedSmartDigraphBase Parent;
 
   206     ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
 
   208     ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
 
   210     SmartDigraph(const SmartDigraph &) : ExtendedSmartDigraphBase() {};
 
   211     ///\brief Assignment of SmartDigraph to another one is \e not allowed.
 
   212     ///Use DigraphCopy() instead.
 
   214     ///Assignment of SmartDigraph to another one is \e not allowed.
 
   215     ///Use DigraphCopy() instead.
 
   216     void operator=(const SmartDigraph &) {}
 
   226     ///Add a new node to the digraph.
 
   228     /// \return the new node.
 
   230     Node addNode() { return Parent::addNode(); }
 
   232     ///Add a new arc to the digraph.
 
   234     ///Add a new arc to the digraph with source node \c s
 
   235     ///and target node \c t.
 
   236     ///\return the new arc.
 
   237     Arc addArc(const Node& s, const Node& t) {
 
   238       return Parent::addArc(s, t);
 
   241     /// \brief Using this it is possible to avoid the superfluous memory
 
   244     /// Using this it is possible to avoid the superfluous memory
 
   245     /// allocation: if you know that the digraph you want to build will
 
   246     /// be very large (e.g. it will contain millions of nodes and/or arcs)
 
   247     /// then it is worth reserving space for this amount before starting
 
   248     /// to build the digraph.
 
   250     void reserveNode(int n) { nodes.reserve(n); };
 
   252     /// \brief Using this it is possible to avoid the superfluous memory
 
   255     /// Using this it is possible to avoid the superfluous memory
 
   256     /// allocation: if you know that the digraph you want to build will
 
   257     /// be very large (e.g. it will contain millions of nodes and/or arcs)
 
   258     /// then it is worth reserving space for this amount before starting
 
   259     /// to build the digraph.
 
   261     void reserveArc(int m) { arcs.reserve(m); };
 
   263     /// \brief Node validity check
 
   265     /// This function gives back true if the given node is valid,
 
   266     /// ie. it is a real node of the graph.
 
   268     /// \warning A removed node (using Snapshot) could become valid again
 
   269     /// when new nodes are added to the graph.
 
   270     bool valid(Node n) const { return Parent::valid(n); }
 
   272     /// \brief Arc validity check
 
   274     /// This function gives back true if the given arc is valid,
 
   275     /// ie. it is a real arc of the graph.
 
   277     /// \warning A removed arc (using Snapshot) could become valid again
 
   278     /// when new arcs are added to the graph.
 
   279     bool valid(Arc a) const { return Parent::valid(a); }
 
   281     ///Clear the digraph.
 
   283     ///Erase all the nodes and arcs from the digraph.
 
   291     ///This function splits a node. First a new node is added to the digraph,
 
   292     ///then the source of each outgoing arc of \c n is moved to this new node.
 
   293     ///If \c connect is \c true (this is the default value), then a new arc
 
   294     ///from \c n to the newly created node is also added.
 
   295     ///\return The newly created node.
 
   297     ///\note The <tt>Arc</tt>s
 
   298     ///referencing a moved arc remain
 
   299     ///valid. However <tt>InArc</tt>'s and <tt>OutArc</tt>'s
 
   300     ///may be invalidated.
 
   301     ///\warning This functionality cannot be used together with the Snapshot
 
   303     Node split(Node n, bool connect = true)
 
   306       nodes[b._id].first_out=nodes[n._id].first_out;
 
   307       nodes[n._id].first_out=-1;
 
   308       for(int i=nodes[b._id].first_out; i!=-1; i=arcs[i].next_out) {
 
   309         arcs[i].source=b._id;
 
   311       if(connect) addArc(n,b);
 
   321     void restoreSnapshot(const Snapshot &s)
 
   323       while(s.arc_num<arcs.size()) {
 
   324         Arc arc = arcFromId(arcs.size()-1);
 
   325         Parent::notifier(Arc()).erase(arc);
 
   326         nodes[arcs.back().source].first_out=arcs.back().next_out;
 
   327         nodes[arcs.back().target].first_in=arcs.back().next_in;
 
   330       while(s.node_num<nodes.size()) {
 
   331         Node node = nodeFromId(nodes.size()-1);
 
   332         Parent::notifier(Node()).erase(node);
 
   339     ///Class to make a snapshot of the digraph and to restrore to it later.
 
   341     ///Class to make a snapshot of the digraph and to restrore to it later.
 
   343     ///The newly added nodes and arcs can be removed using the
 
   344     ///restore() function.
 
   345     ///\note After you restore a state, you cannot restore
 
   346     ///a later state, in other word you cannot add again the arcs deleted
 
   347     ///by restore() using another one Snapshot instance.
 
   349     ///\warning If you do not use correctly the snapshot that can cause
 
   350     ///either broken program, invalid state of the digraph, valid but
 
   351     ///not the restored digraph or no change. Because the runtime performance
 
   352     ///the validity of the snapshot is not stored.
 
   355       SmartDigraph *_graph;
 
   357       friend class SmartDigraph;
 
   358       unsigned int node_num;
 
   359       unsigned int arc_num;
 
   361       ///Default constructor.
 
   363       ///Default constructor.
 
   364       ///To actually make a snapshot you must call save().
 
   366       Snapshot() : _graph(0) {}
 
   367       ///Constructor that immediately makes a snapshot
 
   369       ///This constructor immediately makes a snapshot of the digraph.
 
   370       ///\param graph The digraph we make a snapshot of.
 
   371       Snapshot(SmartDigraph &graph) : _graph(&graph) {
 
   372         node_num=_graph->nodes.size();
 
   373         arc_num=_graph->arcs.size();
 
   378       ///Make a snapshot of the digraph.
 
   380       ///This function can be called more than once. In case of a repeated
 
   381       ///call, the previous snapshot gets lost.
 
   382       ///\param graph The digraph we make the snapshot of.
 
   383       void save(SmartDigraph &graph)
 
   386         node_num=_graph->nodes.size();
 
   387         arc_num=_graph->arcs.size();
 
   390       ///Undo the changes until a snapshot.
 
   392       ///Undo the changes until a snapshot created by save().
 
   394       ///\note After you restored a state, you cannot restore
 
   395       ///a later state, in other word you cannot add again the arcs deleted
 
   399         _graph->restoreSnapshot(*this);
 
   405   class SmartGraphBase {
 
   418     std::vector<NodeT> nodes;
 
   419     std::vector<ArcT> arcs;
 
   425     typedef SmartGraphBase Digraph;
 
   432       friend class SmartGraphBase;
 
   436       explicit Node(int id) { _id = id;}
 
   440       Node (Invalid) { _id = -1; }
 
   441       bool operator==(const Node& node) const {return _id == node._id;}
 
   442       bool operator!=(const Node& node) const {return _id != node._id;}
 
   443       bool operator<(const Node& node) const {return _id < node._id;}
 
   447       friend class SmartGraphBase;
 
   451       explicit Edge(int id) { _id = id;}
 
   455       Edge (Invalid) { _id = -1; }
 
   456       bool operator==(const Edge& arc) const {return _id == arc._id;}
 
   457       bool operator!=(const Edge& arc) const {return _id != arc._id;}
 
   458       bool operator<(const Edge& arc) const {return _id < arc._id;}
 
   462       friend class SmartGraphBase;
 
   466       explicit Arc(int id) { _id = id;}
 
   469       operator Edge() const {
 
   470         return _id != -1 ? edgeFromId(_id / 2) : INVALID;
 
   474       Arc (Invalid) { _id = -1; }
 
   475       bool operator==(const Arc& arc) const {return _id == arc._id;}
 
   476       bool operator!=(const Arc& arc) const {return _id != arc._id;}
 
   477       bool operator<(const Arc& arc) const {return _id < arc._id;}
 
   485     typedef True NodeNumTag;
 
   486     typedef True EdgeNumTag;
 
   487     typedef True ArcNumTag;
 
   489     int nodeNum() const { return nodes.size(); }
 
   490     int edgeNum() const { return arcs.size() / 2; }
 
   491     int arcNum() const { return arcs.size(); }
 
   493     int maxNodeId() const { return nodes.size()-1; }
 
   494     int maxEdgeId() const { return arcs.size() / 2 - 1; }
 
   495     int maxArcId() const { return arcs.size()-1; }
 
   497     Node source(Arc e) const { return Node(arcs[e._id ^ 1].target); }
 
   498     Node target(Arc e) const { return Node(arcs[e._id].target); }
 
   500     Node u(Edge e) const { return Node(arcs[2 * e._id].target); }
 
   501     Node v(Edge e) const { return Node(arcs[2 * e._id + 1].target); }
 
   503     static bool direction(Arc e) {
 
   504       return (e._id & 1) == 1;
 
   507     static Arc direct(Edge e, bool d) {
 
   508       return Arc(e._id * 2 + (d ? 1 : 0));
 
   511     void first(Node& node) const {
 
   512       node._id = nodes.size() - 1;
 
   515     void next(Node& node) const {
 
   519     void first(Arc& arc) const {
 
   520       arc._id = arcs.size() - 1;
 
   523     void next(Arc& arc) const {
 
   527     void first(Edge& arc) const {
 
   528       arc._id = arcs.size() / 2 - 1;
 
   531     void next(Edge& arc) const {
 
   535     void firstOut(Arc &arc, const Node& v) const {
 
   536       arc._id = nodes[v._id].first_out;
 
   538     void nextOut(Arc &arc) const {
 
   539       arc._id = arcs[arc._id].next_out;
 
   542     void firstIn(Arc &arc, const Node& v) const {
 
   543       arc._id = ((nodes[v._id].first_out) ^ 1);
 
   544       if (arc._id == -2) arc._id = -1;
 
   546     void nextIn(Arc &arc) const {
 
   547       arc._id = ((arcs[arc._id ^ 1].next_out) ^ 1);
 
   548       if (arc._id == -2) arc._id = -1;
 
   551     void firstInc(Edge &arc, bool& d, const Node& v) const {
 
   552       int de = nodes[v._id].first_out;
 
   561     void nextInc(Edge &arc, bool& d) const {
 
   562       int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);
 
   572     static int id(Node v) { return v._id; }
 
   573     static int id(Arc e) { return e._id; }
 
   574     static int id(Edge e) { return e._id; }
 
   576     static Node nodeFromId(int id) { return Node(id);}
 
   577     static Arc arcFromId(int id) { return Arc(id);}
 
   578     static Edge edgeFromId(int id) { return Edge(id);}
 
   580     bool valid(Node n) const {
 
   581       return n._id >= 0 && n._id < static_cast<int>(nodes.size());
 
   583     bool valid(Arc a) const {
 
   584       return a._id >= 0 && a._id < static_cast<int>(arcs.size());
 
   586     bool valid(Edge e) const {
 
   587       return e._id >= 0 && 2 * e._id < static_cast<int>(arcs.size());
 
   591       int n = nodes.size();
 
   592       nodes.push_back(NodeT());
 
   593       nodes[n].first_out = -1;
 
   598     Edge addEdge(Node u, Node v) {
 
   600       arcs.push_back(ArcT());
 
   601       arcs.push_back(ArcT());
 
   603       arcs[n].target = u._id;
 
   604       arcs[n | 1].target = v._id;
 
   606       arcs[n].next_out = nodes[v._id].first_out;
 
   607       nodes[v._id].first_out = n;
 
   609       arcs[n | 1].next_out = nodes[u._id].first_out;
 
   610       nodes[u._id].first_out = (n | 1);
 
   622   typedef GraphExtender<SmartGraphBase> ExtendedSmartGraphBase;
 
   626   /// \brief A smart undirected graph class.
 
   628   /// This is a simple and fast graph implementation.
 
   629   /// It is also quite memory efficient, but at the price
 
   630   /// that <b> it does support only limited (only stack-like)
 
   631   /// node and arc deletions</b>.
 
   632   /// Except from this it conforms to
 
   633   /// the \ref concepts::Graph "Graph concept".
 
   636   /// important extra feature that
 
   637   /// its maps are real \ref concepts::ReferenceMap "reference map"s.
 
   639   /// \sa concepts::Graph.
 
   641   class SmartGraph : public ExtendedSmartGraphBase {
 
   644     ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
 
   646     ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
 
   648     SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {};
 
   650     ///\brief Assignment of SmartGraph to another one is \e not allowed.
 
   651     ///Use GraphCopy() instead.
 
   653     ///Assignment of SmartGraph to another one is \e not allowed.
 
   654     ///Use GraphCopy() instead.
 
   655     void operator=(const SmartGraph &) {}
 
   659     typedef ExtendedSmartGraphBase Parent;
 
   667     ///Add a new node to the graph.
 
   669     /// \return the new node.
 
   671     Node addNode() { return Parent::addNode(); }
 
   673     ///Add a new edge to the graph.
 
   675     ///Add a new edge to the graph with node \c s
 
   677     ///\return the new edge.
 
   678     Edge addEdge(const Node& s, const Node& t) {
 
   679       return Parent::addEdge(s, t);
 
   682     /// \brief Node validity check
 
   684     /// This function gives back true if the given node is valid,
 
   685     /// ie. it is a real node of the graph.
 
   687     /// \warning A removed node (using Snapshot) could become valid again
 
   688     /// when new nodes are added to the graph.
 
   689     bool valid(Node n) const { return Parent::valid(n); }
 
   691     /// \brief Arc validity check
 
   693     /// This function gives back true if the given arc is valid,
 
   694     /// ie. it is a real arc of the graph.
 
   696     /// \warning A removed arc (using Snapshot) could become valid again
 
   697     /// when new edges are added to the graph.
 
   698     bool valid(Arc a) const { return Parent::valid(a); }
 
   700     /// \brief Edge validity check
 
   702     /// This function gives back true if the given edge is valid,
 
   703     /// ie. it is a real edge of the graph.
 
   705     /// \warning A removed edge (using Snapshot) could become valid again
 
   706     /// when new edges are added to the graph.
 
   707     bool valid(Edge e) const { return Parent::valid(e); }
 
   711     ///Erase all the nodes and edges from the graph.
 
   723     void saveSnapshot(Snapshot &s)
 
   726       s.node_num = nodes.size();
 
   727       s.arc_num = arcs.size();
 
   730     void restoreSnapshot(const Snapshot &s)
 
   732       while(s.arc_num<arcs.size()) {
 
   734         Edge arc=edgeFromId(n/2);
 
   735         Parent::notifier(Edge()).erase(arc);
 
   736         std::vector<Arc> dir;
 
   737         dir.push_back(arcFromId(n));
 
   738         dir.push_back(arcFromId(n-1));
 
   739         Parent::notifier(Arc()).erase(dir);
 
   740         nodes[arcs[n-1].target].first_out=arcs[n].next_out;
 
   741         nodes[arcs[n].target].first_out=arcs[n-1].next_out;
 
   745       while(s.node_num<nodes.size()) {
 
   746         int n=nodes.size()-1;
 
   747         Node node = nodeFromId(n);
 
   748         Parent::notifier(Node()).erase(node);
 
   755     ///Class to make a snapshot of the digraph and to restrore to it later.
 
   757     ///Class to make a snapshot of the digraph and to restrore to it later.
 
   759     ///The newly added nodes and arcs can be removed using the
 
   760     ///restore() function.
 
   762     ///\note After you restore a state, you cannot restore
 
   763     ///a later state, in other word you cannot add again the arcs deleted
 
   764     ///by restore() using another one Snapshot instance.
 
   766     ///\warning If you do not use correctly the snapshot that can cause
 
   767     ///either broken program, invalid state of the digraph, valid but
 
   768     ///not the restored digraph or no change. Because the runtime performance
 
   769     ///the validity of the snapshot is not stored.
 
   774       friend class SmartGraph;
 
   775       unsigned int node_num;
 
   776       unsigned int arc_num;
 
   778       ///Default constructor.
 
   780       ///Default constructor.
 
   781       ///To actually make a snapshot you must call save().
 
   783       Snapshot() : _graph(0) {}
 
   784       ///Constructor that immediately makes a snapshot
 
   786       ///This constructor immediately makes a snapshot of the digraph.
 
   787       ///\param graph The digraph we make a snapshot of.
 
   788       Snapshot(SmartGraph &graph) {
 
   789         graph.saveSnapshot(*this);
 
   794       ///Make a snapshot of the graph.
 
   796       ///This function can be called more than once. In case of a repeated
 
   797       ///call, the previous snapshot gets lost.
 
   798       ///\param graph The digraph we make the snapshot of.
 
   799       void save(SmartGraph &graph)
 
   801         graph.saveSnapshot(*this);
 
   804       ///Undo the changes until a snapshot.
 
   806       ///Undo the changes until a snapshot created by save().
 
   808       ///\note After you restored a state, you cannot restore
 
   809       ///a later state, in other word you cannot add again the arcs deleted
 
   813         _graph->restoreSnapshot(*this);
 
   821 #endif //LEMON_SMART_GRAPH_H