Snapshot for SmartUGraph an SmartBpUGraph
authordeba
Mon, 04 Sep 2006 11:09:13 +0000
changeset 2190dd887831e9c1
parent 2189 de2b77e3868c
child 2191 ef3560193856
Snapshot for SmartUGraph an SmartBpUGraph
lemon/smart_graph.h
     1.1 --- a/lemon/smart_graph.h	Mon Sep 04 11:08:32 2006 +0000
     1.2 +++ b/lemon/smart_graph.h	Mon Sep 04 11:09:13 2006 +0000
     1.3 @@ -43,20 +43,17 @@
     1.4    ///Base of SmartGraph
     1.5    ///
     1.6    class SmartGraphBase {
     1.7 +  protected:
     1.8  
     1.9 -    friend class SmatGraph;
    1.10 -
    1.11 -  protected:
    1.12      struct NodeT 
    1.13      {
    1.14 -      int first_in,first_out;      
    1.15 -      NodeT() : first_in(-1), first_out(-1) {}
    1.16 +      int first_in, first_out;      
    1.17 +      NodeT() {}
    1.18      };
    1.19      struct EdgeT 
    1.20      {
    1.21        int target, source, next_in, next_out;      
    1.22 -      //FIXME: is this necessary?
    1.23 -      EdgeT() : next_in(-1), next_out(-1) {}  
    1.24 +      EdgeT() {}  
    1.25      };
    1.26  
    1.27      std::vector<NodeT> nodes;
    1.28 @@ -81,71 +78,44 @@
    1.29      typedef True NodeNumTag;
    1.30      typedef True EdgeNumTag;
    1.31  
    1.32 -    ///Number of nodes.
    1.33      int nodeNum() const { return nodes.size(); }
    1.34 -    ///Number of edges.
    1.35      int edgeNum() const { return edges.size(); }
    1.36  
    1.37 -    /// Maximum node ID.
    1.38 -    
    1.39 -    /// Maximum node ID.
    1.40 -    ///\sa id(Node)
    1.41      int maxNodeId() const { return nodes.size()-1; }
    1.42 -    /// Maximum edge ID.
    1.43 -    
    1.44 -    /// Maximum edge ID.
    1.45 -    ///\sa id(Edge)
    1.46      int maxEdgeId() const { return edges.size()-1; }
    1.47  
    1.48      Node addNode() {
    1.49 -      Node n; n.n=nodes.size();
    1.50 -      nodes.push_back(NodeT()); //FIXME: Hmmm...
    1.51 -      return n;
    1.52 +      int n = nodes.size();     
    1.53 +      nodes.push_back(NodeT());
    1.54 +      nodes[n].first_in = -1;
    1.55 +      nodes[n].first_out = -1;
    1.56 +      return Node(n);
    1.57      }
    1.58      
    1.59      Edge addEdge(Node u, Node v) {
    1.60 -      Edge e; e.n=edges.size(); edges.push_back(EdgeT()); //FIXME: Hmmm...
    1.61 -      edges[e.n].source=u.n; edges[e.n].target=v.n;
    1.62 -      edges[e.n].next_out=nodes[u.n].first_out;
    1.63 -      edges[e.n].next_in=nodes[v.n].first_in;
    1.64 -      nodes[u.n].first_out=nodes[v.n].first_in=e.n;
    1.65 +      int n = edges.size(); 
    1.66 +      edges.push_back(EdgeT());
    1.67 +      edges[n].source = u.id; 
    1.68 +      edges[n].target = v.id;
    1.69 +      edges[n].next_out = nodes[u.id].first_out;
    1.70 +      edges[n].next_in = nodes[v.id].first_in;
    1.71 +      nodes[u.id].first_out = nodes[v.id].first_in = n;
    1.72  
    1.73 -      return e;
    1.74 +      return Edge(n);
    1.75      }
    1.76  
    1.77 +    void clear() {
    1.78 +      edges.clear();
    1.79 +      nodes.clear();
    1.80 +    }
    1.81  
    1.82 -    Node source(Edge e) const { return edges[e.n].source; }
    1.83 -    Node target(Edge e) const { return edges[e.n].target; }
    1.84 +    Node source(Edge e) const { return Node(edges[e.id].source); }
    1.85 +    Node target(Edge e) const { return Node(edges[e.id].target); }
    1.86  
    1.87 -    /// Node ID.
    1.88 -    
    1.89 -    /// The ID of a valid Node is a nonnegative integer not greater than
    1.90 -    /// \ref maxNodeId(). The range of the ID's is not surely continuous
    1.91 -    /// and the greatest node ID can be actually less then \ref maxNodeId().
    1.92 -    ///
    1.93 -    /// The ID of the \ref INVALID node is -1.
    1.94 -    ///\return The ID of the node \c v. 
    1.95 -    static int id(Node v) { return v.n; }
    1.96 -    /// Edge ID.
    1.97 -    
    1.98 -    /// The ID of a valid Edge is a nonnegative integer not greater than
    1.99 -    /// \ref maxEdgeId(). The range of the ID's is not surely continuous
   1.100 -    /// and the greatest edge ID can be actually less then \ref maxEdgeId().
   1.101 -    ///
   1.102 -    /// The ID of the \ref INVALID edge is -1.
   1.103 -    ///\return The ID of the edge \c e. 
   1.104 -    static int id(Edge e) { return e.n; }
   1.105 +    static int id(Node v) { return v.id; }
   1.106 +    static int id(Edge e) { return e.id; }
   1.107  
   1.108 -    /// \brief Returns the node from its \c id.
   1.109 -    ///
   1.110 -    /// Returns the node from its \c id. If there is not node
   1.111 -    /// with the given id the effect of the function is undefinied.
   1.112      static Node nodeFromId(int id) { return Node(id);}
   1.113 -
   1.114 -    /// \brief Returns the edge from its \c id.
   1.115 -    ///
   1.116 -    /// Returns the edge from its \c id. If there is not edge
   1.117 -    /// with the given id the effect of the function is undefinied.
   1.118      static Edge edgeFromId(int id) { return Edge(id);}
   1.119  
   1.120      class Node {
   1.121 @@ -153,14 +123,14 @@
   1.122        friend class SmartGraph;
   1.123  
   1.124      protected:
   1.125 -      int n;
   1.126 -      Node(int nn) {n=nn;}
   1.127 +      int id;
   1.128 +      explicit Node(int _id) : id(_id) {}
   1.129      public:
   1.130        Node() {}
   1.131 -      Node (Invalid) { n=-1; }
   1.132 -      bool operator==(const Node i) const {return n==i.n;}
   1.133 -      bool operator!=(const Node i) const {return n!=i.n;}
   1.134 -      bool operator<(const Node i) const {return n<i.n;}
   1.135 +      Node (Invalid) : id(-1) {}
   1.136 +      bool operator==(const Node i) const {return id == i.id;}
   1.137 +      bool operator!=(const Node i) const {return id != i.id;}
   1.138 +      bool operator<(const Node i) const {return id < i.id;}
   1.139      };
   1.140      
   1.141  
   1.142 @@ -169,46 +139,46 @@
   1.143        friend class SmartGraph;
   1.144  
   1.145      protected:
   1.146 -      int n;
   1.147 -      Edge(int nn) {n=nn;}
   1.148 +      int id;
   1.149 +      explicit Edge(int _id) : id(_id) {}
   1.150      public:
   1.151        Edge() { }
   1.152 -      Edge (Invalid) { n=-1; }
   1.153 -      bool operator==(const Edge i) const {return n==i.n;}
   1.154 -      bool operator!=(const Edge i) const {return n!=i.n;}
   1.155 -      bool operator<(const Edge i) const {return n<i.n;}
   1.156 +      Edge (Invalid) : id(-1) {}
   1.157 +      bool operator==(const Edge i) const {return id == i.id;}
   1.158 +      bool operator!=(const Edge i) const {return id != i.id;}
   1.159 +      bool operator<(const Edge i) const {return id < i.id;}
   1.160      };
   1.161  
   1.162      void first(Node& node) const {
   1.163 -      node.n = nodes.size() - 1;
   1.164 +      node.id = nodes.size() - 1;
   1.165      }
   1.166  
   1.167      static void next(Node& node) {
   1.168 -      --node.n;
   1.169 +      --node.id;
   1.170      }
   1.171  
   1.172      void first(Edge& edge) const {
   1.173 -      edge.n = edges.size() - 1;
   1.174 +      edge.id = edges.size() - 1;
   1.175      }
   1.176  
   1.177      static void next(Edge& edge) {
   1.178 -      --edge.n;
   1.179 +      --edge.id;
   1.180      }
   1.181  
   1.182      void firstOut(Edge& edge, const Node& node) const {
   1.183 -      edge.n = nodes[node.n].first_out;
   1.184 +      edge.id = nodes[node.id].first_out;
   1.185      }
   1.186  
   1.187      void nextOut(Edge& edge) const {
   1.188 -      edge.n = edges[edge.n].next_out;
   1.189 +      edge.id = edges[edge.id].next_out;
   1.190      }
   1.191  
   1.192      void firstIn(Edge& edge, const Node& node) const {
   1.193 -      edge.n = nodes[node.n].first_in;
   1.194 +      edge.id = nodes[node.id].first_in;
   1.195      }
   1.196      
   1.197      void nextIn(Edge& edge) const {
   1.198 -      edge.n = edges[edge.n].next_in;
   1.199 +      edge.id = edges[edge.id].next_in;
   1.200      }
   1.201  
   1.202    };
   1.203 @@ -233,36 +203,19 @@
   1.204  
   1.205      typedef ExtendedSmartGraphBase Parent;
   1.206  
   1.207 -    class Snapshot;
   1.208 -    friend class Snapshot;
   1.209 +  private:
   1.210  
   1.211 -  private:
   1.212      ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
   1.213  
   1.214      ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
   1.215      ///
   1.216 -    SmartGraph(const SmartGraph &) :ExtendedSmartGraphBase() {};
   1.217 +    SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {};
   1.218      ///\brief Assignment of SmartGraph to another one is \e not allowed.
   1.219      ///Use GraphCopy() instead.
   1.220  
   1.221      ///Assignment of SmartGraph to another one is \e not allowed.
   1.222      ///Use GraphCopy() instead.
   1.223      void operator=(const SmartGraph &) {}
   1.224 -  protected:
   1.225 -    void restoreSnapshot(const Snapshot &s)
   1.226 -    {
   1.227 -      while(s.edge_num<edges.size()) {
   1.228 -	Parent::getNotifier(Edge()).erase(Edge(edges.size()-1));
   1.229 -	nodes[edges.back().target].first_in=edges.back().next_in;
   1.230 -	nodes[edges.back().source].first_out=edges.back().next_out;
   1.231 -	edges.pop_back();
   1.232 -      }
   1.233 -      //nodes.resize(s.nodes_num);
   1.234 -      while(s.node_num<nodes.size()) {
   1.235 -	Parent::getNotifier(Node()).erase(Node(nodes.size()-1));
   1.236 -	nodes.pop_back();
   1.237 -      }
   1.238 -    }    
   1.239  
   1.240    public:
   1.241      
   1.242 @@ -287,13 +240,12 @@
   1.243        return Parent::addEdge(s, t); 
   1.244      }
   1.245  
   1.246 -    ///\e
   1.247 +    ///Clear the graph.
   1.248      
   1.249 -    ///\bug Undocumented
   1.250 -    ///\bug Doesn't destruct the maps.
   1.251 +    ///Erase all the nodes and edges from the graph.
   1.252 +    ///
   1.253      void clear() {
   1.254 -      edges.clear();
   1.255 -      nodes.clear();
   1.256 +      Parent::clear();
   1.257      }
   1.258  
   1.259      ///Split a node.
   1.260 @@ -314,13 +266,37 @@
   1.261      Node split(Node n, bool connect = true)
   1.262      {
   1.263        Node b = addNode();
   1.264 -      nodes[b.n].first_out=nodes[n.n].first_out;
   1.265 -      nodes[n.n].first_out=-1;
   1.266 -      for(int i=nodes[b.n].first_out;i!=-1;i++) edges[i].source=b.n;
   1.267 +      nodes[b.id].first_out=nodes[n.id].first_out;
   1.268 +      nodes[n.id].first_out=-1;
   1.269 +      for(int i=nodes[b.id].first_out;i!=-1;i++) edges[i].source=b.id;
   1.270        if(connect) addEdge(n,b);
   1.271        return b;
   1.272      }
   1.273  
   1.274 +  public:
   1.275 +    
   1.276 +    class Snapshot;
   1.277 +
   1.278 +  protected:
   1.279 +
   1.280 +    void restoreSnapshot(const Snapshot &s)
   1.281 +    {
   1.282 +      while(s.edge_num<edges.size()) {
   1.283 +        Edge edge = edgeFromId(edges.size()-1);
   1.284 +	Parent::getNotifier(Edge()).erase(edge);
   1.285 +	nodes[edges.back().source].first_out=edges.back().next_out;
   1.286 +	nodes[edges.back().target].first_in=edges.back().next_in;
   1.287 +	edges.pop_back();
   1.288 +      }
   1.289 +      while(s.node_num<nodes.size()) {
   1.290 +        Node node = nodeFromId(nodes.size()-1);
   1.291 +	Parent::getNotifier(Node()).erase(node);
   1.292 +	nodes.pop_back();
   1.293 +      }
   1.294 +    }    
   1.295 +
   1.296 +  public:
   1.297 +
   1.298      ///Class to make a snapshot of the graph and to restrore to it later.
   1.299  
   1.300      ///Class to make a snapshot of the graph and to restrore to it later.
   1.301 @@ -331,6 +307,10 @@
   1.302      ///a later state, in other word you cannot add again the edges deleted
   1.303      ///by restore() using another one Snapshot instance.
   1.304      ///
   1.305 +    ///\warning If you do not use correctly the snapshot that can cause
   1.306 +    ///either broken program, invalid state of the graph, valid but
   1.307 +    ///not the restored graph or no change. Because the runtime performance
   1.308 +    ///the validity of the snapshot is not stored.
   1.309      class Snapshot 
   1.310      {
   1.311        SmartGraph *g;
   1.312 @@ -375,9 +355,6 @@
   1.313        ///\note After you restored a state, you cannot restore
   1.314        ///a later state, in other word you cannot add again the edges deleted
   1.315        ///by restore().
   1.316 -      ///
   1.317 -      ///\todo This function might be called undo().
   1.318 -      
   1.319        void restore()
   1.320        {
   1.321  	g->restoreSnapshot(*this);
   1.322 @@ -407,23 +384,146 @@
   1.323    ///
   1.324    class SmartUGraph : public ExtendedSmartUGraphBase {
   1.325    private:
   1.326 +
   1.327      ///SmartUGraph is \e not copy constructible. Use UGraphCopy() instead.
   1.328  
   1.329      ///SmartUGraph is \e not copy constructible. Use UGraphCopy() instead.
   1.330      ///
   1.331      SmartUGraph(const SmartUGraph &) : ExtendedSmartUGraphBase() {};
   1.332 +
   1.333      ///\brief Assignment of SmartUGraph to another one is \e not allowed.
   1.334      ///Use UGraphCopy() instead.
   1.335  
   1.336      ///Assignment of SmartUGraph to another one is \e not allowed.
   1.337      ///Use UGraphCopy() instead.
   1.338      void operator=(const SmartUGraph &) {}
   1.339 +
   1.340    public:
   1.341 +
   1.342 +    typedef ExtendedSmartUGraphBase Parent;
   1.343 +
   1.344      /// Constructor
   1.345      
   1.346      /// Constructor.
   1.347      ///
   1.348      SmartUGraph() {}
   1.349 +
   1.350 +    ///Add a new node to the graph.
   1.351 +    
   1.352 +    /// \return the new node.
   1.353 +    ///
   1.354 +    Node addNode() { return Parent::addNode(); }
   1.355 +    
   1.356 +    ///Add a new undirected edge to the graph.
   1.357 +    
   1.358 +    ///Add a new undirected edge to the graph with node \c s
   1.359 +    ///and \c t.
   1.360 +    ///\return the new undirected edge.
   1.361 +    UEdge addEdge(const Node& s, const Node& t) { 
   1.362 +      return Parent::addEdge(s, t); 
   1.363 +    }
   1.364 +
   1.365 +    ///Clear the graph.
   1.366 +    
   1.367 +    ///Erase all the nodes and edges from the graph.
   1.368 +    ///
   1.369 +    void clear() {
   1.370 +      Parent::clear();
   1.371 +    }
   1.372 +
   1.373 +  public:
   1.374 +    
   1.375 +    class Snapshot;
   1.376 +
   1.377 +  protected:
   1.378 +
   1.379 +
   1.380 +    void restoreSnapshot(const Snapshot &s)
   1.381 +    {
   1.382 +      while(s.edge_num<edges.size()) {
   1.383 +        UEdge edge = uEdgeFromId(edges.size()-1);
   1.384 +	Parent::getNotifier(UEdge()).erase(edge);
   1.385 +        std::vector<Edge> dir;
   1.386 +        dir.push_back(Parent::direct(edge, true));
   1.387 +        dir.push_back(Parent::direct(edge, false));
   1.388 +	Parent::getNotifier(Edge()).erase(dir);
   1.389 +	nodes[edges.back().source].first_out=edges.back().next_out;
   1.390 +	nodes[edges.back().target].first_in=edges.back().next_in;
   1.391 +	edges.pop_back();
   1.392 +      }
   1.393 +      while(s.node_num<nodes.size()) {
   1.394 +        Node node = nodeFromId(nodes.size()-1);
   1.395 +	Parent::getNotifier(Node()).erase(node);
   1.396 +	nodes.pop_back();
   1.397 +      }
   1.398 +    }    
   1.399 +
   1.400 +  public:
   1.401 +
   1.402 +    ///Class to make a snapshot of the graph and to restrore to it later.
   1.403 +
   1.404 +    ///Class to make a snapshot of the graph and to restrore to it later.
   1.405 +    ///
   1.406 +    ///The newly added nodes and edges can be removed using the
   1.407 +    ///restore() function.
   1.408 +    ///
   1.409 +    ///\note After you restore a state, you cannot restore
   1.410 +    ///a later state, in other word you cannot add again the edges deleted
   1.411 +    ///by restore() using another one Snapshot instance.
   1.412 +    ///
   1.413 +    ///\warning If you do not use correctly the snapshot that can cause
   1.414 +    ///either broken program, invalid state of the graph, valid but
   1.415 +    ///not the restored graph or no change. Because the runtime performance
   1.416 +    ///the validity of the snapshot is not stored.
   1.417 +    class Snapshot 
   1.418 +    {
   1.419 +      SmartUGraph *g;
   1.420 +    protected:
   1.421 +      friend class SmartUGraph;
   1.422 +      unsigned int node_num;
   1.423 +      unsigned int edge_num;
   1.424 +    public:
   1.425 +      ///Default constructor.
   1.426 +      
   1.427 +      ///Default constructor.
   1.428 +      ///To actually make a snapshot you must call save().
   1.429 +      ///
   1.430 +      Snapshot() : g(0) {}
   1.431 +      ///Constructor that immediately makes a snapshot
   1.432 +      
   1.433 +      ///This constructor immediately makes a snapshot of the graph.
   1.434 +      ///\param _g The graph we make a snapshot of.
   1.435 +      Snapshot(SmartUGraph &_g) :g(&_g) {
   1.436 +	node_num=g->nodes.size();
   1.437 +	edge_num=g->edges.size();
   1.438 +      }
   1.439 +
   1.440 +      ///Make a snapshot.
   1.441 +
   1.442 +      ///Make a snapshot of the graph.
   1.443 +      ///
   1.444 +      ///This function can be called more than once. In case of a repeated
   1.445 +      ///call, the previous snapshot gets lost.
   1.446 +      ///\param _g The graph we make the snapshot of.
   1.447 +      void save(SmartUGraph &_g) 
   1.448 +      {
   1.449 +	g=&_g;
   1.450 +	node_num=g->nodes.size();
   1.451 +	edge_num=g->edges.size();
   1.452 +      }
   1.453 +
   1.454 +      ///Undo the changes until a snapshot.
   1.455 +      
   1.456 +      ///Undo the changes until a snapshot created by save().
   1.457 +      ///
   1.458 +      ///\note After you restored a state, you cannot restore
   1.459 +      ///a later state, in other word you cannot add again the edges deleted
   1.460 +      ///by restore().
   1.461 +      void restore()
   1.462 +      {
   1.463 +	g->restoreSnapshot(*this);
   1.464 +      }
   1.465 +    };
   1.466    };
   1.467  
   1.468  
   1.469 @@ -462,10 +562,10 @@
   1.470      protected:
   1.471        int id;
   1.472  
   1.473 -      Node(int _id) : id(_id) {}
   1.474 +      explicit Node(int _id) : id(_id) {}
   1.475      public:
   1.476        Node() {}
   1.477 -      Node(Invalid) { id = -1; }
   1.478 +      Node(Invalid) : id(-1) {}
   1.479        bool operator==(const Node i) const {return id==i.id;}
   1.480        bool operator!=(const Node i) const {return id!=i.id;}
   1.481        bool operator<(const Node i) const {return id<i.id;}
   1.482 @@ -476,10 +576,10 @@
   1.483      protected:
   1.484        int id;
   1.485  
   1.486 -      UEdge(int _id) { id = _id;}
   1.487 +      UEdge(int _id) : id(_id) {}
   1.488      public:
   1.489        UEdge() {}
   1.490 -      UEdge (Invalid) { id = -1; }
   1.491 +      UEdge(Invalid) : id(-1) {}
   1.492        bool operator==(const UEdge i) const {return id==i.id;}
   1.493        bool operator!=(const UEdge i) const {return id!=i.id;}
   1.494        bool operator<(const UEdge i) const {return id<i.id;}
   1.495 @@ -656,7 +756,163 @@
   1.496    /// the \ref concept::BpUGraph "BpUGraph concept".
   1.497    /// \sa concept::BpUGraph.
   1.498    ///
   1.499 -  class SmartBpUGraph : public ExtendedSmartBpUGraphBase {};
   1.500 +  class SmartBpUGraph : public ExtendedSmartBpUGraphBase {
   1.501 +  private:
   1.502 +
   1.503 +    /// \brief SmartBpUGraph is \e not copy constructible.
   1.504 +    ///
   1.505 +    ///SmartBpUGraph is \e not copy constructible.
   1.506 +    SmartBpUGraph(const SmartBpUGraph &) : ExtendedSmartBpUGraphBase() {};
   1.507 +
   1.508 +    /// \brief Assignment of SmartBpUGraph to another one is \e not
   1.509 +    /// allowed.
   1.510 +    ///
   1.511 +    /// Assignment of SmartBpUGraph to another one is \e not allowed.
   1.512 +    void operator=(const SmartBpUGraph &) {}
   1.513 +
   1.514 +  public:
   1.515 +
   1.516 +    typedef ExtendedSmartBpUGraphBase Parent;
   1.517 +
   1.518 +    ///Constructor
   1.519 +    
   1.520 +    ///Constructor.
   1.521 +    ///
   1.522 +    SmartBpUGraph() : ExtendedSmartBpUGraphBase() {}
   1.523 +
   1.524 +    ///Add a new ANode to the graph.
   1.525 +    
   1.526 +    /// \return the new node.
   1.527 +    ///
   1.528 +    Node addANode() { return Parent::addANode(); }
   1.529 +
   1.530 +    ///Add a new BNode to the graph.
   1.531 +    
   1.532 +    /// \return the new node.
   1.533 +    ///
   1.534 +    Node addBNode() { return Parent::addBNode(); }
   1.535 +    
   1.536 +    ///Add a new undirected edge to the graph.
   1.537 +    
   1.538 +    ///Add a new undirected edge to the graph with node \c s
   1.539 +    ///and \c t.
   1.540 +    ///\return the new undirected edge.
   1.541 +    UEdge addEdge(const Node& s, const Node& t) { 
   1.542 +      return Parent::addEdge(s, t); 
   1.543 +    }
   1.544 +
   1.545 +    ///Clear the graph.
   1.546 +    
   1.547 +    ///Erase all the nodes and edges from the graph.
   1.548 +    ///
   1.549 +    void clear() {
   1.550 +      Parent::clear();
   1.551 +    }
   1.552 +    
   1.553 +  public:
   1.554 +
   1.555 +    class Snapshot;
   1.556 +
   1.557 +  protected:
   1.558 +    
   1.559 +    void restoreSnapshot(const Snapshot &s)
   1.560 +    {
   1.561 +      while(s.edge_num<edges.size()) {
   1.562 +        UEdge edge = uEdgeFromId(edges.size()-1);
   1.563 +	Parent::getNotifier(UEdge()).erase(edge);
   1.564 +        std::vector<Edge> dir;
   1.565 +        dir.push_back(Parent::direct(edge, true));
   1.566 +        dir.push_back(Parent::direct(edge, false));
   1.567 +	Parent::getNotifier(Edge()).erase(dir);
   1.568 +	aNodes[edges.back().aNode >> 1].first=edges.back().next_out;
   1.569 +	bNodes[edges.back().bNode >> 1].first=edges.back().next_in;
   1.570 +	edges.pop_back();
   1.571 +      }
   1.572 +      while(s.anode_num<aNodes.size()) {
   1.573 +        Node node = fromANodeId(aNodes.size() - 1);
   1.574 +	Parent::getNotifier(ANode()).erase(node);
   1.575 +	Parent::getNotifier(Node()).erase(node);
   1.576 +	aNodes.pop_back();
   1.577 +      }
   1.578 +      while(s.bnode_num<bNodes.size()) {
   1.579 +        Node node = fromBNodeId(bNodes.size() - 1);
   1.580 +	Parent::getNotifier(BNode()).erase(node);
   1.581 +	Parent::getNotifier(Node()).erase(node);
   1.582 +	bNodes.pop_back();
   1.583 +      }
   1.584 +    }    
   1.585 +
   1.586 +  public:
   1.587 +
   1.588 +    ///Class to make a snapshot of the graph and to restrore to it later.
   1.589 +
   1.590 +    ///Class to make a snapshot of the graph and to restrore to it later.
   1.591 +    ///
   1.592 +    ///The newly added nodes and edges can be removed using the
   1.593 +    ///restore() function.
   1.594 +    ///
   1.595 +    ///\note After you restore a state, you cannot restore
   1.596 +    ///a later state, in other word you cannot add again the edges deleted
   1.597 +    ///by restore() using another one Snapshot instance.
   1.598 +    ///
   1.599 +    ///\warning If you do not use correctly the snapshot that can cause
   1.600 +    ///either broken program, invalid state of the graph, valid but
   1.601 +    ///not the restored graph or no change. Because the runtime performance
   1.602 +    ///the validity of the snapshot is not stored.
   1.603 +    class Snapshot 
   1.604 +    {
   1.605 +      SmartBpUGraph *g;
   1.606 +    protected:
   1.607 +      friend class SmartBpUGraph;
   1.608 +      unsigned int anode_num;
   1.609 +      unsigned int bnode_num;
   1.610 +      unsigned int edge_num;
   1.611 +    public:
   1.612 +      ///Default constructor.
   1.613 +      
   1.614 +      ///Default constructor.
   1.615 +      ///To actually make a snapshot you must call save().
   1.616 +      ///
   1.617 +      Snapshot() : g(0) {}
   1.618 +
   1.619 +      ///Constructor that immediately makes a snapshot
   1.620 +      
   1.621 +      ///This constructor immediately makes a snapshot of the graph.
   1.622 +      ///\param _g The graph we make a snapshot of.
   1.623 +      Snapshot(SmartBpUGraph &_g) : g(&_g) {
   1.624 +	anode_num=g->aNodes.size();
   1.625 +	bnode_num=g->bNodes.size();
   1.626 +	edge_num=g->edges.size();
   1.627 +      }
   1.628 +
   1.629 +      ///Make a snapshot.
   1.630 +
   1.631 +      ///Make a snapshot of the graph.
   1.632 +      ///
   1.633 +      ///This function can be called more than once. In case of a repeated
   1.634 +      ///call, the previous snapshot gets lost.
   1.635 +      ///\param _g The graph we make the snapshot of.
   1.636 +      void save(SmartBpUGraph &_g) 
   1.637 +      {
   1.638 +	g=&_g;
   1.639 +	anode_num=g->aNodes.size();
   1.640 +	bnode_num=g->bNodes.size();
   1.641 +	edge_num=g->edges.size();
   1.642 +      }
   1.643 +
   1.644 +      ///Undo the changes until a snapshot.
   1.645 +      
   1.646 +      ///Undo the changes until a snapshot created by save().
   1.647 +      ///
   1.648 +      ///\note After you restored a state, you cannot restore
   1.649 +      ///a later state, in other word you cannot add again the edges deleted
   1.650 +      ///by restore().
   1.651 +      void restore()
   1.652 +      {
   1.653 +	g->restoreSnapshot(*this);
   1.654 +      }
   1.655 +    };
   1.656 +  };
   1.657  
   1.658    
   1.659    /// @}