| [395] | 1 | // -*- mode:C++ -*- | 
|---|
 | 2 |  | 
|---|
| [405] | 3 | #ifndef HUGO_LIST_GRAPH_H | 
|---|
 | 4 | #define HUGO_LIST_GRAPH_H | 
|---|
| [395] | 5 |  | 
|---|
| [491] | 6 | ///\ingroup graphs | 
|---|
| [395] | 7 | ///\file | 
|---|
| [405] | 8 | ///\brief ListGraph, SymListGraph, NodeSet and EdgeSet classes. | 
|---|
| [395] | 9 |  | 
|---|
 | 10 | #include <vector> | 
|---|
| [782] | 11 | #include <climits> | 
|---|
| [395] | 12 |  | 
|---|
| [542] | 13 | #include <hugo/invalid.h> | 
|---|
| [395] | 14 |  | 
|---|
| [782] | 15 | #include <hugo/map_registry.h> | 
|---|
| [798] | 16 | #include <hugo/default_map_factory.h> | 
|---|
| [782] | 17 |  | 
|---|
 | 18 | #include <hugo/sym_map_factory.h> | 
|---|
 | 19 |  | 
|---|
 | 20 | #include <hugo/map_defines.h> | 
|---|
 | 21 |  | 
|---|
 | 22 |  | 
