src/work/deba/list_graph.h
changeset 700 236117f60eee
parent 695 887c551fb0aa
child 701 c03e073b8394
equal deleted inserted replaced
4:d2cc71166d2a 0:b465b89c15a3
     6 ///\ingroup graphs
     6 ///\ingroup graphs
     7 ///\file
     7 ///\file
     8 ///\brief ListGraph, SymListGraph, NodeSet and EdgeSet classes.
     8 ///\brief ListGraph, SymListGraph, NodeSet and EdgeSet classes.
     9 
     9 
    10 #include <vector>
    10 #include <vector>
    11 #include <limits.h>
    11 #include <climits>
    12 
    12 
    13 #include <hugo/invalid.h>
    13 #include "invalid.h"
       
    14 
       
    15 #include "vector_map_factory.h"
       
    16 #include "map_registry.h"
       
    17 
       
    18 #include "map_defines.h"
    14 
    19 
    15 namespace hugo {
    20 namespace hugo {
    16 
    21 
    17 /// \addtogroup graphs
    22 /// \addtogroup graphs
    18 /// @{
    23 /// @{
    19 
       
    20   class SymListGraph;
       
    21 
    24 
    22   ///A list graph class.
    25   ///A list graph class.
    23 
    26 
    24   ///This is a simple and fast erasable graph implementation.
    27   ///This is a simple and fast erasable graph implementation.
    25   ///
    28   ///
    56     //The first free edge
    59     //The first free edge
    57     int first_free_edge;
    60     int first_free_edge;
    58     
    61     
    59   protected:
    62   protected:
    60     
    63     
    61     template <typename Key> class DynMapBase
       
    62     {
       
    63     protected:
       
    64       const ListGraph* G; 
       
    65     public:
       
    66       virtual void add(const Key k) = 0;
       
    67       virtual void erase(const Key k) = 0;
       
    68       DynMapBase(const ListGraph &_G) : G(&_G) {}
       
    69       virtual ~DynMapBase() {}
       
    70       friend class ListGraph;
       
    71     };
       
    72     
       
    73   public:
    64   public:
    74     template <typename T> class EdgeMap;
       
    75     template <typename T> class NodeMap;
       
    76     
    65     
    77     class Node;
    66     class Node;
    78     class Edge;
    67     class Edge;
    79 
    68 
    80     //  protected:
    69     typedef ListGraph Graph;
    81     // HELPME:
    70 
    82   protected:
       
    83     ///\bug It must be public because of SymEdgeMap.
       
    84     ///
       
    85     mutable std::vector<DynMapBase<Node> * > dyn_node_maps;
       
    86     ///\bug It must be public because of SymEdgeMap.
       
    87     ///
       
    88     mutable std::vector<DynMapBase<Edge> * > dyn_edge_maps;
       
    89     
       
    90   public:
    71   public:
    91 
    72 
    92     class NodeIt;
    73     class NodeIt;
    93     class EdgeIt;
    74     class EdgeIt;
    94     class OutEdgeIt;
    75     class OutEdgeIt;
    95     class InEdgeIt;
    76     class InEdgeIt;
    96     
    77     
       
    78     CREATE_MAP_REGISTRIES;
       
    79     CREATE_MAPS(VectorMapFactory);
       
    80 
    97   public:
    81   public:
    98 
    82 
    99     ListGraph() : nodes(), first_node(-1),
    83     ListGraph() : nodes(), first_node(-1),
   100 		  first_free_node(-1), edges(), first_free_edge(-1) {}
    84 		  first_free_node(-1), edges(), first_free_edge(-1) {}
   101     ListGraph(const ListGraph &_g) : nodes(_g.nodes), first_node(_g.first_node),
    85     ListGraph(const ListGraph &_g) : nodes(_g.nodes), first_node(_g.first_node),
   102 				     first_free_node(_g.first_free_node),
    86 				     first_free_node(_g.first_free_node),
   103 				     edges(_g.edges),
    87 				     edges(_g.edges),
   104 				     first_free_edge(_g.first_free_edge) {}
    88 				     first_free_edge(_g.first_free_edge) {}
   105     
    89     
   106     ~ListGraph()
       
   107     {
       
   108       for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
       
   109 	  i!=dyn_node_maps.end(); ++i) (**i).G=NULL;
       
   110       for(std::vector<DynMapBase<Edge> * >::iterator i=dyn_edge_maps.begin();
       
   111 	  i!=dyn_edge_maps.end(); ++i) (**i).G=NULL;
       
   112     }
       
   113 
    90 
   114     int nodeNum() const { return nodes.size(); }  //FIXME: What is this?
    91     int nodeNum() const { return nodes.size(); }  //FIXME: What is this?
   115     int edgeNum() const { return edges.size(); }  //FIXME: What is this?
    92     int edgeNum() const { return edges.size(); }  //FIXME: What is this?
   116 
    93 
   117     ///Set the expected number of edges
    94     ///Set the expected number of edges
   211       nodes[n].first_in = nodes[n].first_out = -1;
   188       nodes[n].first_in = nodes[n].first_out = -1;
   212       
   189       
   213       Node nn; nn.n=n;
   190       Node nn; nn.n=n;
   214 
   191 
   215       //Update dynamic maps
   192       //Update dynamic maps
   216       for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
   193       node_maps.add(nn);
   217 	  i!=dyn_node_maps.end(); ++i) (**i).add(nn);
       
   218 
   194 
   219       return nn;
   195       return nn;
   220     }
   196     }
   221     
   197     
   222     Edge addEdge(Node u, Node v) {
   198     Edge addEdge(Node u, Node v) {
   243       nodes[u.n].first_out = nodes[v.n].first_in = n;
   219       nodes[u.n].first_out = nodes[v.n].first_in = n;
   244 
   220 
   245       Edge e; e.n=n;
   221       Edge e; e.n=n;
   246 
   222 
   247       //Update dynamic maps
   223       //Update dynamic maps
   248       for(std::vector<DynMapBase<Edge> * >::iterator i=dyn_edge_maps.begin();
   224       edge_maps.add(e);
   249 	  i!=dyn_edge_maps.end(); ++i) (**i).add(e);
       
   250 
   225 
   251       return e;
   226       return e;
   252     }
   227     }
   253 
   228 
   254   private:
   229   private:
   269       edges[n].next_in = first_free_edge;
   244       edges[n].next_in = first_free_edge;
   270       first_free_edge = n;      
   245       first_free_edge = n;      
   271 
   246 
   272       //Update dynamic maps
   247       //Update dynamic maps
   273       Edge e; e.n=n;
   248       Edge e; e.n=n;
   274       for(std::vector<DynMapBase<Edge> * >::iterator i=dyn_edge_maps.begin();
       
   275 	  i!=dyn_edge_maps.end(); ++i) (**i).erase(e);
       
   276     }
   249     }
   277       
   250       
   278   public:
   251   public:
   279 
   252 
   280     void erase(Node nn) {
   253     void erase(Node nn) {
   290       
   263       
   291       nodes[n].next = first_free_node;
   264       nodes[n].next = first_free_node;
   292       first_free_node = n;
   265       first_free_node = n;
   293 
   266 
   294       //Update dynamic maps
   267       //Update dynamic maps
   295       for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
   268       node_maps.erase(nn);
   296 	  i!=dyn_node_maps.end(); ++i) (**i).erase(nn);
   269      }
   297     }
   270     
   298     
   271     void erase(Edge e) { 
   299     void erase(Edge e) { eraseEdge(e.n); }
   272       edge_maps.erase(e);
       
   273       eraseEdge(e.n); 
       
   274     }
   300 
   275 
   301     ///\bug Dynamic maps must be updated!
   276     ///\bug Dynamic maps must be updated!
   302     ///
   277     ///
   303     void clear() {
   278     void clear() {
   304       nodes.clear();edges.clear();
   279       nodes.clear();edges.clear();
   392       friend class ListGraph;
   367       friend class ListGraph;
   393     public: 
   368     public: 
   394       InEdgeIt() : Edge() { }
   369       InEdgeIt() : Edge() { }
   395       InEdgeIt (Invalid i) : Edge(i) { }
   370       InEdgeIt (Invalid i) : Edge(i) { }
   396       InEdgeIt(const ListGraph& G,Node v) :Edge(G.nodes[v.n].first_in) {}
   371       InEdgeIt(const ListGraph& G,Node v) :Edge(G.nodes[v.n].first_in) {}
   397     };
       
   398 
       
   399     template <typename T> class NodeMap : public DynMapBase<Node>
       
   400     {
       
   401       std::vector<T> container;
       
   402 
       
   403     public:
       
   404       typedef T ValueType;
       
   405       typedef Node KeyType;
       
   406 
       
   407       NodeMap(const ListGraph &_G) :
       
   408 	DynMapBase<Node>(_G), container(_G.maxNodeId())
       
   409       {
       
   410 	G->dyn_node_maps.push_back(this);
       
   411       }
       
   412       NodeMap(const ListGraph &_G,const T &t) :
       
   413 	DynMapBase<Node>(_G), container(_G.maxNodeId(),t)
       
   414       {
       
   415 	G->dyn_node_maps.push_back(this);
       
   416       }
       
   417       
       
   418       NodeMap(const NodeMap<T> &m) :
       
   419  	DynMapBase<Node>(*m.G), container(m.container)
       
   420       {
       
   421  	G->dyn_node_maps.push_back(this);
       
   422       }
       
   423 
       
   424       template<typename TT> friend class NodeMap;
       
   425  
       
   426       ///\todo It can copy between different types.
       
   427       ///
       
   428       template<typename TT> NodeMap(const NodeMap<TT> &m) :
       
   429 	DynMapBase<Node>(*m.G), container(m.container.size())
       
   430 
       
   431       {
       
   432 	G->dyn_node_maps.push_back(this);
       
   433 	typename std::vector<TT>::const_iterator i;
       
   434 	for(typename std::vector<TT>::const_iterator i=m.container.begin();
       
   435 	    i!=m.container.end();
       
   436 	    i++)
       
   437 	  container.push_back(*i);
       
   438       }
       
   439       ~NodeMap()
       
   440       {
       
   441 	if(G) {
       
   442 	  std::vector<DynMapBase<Node>* >::iterator i;
       
   443 	  for(i=G->dyn_node_maps.begin();
       
   444 	      i!=G->dyn_node_maps.end() && *i!=this; ++i) ;
       
   445 	  //if(*i==this) G->dyn_node_maps.erase(i); //FIXME: Way too slow...
       
   446 	  //A better way to do that: (Is this really important?)
       
   447 	  if(*i==this) {
       
   448 	    *i=G->dyn_node_maps.back();
       
   449 	    G->dyn_node_maps.pop_back();
       
   450 	  }
       
   451 	}
       
   452       }
       
   453 
       
   454       void add(const Node k) 
       
   455       {
       
   456 	if(k.n>=int(container.size())) container.resize(k.n+1);
       
   457       }
       
   458 
       
   459       void erase(const Node) { }
       
   460       
       
   461       void set(Node n, T a) { container[n.n]=a; }
       
   462       //'T& operator[](Node n)' would be wrong here
       
   463       typename std::vector<T>::reference
       
   464       operator[](Node n) { return container[n.n]; }
       
   465       //'const T& operator[](Node n)' would be wrong here
       
   466       typename std::vector<T>::const_reference 
       
   467       operator[](Node n) const { return container[n.n]; }
       
   468 
       
   469       ///\warning There is no safety check at all!
       
   470       ///Using operator = between maps attached to different graph may
       
   471       ///cause serious problem.
       
   472       ///\todo Is this really so?
       
   473       ///\todo It can copy between different types.
       
   474       const NodeMap<T>& operator=(const NodeMap<T> &m)
       
   475       {
       
   476 	container = m.container;
       
   477 	return *this;
       
   478       }
       
   479       template<typename TT>
       
   480       const NodeMap<T>& operator=(const NodeMap<TT> &m)
       
   481       {
       
   482 	std::copy(m.container.begin(), m.container.end(), container.begin());
       
   483 	return *this;
       
   484       }
       
   485       
       
   486       void update() {}    //Useless for Dynamic Maps
       
   487       void update(T a) {}  //Useless for Dynamic Maps
       
   488     };
       
   489     
       
   490     template <typename T> class EdgeMap : public DynMapBase<Edge>
       
   491     {
       
   492     protected:
       
   493       std::vector<T> container;
       
   494 
       
   495     public:
       
   496       typedef T ValueType;
       
   497       typedef Edge KeyType;
       
   498 
       
   499       EdgeMap(const ListGraph &_G) :
       
   500 	DynMapBase<Edge>(_G), container(_G.maxEdgeId())
       
   501       {
       
   502 	//FIXME: What if there are empty Id's?
       
   503 	//FIXME: Can I use 'this' in a constructor?
       
   504 	G->dyn_edge_maps.push_back(this);
       
   505       }
       
   506       EdgeMap(const ListGraph &_G,const T &t) :
       
   507 	DynMapBase<Edge>(_G), container(_G.maxEdgeId(),t)
       
   508       {
       
   509 	G->dyn_edge_maps.push_back(this);
       
   510       } 
       
   511       EdgeMap(const EdgeMap<T> &m) :
       
   512  	DynMapBase<Edge>(*m.G), container(m.container)
       
   513       {
       
   514  	G->dyn_edge_maps.push_back(this);
       
   515       }
       
   516 
       
   517       template<typename TT> friend class EdgeMap;
       
   518 
       
   519       ///\todo It can copy between different types.
       
   520       ///
       
   521       template<typename TT> EdgeMap(const EdgeMap<TT> &m) :
       
   522 	DynMapBase<Edge>(*m.G), container(m.container.size())
       
   523       {
       
   524 	G->dyn_edge_maps.push_back(this);
       
   525 	typename std::vector<TT>::const_iterator i;
       
   526 	for(typename std::vector<TT>::const_iterator i=m.container.begin();
       
   527 	    i!=m.container.end();
       
   528 	    i++)
       
   529 	  container.push_back(*i);
       
   530       }
       
   531       ~EdgeMap()
       
   532       {
       
   533 	if(G) {
       
   534 	  std::vector<DynMapBase<Edge>* >::iterator i;
       
   535 	  for(i=G->dyn_edge_maps.begin();
       
   536 	      i!=G->dyn_edge_maps.end() && *i!=this; ++i) ;
       
   537 	  //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow...
       
   538 	  //A better way to do that: (Is this really important?)
       
   539 	  if(*i==this) {
       
   540 	    *i=G->dyn_edge_maps.back();
       
   541 	    G->dyn_edge_maps.pop_back();
       
   542 	  }
       
   543 	}
       
   544       }
       
   545       
       
   546       void add(const Edge k) 
       
   547       {
       
   548 	if(k.n>=int(container.size())) container.resize(k.n+1);
       
   549       }
       
   550       void erase(const Edge) { }
       
   551       
       
   552       void set(Edge n, T a) { container[n.n]=a; }
       
   553       //T get(Edge n) const { return container[n.n]; }
       
   554       typename std::vector<T>::reference
       
   555       operator[](Edge n) { return container[n.n]; }
       
   556       typename std::vector<T>::const_reference
       
   557       operator[](Edge n) const { return container[n.n]; }
       
   558 
       
   559       ///\warning There is no safety check at all!
       
   560       ///Using operator = between maps attached to different graph may
       
   561       ///cause serious problem.
       
   562       ///\todo Is this really so?
       
   563       ///\todo It can copy between different types.
       
   564       const EdgeMap<T>& operator=(const EdgeMap<T> &m)
       
   565       {
       
   566 	container = m.container;
       
   567 	return *this;
       
   568       }
       
   569       template<typename TT>
       
   570       const EdgeMap<T>& operator=(const EdgeMap<TT> &m)
       
   571       {
       
   572 	std::copy(m.container.begin(), m.container.end(), container.begin());
       
   573 	return *this;
       
   574       }
       
   575       
       
   576       void update() {}    //Useless for DynMaps
       
   577       void update(T a) {}  //Useless for DynMaps
       
   578     };
   372     };
   579 
   373 
   580   };
   374   };
   581 
   375 
   582   ///Graph for bidirectional edges.
   376   ///Graph for bidirectional edges.
   598   ///
   392   ///
   599   ///Here erase(Edge) deletes a pair of edges.
   393   ///Here erase(Edge) deletes a pair of edges.
   600   ///
   394   ///
   601   ///\todo this date structure need some reconsiderations. Maybe it
   395   ///\todo this date structure need some reconsiderations. Maybe it
   602   ///should be implemented independently from ListGraph.
   396   ///should be implemented independently from ListGraph.
   603 
       
   604   class SymListGraph : public ListGraph
       
   605   {
       
   606   public:
       
   607     template<typename T> class SymEdgeMap;
       
   608     template<typename T> friend class SymEdgeMap;
       
   609 
       
   610     SymListGraph() : ListGraph() { }
       
   611     SymListGraph(const ListGraph &_g) : ListGraph(_g) { }
       
   612     ///Adds a pair of oppositely directed edges to the graph.
       
   613     Edge addEdge(Node u, Node v)
       
   614     {
       
   615       Edge e = ListGraph::addEdge(u,v);
       
   616       ListGraph::addEdge(v,u);
       
   617       return e;
       
   618     }
       
   619 
       
   620     void erase(Node n) { ListGraph::erase(n); }
       
   621     ///The oppositely directed edge.
       
   622 
       
   623     ///Returns the oppositely directed
       
   624     ///pair of the edge \c e.
       
   625     Edge opposite(Edge e) const
       
   626     {
       
   627       Edge f;
       
   628       f.idref() = e.idref() - 2*(e.idref()%2) + 1;
       
   629       return f;
       
   630     }
       
   631     
       
   632     ///Removes a pair of oppositely directed edges to the graph.
       
   633     void erase(Edge e) {
       
   634       ListGraph::erase(opposite(e));
       
   635       ListGraph::erase(e);
       
   636     }
       
   637     
       
   638     ///Common data storage for the edge pairs.
       
   639 
       
   640     ///This map makes it possible to store data shared by the oppositely
       
   641     ///directed pairs of edges.
       
   642     template <typename T> class SymEdgeMap : public DynMapBase<Edge>
       
   643     {
       
   644       std::vector<T> container;
       
   645       
       
   646     public:
       
   647       typedef T ValueType;
       
   648       typedef Edge KeyType;
       
   649 
       
   650       SymEdgeMap(const SymListGraph &_G) :
       
   651 	DynMapBase<Edge>(_G), container(_G.maxEdgeId()/2)
       
   652       {
       
   653 	static_cast<const SymListGraph*>(G)->dyn_edge_maps.push_back(this);
       
   654       }
       
   655       SymEdgeMap(const SymListGraph &_G,const T &t) :
       
   656 	DynMapBase<Edge>(_G), container(_G.maxEdgeId()/2,t)
       
   657       {
       
   658 	G->dyn_edge_maps.push_back(this);
       
   659       }
       
   660 
       
   661       SymEdgeMap(const SymEdgeMap<T> &m) :
       
   662  	DynMapBase<SymEdge>(*m.G), container(m.container)
       
   663       {
       
   664  	G->dyn_node_maps.push_back(this);
       
   665       }
       
   666 
       
   667       //      template<typename TT> friend class SymEdgeMap;
       
   668 
       
   669       ///\todo It can copy between different types.
       
   670       ///
       
   671 
       
   672       template<typename TT> SymEdgeMap(const SymEdgeMap<TT> &m) :
       
   673 	DynMapBase<SymEdge>(*m.G), container(m.container.size())
       
   674       {
       
   675 	G->dyn_node_maps.push_back(this);
       
   676 	typename std::vector<TT>::const_iterator i;
       
   677 	for(typename std::vector<TT>::const_iterator i=m.container.begin();
       
   678 	    i!=m.container.end();
       
   679 	    i++)
       
   680 	  container.push_back(*i);
       
   681       }
       
   682  
       
   683       ~SymEdgeMap()
       
   684       {
       
   685 	if(G) {
       
   686 	  std::vector<DynMapBase<Edge>* >::iterator i;
       
   687 	  for(i=static_cast<const SymListGraph*>(G)->dyn_edge_maps.begin();
       
   688 	      i!=static_cast<const SymListGraph*>(G)->dyn_edge_maps.end()
       
   689 		&& *i!=this; ++i) ;
       
   690 	  //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow...
       
   691 	  //A better way to do that: (Is this really important?)
       
   692 	  if(*i==this) {
       
   693 	    *i=static_cast<const SymListGraph*>(G)->dyn_edge_maps.back();
       
   694 	    static_cast<const SymListGraph*>(G)->dyn_edge_maps.pop_back();
       
   695 	  }
       
   696 	}
       
   697       }
       
   698       
       
   699       void add(const Edge k) 
       
   700       {
       
   701 	if(!k.idref()%2&&k.idref()/2>=int(container.size()))
       
   702 	  container.resize(k.idref()/2+1);
       
   703       }
       
   704       void erase(const Edge k) { }
       
   705       
       
   706       void set(Edge n, T a) { container[n.idref()/2]=a; }
       
   707       //T get(Edge n) const { return container[n.idref()/2]; }
       
   708       typename std::vector<T>::reference
       
   709       operator[](Edge n) { return container[n.idref()/2]; }
       
   710       typename std::vector<T>::const_reference
       
   711       operator[](Edge n) const { return container[n.idref()/2]; }
       
   712 
       
   713       ///\warning There is no safety check at all!
       
   714       ///Using operator = between maps attached to different graph may
       
   715       ///cause serious problem.
       
   716       ///\todo Is this really so?
       
   717       ///\todo It can copy between different types.
       
   718       const SymEdgeMap<T>& operator=(const SymEdgeMap<T> &m)
       
   719       {
       
   720 	container = m.container;
       
   721 	return *this;
       
   722       }
       
   723       template<typename TT>
       
   724       const SymEdgeMap<T>& operator=(const SymEdgeMap<TT> &m)
       
   725       {
       
   726 	std::copy(m.container.begin(), m.container.end(), container.begin());
       
   727 	return *this;
       
   728       }
       
   729       
       
   730       void update() {}    //Useless for DynMaps
       
   731       void update(T a) {}  //Useless for DynMaps
       
   732 
       
   733     };
       
   734 
   397 
   735   };
   398   };
   736   
   399   
   737 
   400 
   738   ///A graph class containing only nodes.
   401   ///A graph class containing only nodes.