src/lemon/smart_graph.h
changeset 973 6a6f3ac07b20
parent 969 0631847b37e5
child 974 785062a83f8e
equal deleted inserted replaced
5:87fee299ff83 6:0e0b78863514
    23 
    23 
    24 #include <vector>
    24 #include <vector>
    25 
    25 
    26 #include <lemon/invalid.h>
    26 #include <lemon/invalid.h>
    27 
    27 
    28 #include <lemon/erasable_graph_extender.h>
       
    29 #include <lemon/clearable_graph_extender.h>
    28 #include <lemon/clearable_graph_extender.h>
    30 #include <lemon/extendable_graph_extender.h>
    29 #include <lemon/extendable_graph_extender.h>
    31 
    30 
    32 #include <lemon/idmappable_graph_extender.h>
    31 #include <lemon/idmappable_graph_extender.h>
    33 
    32 
    43 namespace lemon {
    42 namespace lemon {
    44 
    43 
    45   /// \addtogroup graphs
    44   /// \addtogroup graphs
    46   /// @{
    45   /// @{
    47 
    46 
       
    47   class SmartGraph;
    48   ///Base of SmartGraph
    48   ///Base of SmartGraph
    49 
    49 
    50   ///Base of SmartGraph
    50   ///Base of SmartGraph
    51   ///
    51   ///
    52   class SmartGraphBase {
    52   class SmartGraphBase {
    53 
    53 
       
    54     friend class SmatGraph;
       
    55 
       
    56   protected:
    54     struct NodeT 
    57     struct NodeT 
    55     {
    58     {
    56       int first_in,first_out;      
    59       int first_in,first_out;      
    57       NodeT() : first_in(-1), first_out(-1) {}
    60       NodeT() : first_in(-1), first_out(-1) {}
    58     };
    61     };
   141     }
   144     }
   142 
   145 
   143 
   146 
   144     class Node {
   147     class Node {
   145       friend class SmartGraphBase;
   148       friend class SmartGraphBase;
       
   149       friend class SmartGraph;
   146 
   150 
   147     protected:
   151     protected:
   148       int n;
   152       int n;
       
   153       ///\todo It should be removed (or at least define a setToId() instead).
       
   154       ///
   149       Node(int nn) {n=nn;}
   155       Node(int nn) {n=nn;}
   150     public:
   156     public:
   151       Node() {}
   157       Node() {}
   152       Node (Invalid) { n=-1; }
   158       Node (Invalid) { n=-1; }
   153       bool operator==(const Node i) const {return n==i.n;}
   159       bool operator==(const Node i) const {return n==i.n;}
   156     };
   162     };
   157     
   163     
   158 
   164 
   159     class Edge {
   165     class Edge {
   160       friend class SmartGraphBase;
   166       friend class SmartGraphBase;
       
   167       friend class SmartGraph;
   161 
   168 
   162     protected:
   169     protected:
   163       int n;
   170       int n;
       
   171       ///\todo It should be removed (or at least define a setToId() instead).
       
   172       ///
   164       Edge(int nn) {n=nn;}
   173       Edge(int nn) {n=nn;}
   165     public:
   174     public:
   166       Edge() { }
   175       Edge() { }
   167       Edge (Invalid) { n=-1; }
   176       Edge (Invalid) { n=-1; }
   168       bool operator==(const Edge i) const {return n==i.n;}
   177       bool operator==(const Edge i) const {return n==i.n;}
   207       int e = (prev.n==-1)? nodes[u.n].first_out : edges[prev.n].next_out;
   216       int e = (prev.n==-1)? nodes[u.n].first_out : edges[prev.n].next_out;
   208       while(e!=-1 && edges[e].tail!=v.n) e = edges[e].next_out;
   217       while(e!=-1 && edges[e].tail!=v.n) e = edges[e].next_out;
   209       prev.n=e;
   218       prev.n=e;
   210       return prev;
   219       return prev;
   211     }
   220     }
       
   221 
   212   };
   222   };
   213 
   223 
   214   typedef AlterableGraphExtender<SmartGraphBase> AlterableSmartGraphBase;
   224   typedef AlterableGraphExtender<SmartGraphBase> AlterableSmartGraphBase;
   215   typedef IterableGraphExtender<AlterableSmartGraphBase> IterableSmartGraphBase;
   225   typedef IterableGraphExtender<AlterableSmartGraphBase> IterableSmartGraphBase;
   216   typedef IdMappableGraphExtender<IterableSmartGraphBase> IdMappableSmartGraphBase;
   226   typedef IdMappableGraphExtender<IterableSmartGraphBase> IdMappableSmartGraphBase;
   238   ///
   248   ///
   239   ///\author Alpar Juttner
   249   ///\author Alpar Juttner
   240   class SmartGraph :public ClearableSmartGraphBase {
   250   class SmartGraph :public ClearableSmartGraphBase {
   241   public:
   251   public:
   242     /// Finds an edge between two nodes.
   252     /// Finds an edge between two nodes.
   243 
   253     
   244     /// Finds an edge from node \c u to node \c v.
   254     /// Finds an edge from node \c u to node \c v.
   245     ///
   255     ///
   246     /// If \c prev is \ref INVALID (this is the default value), then
   256     /// If \c prev is \ref INVALID (this is the default value), then
   247     /// it finds the first edge from \c u to \c v. Otherwise it looks for
   257     /// it finds the first edge from \c u to \c v. Otherwise it looks for
   248     /// the next edge from \c u to \c v after \c prev.
   258     /// the next edge from \c u to \c v after \c prev.
   257     /// \todo Possibly it should be a global function.
   267     /// \todo Possibly it should be a global function.
   258     Edge findEdge(Node u,Node v, Edge prev = INVALID) 
   268     Edge findEdge(Node u,Node v, Edge prev = INVALID) 
   259     {
   269     {
   260       return _findEdge(u,v,prev);
   270       return _findEdge(u,v,prev);
   261     }
   271     }
   262 };
   272     
       
   273     ///Internal data structure to store snapshots
       
   274     
       
   275     ///\ingroup graphs
       
   276     ///\sa makeSnapShot()
       
   277     ///\sa rollBack()
       
   278     struct SnapShot 
       
   279     {
       
   280       unsigned int node_num;
       
   281       unsigned int edge_num;
       
   282     };
       
   283     
       
   284     ///Make a snapshot of the graph.
       
   285 
       
   286     ///Make a snapshot of the graph.
       
   287     ///
       
   288     ///The newly added nodes and edges can be removed using the
       
   289     ///rollBack() function.
       
   290     ///
       
   291     ///\return An stucture SnapShot describing the pesent state of the
       
   292     ///graph.
       
   293     ///\note After you rolled back to a state, you cannot roll "back" to
       
   294     ///a later state, in other word you cannot add again the edges deleted
       
   295     ///by rollBack().
       
   296     SnapShot makeSnapShot() 
       
   297     {
       
   298       SnapShot s;
       
   299       s.node_num=nodes.size();
       
   300       s.edge_num=edges.size();
       
   301       return s;
       
   302     }
       
   303     
       
   304     ///Undo the changes until a snapshot.
       
   305 
       
   306     ///Undo the changes until a snapshot created by makeSnapShot().
       
   307     ///
       
   308     ///\param s an internal stucture given back by makeSnapShot()
       
   309     ///\note After you rolled back to a state, you cannot "roll forward" to
       
   310     ///a later state, in other word you cannot add again the edges deleted
       
   311     ///by rollBack().
       
   312     ///
       
   313     ///\todo This function might be called undo().
       
   314     
       
   315     void rollBack(const SnapShot &s)
       
   316     {
       
   317       while(s.edge_num>edges.size()) {
       
   318 	edge_observers.erase(Edge(edges.size()-1));
       
   319 	nodes[edges.back().head].first_in=edges.back().next_in;
       
   320 	nodes[edges.back().tail].first_out=edges.back().next_out;
       
   321 	edges.pop_back();
       
   322       }
       
   323       //nodes.resize(s.nodes_num);
       
   324       while(s.node_num>nodes.size()) {
       
   325 	node_observers.erase(Node(nodes.size()-1));
       
   326 	nodes.pop_back();
       
   327       }
       
   328     }
       
   329   };
   263   
   330   
   264   template <>
   331   template <>
   265   int countNodes<SmartGraph>(const SmartGraph& graph) {
   332   int countNodes<SmartGraph>(const SmartGraph& graph) {
   266     return graph.nodeNum();
   333     return graph.nodeNum();
   267   }
   334   }