smart_graph.h

Go to the documentation of this file.
00001 /* -*- C++ -*- 00002 * src/lemon/smart_graph.h - Part of LEMON, a generic C++ optimization library 00003 * 00004 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 00005 * (Egervary Combinatorial Optimization Research Group, 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 #include <climits> 00026 00027 #include <lemon/invalid.h> 00028 00029 #include <lemon/array_map.h> 00030 #include <lemon/sym_map.h> 00031 00032 #include <lemon/map_registry.h> 00033 00034 #include <lemon/map_defines.h> 00035 00036 namespace lemon { 00037 00040 // class SymSmartGraph; 00041 00043 00059 class SmartGraph { 00060 00061 struct NodeT 00062 { 00063 int first_in,first_out; 00064 NodeT() : first_in(-1), first_out(-1) {} 00065 }; 00066 struct EdgeT 00067 { 00068 int head, tail, next_in, next_out; 00069 //FIXME: is this necessary? 00070 EdgeT() : next_in(-1), next_out(-1) {} 00071 }; 00072 00073 std::vector<NodeT> nodes; 00074 00075 std::vector<EdgeT> edges; 00076 00077 00078 public: 00079 00080 typedef SmartGraph Graph; 00081 00082 class Node; 00083 class Edge; 00084 00085 class NodeIt; 00086 class EdgeIt; 00087 class OutEdgeIt; 00088 class InEdgeIt; 00089 00090 // Create map registries. 00091 CREATE_MAP_REGISTRIES; 00092 // Create node and edge maps. 00093 CREATE_MAPS(ArrayMap); 00094 00095 public: 00096 00097 SmartGraph() : nodes(), edges() { } 00098 SmartGraph(const SmartGraph &_g) : nodes(_g.nodes), edges(_g.edges) { } 00099 00101 int nodeNum() const { return nodes.size(); } 00103 int edgeNum() const { return edges.size(); } 00104 00106 00109 int maxNodeId() const { return nodes.size()-1; } 00111 00114 int maxEdgeId() const { return edges.size()-1; } 00115 00116 Node tail(Edge e) const { return edges[e.n].tail; } 00117 Node head(Edge e) const { return edges[e.n].head; } 00118 00119 NodeIt& first(NodeIt& v) const { 00120 v=NodeIt(*this); return v; } 00121 EdgeIt& first(EdgeIt& e) const { 00122 e=EdgeIt(*this); return e; } 00123 OutEdgeIt& first(OutEdgeIt& e, const Node v) const { 00124 e=OutEdgeIt(*this,v); return e; } 00125 InEdgeIt& first(InEdgeIt& e, const Node v) const { 00126 e=InEdgeIt(*this,v); return e; } 00127 00129 00136 static int id(Node v) { return v.n; } 00138 00145 static int id(Edge e) { return e.n; } 00146 00147 Node addNode() { 00148 Node n; n.n=nodes.size(); 00149 nodes.push_back(NodeT()); //FIXME: Hmmm... 00150 00151 00152 node_maps.add(n); 00153 return n; 00154 } 00155 00156 Edge addEdge(Node u, Node v) { 00157 Edge e; e.n=edges.size(); edges.push_back(EdgeT()); //FIXME: Hmmm... 00158 edges[e.n].tail=u.n; edges[e.n].head=v.n; 00159 edges[e.n].next_out=nodes[u.n].first_out; 00160 edges[e.n].next_in=nodes[v.n].first_in; 00161 nodes[u.n].first_out=nodes[v.n].first_in=e.n; 00162 00163 edge_maps.add(e); 00164 00165 return e; 00166 } 00167 00169 00176 Edge findEdge(Node u,Node v, Edge prev = INVALID) 00177 { 00178 int e = (prev.n==-1)? nodes[u.n].first_out : edges[prev.n].next_out; 00179 while(e!=-1 && edges[e].tail!=v.n) e = edges[e].next_out; 00180 prev.n=e; 00181 return prev; 00182 } 00183 00184 void clear() { 00185 edge_maps.clear(); 00186 edges.clear(); 00187 node_maps.clear(); 00188 nodes.clear(); 00189 } 00190 00191 class Node { 00192 friend class SmartGraph; 00193 template <typename T> friend class NodeMap; 00194 00195 friend class Edge; 00196 friend class OutEdgeIt; 00197 friend class InEdgeIt; 00198 friend class SymEdge; 00199 00200 protected: 00201 int n; 00202 friend int SmartGraph::id(Node v); 00203 Node(int nn) {n=nn;} 00204 public: 00205 Node() {} 00206 Node (Invalid) { n=-1; } 00207 bool operator==(const Node i) const {return n==i.n;} 00208 bool operator!=(const Node i) const {return n!=i.n;} 00209 bool operator<(const Node i) const {return n<i.n;} 00210 // ///Validity check 00211 // operator bool() { return n!=-1; } 00212 }; 00213 00214 class NodeIt : public Node { 00215 const SmartGraph *G; 00216 friend class SmartGraph; 00217 public: 00218 NodeIt() : Node() { } 00219 NodeIt(const SmartGraph& _G,Node n) : Node(n), G(&_G) { } 00220 NodeIt(Invalid i) : Node(i) { } 00221 NodeIt(const SmartGraph& _G) : Node(_G.nodes.size()?0:-1), G(&_G) { } 00222 NodeIt &operator++() { 00223 n=(n+2)%(G->nodes.size()+1)-1; 00224 return *this; 00225 } 00226 // ///Validity check 00227 // operator bool() { return Node::operator bool(); } 00228 }; 00229 00230 class Edge { 00231 friend class SmartGraph; 00232 template <typename T> friend class EdgeMap; 00233 00234 friend class SymSmartGraph; 00235 00236 friend class Node; 00237 friend class NodeIt; 00238 protected: 00239 int n; 00240 friend int SmartGraph::id(Edge e); 00241 Edge(int nn) {n=nn;} 00242 public: 00244 00245 Edge() { } 00246 Edge (Invalid) { n=-1; } 00247 bool operator==(const Edge i) const {return n==i.n;} 00248 bool operator!=(const Edge i) const {return n!=i.n;} 00249 bool operator<(const Edge i) const {return n<i.n;} 00250 // ///Validity check 00251 // operator bool() { return n!=-1; } 00252 00254 void setToId(int id) { n=id; } 00255 }; 00256 00257 class EdgeIt : public Edge { 00258 const SmartGraph *G; 00259 friend class SmartGraph; 00260 public: 00261 EdgeIt(const SmartGraph& _G) : Edge(_G.edges.size()-1), G(&_G) { } 00262 EdgeIt(const SmartGraph& _G, Edge e) : Edge(e), G(&_G) { } 00263 EdgeIt (Invalid i) : Edge(i) { } 00264 EdgeIt() : Edge() { } 00265 EdgeIt &operator++() { --n; return *this; } 00266 // ///Validity check 00267 // operator bool() { return Edge::operator bool(); } 00268 }; 00269 00270 class OutEdgeIt : public Edge { 00271 const SmartGraph *G; 00272 friend class SmartGraph; 00273 public: 00274 OutEdgeIt() : Edge() { } 00275 OutEdgeIt(const SmartGraph& _G, Edge e) : Edge(e), G(&_G) { } 00276 OutEdgeIt (Invalid i) : Edge(i) { } 00277 00278 OutEdgeIt(const SmartGraph& _G,const Node v) 00279 : Edge(_G.nodes[v.n].first_out), G(&_G) {} 00280 OutEdgeIt &operator++() { n=G->edges[n].next_out; return *this; } 00281 // ///Validity check 00282 // operator bool() { return Edge::operator bool(); } 00283 }; 00284 00285 class InEdgeIt : public Edge { 00286 const SmartGraph *G; 00287 friend class SmartGraph; 00288 public: 00289 InEdgeIt() : Edge() { } 00290 InEdgeIt(const SmartGraph& _G, Edge e) : Edge(e), G(&_G) { } 00291 InEdgeIt (Invalid i) : Edge(i) { } 00292 InEdgeIt(const SmartGraph& _G,Node v) 00293 : Edge(_G.nodes[v.n].first_in), G(&_G) { } 00294 InEdgeIt &operator++() { n=G->edges[n].next_in; return *this; } 00295 // ///Validity check 00296 // operator bool() { return Edge::operator bool(); } 00297 }; 00298 00299 }; 00300 00302 00319 //\sa SmartGraph. 00320 00321 class SymSmartGraph : public SmartGraph 00322 { 00323 public: 00324 typedef SymSmartGraph Graph; 00325 00326 // Create symmetric map registry. 00327 CREATE_SYM_EDGE_MAP_REGISTRY; 00328 // Create symmetric edge map. 00329 CREATE_SYM_EDGE_MAP(ArrayMap); 00330 00331 00332 SymSmartGraph() : SmartGraph() { } 00333 SymSmartGraph(const SmartGraph &_g) : SmartGraph(_g) { } 00335 Edge addEdge(Node u, Node v) 00336 { 00337 Edge e = SmartGraph::addEdge(u,v); 00338 Edge f = SmartGraph::addEdge(v,u); 00339 sym_edge_maps.add(e); 00340 sym_edge_maps.add(f); 00341 return e; 00342 } 00343 00345 00348 static Edge opposite(Edge e) 00349 { 00350 Edge f; 00351 f.n = e.n - 2*(e.n%2) + 1; 00352 return f; 00353 } 00354 00355 00356 }; 00357 00359 } //namespace lemon 00360 00361 00362 00363 00364 #endif //LEMON_SMART_GRAPH_H

Generated on Thu Sep 30 12:18:33 2004 for LEMON by doxygen 1.3.8