src/work/alpar/list_graph.h
changeset 398 ecebcedd8960
parent 396 639c9daed784
child 400 cb377609cf1d
equal deleted inserted replaced
0:6af55c42621b 1:5e08a51a0375
     2 
     2 
     3 #ifndef HUGO_SMART_GRAPH_H
     3 #ifndef HUGO_SMART_GRAPH_H
     4 #define HUGO_SMART_GRAPH_H
     4 #define HUGO_SMART_GRAPH_H
     5 
     5 
     6 ///\file
     6 ///\file
     7 ///\brief SmartGraph and SymSmartGraph classes.
     7 ///\brief ListGraph and SymListGraph classes.
     8 
     8 
     9 #include <vector>
     9 #include <vector>
    10 #include <limits.h>
    10 #include <limits.h>
    11 
    11 
    12 #include "invalid.h"
    12 #include "invalid.h"
    13 
    13 
    14 namespace hugo {
    14 namespace hugo {
    15 
    15 
    16   class SymSmartGraph;
    16   class SymListGraph;
    17 
    17 
    18   ///A smart graph class.
    18   ///A smart graph class.
    19 
    19 
    20   ///This is a simple and fast graph implementation.
    20   ///This is a simple and fast erasable graph implementation.
    21   ///It is also quite memory efficient, but at the price
    21   ///
    22   ///that <b> it does not support node and edge deletion</b>.
       
    23   ///It conforms to the graph interface documented under
    22   ///It conforms to the graph interface documented under
    24   ///the description of \ref GraphSkeleton.
    23   ///the description of \ref GraphSkeleton.
    25   ///\sa \ref GraphSkeleton.
    24   ///\sa \ref GraphSkeleton.
    26   class SmartGraph {
    25   class ListGraph {
    27 
    26 
       
    27     //Nodes are double linked.
       
    28     //The free nodes are only single linked using the "next" field.
    28     struct NodeT 
    29     struct NodeT 
    29     {
    30     {
    30       int first_in,first_out;      
    31       int first_in,first_out;
    31       NodeT() : first_in(-1), first_out(-1) {}
    32       int prev, next;
    32     };
    33       //      NodeT() {}
       
    34     };
       
    35     //Edges are double linked.
       
    36     //The free edges are only single linked using the "next_in" field.
    33     struct EdgeT 
    37     struct EdgeT 
    34     {
    38     {
    35       int head, tail, next_in, next_out;      
    39       int head, tail;
       
    40       int prev_in, prev_out;
       
    41       int next_in, next_out;
    36       //FIXME: is this necessary?
    42       //FIXME: is this necessary?
    37       EdgeT() : next_in(-1), next_out(-1) {}  
    43       //      EdgeT() : next_in(-1), next_out(-1) prev_in(-1), prev_out(-1) {}  
    38     };
    44     };
    39 
    45 
    40     std::vector<NodeT> nodes;
    46     std::vector<NodeT> nodes;
    41 
    47     //The first node
       
    48     int first_node;
       
    49     //The first free node
       
    50     int first_free_node;
    42     std::vector<EdgeT> edges;
    51     std::vector<EdgeT> edges;
    43     
    52     //The first free edge
       
    53     int first_free_edge;
       
    54     
       
    55   protected:
       
    56     
       
    57     template <typename Key> class DynMapBase
       
    58     {
    44     protected:
    59     protected:
    45     
    60       const ListGraph* G; 
    46     template <typename Key> class DynMapBase
       
    47     {
       
    48     protected:
       
    49       const SmartGraph* G; 
       
    50     public:
    61     public:
    51       virtual void add(const Key k) = NULL;
    62       virtual void add(const Key k) = NULL;
    52       virtual void erase(const Key k) = NULL;
    63       virtual void erase(const Key k) = NULL;
    53       DynMapBase(const SmartGraph &_G) : G(&_G) {}
    64       DynMapBase(const ListGraph &_G) : G(&_G) {}
    54       virtual ~DynMapBase() {}
    65       virtual ~DynMapBase() {}
    55       friend class SmartGraph;
    66       friend class ListGraph;
    56     };
    67     };
    57     
    68     
    58   public:
    69   public:
    59     template <typename T> class EdgeMap;
    70     template <typename T> class EdgeMap;
    60     template <typename T> class EdgeMap;
    71     template <typename T> class EdgeMap;
    61 
    72     
    62     class Node;
    73     class Node;
    63     class Edge;
    74     class Edge;
    64 
    75 
    65     //  protected:
    76     //  protected:
    66     // HELPME:
    77     // HELPME:
    82     template <typename T> class NodeMap;
    93     template <typename T> class NodeMap;
    83     template <typename T> class EdgeMap;
    94     template <typename T> class EdgeMap;
    84     
    95     
    85   public:
    96   public:
    86 
    97 
    87     SmartGraph() : nodes(), edges() { }
    98     ListGraph() : nodes(), first_node(-1),
    88     SmartGraph(const SmartGraph &_g) : nodes(_g.nodes), edges(_g.edges) { }
    99 		  first_free_node(-1), edges(), first_free_edge(-1) {}
    89     
   100     ListGraph(const ListGraph &_g) : nodes(_g.nodes), first_node(_g.first_node),
    90     ~SmartGraph()
   101 				     first_free_node(_g.first_free_node),
       
   102 				     edges(_g.edges),
       
   103 				     first_free_edge(_g.first_free_edge) {}
       
   104     
       
   105     ~ListGraph()
    91     {
   106     {
    92       for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
   107       for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
    93 	  i!=dyn_node_maps.end(); ++i) (**i).G=NULL;
   108 	  i!=dyn_node_maps.end(); ++i) (**i).G=NULL;
    94       for(std::vector<DynMapBase<Edge> * >::iterator i=dyn_edge_maps.begin();
   109       for(std::vector<DynMapBase<Edge> * >::iterator i=dyn_edge_maps.begin();
    95 	  i!=dyn_edge_maps.end(); ++i) (**i).G=NULL;
   110 	  i!=dyn_edge_maps.end(); ++i) (**i).G=NULL;
   137     
   152     
   138     template <typename It> It getNext(It it) const
   153     template <typename It> It getNext(It it) const
   139     { It tmp(it); return next(tmp); }
   154     { It tmp(it); return next(tmp); }
   140 
   155 
   141     NodeIt& next(NodeIt& it) const { 
   156     NodeIt& next(NodeIt& it) const { 
   142       it.n=(it.n+2)%(nodes.size()+1)-1; 
   157       it.n=nodes[it.n].next; 
   143       return it; 
   158       return it; 
   144     }
   159     }
   145     OutEdgeIt& next(OutEdgeIt& it) const
   160     OutEdgeIt& next(OutEdgeIt& it) const
   146     { it.n=edges[it.n].next_out; return it; }
   161     { it.n=edges[it.n].next_out; return it; }
   147     InEdgeIt& next(InEdgeIt& it) const
   162     InEdgeIt& next(InEdgeIt& it) const
   148     { it.n=edges[it.n].next_in; return it; }
   163     { it.n=edges[it.n].next_in; return it; }
   149     EdgeIt& next(EdgeIt& it) const { --it.n; return it; }
   164     EdgeIt& next(EdgeIt& it) const {
       
   165       if(edges[it.n].next_in!=-1) { 
       
   166 	it.n=edges[it.n].next_in;
       
   167       }
       
   168       else {
       
   169 	int n;
       
   170 	for(n=nodes[edges[it.n].head].next;
       
   171 	    n!=-1 && nodes[n].first_in == -1;
       
   172 	    n = nodes[n].next) ;
       
   173 	it.n = (n==-1)?-1:nodes[n].first_in;
       
   174       }
       
   175       return it;
       
   176     }
   150 
   177 
   151     int id(Node v) const { return v.n; }
   178     int id(Node v) const { return v.n; }
   152     int id(Edge e) const { return e.n; }
   179     int id(Edge e) const { return e.n; }
   153 
   180 
       
   181     /// Adds a new node to the graph.
       
   182 
       
   183     /// \todo It adds the nodes in a reversed order.
       
   184     /// (i.e. the lastly added node becomes the first.)
   154     Node addNode() {
   185     Node addNode() {
   155       Node n; n.n=nodes.size();
   186       int n;
   156       nodes.push_back(NodeT()); //FIXME: Hmmm...
   187       
   157 
   188       if(first_free_node==-1)
       
   189 	{
       
   190 	  n = nodes.size();
       
   191 	  nodes.push_back(NodeT());
       
   192 	}
       
   193       else {
       
   194 	n = first_free_node;
       
   195 	first_free_node = nodes[n].next;
       
   196       }
       
   197       
       
   198       nodes[n].next = first_node;
       
   199       if(first_node != -1) nodes[first_node].prev = n;
       
   200       first_node = n;
       
   201       nodes[n].prev = -1;
       
   202       
       
   203       nodes[n].first_in = nodes[n].first_out = -1;
       
   204       
       
   205       Node nn; nn.n=n;
       
   206 
       
   207       //Update dynamic maps
   158       for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
   208       for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
   159 	  i!=dyn_node_maps.end(); ++i) (**i).add(n.n);
   209 	  i!=dyn_node_maps.end(); ++i) (**i).add(nn);
   160 
   210 
   161       return n;
   211       return nn;
   162     }
   212     }
   163     
   213     
   164     Edge addEdge(Node u, Node v) {
   214     Edge addEdge(Node u, Node v) {
   165       Edge e; e.n=edges.size(); edges.push_back(EdgeT()); //FIXME: Hmmm...
   215       int n;
   166       edges[e.n].tail=u.n; edges[e.n].head=v.n;
   216       
   167       edges[e.n].next_out=nodes[u.n].first_out;
   217       if(first_free_edge==-1)
   168       edges[e.n].next_in=nodes[v.n].first_in;
   218 	{
   169       nodes[u.n].first_out=nodes[v.n].first_in=e.n;
   219 	  n = edges.size();
   170 
   220 	  edges.push_back(EdgeT());
       
   221 	}
       
   222       else {
       
   223 	n = first_free_edge;
       
   224 	first_free_edge = edges[n].next_in;
       
   225       }
       
   226       
       
   227       edges[n].tail = u.n; edges[n].head = v.n;
       
   228 
       
   229       edges[n].next_out = nodes[u.n].first_out;
       
   230       if(nodes[u.n].first_out != -1) edges[nodes[u.n].first_out].prev_out = n;
       
   231       edges[n].next_in = nodes[v.n].first_in;
       
   232       if(nodes[v.n].first_in != -1) edges[nodes[v.n].first_in].prev_in = n;
       
   233       edges[n].prev_in = edges[n].prev_out = -1;
       
   234 	
       
   235       nodes[u.n].first_out = nodes[v.n].first_in = n;
       
   236 
       
   237       Edge e; e.n=n;
       
   238 
       
   239       //Update dynamic maps
   171       for(std::vector<DynMapBase<Edge> * >::iterator i=dyn_edge_maps.begin();
   240       for(std::vector<DynMapBase<Edge> * >::iterator i=dyn_edge_maps.begin();
   172 	  i!=dyn_edge_maps.end(); ++i) (**i).add(e);
   241 	  i!=dyn_edge_maps.end(); ++i) (**i).add(e);
   173 
   242 
   174       return e;
   243       return e;
   175     }
   244     }
   176 
   245 
   177     void clear() {nodes.clear();edges.clear();}
   246   private:
       
   247     void eraseEdge(int n) {
       
   248       
       
   249       if(edges[n].next_in!=-1)
       
   250 	edges[edges[n].next_in].prev_in = edges[n].prev_in;
       
   251       if(edges[n].prev_in!=-1)
       
   252 	edges[edges[n].prev_in].next_in = edges[n].next_in;
       
   253       else nodes[edges[n].head].first_in = edges[n].next_in;
       
   254       
       
   255       if(edges[n].next_out!=-1)
       
   256 	edges[edges[n].next_out].prev_out = edges[n].prev_out;
       
   257       if(edges[n].prev_out!=-1)
       
   258 	edges[edges[n].prev_out].next_out = edges[n].next_out;
       
   259       else nodes[edges[n].tail].first_out = edges[n].next_out;
       
   260       
       
   261       edges[n].next_in = first_free_edge;
       
   262       first_free_edge = -1;      
       
   263 
       
   264       //Update dynamic maps
       
   265       Edge e; e.n=n;
       
   266       for(std::vector<DynMapBase<Edge> * >::iterator i=dyn_edge_maps.begin();
       
   267 	  i!=dyn_edge_maps.end(); ++i) (**i).erase(e);
       
   268     }
       
   269       
       
   270   public:
       
   271 
       
   272     void erase(Node nn) {
       
   273       int n=nn.n;
       
   274       
       
   275       int m;
       
   276       while((m=nodes[n].first_in)!=-1) eraseEdge(m);
       
   277       while((m=nodes[n].first_out)!=-1) eraseEdge(m);
       
   278 
       
   279       if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev;
       
   280       if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next;
       
   281       else first_node = nodes[n].next;
       
   282       
       
   283       nodes[n].next = first_free_node;
       
   284       first_free_node = n;
       
   285 
       
   286       //Update dynamic maps
       
   287       for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
       
   288 	  i!=dyn_node_maps.end(); ++i) (**i).erase(nn);
       
   289     }
       
   290     
       
   291     void erase(Edge e) { eraseEdge(e.n); }
       
   292 
       
   293     ///\bug Dynamic maps must be updated!
       
   294     ///
       
   295     void clear() {
       
   296       nodes.clear();edges.clear();
       
   297       first_node=first_free_node=first_free_edge=-1;
       
   298     }
   178 
   299 
   179     class Node {
   300     class Node {
   180       friend class SmartGraph;
   301       friend class ListGraph;
   181       template <typename T> friend class NodeMap;
   302       template <typename T> friend class NodeMap;
   182       
   303       
   183       friend class Edge;
   304       friend class Edge;
   184       friend class OutEdgeIt;
   305       friend class OutEdgeIt;
   185       friend class InEdgeIt;
   306       friend class InEdgeIt;
   186       friend class SymEdge;
   307       friend class SymEdge;
   187 
   308 
   188     protected:
   309     protected:
   189       int n;
   310       int n;
   190       friend int SmartGraph::id(Node v) const; 
   311       friend int ListGraph::id(Node v) const; 
   191       Node(int nn) {n=nn;}
   312       Node(int nn) {n=nn;}
   192     public:
   313     public:
   193       Node() {}
   314       Node() {}
   194       Node (Invalid i) { n=-1; }
   315       Node (Invalid i) { n=-1; }
   195       bool operator==(const Node i) const {return n==i.n;}
   316       bool operator==(const Node i) const {return n==i.n;}
   196       bool operator!=(const Node i) const {return n!=i.n;}
   317       bool operator!=(const Node i) const {return n!=i.n;}
   197       bool operator<(const Node i) const {return n<i.n;}
   318       bool operator<(const Node i) const {return n<i.n;}
   198     };
   319     };
   199     
   320     
   200     class NodeIt : public Node {
   321     class NodeIt : public Node {
   201       friend class SmartGraph;
   322       friend class ListGraph;
   202     public:
   323     public:
   203       NodeIt(const SmartGraph& G) : Node(G.nodes.size()?0:-1) { }
   324       NodeIt(const ListGraph& G) : Node(G.first_node) { }
   204       NodeIt() : Node() { }
   325       NodeIt() : Node() { }
   205     };
   326     };
   206 
   327 
   207     class Edge {
   328     class Edge {
   208       friend class SmartGraph;
   329       friend class ListGraph;
   209       template <typename T> friend class EdgeMap;
   330       template <typename T> friend class EdgeMap;
   210 
   331 
   211       //template <typename T> friend class SymSmartGraph::SymEdgeMap;      
   332       //template <typename T> friend class SymListGraph::SymEdgeMap;      
   212       //friend Edge SymSmartGraph::opposite(Edge) const;
   333       //friend Edge SymListGraph::opposite(Edge) const;
   213       
   334       
   214       friend class Node;
   335       friend class Node;
   215       friend class NodeIt;
   336       friend class NodeIt;
   216     protected:
   337     protected:
   217       int n;
   338       int n;
   218       friend int SmartGraph::id(Edge e) const;
   339       friend int ListGraph::id(Edge e) const;
   219 
   340 
   220       Edge(int nn) {n=nn;}
   341       Edge(int nn) {n=nn;}
   221     public:
   342     public:
   222       Edge() { }
   343       Edge() { }
   223       Edge (Invalid) { n=-1; }
   344       Edge (Invalid) { n=-1; }
   224       bool operator==(const Edge i) const {return n==i.n;}
   345       bool operator==(const Edge i) const {return n==i.n;}
   225       bool operator!=(const Edge i) const {return n!=i.n;}
   346       bool operator!=(const Edge i) const {return n!=i.n;}
   226       bool operator<(const Edge i) const {return n<i.n;}
   347       bool operator<(const Edge i) const {return n<i.n;}
   227       ///\bug This is a workaround until somebody tells me how to
   348       ///\bug This is a workaround until somebody tells me how to
   228       ///make class \c SymSmartGraph::SymEdgeMap friend of Edge
   349       ///make class \c SymListGraph::SymEdgeMap friend of Edge
   229       int &idref() {return n;}
   350       int &idref() {return n;}
   230       const int &idref() const {return n;}
   351       const int &idref() const {return n;}
   231     };
   352     };
   232     
   353     
   233     class EdgeIt : public Edge {
   354     class EdgeIt : public Edge {
   234       friend class SmartGraph;
   355       friend class ListGraph;
   235     public:
   356     public:
   236       EdgeIt(const SmartGraph& G) : Edge(G.edges.size()-1) { }
   357       EdgeIt(const ListGraph& G) : Edge() {
       
   358       	int m;
       
   359 	for(m=G.first_node;
       
   360 	    m!=-1 && G.nodes[m].first_in == -1; m = G.nodes[m].next);
       
   361 	n = (m==-1)?-1:G.nodes[m].first_in;
       
   362       }
   237       EdgeIt (Invalid i) : Edge(i) { }
   363       EdgeIt (Invalid i) : Edge(i) { }
   238       EdgeIt() : Edge() { }
   364       EdgeIt() : Edge() { }
   239       ///\bug This is a workaround until somebody tells me how to
   365       ///\bug This is a workaround until somebody tells me how to
   240       ///make class \c SymSmartGraph::SymEdgeMap friend of Edge
   366       ///make class \c SymListGraph::SymEdgeMap friend of Edge
   241       int &idref() {return n;}
   367       int &idref() {return n;}
   242     };
   368     };
   243     
   369     
   244     class OutEdgeIt : public Edge {
   370     class OutEdgeIt : public Edge {
   245       friend class SmartGraph;
   371       friend class ListGraph;
   246     public: 
   372     public: 
   247       OutEdgeIt() : Edge() { }
   373       OutEdgeIt() : Edge() { }
   248       OutEdgeIt (Invalid i) : Edge(i) { }
   374       OutEdgeIt (Invalid i) : Edge(i) { }
   249 
   375 
   250       OutEdgeIt(const SmartGraph& G,const Node v)
   376       OutEdgeIt(const ListGraph& G,const Node v)
   251 	: Edge(G.nodes[v.n].first_out) {}
   377 	: Edge(G.nodes[v.n].first_out) {}
   252     };
   378     };
   253     
   379     
   254     class InEdgeIt : public Edge {
   380     class InEdgeIt : public Edge {
   255       friend class SmartGraph;
   381       friend class ListGraph;
   256     public: 
   382     public: 
   257       InEdgeIt() : Edge() { }
   383       InEdgeIt() : Edge() { }
   258       InEdgeIt (Invalid i) : Edge(i) { }
   384       InEdgeIt (Invalid i) : Edge(i) { }
   259       InEdgeIt(const SmartGraph& G,Node v) :Edge(G.nodes[v.n].first_in){}
   385       InEdgeIt(const ListGraph& G,Node v) :Edge(G.nodes[v.n].first_in){}
   260     };
   386     };
   261 
   387 
   262     template <typename T> class NodeMap : public DynMapBase<Node>
   388     template <typename T> class NodeMap : public DynMapBase<Node>
   263     {
   389     {
   264       std::vector<T> container;
   390       std::vector<T> container;
   265 
   391 
   266     public:
   392     public:
   267       typedef T ValueType;
   393       typedef T ValueType;
   268       typedef Node KeyType;
   394       typedef Node KeyType;
   269 
   395 
   270       NodeMap(const SmartGraph &_G) :
   396       NodeMap(const ListGraph &_G) :
   271 	DynMapBase<Node>(_G), container(_G.maxNodeId())
   397 	DynMapBase<Node>(_G), container(_G.maxNodeId())
   272       {
   398       {
   273 	G->dyn_node_maps.push_back(this);
   399 	G->dyn_node_maps.push_back(this);
   274       }
   400       }
   275       NodeMap(const SmartGraph &_G,const T &t) :
   401       NodeMap(const ListGraph &_G,const T &t) :
   276 	DynMapBase<Node>(_G), container(_G.maxNodeId(),t)
   402 	DynMapBase<Node>(_G), container(_G.maxNodeId(),t)
   277       {
   403       {
   278 	G->dyn_node_maps.push_back(this);
   404 	G->dyn_node_maps.push_back(this);
   279       }
   405       }
   280       
   406       
   355 
   481 
   356     public:
   482     public:
   357       typedef T ValueType;
   483       typedef T ValueType;
   358       typedef Edge KeyType;
   484       typedef Edge KeyType;
   359 
   485 
   360       EdgeMap(const SmartGraph &_G) :
   486       EdgeMap(const ListGraph &_G) :
   361 	DynMapBase<Edge>(_G), container(_G.maxEdgeId())
   487 	DynMapBase<Edge>(_G), container(_G.maxEdgeId())
   362       {
   488       {
   363 	//FIXME: What if there are empty Id's?
   489 	//FIXME: What if there are empty Id's?
   364 	//FIXME: Can I use 'this' in a constructor?
   490 	//FIXME: Can I use 'this' in a constructor?
   365 	G->dyn_edge_maps.push_back(this);
   491 	G->dyn_edge_maps.push_back(this);
   366       }
   492       }
   367       EdgeMap(const SmartGraph &_G,const T &t) :
   493       EdgeMap(const ListGraph &_G,const T &t) :
   368 	DynMapBase<Edge>(_G), container(_G.maxEdgeId(),t)
   494 	DynMapBase<Edge>(_G), container(_G.maxEdgeId(),t)
   369       {
   495       {
   370 	G->dyn_edge_maps.push_back(this);
   496 	G->dyn_edge_maps.push_back(this);
   371       } 
   497       } 
   372       EdgeMap(const EdgeMap<T> &m) :
   498       EdgeMap(const EdgeMap<T> &m) :
   444 
   570 
   445   ///The purpose of this graph structure is to handle graphs
   571   ///The purpose of this graph structure is to handle graphs
   446   ///having bidirectional edges. Here the function \c addEdge(u,v) adds a pair
   572   ///having bidirectional edges. Here the function \c addEdge(u,v) adds a pair
   447   ///of oppositely directed edges.
   573   ///of oppositely directed edges.
   448   ///There is a new edge map type called
   574   ///There is a new edge map type called
   449   ///\ref SymSmartGraph::SymEdgeMap "SymEdgeMap"
   575   ///\ref SymListGraph::SymEdgeMap "SymEdgeMap"
   450   ///that complements this
   576   ///that complements this
   451   ///feature by
   577   ///feature by
   452   ///storing shared values for the edge pairs. The usual
   578   ///storing shared values for the edge pairs. The usual
   453   ///\ref GraphSkeleton::EdgeMap "EdgeMap"
   579   ///\ref GraphSkeleton::EdgeMap "EdgeMap"
   454   ///can be used
   580   ///can be used
   455   ///as well.
   581   ///as well.
   456   ///
   582   ///
   457   ///The oppositely directed edge can also be obtained easily
   583   ///The oppositely directed edge can also be obtained easily
   458   ///using \ref opposite.
   584   ///using \ref opposite.
   459   ///\warning It shares the similarity with \ref SmartGraph that
   585   ///
   460   ///it is not possible to delete edges or nodes from the graph.
   586   ///Here erase(Edge) deletes a pair of edges.
   461   //\sa \ref SmartGraph.
   587   ///
   462 
   588   ///\todo this date structure need some reconsiderations. Maybe it
   463   class SymSmartGraph : public SmartGraph
   589   ///should be implemented independently from ListGraph.
       
   590 
       
   591   class SymListGraph : public ListGraph
   464   {
   592   {
   465   public:
   593   public:
   466     template<typename T> class SymEdgeMap;
   594     template<typename T> class SymEdgeMap;
   467     template<typename T> friend class SymEdgeMap;
   595     template<typename T> friend class SymEdgeMap;
   468 
   596 
   469     SymSmartGraph() : SmartGraph() { }
   597     SymListGraph() : ListGraph() { }
   470     SymSmartGraph(const SmartGraph &_g) : SmartGraph(_g) { }
   598     SymListGraph(const ListGraph &_g) : ListGraph(_g) { }
       
   599     ///Adds a pair of oppositely directed edges to the graph.
   471     Edge addEdge(Node u, Node v)
   600     Edge addEdge(Node u, Node v)
   472     {
   601     {
   473       Edge e = SmartGraph::addEdge(u,v);
   602       Edge e = ListGraph::addEdge(u,v);
   474       SmartGraph::addEdge(v,u);
   603       ListGraph::addEdge(v,u);
   475       return e;
   604       return e;
   476     }
   605     }
   477 
   606 
       
   607     void erase(Node n) { ListGraph::erase(n); }
   478     ///The oppositely directed edge.
   608     ///The oppositely directed edge.
   479 
   609 
   480     ///Returns the oppositely directed
   610     ///Returns the oppositely directed
   481     ///pair of the edge \c e.
   611     ///pair of the edge \c e.
   482     Edge opposite(Edge e) const
   612     Edge opposite(Edge e) const
   484       Edge f;
   614       Edge f;
   485       f.idref() = e.idref() - 2*(e.idref()%2) + 1;
   615       f.idref() = e.idref() - 2*(e.idref()%2) + 1;
   486       return f;
   616       return f;
   487     }
   617     }
   488     
   618     
       
   619     ///Removes a pair of oppositely directed edges to the graph.
       
   620     void erase(Edge e) {
       
   621       ListGraph::erase(opposite(e));
       
   622       ListGraph::erase(e);
       
   623     }
       
   624     
   489     ///Common data storage for the edge pairs.
   625     ///Common data storage for the edge pairs.
   490 
   626 
   491     ///This map makes it possible to store data shared by the oppositely
   627     ///This map makes it possible to store data shared by the oppositely
   492     ///directed pairs of edges.
   628     ///directed pairs of edges.
   493     template <typename T> class SymEdgeMap : public DynMapBase<Edge>
   629     template <typename T> class SymEdgeMap : public DynMapBase<Edge>
   496       
   632       
   497     public:
   633     public:
   498       typedef T ValueType;
   634       typedef T ValueType;
   499       typedef Edge KeyType;
   635       typedef Edge KeyType;
   500 
   636 
   501       SymEdgeMap(const SymSmartGraph &_G) :
   637       SymEdgeMap(const SymListGraph &_G) :
   502 	DynMapBase<Edge>(_G), container(_G.maxEdgeId()/2)
   638 	DynMapBase<Edge>(_G), container(_G.maxEdgeId()/2)
   503       {
   639       {
   504 	static_cast<const SymSmartGraph*>(G)->dyn_edge_maps.push_back(this);
   640 	static_cast<const SymListGraph*>(G)->dyn_edge_maps.push_back(this);
   505       }
   641       }
   506       SymEdgeMap(const SymSmartGraph &_G,const T &t) :
   642       SymEdgeMap(const SymListGraph &_G,const T &t) :
   507 	DynMapBase<Edge>(_G), container(_G.maxEdgeId()/2,t)
   643 	DynMapBase<Edge>(_G), container(_G.maxEdgeId()/2,t)
   508       {
   644       {
   509 	G->dyn_edge_maps.push_back(this);
   645 	G->dyn_edge_maps.push_back(this);
   510       }
   646       }
   511 
   647 
   533  
   669  
   534       ~SymEdgeMap()
   670       ~SymEdgeMap()
   535       {
   671       {
   536 	if(G) {
   672 	if(G) {
   537 	  std::vector<DynMapBase<Edge>* >::iterator i;
   673 	  std::vector<DynMapBase<Edge>* >::iterator i;
   538 	  for(i=static_cast<const SymSmartGraph*>(G)->dyn_edge_maps.begin();
   674 	  for(i=static_cast<const SymListGraph*>(G)->dyn_edge_maps.begin();
   539 	      i!=static_cast<const SymSmartGraph*>(G)->dyn_edge_maps.end()
   675 	      i!=static_cast<const SymListGraph*>(G)->dyn_edge_maps.end()
   540 		&& *i!=this; ++i) ;
   676 		&& *i!=this; ++i) ;
   541 	  //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow...
   677 	  //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow...
   542 	  //A better way to do that: (Is this really important?)
   678 	  //A better way to do that: (Is this really important?)
   543 	  if(*i==this) {
   679 	  if(*i==this) {
   544 	    *i=static_cast<const SymSmartGraph*>(G)->dyn_edge_maps.back();
   680 	    *i=static_cast<const SymListGraph*>(G)->dyn_edge_maps.back();
   545 	    static_cast<const SymSmartGraph*>(G)->dyn_edge_maps.pop_back();
   681 	    static_cast<const SymListGraph*>(G)->dyn_edge_maps.pop_back();
   546 	  }
   682 	  }
   547 	}
   683 	}
   548       }
   684       }
   549       
   685       
   550       void add(const Edge k) 
   686       void add(const Edge k)