Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

smart_graph.h

Go to the documentation of this file.
00001 /* -*- C++ -*-
00002  * lemon/smart_graph.h - Part of LEMON, a generic C++ optimization library
00003  *
00004  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
00005  * (Egervary Research Group on Combinatorial Optimization, EGRES).
00006  *
00007  * Permission to use, modify and distribute this software is granted
00008  * provided that this copyright notice appears in all copies. For
00009  * precise terms see the accompanying LICENSE file.
00010  *
00011  * This software is provided "AS IS" with no warranty of any kind,
00012  * express or implied, and with no claim as to its suitability for any
00013  * purpose.
00014  *
00015  */
00016 
00017 #ifndef LEMON_SMART_GRAPH_H
00018 #define LEMON_SMART_GRAPH_H
00019 
00023 
00024 #include <vector>
00025 
00026 #include <lemon/invalid.h>
00027 
00028 #include <lemon/bits/clearable_graph_extender.h>
00029 #include <lemon/bits/extendable_graph_extender.h>
00030 #include <lemon/bits/iterable_graph_extender.h>
00031 #include <lemon/bits/alteration_notifier.h>
00032 #include <lemon/bits/default_map.h>
00033 
00034 #include <lemon/bits/undir_graph_extender.h>
00035 
00036 #include <lemon/utility.h>
00037 
00038 namespace lemon {
00039 
00040   class SmartGraph;
00042 
00045   class SmartGraphBase {
00046 
00047     friend class SmatGraph;
00048 
00049   protected:
00050     struct NodeT 
00051     {
00052       int first_in,first_out;      
00053       NodeT() : first_in(-1), first_out(-1) {}
00054     };
00055     struct EdgeT 
00056     {
00057       int target, source, next_in, next_out;      
00058       //FIXME: is this necessary?
00059       EdgeT() : next_in(-1), next_out(-1) {}  
00060     };
00061 
00062     std::vector<NodeT> nodes;
00063 
00064     std::vector<EdgeT> edges;
00065     
00066     
00067   public:
00068 
00069     typedef SmartGraphBase Graph;
00070 
00071     class Node;
00072     class Edge;
00073 
00074     
00075   public:
00076 
00077     SmartGraphBase() : nodes(), edges() { }
00078     SmartGraphBase(const SmartGraphBase &_g) : nodes(_g.nodes), edges(_g.edges) { }
00079     
00080     typedef True NodeNumTag;
00081     typedef True EdgeNumTag;
00082 
00084     int nodeNum() const { return nodes.size(); }
00086     int edgeNum() const { return edges.size(); }
00087 
00089     
00092     int maxId(Node) const { return nodes.size()-1; }
00094     
00097     int maxId(Edge) const { return edges.size()-1; }
00098 
00099     Node source(Edge e) const { return edges[e.n].source; }
00100     Node target(Edge e) const { return edges[e.n].target; }
00101 
00103     
00110     static int id(Node v) { return v.n; }
00112     
00119     static int id(Edge e) { return e.n; }
00120 
00121     static Node fromId(int id, Node) { return Node(id);}
00122 
00123     static Edge fromId(int id, Edge) { return Edge(id);}
00124 
00125     Node addNode() {
00126       Node n; n.n=nodes.size();
00127       nodes.push_back(NodeT()); //FIXME: Hmmm...
00128       return n;
00129     }
00130     
00131     Edge addEdge(Node u, Node v) {
00132       Edge e; e.n=edges.size(); edges.push_back(EdgeT()); //FIXME: Hmmm...
00133       edges[e.n].source=u.n; edges[e.n].target=v.n;
00134       edges[e.n].next_out=nodes[u.n].first_out;
00135       edges[e.n].next_in=nodes[v.n].first_in;
00136       nodes[u.n].first_out=nodes[v.n].first_in=e.n;
00137 
00138       return e;
00139     }
00140 
00141     void clear() {
00142       edges.clear();
00143       nodes.clear();
00144     }
00145 
00146 
00147     class Node {
00148       friend class SmartGraphBase;
00149       friend class SmartGraph;
00150 
00151     protected:
00152       int n;
00154 
00157       Node(int nn) {n=nn;}
00158     public:
00159       Node() {}
00160       Node (Invalid) { n=-1; }
00161       bool operator==(const Node i) const {return n==i.n;}
00162       bool operator!=(const Node i) const {return n!=i.n;}
00163       bool operator<(const Node i) const {return n<i.n;}
00164     };
00165     
00166 
00167     class Edge {
00168       friend class SmartGraphBase;
00169       friend class SmartGraph;
00170 
00171     protected:
00172       int n;
00175       Edge(int nn) {n=nn;}
00176     public:
00177       Edge() { }
00178       Edge (Invalid) { n=-1; }
00179       bool operator==(const Edge i) const {return n==i.n;}
00180       bool operator!=(const Edge i) const {return n!=i.n;}
00181       bool operator<(const Edge i) const {return n<i.n;}
00182     };
00183 
00184     void first(Node& node) const {
00185       node.n = nodes.size() - 1;
00186     }
00187 
00188     static void next(Node& node) {
00189       --node.n;
00190     }
00191 
00192     void first(Edge& edge) const {
00193       edge.n = edges.size() - 1;
00194     }
00195 
00196     static void next(Edge& edge) {
00197       --edge.n;
00198     }
00199 
00200     void firstOut(Edge& edge, const Node& node) const {
00201       edge.n = nodes[node.n].first_out;
00202     }
00203 
00204     void nextOut(Edge& edge) const {
00205       edge.n = edges[edge.n].next_out;
00206     }
00207 
00208     void firstIn(Edge& edge, const Node& node) const {
00209       edge.n = nodes[node.n].first_in;
00210     }
00211     
00212     void nextIn(Edge& edge) const {
00213       edge.n = edges[edge.n].next_in;
00214     }
00215 
00216     Edge _findEdge(Node u,Node v, Edge prev = INVALID) 
00217     {
00218       int e = (prev.n==-1)? nodes[u.n].first_out : edges[prev.n].next_out;
00219       while(e!=-1 && edges[e].target!=v.n) e = edges[e].next_out;
00220       prev.n=e;
00221       return prev;
00222     }
00223 
00224     Node _split(Node n, bool connect = true)
00225     {
00226       Node b = addNode();
00227       nodes[b.n].first_out=nodes[n.n].first_out;
00228       nodes[n.n].first_out=-1;
00229       for(int i=nodes[b.n].first_out;i!=-1;i++) edges[i].source=b.n;
00230       if(connect) addEdge(n,b);
00231       return b;
00232     }
00233 
00234   };
00235 
00236   typedef AlterableGraphExtender<SmartGraphBase> AlterableSmartGraphBase;
00237   typedef IterableGraphExtender<AlterableSmartGraphBase> IterableSmartGraphBase;
00238   typedef DefaultMappableGraphExtender<IterableSmartGraphBase> MappableSmartGraphBase;
00239   typedef ExtendableGraphExtender<MappableSmartGraphBase> ExtendableSmartGraphBase;
00240   typedef ClearableGraphExtender<ExtendableSmartGraphBase> ClearableSmartGraphBase;
00241 
00244 
00246 
00256   class SmartGraph : public ClearableSmartGraphBase {
00257   public:
00259     
00274     Edge findEdge(Node u,Node v, Edge prev = INVALID) 
00275     {
00276       return _findEdge(u,v,prev);
00277     }
00278     
00279     class SnapShot;
00280     friend class SnapShot;
00281 
00282   protected:
00283     void restoreSnapShot(const SnapShot &s)
00284     {
00285       while(s.edge_num<edges.size()) {
00286         Parent::getNotifier(Edge()).erase(Edge(edges.size()-1));
00287         nodes[edges.back().target].first_in=edges.back().next_in;
00288         nodes[edges.back().source].first_out=edges.back().next_out;
00289         edges.pop_back();
00290       }
00291       //nodes.resize(s.nodes_num);
00292       while(s.node_num<nodes.size()) {
00293         Parent::getNotifier(Node()).erase(Node(nodes.size()-1));
00294         nodes.pop_back();
00295       }
00296     }    
00297 
00298   public:
00299 
00301     
00315     Node split(Node n, bool connect = true) 
00316     {
00317       return _split(n,connect);
00318     }
00319   
00320 
00322 
00331     class SnapShot 
00332     {
00333       SmartGraph *g;
00334     protected:
00335       friend class SmartGraph;
00336       unsigned int node_num;
00337       unsigned int edge_num;
00338     public:
00340       
00344       SnapShot() : g(0) {}
00346       
00349       SnapShot(SmartGraph &_g) :g(&_g) {
00350         node_num=g->nodes.size();
00351         edge_num=g->edges.size();
00352       }
00353 
00355 
00361       void save(SmartGraph &_g) 
00362       {
00363         g=&_g;
00364         node_num=g->nodes.size();
00365         edge_num=g->edges.size();
00366       }
00367 
00369       
00377       
00378       void restore()
00379       {
00380         g->restoreSnapShot(*this);
00381       }
00382     };
00383   };
00384 
00385 
00386   /**************** Undirected List Graph ****************/
00387 
00388   typedef ClearableUndirGraphExtender<
00389     ExtendableUndirGraphExtender<
00390     MappableUndirGraphExtender<
00391     IterableUndirGraphExtender<
00392     AlterableUndirGraphExtender<
00393     UndirGraphExtender<SmartGraphBase> > > > > > UndirSmartGraphBase;
00394 
00396 
00407   class UndirSmartGraph : public UndirSmartGraphBase {
00408   };
00409 
00410   
00412 } //namespace lemon
00413 
00414 
00415 #endif //LEMON_SMART_GRAPH_H

Generated on Sat Aug 27 14:14:55 2005 for LEMON by  doxygen 1.4.4