|---|
| [395] | 23 | namespace hugo { | 
|---|
 | 24 |  | 
|---|
| [406] | 25 | /// \addtogroup graphs | 
|---|
 | 26 | /// @{ | 
|---|
 | 27 |  | 
|---|
| [782] | 28 | //  class SymListGraph; | 
|---|
| [395] | 29 |  | 
|---|
| [401] | 30 |   ///A list graph class. | 
|---|
| [395] | 31 |  | 
|---|
| [397] | 32 |   ///This is a simple and fast erasable graph implementation. | 
|---|
 | 33 |   /// | 
|---|
| [395] | 34 |   ///It conforms to the graph interface documented under | 
|---|
 | 35 |   ///the description of \ref GraphSkeleton. | 
|---|
 | 36 |   ///\sa \ref GraphSkeleton. | 
|---|
| [397] | 37 |   class ListGraph { | 
|---|
| [395] | 38 |  | 
|---|
| [397] | 39 |     //Nodes are double linked. | 
|---|
 | 40 |     //The free nodes are only single linked using the "next" field. | 
|---|
| [395] | 41 |     struct NodeT  | 
|---|
 | 42 |     { | 
|---|
| [397] | 43 |       int first_in,first_out; | 
|---|
 | 44 |       int prev, next; | 
|---|
 | 45 |       //      NodeT() {} | 
|---|
| [395] | 46 |     }; | 
|---|
| [397] | 47 |     //Edges are double linked. | 
|---|
 | 48 |     //The free edges are only single linked using the "next_in" field. | 
|---|
| [395] | 49 |     struct EdgeT  | 
|---|
 | 50 |     { | 
|---|
| [397] | 51 |       int head, tail; | 
|---|
 | 52 |       int prev_in, prev_out; | 
|---|
 | 53 |       int next_in, next_out; | 
|---|
| [395] | 54 |       //FIXME: is this necessary? | 
|---|
| [397] | 55 |       //      EdgeT() : next_in(-1), next_out(-1) prev_in(-1), prev_out(-1) {}   | 
|---|
| [395] | 56 |     }; | 
|---|
 | 57 |  | 
|---|
 | 58 |     std::vector<NodeT> nodes; | 
|---|
| [397] | 59 |     //The first node | 
|---|
 | 60 |     int first_node; | 
|---|
 | 61 |     //The first free node | 
|---|
 | 62 |     int first_free_node; | 
|---|
| [395] | 63 |     std::vector<EdgeT> edges; | 
|---|
| [397] | 64 |     //The first free edge | 
|---|
 | 65 |     int first_free_edge; | 
|---|
| [395] | 66 |      | 
|---|
| [782] | 67 |   public: | 
|---|
| [395] | 68 |      | 
|---|
| [782] | 69 |     typedef ListGraph Graph; | 
|---|
| [397] | 70 |      | 
|---|
| [395] | 71 |     class Node; | 
|---|
 | 72 |     class Edge; | 
|---|
 | 73 |  | 
|---|
 | 74 |      | 
|---|
 | 75 |   public: | 
|---|
 | 76 |  | 
|---|
 | 77 |     class NodeIt; | 
|---|
 | 78 |     class EdgeIt; | 
|---|
 | 79 |     class OutEdgeIt; | 
|---|
 | 80 |     class InEdgeIt; | 
|---|
| [782] | 81 |  | 
|---|
 | 82 |     CREATE_MAP_REGISTRIES; | 
|---|
| [798] | 83 |     CREATE_MAPS(DefaultMapFactory); | 
|---|
| [782] | 84 |  | 
|---|
| [395] | 85 |   public: | 
|---|
 | 86 |  | 
|---|
| [782] | 87 |     ListGraph()  | 
|---|
 | 88 |       : nodes(), first_node(-1), | 
|---|
 | 89 |         first_free_node(-1), edges(), first_free_edge(-1) {} | 
|---|
 | 90 |  | 
|---|
 | 91 |     ListGraph(const ListGraph &_g)  | 
|---|
 | 92 |       : nodes(_g.nodes), first_node(_g.first_node), | 
|---|
 | 93 |         first_free_node(_g.first_free_node), edges(_g.edges), | 
|---|
 | 94 |         first_free_edge(_g.first_free_edge) {} | 
|---|
| [395] | 95 |      | 
|---|
| [813] | 96 |     ///Number of nodes. | 
|---|
 | 97 |     int nodeNum() const { return nodes.size(); } | 
|---|
 | 98 |     ///Number of edges. | 
|---|
 | 99 |     int edgeNum() const { return edges.size(); } | 
|---|
| [395] | 100 |  | 
|---|
| [813] | 101 |     ///Set the expected maximum number of edges. | 
|---|
| [695] | 102 |  | 
|---|
 | 103 |     ///With this function, it is possible to set the expected number of edges. | 
|---|
 | 104 |     ///The use of this fasten the building of the graph and makes | 
|---|
 | 105 |     ///it possible to avoid the superfluous memory allocation. | 
|---|
 | 106 |     void reserveEdge(int n) { edges.reserve(n); }; | 
|---|
 | 107 |      | 
|---|
| [813] | 108 |     /// Maximum node ID. | 
|---|
 | 109 |      | 
|---|
 | 110 |     /// Maximum node ID. | 
|---|
 | 111 |     ///\sa id(Node) | 
|---|
 | 112 |     int maxNodeId() const { return nodes.size()-1; }  | 
|---|
 | 113 |     /// Maximum edge ID. | 
|---|
 | 114 |      | 
|---|
 | 115 |     /// Maximum edge ID. | 
|---|
 | 116 |     ///\sa id(Edge) | 
|---|
 | 117 |     int maxEdgeId() const { return edges.size()-1; } | 
|---|
| [395] | 118 |  | 
|---|
 | 119 |     Node tail(Edge e) const { return edges[e.n].tail; } | 
|---|
 | 120 |     Node head(Edge e) const { return edges[e.n].head; } | 
|---|
 | 121 |  | 
|---|
| [713] | 122 |     NodeIt& first(NodeIt& v) const {  | 
|---|
| [395] | 123 |       v=NodeIt(*this); return v; } | 
|---|
| [713] | 124 |     EdgeIt& first(EdgeIt& e) const {  | 
|---|
| [395] | 125 |       e=EdgeIt(*this); return e; } | 
|---|
| [713] | 126 |     OutEdgeIt& first(OutEdgeIt& e, const Node v) const {  | 
|---|
| [395] | 127 |       e=OutEdgeIt(*this,v); return e; } | 
|---|
| [713] | 128 |     InEdgeIt& first(InEdgeIt& e, const Node v) const {  | 
|---|
| [395] | 129 |       e=InEdgeIt(*this,v); return e; } | 
|---|
 | 130 |  | 
|---|
| [813] | 131 |     /// Node ID. | 
|---|
 | 132 |      | 
|---|
 | 133 |     /// The ID of a valid Node is a nonnegative integer not greater than | 
|---|
 | 134 |     /// \ref maxNodeId(). The range of the ID's is not surely continuous | 
|---|
 | 135 |     /// and the greatest node ID can be actually less then \ref maxNodeId(). | 
|---|
 | 136 |     /// | 
|---|
 | 137 |     /// The ID of the \ref INVALID node is -1. | 
|---|
 | 138 |     ///\return The ID of the node \c v.  | 
|---|
| [713] | 139 |     static int id(Node v) { return v.n; } | 
|---|
| [813] | 140 |     /// Edge ID. | 
|---|
 | 141 |      | 
|---|
 | 142 |     /// The ID of a valid Edge is a nonnegative integer not greater than | 
|---|
 | 143 |     /// \ref maxEdgeId(). The range of the ID's is not surely continuous | 
|---|
 | 144 |     /// and the greatest edge ID can be actually less then \ref maxEdgeId(). | 
|---|
 | 145 |     /// | 
|---|
 | 146 |     /// The ID of the \ref INVALID edge is -1. | 
|---|
 | 147 |     ///\return The ID of the edge \c e.  | 
|---|
| [713] | 148 |     static int id(Edge e) { return e.n; } | 
|---|
| [395] | 149 |  | 
|---|
| [397] | 150 |     /// Adds a new node to the graph. | 
|---|
 | 151 |  | 
|---|
| [813] | 152 |     /// \warning It adds the new node to the front of the list. | 
|---|
| [397] | 153 |     /// (i.e. the lastly added node becomes the first.) | 
|---|
| [395] | 154 |     Node addNode() { | 
|---|
| [397] | 155 |       int n; | 
|---|
 | 156 |        | 
|---|
 | 157 |       if(first_free_node==-1) | 
|---|
 | 158 |         { | 
|---|
 | 159 |           n = nodes.size(); | 
|---|
 | 160 |           nodes.push_back(NodeT()); | 
|---|
 | 161 |         } | 
|---|
 | 162 |       else { | 
|---|
 | 163 |         n = first_free_node; | 
|---|
 | 164 |         first_free_node = nodes[n].next; | 
|---|
 | 165 |       } | 
|---|
 | 166 |        | 
|---|
 | 167 |       nodes[n].next = first_node; | 
|---|
 | 168 |       if(first_node != -1) nodes[first_node].prev = n; | 
|---|
 | 169 |       first_node = n; | 
|---|
 | 170 |       nodes[n].prev = -1; | 
|---|
 | 171 |        | 
|---|
 | 172 |       nodes[n].first_in = nodes[n].first_out = -1; | 
|---|
 | 173 |        | 
|---|
 | 174 |       Node nn; nn.n=n; | 
|---|
| [395] | 175 |  | 
|---|
| [397] | 176 |       //Update dynamic maps | 
|---|
| [782] | 177 |       node_maps.add(nn); | 
|---|
| [395] | 178 |  | 
|---|
| [397] | 179 |       return nn; | 
|---|
| [395] | 180 |     } | 
|---|
 | 181 |      | 
|---|
 | 182 |     Edge addEdge(Node u, Node v) { | 
|---|
| [397] | 183 |       int n; | 
|---|
 | 184 |        | 
|---|
 | 185 |       if(first_free_edge==-1) | 
|---|
 | 186 |         { | 
|---|
 | 187 |           n = edges.size(); | 
|---|
 | 188 |           edges.push_back(EdgeT()); | 
|---|
 | 189 |         } | 
|---|
 | 190 |       else { | 
|---|
 | 191 |         n = first_free_edge; | 
|---|
 | 192 |         first_free_edge = edges[n].next_in; | 
|---|
 | 193 |       } | 
|---|
 | 194 |        | 
|---|
 | 195 |       edges[n].tail = u.n; edges[n].head = v.n; | 
|---|
| [395] | 196 |  | 
|---|
| [397] | 197 |       edges[n].next_out = nodes[u.n].first_out; | 
|---|
 | 198 |       if(nodes[u.n].first_out != -1) edges[nodes[u.n].first_out].prev_out = n; | 
|---|
 | 199 |       edges[n].next_in = nodes[v.n].first_in; | 
|---|
 | 200 |       if(nodes[v.n].first_in != -1) edges[nodes[v.n].first_in].prev_in = n; | 
|---|
 | 201 |       edges[n].prev_in = edges[n].prev_out = -1; | 
|---|
 | 202 |          | 
|---|
 | 203 |       nodes[u.n].first_out = nodes[v.n].first_in = n; | 
|---|
 | 204 |  | 
|---|
 | 205 |       Edge e; e.n=n; | 
|---|
 | 206 |  | 
|---|
 | 207 |       //Update dynamic maps | 
|---|
| [782] | 208 |       edge_maps.add(e); | 
|---|
| [395] | 209 |  | 
|---|
 | 210 |       return e; | 
|---|
 | 211 |     } | 
|---|
| [774] | 212 |      | 
|---|
 | 213 |     /// Finds an edge between two nodes. | 
|---|
| [395] | 214 |  | 
|---|
| [774] | 215 |     /// Finds an edge from node \c u to node \c v. | 
|---|
 | 216 |     /// | 
|---|
 | 217 |     /// If \c prev is \ref INVALID (this is the default value), then | 
|---|
 | 218 |     /// It finds the first edge from \c u to \c v. Otherwise it looks for | 
|---|
 | 219 |     /// the next edge from \c u to \c v after \c prev. | 
|---|
 | 220 |     /// \return The found edge or INVALID if there is no such an edge. | 
|---|
 | 221 |     Edge findEdge(Node u,Node v, Edge prev = INVALID)  | 
|---|
 | 222 |     { | 
|---|
 | 223 |       int e = (prev.n==-1)? nodes[u.n].first_out : edges[prev.n].next_out; | 
|---|
 | 224 |       while(e!=-1 && edges[e].tail!=v.n) e = edges[e].next_out; | 
|---|
 | 225 |       prev.n=e; | 
|---|
 | 226 |       return prev; | 
|---|
 | 227 |     } | 
|---|
 | 228 |      | 
|---|
| [397] | 229 |   private: | 
|---|
 | 230 |     void eraseEdge(int n) { | 
|---|
 | 231 |        | 
|---|
 | 232 |       if(edges[n].next_in!=-1) | 
|---|
 | 233 |         edges[edges[n].next_in].prev_in = edges[n].prev_in; | 
|---|
 | 234 |       if(edges[n].prev_in!=-1) | 
|---|
 | 235 |         edges[edges[n].prev_in].next_in = edges[n].next_in; | 
|---|
 | 236 |       else nodes[edges[n].head].first_in = edges[n].next_in; | 
|---|
 | 237 |        | 
|---|
 | 238 |       if(edges[n].next_out!=-1) | 
|---|
 | 239 |         edges[edges[n].next_out].prev_out = edges[n].prev_out; | 
|---|
 | 240 |       if(edges[n].prev_out!=-1) | 
|---|
 | 241 |         edges[edges[n].prev_out].next_out = edges[n].next_out; | 
|---|
 | 242 |       else nodes[edges[n].tail].first_out = edges[n].next_out; | 
|---|
 | 243 |        | 
|---|
 | 244 |       edges[n].next_in = first_free_edge; | 
|---|
| [695] | 245 |       first_free_edge = n;       | 
|---|
| [397] | 246 |  | 
|---|
 | 247 |       //Update dynamic maps | 
|---|
 | 248 |       Edge e; e.n=n; | 
|---|
| [782] | 249 |       edge_maps.erase(e); | 
|---|
 | 250 |  | 
|---|
| [397] | 251 |     } | 
|---|
 | 252 |        | 
|---|
 | 253 |   public: | 
|---|
 | 254 |  | 
|---|
 | 255 |     void erase(Node nn) { | 
|---|
 | 256 |       int n=nn.n; | 
|---|
 | 257 |        | 
|---|
 | 258 |       int m; | 
|---|
 | 259 |       while((m=nodes[n].first_in)!=-1) eraseEdge(m); | 
|---|
 | 260 |       while((m=nodes[n].first_out)!=-1) eraseEdge(m); | 
|---|
 | 261 |  | 
|---|
 | 262 |       if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev; | 
|---|
 | 263 |       if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next; | 
|---|
 | 264 |       else first_node = nodes[n].next; | 
|---|
 | 265 |        | 
|---|
 | 266 |       nodes[n].next = first_free_node; | 
|---|
 | 267 |       first_free_node = n; | 
|---|
 | 268 |  | 
|---|
 | 269 |       //Update dynamic maps | 
|---|
| [782] | 270 |       node_maps.erase(nn); | 
|---|
 | 271 |  | 
|---|
| [397] | 272 |     } | 
|---|
 | 273 |      | 
|---|
 | 274 |     void erase(Edge e) { eraseEdge(e.n); } | 
|---|
 | 275 |  | 
|---|
 | 276 |     void clear() { | 
|---|
| [782] | 277 |       edge_maps.clear(); | 
|---|
 | 278 |       edges.clear(); | 
|---|
 | 279 |       node_maps.clear(); | 
|---|
 | 280 |       nodes.clear(); | 
|---|
| [397] | 281 |       first_node=first_free_node=first_free_edge=-1; | 
|---|
 | 282 |     } | 
|---|
| [395] | 283 |  | 
|---|
 | 284 |     class Node { | 
|---|
| [397] | 285 |       friend class ListGraph; | 
|---|
| [395] | 286 |       template <typename T> friend class NodeMap; | 
|---|
| [400] | 287 |         | 
|---|
| [395] | 288 |       friend class Edge; | 
|---|
 | 289 |       friend class OutEdgeIt; | 
|---|
 | 290 |       friend class InEdgeIt; | 
|---|
 | 291 |       friend class SymEdge; | 
|---|
 | 292 |  | 
|---|
 | 293 |     protected: | 
|---|
 | 294 |       int n; | 
|---|
| [722] | 295 |       friend int ListGraph::id(Node v);  | 
|---|
| [395] | 296 |       Node(int nn) {n=nn;} | 
|---|
 | 297 |     public: | 
|---|
 | 298 |       Node() {} | 
|---|
| [503] | 299 |       Node (Invalid) { n=-1; } | 
|---|
| [395] | 300 |       bool operator==(const Node i) const {return n==i.n;} | 
|---|
 | 301 |       bool operator!=(const Node i) const {return n!=i.n;} | 
|---|
 | 302 |       bool operator<(const Node i) const {return n<i.n;} | 
|---|
| [774] | 303 |       //      ///Validity check | 
|---|
 | 304 |       //      operator bool() { return n!=-1; } | 
|---|
| [395] | 305 |     }; | 
|---|
 | 306 |      | 
|---|
 | 307 |     class NodeIt : public Node { | 
|---|
| [774] | 308 |       const ListGraph *G; | 
|---|
| [397] | 309 |       friend class ListGraph; | 
|---|
| [395] | 310 |     public: | 
|---|
| [400] | 311 |       NodeIt() : Node() { } | 
|---|
 | 312 |       NodeIt(Invalid i) : Node(i) { } | 
|---|
| [774] | 313 |       NodeIt(const ListGraph& _G) : Node(_G.first_node), G(&_G) { } | 
|---|
| [579] | 314 |       ///\todo Undocumented conversion Node -\> NodeIt. | 
|---|
| [774] | 315 |       NodeIt(const ListGraph& _G,Node n) : Node(n), G(&_G) { } | 
|---|
 | 316 |       NodeIt &operator++() { | 
|---|
 | 317 |         n=G->nodes[n].next;  | 
|---|
 | 318 |         return *this;  | 
|---|
 | 319 |       } | 
|---|
 | 320 |       //      ///Validity check | 
|---|
 | 321 |       //      operator bool() { return Node::operator bool(); }       | 
|---|
| [395] | 322 |     }; | 
|---|
 | 323 |  | 
|---|
 | 324 |     class Edge { | 
|---|
| [397] | 325 |       friend class ListGraph; | 
|---|
| [395] | 326 |       template <typename T> friend class EdgeMap; | 
|---|
 | 327 |  | 
|---|
| [397] | 328 |       //template <typename T> friend class SymListGraph::SymEdgeMap;       | 
|---|
 | 329 |       //friend Edge SymListGraph::opposite(Edge) const; | 
|---|
| [395] | 330 |        | 
|---|
 | 331 |       friend class Node; | 
|---|
 | 332 |       friend class NodeIt; | 
|---|
 | 333 |     protected: | 
|---|
 | 334 |       int n; | 
|---|
| [722] | 335 |       friend int ListGraph::id(Edge e); | 
|---|
| [395] | 336 |  | 
|---|
| [706] | 337 |     public: | 
|---|
 | 338 |       /// An Edge with id \c n. | 
|---|
 | 339 |  | 
|---|
 | 340 |       /// \bug It should be | 
|---|
 | 341 |       /// obtained by a member function of the Graph. | 
|---|
| [395] | 342 |       Edge(int nn) {n=nn;} | 
|---|
| [706] | 343 |  | 
|---|
| [395] | 344 |       Edge() { } | 
|---|
 | 345 |       Edge (Invalid) { n=-1; } | 
|---|
 | 346 |       bool operator==(const Edge i) const {return n==i.n;} | 
|---|
 | 347 |       bool operator!=(const Edge i) const {return n!=i.n;} | 
|---|
 | 348 |       bool operator<(const Edge i) const {return n<i.n;} | 
|---|
 | 349 |       ///\bug This is a workaround until somebody tells me how to | 
|---|
| [397] | 350 |       ///make class \c SymListGraph::SymEdgeMap friend of Edge | 
|---|
| [395] | 351 |       int &idref() {return n;} | 
|---|
| [774] | 352 |       const int &idref() const {return n;}  | 
|---|
 | 353 |       //      ///Validity check | 
|---|
 | 354 |       //      operator bool() { return n!=-1; } | 
|---|
 | 355 |    }; | 
|---|
| [395] | 356 |      | 
|---|
 | 357 |     class EdgeIt : public Edge { | 
|---|
| [774] | 358 |       const ListGraph *G; | 
|---|
| [397] | 359 |       friend class ListGraph; | 
|---|
| [395] | 360 |     public: | 
|---|
| [774] | 361 |       EdgeIt(const ListGraph& _G) : Edge(), G(&_G) { | 
|---|
| [397] | 362 |         int m; | 
|---|
| [774] | 363 |         for(m=_G.first_node; | 
|---|
 | 364 |             m!=-1 && _G.nodes[m].first_in == -1; m = _G.nodes[m].next); | 
|---|
 | 365 |         n = (m==-1)?-1:_G.nodes[m].first_in; | 
|---|
| [397] | 366 |       } | 
|---|
| [395] | 367 |       EdgeIt (Invalid i) : Edge(i) { } | 
|---|
| [774] | 368 |       EdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { } | 
|---|
| [395] | 369 |       EdgeIt() : Edge() { } | 
|---|
 | 370 |       ///\bug This is a workaround until somebody tells me how to | 
|---|
| [397] | 371 |       ///make class \c SymListGraph::SymEdgeMap friend of Edge | 
|---|
| [395] | 372 |       int &idref() {return n;} | 
|---|
| [774] | 373 |       EdgeIt &operator++() { | 
|---|
 | 374 |         if(G->edges[n].next_in!=-1) n=G->edges[n].next_in; | 
|---|
 | 375 |         else { | 
|---|
 | 376 |           int nn; | 
|---|
 | 377 |           for(nn=G->nodes[G->edges[n].head].next; | 
|---|
 | 378 |               nn!=-1 && G->nodes[nn].first_in == -1; | 
|---|
 | 379 |               nn = G->nodes[nn].next) ; | 
|---|
 | 380 |           n = (nn==-1)?-1:G->nodes[nn].first_in; | 
|---|
 | 381 |         } | 
|---|
 | 382 |         return *this; | 
|---|
 | 383 |       } | 
|---|
 | 384 |       //      ///Validity check | 
|---|
 | 385 |       //      operator bool() { return Edge::operator bool(); }       | 
|---|
| [395] | 386 |     }; | 
|---|
 | 387 |      | 
|---|
 | 388 |     class OutEdgeIt : public Edge { | 
|---|
| [774] | 389 |       const ListGraph *G; | 
|---|
| [397] | 390 |       friend class ListGraph; | 
|---|
| [395] | 391 |     public:  | 
|---|
 | 392 |       OutEdgeIt() : Edge() { } | 
|---|
| [774] | 393 |       OutEdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { } | 
|---|
| [395] | 394 |       OutEdgeIt (Invalid i) : Edge(i) { } | 
|---|
 | 395 |  | 
|---|
| [774] | 396 |       OutEdgeIt(const ListGraph& _G,const Node v) | 
|---|
 | 397 |         : Edge(_G.nodes[v.n].first_out), G(&_G) {} | 
|---|
 | 398 |       OutEdgeIt &operator++() { n=G->edges[n].next_out; return *this; } | 
|---|
 | 399 |       //      ///Validity check | 
|---|
 | 400 |       //      operator bool() { return Edge::operator bool(); }       | 
|---|
| [395] | 401 |     }; | 
|---|
 | 402 |      | 
|---|
 | 403 |     class InEdgeIt : public Edge { | 
|---|
| [774] | 404 |       const ListGraph *G; | 
|---|
| [397] | 405 |       friend class ListGraph; | 
|---|
| [395] | 406 |     public:  | 
|---|
 | 407 |       InEdgeIt() : Edge() { } | 
|---|
| [774] | 408 |       InEdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { } | 
|---|
| [395] | 409 |       InEdgeIt (Invalid i) : Edge(i) { } | 
|---|
| [774] | 410 |       InEdgeIt(const ListGraph& _G,Node v) | 
|---|
 | 411 |         : Edge(_G.nodes[v.n].first_in), G(&_G) { } | 
|---|
 | 412 |       InEdgeIt &operator++() { n=G->edges[n].next_in; return *this; } | 
|---|
 | 413 |       //      ///Validity check | 
|---|
 | 414 |       //      operator bool() { return Edge::operator bool(); }       | 
|---|
| [395] | 415 |     }; | 
|---|
 | 416 |   }; | 
|---|
 | 417 |  | 
|---|
 | 418 |   ///Graph for bidirectional edges. | 
|---|
 | 419 |  | 
|---|
 | 420 |   ///The purpose of this graph structure is to handle graphs | 
|---|
 | 421 |   ///having bidirectional edges. Here the function \c addEdge(u,v) adds a pair | 
|---|
 | 422 |   ///of oppositely directed edges. | 
|---|
 | 423 |   ///There is a new edge map type called | 
|---|
| [397] | 424 |   ///\ref SymListGraph::SymEdgeMap "SymEdgeMap" | 
|---|
| [395] | 425 |   ///that complements this | 
|---|
 | 426 |   ///feature by | 
|---|
 | 427 |   ///storing shared values for the edge pairs. The usual | 
|---|
 | 428 |   ///\ref GraphSkeleton::EdgeMap "EdgeMap" | 
|---|
 | 429 |   ///can be used | 
|---|
 | 430 |   ///as well. | 
|---|
 | 431 |   /// | 
|---|
 | 432 |   ///The oppositely directed edge can also be obtained easily | 
|---|
 | 433 |   ///using \ref opposite. | 
|---|
| [397] | 434 |   /// | 
|---|
 | 435 |   ///Here erase(Edge) deletes a pair of edges. | 
|---|
 | 436 |   /// | 
|---|
 | 437 |   ///\todo this date structure need some reconsiderations. Maybe it | 
|---|
 | 438 |   ///should be implemented independently from ListGraph. | 
|---|
| [782] | 439 |    | 
|---|
| [397] | 440 |   class SymListGraph : public ListGraph | 
|---|
| [395] | 441 |   { | 
|---|
 | 442 |   public: | 
|---|
| [782] | 443 |  | 
|---|
 | 444 |     typedef SymListGraph Graph; | 
|---|
 | 445 |  | 
|---|
 | 446 |     KEEP_NODE_MAP(ListGraph); | 
|---|
 | 447 |     KEEP_EDGE_MAP(ListGraph); | 
|---|
 | 448 |  | 
|---|
 | 449 |     CREATE_SYM_EDGE_MAP_REGISTRY; | 
|---|
| [798] | 450 |     CREATE_SYM_EDGE_MAP_FACTORY(DefaultMapFactory); | 
|---|
| [782] | 451 |     IMPORT_SYM_EDGE_MAP(SymEdgeMapFactory); | 
|---|
| [395] | 452 |  | 
|---|
| [397] | 453 |     SymListGraph() : ListGraph() { } | 
|---|
 | 454 |     SymListGraph(const ListGraph &_g) : ListGraph(_g) { } | 
|---|
 | 455 |     ///Adds a pair of oppositely directed edges to the graph. | 
|---|
| [395] | 456 |     Edge addEdge(Node u, Node v) | 
|---|
 | 457 |     { | 
|---|
| [397] | 458 |       Edge e = ListGraph::addEdge(u,v); | 
|---|
| [782] | 459 |       Edge f = ListGraph::addEdge(v,u); | 
|---|
 | 460 |       sym_edge_maps.add(e); | 
|---|
 | 461 |       sym_edge_maps.add(f); | 
|---|
 | 462 |        | 
|---|
| [395] | 463 |       return e; | 
|---|
 | 464 |     } | 
|---|
 | 465 |  | 
|---|
| [782] | 466 |     void erase(Node n) { ListGraph::erase(n);} | 
|---|
| [395] | 467 |     ///The oppositely directed edge. | 
|---|
 | 468 |  | 
|---|
 | 469 |     ///Returns the oppositely directed | 
|---|
 | 470 |     ///pair of the edge \c e. | 
|---|
| [713] | 471 |     static Edge opposite(Edge e) | 
|---|
| [395] | 472 |     { | 
|---|
 | 473 |       Edge f; | 
|---|
 | 474 |       f.idref() = e.idref() - 2*(e.idref()%2) + 1; | 
|---|
 | 475 |       return f; | 
|---|
 | 476 |     } | 
|---|
 | 477 |      | 
|---|
| [397] | 478 |     ///Removes a pair of oppositely directed edges to the graph. | 
|---|
 | 479 |     void erase(Edge e) { | 
|---|
| [782] | 480 |       Edge f = opposite(e); | 
|---|
 | 481 |       sym_edge_maps.erase(e); | 
|---|
 | 482 |       sym_edge_maps.erase(f); | 
|---|
 | 483 |       ListGraph::erase(f); | 
|---|
| [397] | 484 |       ListGraph::erase(e); | 
|---|
| [782] | 485 |     }     | 
|---|
 | 486 |   }; | 
|---|
| [395] | 487 |  | 
|---|
| [400] | 488 |  | 
|---|
| [401] | 489 |   ///A graph class containing only nodes. | 
|---|
| [400] | 490 |  | 
|---|
| [401] | 491 |   ///This class implements a graph structure without edges. | 
|---|
 | 492 |   ///The most useful application of this class is to be the node set of an | 
|---|
 | 493 |   ///\ref EdgeSet class. | 
|---|
| [400] | 494 |   /// | 
|---|
 | 495 |   ///It conforms to the graph interface documented under | 
|---|
| [401] | 496 |   ///the description of \ref GraphSkeleton with the exception that you cannot | 
|---|
 | 497 |   ///add (or delete) edges. The usual edge iterators are exists, but they are | 
|---|
 | 498 |   ///always \ref INVALID. | 
|---|
 | 499 |   ///\sa \ref GraphSkeleton | 
|---|
| [508] | 500 |   ///\sa \ref EdgeSet | 
|---|
| [400] | 501 |   class NodeSet { | 
|---|
 | 502 |  | 
|---|
 | 503 |     //Nodes are double linked. | 
|---|
 | 504 |     //The free nodes are only single linked using the "next" field. | 
|---|
 | 505 |     struct NodeT  | 
|---|
 | 506 |     { | 
|---|
 | 507 |       int first_in,first_out; | 
|---|
 | 508 |       int prev, next; | 
|---|
 | 509 |       //      NodeT() {} | 
|---|
 | 510 |     }; | 
|---|
 | 511 |  | 
|---|
 | 512 |     std::vector<NodeT> nodes; | 
|---|
 | 513 |     //The first node | 
|---|
 | 514 |     int first_node; | 
|---|
 | 515 |     //The first free node | 
|---|
 | 516 |     int first_free_node; | 
|---|
 | 517 |      | 
|---|
 | 518 |   public: | 
|---|
| [782] | 519 |  | 
|---|
 | 520 |     typedef NodeSet Graph; | 
|---|
| [400] | 521 |      | 
|---|
 | 522 |     class Node; | 
|---|
 | 523 |     class Edge; | 
|---|
 | 524 |  | 
|---|
 | 525 |   public: | 
|---|
 | 526 |  | 
|---|
 | 527 |     class NodeIt; | 
|---|
 | 528 |     class EdgeIt; | 
|---|
 | 529 |     class OutEdgeIt; | 
|---|
 | 530 |     class InEdgeIt; | 
|---|
 | 531 |      | 
|---|
| [782] | 532 |     CREATE_MAP_REGISTRIES; | 
|---|
| [798] | 533 |     CREATE_MAPS(DefaultMapFactory); | 
|---|
| [400] | 534 |      | 
|---|
 | 535 |   public: | 
|---|
 | 536 |  | 
|---|
| [408] | 537 |     ///Default constructor | 
|---|
| [782] | 538 |     NodeSet()  | 
|---|
 | 539 |       : nodes(), first_node(-1), first_free_node(-1) {} | 
|---|
| [408] | 540 |     ///Copy constructor | 
|---|
| [782] | 541 |     NodeSet(const NodeSet &_g)  | 
|---|
 | 542 |       : nodes(_g.nodes), first_node(_g.first_node), | 
|---|
 | 543 |         first_free_node(_g.first_free_node) {} | 
|---|
| [400] | 544 |      | 
|---|
| [813] | 545 |     ///Number of nodes. | 
|---|
 | 546 |     int nodeNum() const { return nodes.size(); } | 
|---|
 | 547 |     ///Number of edges. | 
|---|
 | 548 |     int edgeNum() const { return 0; } | 
|---|
| [400] | 549 |  | 
|---|
| [813] | 550 |     /// Maximum node ID. | 
|---|
 | 551 |      | 
|---|
 | 552 |     /// Maximum node ID. | 
|---|
 | 553 |     ///\sa id(Node) | 
|---|
 | 554 |     int maxNodeId() const { return nodes.size()-1; } | 
|---|
 | 555 |     /// Maximum edge ID. | 
|---|
 | 556 |      | 
|---|
 | 557 |     /// Maximum edge ID. | 
|---|
 | 558 |     ///\sa id(Edge) | 
|---|
 | 559 |     int maxEdgeId() const { return 0; } | 
|---|
| [400] | 560 |  | 
|---|
 | 561 |     Node tail(Edge e) const { return INVALID; } | 
|---|
 | 562 |     Node head(Edge e) const { return INVALID; } | 
|---|
 | 563 |  | 
|---|
 | 564 |     NodeIt& first(NodeIt& v) const {  | 
|---|
 | 565 |       v=NodeIt(*this); return v; } | 
|---|
 | 566 |     EdgeIt& first(EdgeIt& e) const {  | 
|---|
 | 567 |       e=EdgeIt(*this); return e; } | 
|---|
 | 568 |     OutEdgeIt& first(OutEdgeIt& e, const Node v) const {  | 
|---|
 | 569 |       e=OutEdgeIt(*this,v); return e; } | 
|---|
 | 570 |     InEdgeIt& first(InEdgeIt& e, const Node v) const {  | 
|---|
 | 571 |       e=InEdgeIt(*this,v); return e; } | 
|---|
 | 572 |  | 
|---|
| [813] | 573 |     /// Node ID. | 
|---|
 | 574 |      | 
|---|
 | 575 |     /// The ID of a valid Node is a nonnegative integer not greater than | 
|---|
 | 576 |     /// \ref maxNodeId(). The range of the ID's is not surely continuous | 
|---|
 | 577 |     /// and the greatest node ID can be actually less then \ref maxNodeId(). | 
|---|
 | 578 |     /// | 
|---|
 | 579 |     /// The ID of the \ref INVALID node is -1. | 
|---|
 | 580 |     ///\return The ID of the node \c v.  | 
|---|
| [400] | 581 |     int id(Node v) const { return v.n; } | 
|---|
| [813] | 582 |     /// Edge ID. | 
|---|
 | 583 |      | 
|---|
 | 584 |     /// The ID of a valid Edge is a nonnegative integer not greater than | 
|---|
 | 585 |     /// \ref maxEdgeId(). The range of the ID's is not surely continuous | 
|---|
 | 586 |     /// and the greatest edge ID can be actually less then \ref maxEdgeId(). | 
|---|
 | 587 |     /// | 
|---|
 | 588 |     /// The ID of the \ref INVALID edge is -1. | 
|---|
 | 589 |     ///\return The ID of the edge \c e.  | 
|---|
| [400] | 590 |     int id(Edge e) const { return -1; } | 
|---|
 | 591 |  | 
|---|
 | 592 |     /// Adds a new node to the graph. | 
|---|
 | 593 |  | 
|---|
| [813] | 594 |     /// \warning It adds the new node to the front of the list. | 
|---|
| [400] | 595 |     /// (i.e. the lastly added node becomes the first.) | 
|---|
 | 596 |     Node addNode() { | 
|---|
 | 597 |       int n; | 
|---|
 | 598 |        | 
|---|
 | 599 |       if(first_free_node==-1) | 
|---|
 | 600 |         { | 
|---|
 | 601 |           n = nodes.size(); | 
|---|
 | 602 |           nodes.push_back(NodeT()); | 
|---|
 | 603 |         } | 
|---|
 | 604 |       else { | 
|---|
 | 605 |         n = first_free_node; | 
|---|
 | 606 |         first_free_node = nodes[n].next; | 
|---|
 | 607 |       } | 
|---|
 | 608 |        | 
|---|
 | 609 |       nodes[n].next = first_node; | 
|---|
 | 610 |       if(first_node != -1) nodes[first_node].prev = n; | 
|---|
 | 611 |       first_node = n; | 
|---|
 | 612 |       nodes[n].prev = -1; | 
|---|
 | 613 |        | 
|---|
 | 614 |       nodes[n].first_in = nodes[n].first_out = -1; | 
|---|
 | 615 |        | 
|---|
 | 616 |       Node nn; nn.n=n; | 
|---|
 | 617 |  | 
|---|
 | 618 |       //Update dynamic maps | 
|---|
| [782] | 619 |       node_maps.add(nn); | 
|---|
| [400] | 620 |  | 
|---|
 | 621 |       return nn; | 
|---|
 | 622 |     } | 
|---|
 | 623 |      | 
|---|
 | 624 |     void erase(Node nn) { | 
|---|
 | 625 |       int n=nn.n; | 
|---|
 | 626 |        | 
|---|
 | 627 |       if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev; | 
|---|
 | 628 |       if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next; | 
|---|
 | 629 |       else first_node = nodes[n].next; | 
|---|
 | 630 |        | 
|---|
 | 631 |       nodes[n].next = first_free_node; | 
|---|
 | 632 |       first_free_node = n; | 
|---|
 | 633 |  | 
|---|
 | 634 |       //Update dynamic maps | 
|---|
| [782] | 635 |       node_maps.erase(nn); | 
|---|
| [400] | 636 |     } | 
|---|
 | 637 |      | 
|---|
| [774] | 638 |          | 
|---|
 | 639 |     Edge findEdge(Node u,Node v, Edge prev = INVALID)  | 
|---|
 | 640 |     { | 
|---|
 | 641 |       return INVALID; | 
|---|
 | 642 |     } | 
|---|
 | 643 |      | 
|---|
| [400] | 644 |     void clear() { | 
|---|
| [782] | 645 |       node_maps.clear(); | 
|---|
| [400] | 646 |       nodes.clear(); | 
|---|
 | 647 |       first_node = first_free_node = -1; | 
|---|
 | 648 |     } | 
|---|
 | 649 |  | 
|---|
 | 650 |     class Node { | 
|---|
 | 651 |       friend class NodeSet; | 
|---|
 | 652 |       template <typename T> friend class NodeMap; | 
|---|
 | 653 |        | 
|---|
 | 654 |       friend class Edge; | 
|---|
 | 655 |       friend class OutEdgeIt; | 
|---|
 | 656 |       friend class InEdgeIt; | 
|---|
 | 657 |  | 
|---|
 | 658 |     protected: | 
|---|
 | 659 |       int n; | 
|---|
 | 660 |       friend int NodeSet::id(Node v) const;  | 
|---|
 | 661 |       Node(int nn) {n=nn;} | 
|---|
 | 662 |     public: | 
|---|
 | 663 |       Node() {} | 
|---|
 | 664 |       Node (Invalid i) { n=-1; } | 
|---|
 | 665 |       bool operator==(const Node i) const {return n==i.n;} | 
|---|
 | 666 |       bool operator!=(const Node i) const {return n!=i.n;} | 
|---|
 | 667 |       bool operator<(const Node i) const {return n<i.n;} | 
|---|
 | 668 |     }; | 
|---|
 | 669 |      | 
|---|
 | 670 |     class NodeIt : public Node { | 
|---|
| [774] | 671 |       const NodeSet *G; | 
|---|
| [400] | 672 |       friend class NodeSet; | 
|---|
 | 673 |     public: | 
|---|
| [579] | 674 |       NodeIt() : Node() { } | 
|---|
| [774] | 675 |       NodeIt(const NodeSet& _G,Node n) : Node(n), G(&_G) { } | 
|---|
| [579] | 676 |       NodeIt(Invalid i) : Node(i) { } | 
|---|
| [774] | 677 |       NodeIt(const NodeSet& _G) : Node(_G.first_node), G(&_G) { } | 
|---|
 | 678 |       NodeIt &operator++() { | 
|---|
 | 679 |         n=G->nodes[n].next;  | 
|---|
 | 680 |         return *this;  | 
|---|
 | 681 |       } | 
|---|
| [400] | 682 |     }; | 
|---|
 | 683 |  | 
|---|
 | 684 |     class Edge { | 
|---|
 | 685 |       //friend class NodeSet; | 
|---|
 | 686 |       //template <typename T> friend class EdgeMap; | 
|---|
 | 687 |  | 
|---|
 | 688 |       //template <typename T> friend class SymNodeSet::SymEdgeMap;       | 
|---|
 | 689 |       //friend Edge SymNodeSet::opposite(Edge) const; | 
|---|
 | 690 |        | 
|---|
 | 691 |       //      friend class Node; | 
|---|
 | 692 |       //      friend class NodeIt; | 
|---|
 | 693 |     protected: | 
|---|
 | 694 |       //friend int NodeSet::id(Edge e) const; | 
|---|
 | 695 |       //      Edge(int nn) {} | 
|---|
 | 696 |     public: | 
|---|
 | 697 |       Edge() { } | 
|---|
 | 698 |       Edge (Invalid) { } | 
|---|
 | 699 |       bool operator==(const Edge i) const {return true;} | 
|---|
 | 700 |       bool operator!=(const Edge i) const {return false;} | 
|---|
 | 701 |       bool operator<(const Edge i) const {return false;} | 
|---|
 | 702 |       ///\bug This is a workaround until somebody tells me how to | 
|---|
 | 703 |       ///make class \c SymNodeSet::SymEdgeMap friend of Edge | 
|---|
 | 704 |       //      int idref() {return -1;} | 
|---|
 | 705 |       //      int idref() const {return -1;} | 
|---|
 | 706 |     }; | 
|---|
 | 707 |      | 
|---|
 | 708 |     class EdgeIt : public Edge { | 
|---|
 | 709 |       //friend class NodeSet; | 
|---|
 | 710 |     public: | 
|---|
 | 711 |       EdgeIt(const NodeSet& G) : Edge() { } | 
|---|
| [774] | 712 |       EdgeIt(const NodeSet&, Edge) : Edge() { } | 
|---|
| [400] | 713 |       EdgeIt (Invalid i) : Edge(i) { } | 
|---|
 | 714 |       EdgeIt() : Edge() { } | 
|---|
 | 715 |       ///\bug This is a workaround until somebody tells me how to | 
|---|
 | 716 |       ///make class \c SymNodeSet::SymEdgeMap friend of Edge | 
|---|
 | 717 |       //      int idref() {return -1;} | 
|---|
| [774] | 718 |       EdgeIt operator++() { return INVALID; } | 
|---|
| [400] | 719 |     }; | 
|---|
 | 720 |      | 
|---|
 | 721 |     class OutEdgeIt : public Edge { | 
|---|
 | 722 |       friend class NodeSet; | 
|---|
 | 723 |     public:  | 
|---|
 | 724 |       OutEdgeIt() : Edge() { } | 
|---|
| [774] | 725 |       OutEdgeIt(const NodeSet&, Edge) : Edge() { } | 
|---|
| [400] | 726 |       OutEdgeIt (Invalid i) : Edge(i) { } | 
|---|
 | 727 |       OutEdgeIt(const NodeSet& G,const Node v)  : Edge() {} | 
|---|
| [774] | 728 |       OutEdgeIt operator++() { return INVALID; } | 
|---|
| [400] | 729 |     }; | 
|---|
 | 730 |      | 
|---|
 | 731 |     class InEdgeIt : public Edge { | 
|---|
 | 732 |       friend class NodeSet; | 
|---|
 | 733 |     public:  | 
|---|
 | 734 |       InEdgeIt() : Edge() { } | 
|---|
| [774] | 735 |       InEdgeIt(const NodeSet&, Edge) : Edge() { } | 
|---|
| [400] | 736 |       InEdgeIt (Invalid i) : Edge(i) { } | 
|---|
 | 737 |       InEdgeIt(const NodeSet& G,Node v) :Edge() {} | 
|---|
| [774] | 738 |       InEdgeIt operator++() { return INVALID; } | 
|---|
| [400] | 739 |     }; | 
|---|
 | 740 |  | 
|---|
 | 741 |   }; | 
|---|
 | 742 |  | 
|---|
 | 743 |  | 
|---|
 | 744 |  | 
|---|
| [401] | 745 |   ///Graph structure using a node set of another graph. | 
|---|
 | 746 |  | 
|---|
 | 747 |   ///This structure can be used to establish another graph over a node set | 
|---|
 | 748 |   /// of an existing one. The node iterator will go through the nodes of the | 
|---|
 | 749 |   /// original graph, and the NodeMap's of both graphs will convert to | 
|---|
 | 750 |   /// each other. | 
|---|
 | 751 |   /// | 
|---|
| [404] | 752 |   ///\warning Adding or deleting nodes from the graph is not safe if an | 
|---|
 | 753 |   ///\ref EdgeSet is currently attached to it! | 
|---|
 | 754 |   /// | 
|---|
 | 755 |   ///\todo Make it possible to add/delete edges from the base graph | 
|---|
 | 756 |   ///(and from \ref EdgeSet, as well) | 
|---|
 | 757 |   /// | 
|---|
| [401] | 758 |   ///\param GG The type of the graph which shares its node set with this class. | 
|---|
 | 759 |   ///Its interface must conform with \ref GraphSkeleton. | 
|---|
| [400] | 760 |   /// | 
|---|
 | 761 |   ///It conforms to the graph interface documented under | 
|---|
 | 762 |   ///the description of \ref GraphSkeleton. | 
|---|
 | 763 |   ///\sa \ref GraphSkeleton. | 
|---|
| [401] | 764 |   ///\sa \ref NodeSet. | 
|---|
| [400] | 765 |   template<typename GG> | 
|---|
 | 766 |   class EdgeSet { | 
|---|
 | 767 |  | 
|---|
 | 768 |     typedef GG NodeGraphType; | 
|---|
 | 769 |  | 
|---|
 | 770 |     NodeGraphType &G; | 
|---|
 | 771 |  | 
|---|
| [515] | 772 |   public: | 
|---|
| [782] | 773 |  | 
|---|
| [400] | 774 |     class Node; | 
|---|
| [705] | 775 |     class Edge; | 
|---|
 | 776 |     class OutEdgeIt; | 
|---|
 | 777 |     class InEdgeIt; | 
|---|
 | 778 |     class SymEdge; | 
|---|
| [782] | 779 |  | 
|---|
 | 780 |     typedef EdgeSet Graph; | 
|---|
 | 781 |  | 
|---|
| [531] | 782 |     int id(Node v) const;  | 
|---|
 | 783 |  | 
|---|
 | 784 |     class Node : public NodeGraphType::Node { | 
|---|
 | 785 |       friend class EdgeSet; | 
|---|
 | 786 |       //      template <typename T> friend class NodeMap; | 
|---|
 | 787 |        | 
|---|
 | 788 |       friend class Edge; | 
|---|
 | 789 |       friend class OutEdgeIt; | 
|---|
 | 790 |       friend class InEdgeIt; | 
|---|
 | 791 |       friend class SymEdge; | 
|---|
 | 792 |  | 
|---|
 | 793 |     public: | 
|---|
 | 794 |       friend int EdgeSet::id(Node v) const;  | 
|---|
 | 795 |       //      Node(int nn) {n=nn;} | 
|---|
 | 796 |     public: | 
|---|
 | 797 |       Node() : NodeGraphType::Node() {} | 
|---|
 | 798 |       Node (Invalid i) : NodeGraphType::Node(i) {} | 
|---|
 | 799 |       Node(const typename NodeGraphType::Node &n) : NodeGraphType::Node(n) {} | 
|---|
 | 800 |     }; | 
|---|
 | 801 |      | 
|---|
 | 802 |     class NodeIt : public NodeGraphType::NodeIt { | 
|---|
 | 803 |       friend class EdgeSet; | 
|---|
 | 804 |     public: | 
|---|
 | 805 |       NodeIt() : NodeGraphType::NodeIt() { } | 
|---|
| [774] | 806 |       NodeIt(const EdgeSet& _G,Node n) : NodeGraphType::NodeIt(_G.G,n) { } | 
|---|
| [531] | 807 |       NodeIt (Invalid i) : NodeGraphType::NodeIt(i) {} | 
|---|
 | 808 |       NodeIt(const EdgeSet& _G) : NodeGraphType::NodeIt(_G.G) { } | 
|---|
 | 809 |       NodeIt(const typename NodeGraphType::NodeIt &n) | 
|---|
 | 810 |         : NodeGraphType::NodeIt(n) {} | 
|---|
| [579] | 811 |  | 
|---|
| [531] | 812 |       operator Node() { return Node(*this);} | 
|---|
| [774] | 813 |       NodeIt &operator++() | 
|---|
 | 814 |       { this->NodeGraphType::NodeIt::operator++(); return *this;}  | 
|---|
| [531] | 815 |     }; | 
|---|
| [515] | 816 |  | 
|---|
 | 817 |   private: | 
|---|
| [400] | 818 |     //Edges are double linked. | 
|---|
 | 819 |     //The free edges are only single linked using the "next_in" field. | 
|---|
 | 820 |     struct NodeT  | 
|---|
 | 821 |     { | 
|---|
 | 822 |       int first_in,first_out; | 
|---|
 | 823 |       NodeT() : first_in(-1), first_out(-1) { } | 
|---|
 | 824 |     }; | 
|---|
 | 825 |  | 
|---|
 | 826 |     struct EdgeT  | 
|---|
 | 827 |     { | 
|---|
 | 828 |       Node head, tail; | 
|---|
 | 829 |       int prev_in, prev_out; | 
|---|
 | 830 |       int next_in, next_out; | 
|---|
 | 831 |     }; | 
|---|
 | 832 |  | 
|---|
 | 833 |      | 
|---|
| [515] | 834 |     typename NodeGraphType::template NodeMap<NodeT> nodes; | 
|---|
| [400] | 835 |      | 
|---|
 | 836 |     std::vector<EdgeT> edges; | 
|---|
 | 837 |     //The first free edge | 
|---|
 | 838 |     int first_free_edge; | 
|---|
 | 839 |      | 
|---|
 | 840 |   public: | 
|---|
 | 841 |      | 
|---|
 | 842 |     class Node; | 
|---|
 | 843 |     class Edge; | 
|---|
 | 844 |  | 
|---|
 | 845 |     class NodeIt; | 
|---|
 | 846 |     class EdgeIt; | 
|---|
 | 847 |     class OutEdgeIt; | 
|---|
 | 848 |     class InEdgeIt; | 
|---|
| [782] | 849 |  | 
|---|
 | 850 |  | 
|---|
 | 851 |     CREATE_EDGE_MAP_REGISTRY; | 
|---|
| [798] | 852 |     CREATE_EDGE_MAP_FACTORY(DefaultMapFactory); | 
|---|
| [782] | 853 |     IMPORT_EDGE_MAP(EdgeMapFactory); | 
|---|
| [400] | 854 |      | 
|---|
 | 855 |      | 
|---|
 | 856 |   public: | 
|---|
 | 857 |  | 
|---|
| [408] | 858 |     ///Constructor | 
|---|
 | 859 |      | 
|---|
 | 860 |     ///Construates a new graph based on the nodeset of an existing one. | 
|---|
 | 861 |     ///\param _G the base graph. | 
|---|
 | 862 |     ///\todo It looks like a copy constructor, but it isn't. | 
|---|
| [782] | 863 |     EdgeSet(NodeGraphType &_G)  | 
|---|
 | 864 |       : G(_G), nodes(_G), edges(), | 
|---|
 | 865 |         first_free_edge(-1) {} | 
|---|
| [408] | 866 |     ///Copy constructor | 
|---|
 | 867 |  | 
|---|
 | 868 |     ///Makes a copy of an EdgeSet. | 
|---|
 | 869 |     ///It will be based on the same graph. | 
|---|
| [782] | 870 |     EdgeSet(const EdgeSet &_g)  | 
|---|
 | 871 |       : G(_g.G), nodes(_g.G), edges(_g.edges), | 
|---|
 | 872 |         first_free_edge(_g.first_free_edge) {} | 
|---|
| [400] | 873 |      | 
|---|
| [813] | 874 |     ///Number of nodes. | 
|---|
 | 875 |     int nodeNum() const { return G.nodeNum(); } | 
|---|
 | 876 |     ///Number of edges. | 
|---|
 | 877 |     int edgeNum() const { return edges.size(); } | 
|---|
| [400] | 878 |  | 
|---|
| [813] | 879 |     /// Maximum node ID. | 
|---|
 | 880 |      | 
|---|
 | 881 |     /// Maximum node ID. | 
|---|
 | 882 |     ///\sa id(Node) | 
|---|
 | 883 |     int maxNodeId() const { return G.maxNodeId(); } | 
|---|
 | 884 |     /// Maximum edge ID. | 
|---|
 | 885 |      | 
|---|
 | 886 |     /// Maximum edge ID. | 
|---|
 | 887 |     ///\sa id(Edge) | 
|---|
 | 888 |     int maxEdgeId() const { return edges.size()-1; } | 
|---|
| [400] | 889 |  | 
|---|
 | 890 |     Node tail(Edge e) const { return edges[e.n].tail; } | 
|---|
 | 891 |     Node head(Edge e) const { return edges[e.n].head; } | 
|---|
 | 892 |  | 
|---|
 | 893 |     NodeIt& first(NodeIt& v) const {  | 
|---|
 | 894 |       v=NodeIt(*this); return v; } | 
|---|
 | 895 |     EdgeIt& first(EdgeIt& e) const {  | 
|---|
 | 896 |       e=EdgeIt(*this); return e; } | 
|---|
 | 897 |     OutEdgeIt& first(OutEdgeIt& e, const Node v) const {  | 
|---|
 | 898 |       e=OutEdgeIt(*this,v); return e; } | 
|---|
 | 899 |     InEdgeIt& first(InEdgeIt& e, const Node v) const {  | 
|---|
 | 900 |       e=InEdgeIt(*this,v); return e; } | 
|---|
 | 901 |  | 
|---|
| [813] | 902 |     /// Node ID. | 
|---|
 | 903 |      | 
|---|
 | 904 |     /// The ID of a valid Node is a nonnegative integer not greater than | 
|---|
 | 905 |     /// \ref maxNodeId(). The range of the ID's is not surely continuous | 
|---|
 | 906 |     /// and the greatest node ID can be actually less then \ref maxNodeId(). | 
|---|
 | 907 |     /// | 
|---|
 | 908 |     /// The ID of the \ref INVALID node is -1. | 
|---|
 | 909 |     ///\return The ID of the node \c v.  | 
|---|
 | 910 |     int id(Node v) { return G.id(v); } | 
|---|
 | 911 |     /// Edge ID. | 
|---|
 | 912 |      | 
|---|
 | 913 |     /// The ID of a valid Edge is a nonnegative integer not greater than | 
|---|
 | 914 |     /// \ref maxEdgeId(). The range of the ID's is not surely continuous | 
|---|
 | 915 |     /// and the greatest edge ID can be actually less then \ref maxEdgeId(). | 
|---|
 | 916 |     /// | 
|---|
 | 917 |     /// The ID of the \ref INVALID edge is -1. | 
|---|
 | 918 |     ///\return The ID of the edge \c e.  | 
|---|
| [400] | 919 |     int id(Edge e) const { return e.n; } | 
|---|
 | 920 |  | 
|---|
 | 921 |     /// Adds a new node to the graph. | 
|---|
| [579] | 922 |     Node addNode() { return G.addNode(); } | 
|---|
| [400] | 923 |      | 
|---|
 | 924 |     Edge addEdge(Node u, Node v) { | 
|---|
 | 925 |       int n; | 
|---|
 | 926 |        | 
|---|
 | 927 |       if(first_free_edge==-1) | 
|---|
 | 928 |         { | 
|---|
 | 929 |           n = edges.size(); | 
|---|
 | 930 |           edges.push_back(EdgeT()); | 
|---|
 | 931 |         } | 
|---|
 | 932 |       else { | 
|---|
 | 933 |         n = first_free_edge; | 
|---|
 | 934 |         first_free_edge = edges[n].next_in; | 
|---|
 | 935 |       } | 
|---|
 | 936 |        | 
|---|
| [401] | 937 |       edges[n].tail = u; edges[n].head = v; | 
|---|
| [400] | 938 |  | 
|---|
| [401] | 939 |       edges[n].next_out = nodes[u].first_out; | 
|---|
 | 940 |       if(nodes[u].first_out != -1) edges[nodes[u].first_out].prev_out = n; | 
|---|
 | 941 |       edges[n].next_in = nodes[v].first_in; | 
|---|
 | 942 |       if(nodes[v].first_in != -1) edges[nodes[v].first_in].prev_in = n; | 
|---|
| [400] | 943 |       edges[n].prev_in = edges[n].prev_out = -1; | 
|---|
 | 944 |          | 
|---|
| [401] | 945 |       nodes[u].first_out = nodes[v].first_in = n; | 
|---|
| [400] | 946 |  | 
|---|
 | 947 |       Edge e; e.n=n; | 
|---|
 | 948 |  | 
|---|
 | 949 |       //Update dynamic maps | 
|---|
| [782] | 950 |       edge_maps.add(e); | 
|---|
| [400] | 951 |  | 
|---|
 | 952 |       return e; | 
|---|
 | 953 |     } | 
|---|
 | 954 |  | 
|---|
| [774] | 955 |     /// Finds an edge between two nodes. | 
|---|
 | 956 |  | 
|---|
 | 957 |     /// Finds an edge from node \c u to node \c v. | 
|---|
 | 958 |     /// | 
|---|
 | 959 |     /// If \c prev is \ref INVALID (this is the default value), then | 
|---|
 | 960 |     /// It finds the first edge from \c u to \c v. Otherwise it looks for | 
|---|
 | 961 |     /// the next edge from \c u to \c v after \c prev. | 
|---|
 | 962 |     /// \return The found edge or INVALID if there is no such an edge. | 
|---|
 | 963 |     Edge findEdge(Node u,Node v, Edge prev = INVALID)  | 
|---|
 | 964 |     { | 
|---|
 | 965 |       int e = (prev.n==-1)? nodes[u].first_out : edges[prev.n].next_out; | 
|---|
 | 966 |       while(e!=-1 && edges[e].tail!=v) e = edges[e].next_out; | 
|---|
 | 967 |       prev.n=e; | 
|---|
 | 968 |       return prev; | 
|---|
 | 969 |     } | 
|---|
 | 970 |      | 
|---|
| [400] | 971 |   private: | 
|---|
 | 972 |     void eraseEdge(int n) { | 
|---|
 | 973 |        | 
|---|
 | 974 |       if(edges[n].next_in!=-1) | 
|---|
 | 975 |         edges[edges[n].next_in].prev_in = edges[n].prev_in; | 
|---|
 | 976 |       if(edges[n].prev_in!=-1) | 
|---|
 | 977 |         edges[edges[n].prev_in].next_in = edges[n].next_in; | 
|---|
 | 978 |       else nodes[edges[n].head].first_in = edges[n].next_in; | 
|---|
 | 979 |        | 
|---|
 | 980 |       if(edges[n].next_out!=-1) | 
|---|
 | 981 |         edges[edges[n].next_out].prev_out = edges[n].prev_out; | 
|---|
 | 982 |       if(edges[n].prev_out!=-1) | 
|---|
 | 983 |         edges[edges[n].prev_out].next_out = edges[n].next_out; | 
|---|
 | 984 |       else nodes[edges[n].tail].first_out = edges[n].next_out; | 
|---|
 | 985 |        | 
|---|
 | 986 |       edges[n].next_in = first_free_edge; | 
|---|
 | 987 |       first_free_edge = -1;       | 
|---|
 | 988 |  | 
|---|
 | 989 |       //Update dynamic maps | 
|---|
| [782] | 990 |       Edge e; e.n = n; | 
|---|
 | 991 |       edge_maps.erase(e); | 
|---|
| [400] | 992 |     } | 
|---|
 | 993 |        | 
|---|
 | 994 |   public: | 
|---|
 | 995 |  | 
|---|
 | 996 | //     void erase(Node nn) { | 
|---|
 | 997 | //       int n=nn.n; | 
|---|
 | 998 | //       int m; | 
|---|
 | 999 | //       while((m=nodes[n].first_in)!=-1) eraseEdge(m); | 
|---|
 | 1000 | //       while((m=nodes[n].first_out)!=-1) eraseEdge(m); | 
|---|
 | 1001 | //     } | 
|---|
 | 1002 |      | 
|---|
 | 1003 |     void erase(Edge e) { eraseEdge(e.n); } | 
|---|
 | 1004 |  | 
|---|
| [579] | 1005 |     ///Clear all edges. (Doesn't clear the nodes!) | 
|---|
 | 1006 |     void clear() { | 
|---|
| [782] | 1007 |       edge_maps.clear(); | 
|---|
| [579] | 1008 |       edges.clear(); | 
|---|
 | 1009 |       first_free_edge=-1; | 
|---|
 | 1010 |     } | 
|---|
 | 1011 |  | 
|---|
 | 1012 |  | 
|---|
| [400] | 1013 |     class Edge { | 
|---|
| [579] | 1014 |     public: | 
|---|
| [400] | 1015 |       friend class EdgeSet; | 
|---|
 | 1016 |       template <typename T> friend class EdgeMap; | 
|---|
 | 1017 |  | 
|---|
 | 1018 |       friend class Node; | 
|---|
 | 1019 |       friend class NodeIt; | 
|---|
| [579] | 1020 |     public: | 
|---|
| [774] | 1021 |       ///\bug It should be at least protected | 
|---|
| [579] | 1022 |       /// | 
|---|
 | 1023 |       int n; | 
|---|
| [400] | 1024 |     protected: | 
|---|
 | 1025 |       friend int EdgeSet::id(Edge e) const; | 
|---|
 | 1026 |  | 
|---|
 | 1027 |       Edge(int nn) {n=nn;} | 
|---|
 | 1028 |     public: | 
|---|
 | 1029 |       Edge() { } | 
|---|
 | 1030 |       Edge (Invalid) { n=-1; } | 
|---|
 | 1031 |       bool operator==(const Edge i) const {return n==i.n;} | 
|---|
 | 1032 |       bool operator!=(const Edge i) const {return n!=i.n;} | 
|---|
 | 1033 |       bool operator<(const Edge i) const {return n<i.n;} | 
|---|
 | 1034 |       ///\bug This is a workaround until somebody tells me how to | 
|---|
 | 1035 |       ///make class \c SymEdgeSet::SymEdgeMap friend of Edge | 
|---|
 | 1036 |       int &idref() {return n;} | 
|---|
 | 1037 |       const int &idref() const {return n;} | 
|---|
 | 1038 |     }; | 
|---|
 | 1039 |      | 
|---|
 | 1040 |     class EdgeIt : public Edge { | 
|---|
 | 1041 |       friend class EdgeSet; | 
|---|
| [579] | 1042 |       template <typename T> friend class EdgeMap; | 
|---|
 | 1043 |      | 
|---|
| [774] | 1044 |       const EdgeSet *G; | 
|---|
| [400] | 1045 |     public: | 
|---|
| [774] | 1046 |       EdgeIt(const EdgeSet& _G) : Edge(), G(&_G) { | 
|---|
| [503] | 1047 |         //              typename NodeGraphType::Node m; | 
|---|
 | 1048 |         NodeIt m; | 
|---|
| [774] | 1049 |         for(G->first(m); | 
|---|
 | 1050 |             m!=INVALID && G->nodes[m].first_in == -1;  ++m); | 
|---|
 | 1051 |         ///\bug AJJAJ! This is a non sense!!!!!!! | 
|---|
 | 1052 |         this->n = m!=INVALID?-1:G->nodes[m].first_in; | 
|---|
| [400] | 1053 |       } | 
|---|
| [774] | 1054 |       EdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { } | 
|---|
| [400] | 1055 |       EdgeIt (Invalid i) : Edge(i) { } | 
|---|
 | 1056 |       EdgeIt() : Edge() { } | 
|---|
| [774] | 1057 |       ///. | 
|---|
 | 1058 |        | 
|---|
 | 1059 |       ///\bug UNIMPLEMENTED!!!!! | 
|---|
 | 1060 |       // | 
|---|
 | 1061 |       EdgeIt &operator++() { | 
|---|
 | 1062 |         return *this; | 
|---|
 | 1063 |       } | 
|---|
 | 1064 |        ///\bug This is a workaround until somebody tells me how to | 
|---|
| [400] | 1065 |       ///make class \c SymEdgeSet::SymEdgeMap friend of Edge | 
|---|
| [515] | 1066 |       int &idref() {return this->n;} | 
|---|
| [400] | 1067 |     }; | 
|---|
 | 1068 |      | 
|---|
 | 1069 |     class OutEdgeIt : public Edge { | 
|---|
| [774] | 1070 |       const EdgeSet *G; | 
|---|
| [400] | 1071 |       friend class EdgeSet; | 
|---|
 | 1072 |     public:  | 
|---|
 | 1073 |       OutEdgeIt() : Edge() { } | 
|---|
 | 1074 |       OutEdgeIt (Invalid i) : Edge(i) { } | 
|---|
| [774] | 1075 |       OutEdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { } | 
|---|
| [400] | 1076 |  | 
|---|
| [774] | 1077 |       OutEdgeIt(const EdgeSet& _G,const Node v) : | 
|---|
 | 1078 |         Edge(_G.nodes[v].first_out), G(&_G) { } | 
|---|
| [782] | 1079 |       OutEdgeIt &operator++() { n = G->edges[n].next_out; return *this; } | 
|---|
| [400] | 1080 |     }; | 
|---|
 | 1081 |      | 
|---|
 | 1082 |     class InEdgeIt : public Edge { | 
|---|
| [774] | 1083 |       const EdgeSet *G; | 
|---|
| [400] | 1084 |       friend class EdgeSet; | 
|---|
 | 1085 |     public:  | 
|---|
 | 1086 |       InEdgeIt() : Edge() { } | 
|---|
 | 1087 |       InEdgeIt (Invalid i) : Edge(i) { } | 
|---|
| [774] | 1088 |       InEdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { } | 
|---|
 | 1089 |       InEdgeIt(const EdgeSet& _G,Node v) | 
|---|
 | 1090 |         : Edge(_G.nodes[v].first_in), G(&_G) { } | 
|---|
 | 1091 |       InEdgeIt &operator++() { n=G->edges[n].next_in; return *this; } | 
|---|
| [400] | 1092 |     }; | 
|---|
 | 1093 |  | 
|---|
| [782] | 1094 |      | 
|---|
 | 1095 |     template <typename V> class NodeMap  | 
|---|
 | 1096 |       : public NodeGraphType::template NodeMap<V> | 
|---|
| [400] | 1097 |     { | 
|---|
| [579] | 1098 |       //This is a must, the constructors need it. | 
|---|
| [782] | 1099 |       typedef typename NodeGraphType::template NodeMap<V> MapImpl; | 
|---|
 | 1100 |       typedef V Value; | 
|---|
| [400] | 1101 |     public: | 
|---|
| [782] | 1102 |       NodeMap() : MapImpl() {} | 
|---|
 | 1103 |        | 
|---|
 | 1104 |       NodeMap(const EdgeSet& graph)  | 
|---|
 | 1105 |         : MapImpl(graph.G) { } | 
|---|
| [400] | 1106 |  | 
|---|
| [782] | 1107 |       NodeMap(const EdgeSet& graph, const Value& value)  | 
|---|
 | 1108 |         : MapImpl(graph.G, value) { } | 
|---|
| [400] | 1109 |  | 
|---|
| [782] | 1110 |       NodeMap(const NodeMap& copy)  | 
|---|
 | 1111 |         : MapImpl(static_cast<const MapImpl&>(copy)) {} | 
|---|
| [400] | 1112 |  | 
|---|
| [782] | 1113 |       template<typename CMap> | 
|---|
 | 1114 |       NodeMap(const CMap& copy) | 
|---|
 | 1115 |         : MapImpl(copy) { } | 
|---|
 | 1116 |  | 
|---|
 | 1117 |       NodeMap& operator=(const NodeMap& copy) { | 
|---|
 | 1118 |         MapImpl::operator=(static_cast<const MapImpl&>(copy)); | 
|---|
 | 1119 |         return *this; | 
|---|
| [400] | 1120 |       } | 
|---|
 | 1121 |  | 
|---|
| [782] | 1122 |       template <typename CMap> | 
|---|
 | 1123 |       NodeMap& operator=(const CMap& copy) { | 
|---|
 | 1124 |         MapImpl::operator=(copy); | 
|---|
| [400] | 1125 |         return *this; | 
|---|
 | 1126 |       } | 
|---|
| [579] | 1127 |  | 
|---|
| [400] | 1128 |     }; | 
|---|
 | 1129 |   }; | 
|---|
| [406] | 1130 |  | 
|---|
| [579] | 1131 |   template<typename GG> | 
|---|
 | 1132 |   inline int EdgeSet<GG>::id(Node v) const { return G.id(v); } | 
|---|
| [531] | 1133 |  | 
|---|
| [406] | 1134 | /// @}   | 
|---|
 | 1135 |  | 
|---|
| [395] | 1136 | } //namespace hugo | 
|---|
 | 1137 |  | 
|---|
| [405] | 1138 | #endif //HUGO_LIST_GRAPH_H | 
|---|