OpenFPM_data  0.1.0
Project that contain the implementation and interfaces for basic structure like vectors, grids, graph ... .
 All Data Structures Namespaces Functions Variables Typedefs Friends
map_graph.hpp
1 /*
2  * map_graph.hpp
3  *
4  * Created on: Nov 21, 2014
5  * Author: Pietro Incardona
6  *
7  *
8  * Graph structure that store a CSR graph format
9  *
10  * This Graph format is suppose to have a list of vertex that store an index x that indicate where
11  * in the adjacency list we have the list of all the neighborhood vertex, plus an adjacency list
12  * that store all the neighborhood for each vertex:
13  *
14  * In reality inside Graph_CSR
15  *
16  * VertexList store the Vertex index that indicate the end of the neighborhood list,
17  * the start is indicated by i * v_slot (id of the vertex, v_slot maximum number of
18  * neighborhood for a vertex)
19  *
20  * EdgeList store for each vertex at position i * v_slot (id of the vertex, v_slot maximum
21  * number of neighborhood for a vertex) the list of all the neighborhood of the vertex i
22  *
23  * Example
24  *
25  * Suppose an undirected graph of 4 vertex
26  *
27  * 1 -> 2 3 4
28  * 2 -> 1
29  * 3 -> 4 1
30  * 4 -> 1 3
31  *
32  * suppose that v_slot is 4 ( each vertex has less tha 4 neighborhood )
33  *
34  * we will have
35  *
36  * Vertex list 3 5 10 14
37  * Edge list 2 3 4 0 1 0 0 0 4 1 0 0 1 3 0 0
38  *
39  * Vertex properties and edge properties are stored in a separate structure
40  *
41  */
42 
43 #ifndef MAP_GRAPH_HPP_
44 #define MAP_GRAPH_HPP_
45 
46 #include "Vector/map_vector.hpp"
47 #ifdef METIS_GP
48 #include "metis_util.hpp"
49 #endif
50 
51 #define NO_EDGE -1
52 
56 class no_edge
57 {
58 public:
59  typedef boost::fusion::vector<> type;
60  typedef typename memory_traits_inte<type>::type memory_int;
62 
63  type data;
64 
65  static const unsigned int max_prop = 0;
66 };
67 
68 template<typename V, typename E, template<typename, typename, typename, unsigned int> class VertexList, template<typename, typename, typename, unsigned int> class EdgeList, typename Memory,
69  typename grow_p>
70 class Graph_CSR;
71 
79 class e_map
80 {
81 public:
82  typedef boost::fusion::vector<size_t, size_t> type;
83  typedef typename memory_traits_inte<type>::type memory_int;
85 
86  type data;
87 
88  static const unsigned int vid = 0;
89  static const unsigned int eid = 1;
90  static const unsigned int max_prop = 2;
91 
92  // Setter method
93 
94  inline void setvid(size_t vid_)
95  {
96  boost::fusion::at_c<0>(data) = vid_;
97  }
98  ;
99  inline void seteid(size_t eid_)
100  {
101  boost::fusion::at_c<1>(data) = eid_;
102  }
103  ;
104 };
105 
106 class edge_key
107 {
108 public:
109 
110  // Actual source node
111  size_t pos;
112 
113  //Actual target node
114  size_t pos_e;
115 
116  void begin()
117  {
118  pos = 0;
119  pos_e = 0;
120  }
121 
127  size_t & source()
128  {
129  return pos;
130  }
131 
138  size_t & target_t()
139  {
140  return pos_e;
141  }
142 };
143 
148 template<typename Graph>
150 {
152  const Graph & g;
153 
154  // Actual edge key
155  edge_key ek;
156 
157 public:
158 
165  edge_iterator(const Graph & g) :
166  g(g)
167  {
168  ek.begin();
169  }
170 
178  {
179  // Check if reach the end of the edge list
180  if (ek.pos_e + 1 >= g.getNChilds(ek.pos))
181  {
182  // increment the node position and reset
183  ek.pos++;
184  ek.pos_e = 0;
185 
186  // skip every vertex without edges
187  while (ek.pos < g.getNVertex() && g.getNChilds(ek.pos) == 0)
188  {
189  ek.pos++;
190  }
191  }
192  else
193  {
194  // increment the edge position
195  ek.pos_e++;
196  }
197 
198  return *this;
199  }
200 
209  bool isNext()
210  {
211  if (ek.pos < g.getNVertex())
212  {
214 
215  return true;
216  }
217 
219  return false;
220  }
221 
229  edge_key get()
230  {
231  return ek;
232  }
233 
239  size_t source()
240  {
241  return ek.pos;
242  }
243 
249  size_t target()
250  {
251  return g.getChild(ek.pos, ek.pos_e);
252  }
253 };
254 
282 template<typename V, typename E = no_edge, template<typename, typename, typename, unsigned int> class VertexList = openfpm::vector,
283  template<typename, typename, typename, unsigned int> class EdgeList = openfpm::vector, typename Memory = HeapMemory, typename grow_p = openfpm::grow_policy_double>
284 class Graph_CSR
285 {
287  size_t v_slot;
288 
290  VertexList<V, Memory, grow_p, openfpm::vect_isel<V>::value> v;
291 
293  VertexList<size_t, Memory, grow_p, openfpm::vect_isel<size_t>::value> v_l;
294 
296  EdgeList<E, Memory, grow_p, openfpm::vect_isel<E>::value> e;
297 
299  EdgeList<e_map, Memory, grow_p, openfpm::vect_isel<e_map>::value> e_l;
300 
302  EdgeList<E, Memory, grow_p, openfpm::vect_isel<E>::value> e_invalid;
303 
313  template<typename CheckPolicy = NoCheck> inline size_t addEdge_(size_t v1, size_t v2)
314  {
315  // If v1 and v2 does not satisfy some criteria return
316  if (CheckPolicy::valid(v1, v.size()) == false)
317  return NO_EDGE;
318  if (CheckPolicy::valid(v2, v.size()) == false)
319  return NO_EDGE;
320 
321  // get the number of adjacent vertex
322  size_t id_x_end = v_l.template get<0>(v1);
323 
324 #ifdef DEBUG
325  // Check that v1 and v2 exist
326 
327  if (v1 >= v.size() || v2 >= v.size())
328  {
329  std::cerr << "Error graph: trying to create an edge between vertex that does not exist" << "\n";
330  }
331 
332  // Check that the edge does not already exist
333 
334  for (size_t s = 0; s < id_x_end; s++)
335  {
336  if (e_l.template get<e_map::vid>(v1 * v_slot + s) == v2)
337  {
338  std::cerr << "Error graph: the edge already exist" << "\n";
339  }
340  }
341 #endif
342 
343  // Check if there is space for another edge
344 
345  if (id_x_end >= v_slot)
346  {
347  // Unfortunately there is not space we need to reallocate memory
348  // Reallocate with double slot
349 
350  // Create an new Graph
351 
353 
354  // Copy the graph
355 
356  for (size_t i = 0; i < v.size(); i++)
357  {
358  // copy the property from the old graph
359 
360  g_new.v.set(i, v, 2 * i);
361  }
362 
363  // swap the new graph with the old one
364 
365  swap(g_new);
366  }
367 
368  // Here we are sure than v and e has enough slots to store a new edge
369  // Check that e_l has enough space to store new edge
370  // should be always e.size == e_l.size
371 
372  if (id_x_end >= e_l.size())
373  {
374  // Resize the basic structure
375 
376  e_l.resize(v.size() * v_slot);
377  }
378 
379  // add in e_l the adjacent vertex for v1 and fill the edge id
380  e_l.template get<e_map::vid>(v1 * v_slot + id_x_end) = v2;
381  e_l.template get<e_map::eid>(v1 * v_slot + id_x_end) = e.size();
382 
383  // add an empty edge
384  e.resize(e.size() + 1);
385 
386  // Increment the ending point
387  ++v_l.template get<0>(v1);
388 
389  // return the created edge
390  return e.size() - 1;
391  }
392 
393 public:
394 
396  typedef V V_type;
397 
399  typedef E E_type;
400 
402  typedef typename VertexList<V, Memory, grow_p, openfpm::vect_isel<V>::value>::container V_container;
403 
405  typedef typename EdgeList<E, Memory, grow_p, openfpm::vect_isel<E>::value>::container E_container;
406 
414  {
416 
417  dup.v_slot = v_slot;
418 
420 
421  dup.v.swap(v.duplicate());
422  dup.v_l.swap(v_l.duplicate());
423  dup.e.swap(e.duplicate());
424  dup.e_l.swap(e_l.duplicate());
425  dup.e_invalid.swap(e_invalid.duplicate());
426 
427  return dup;
428  }
429 
436  Graph_CSR(0, 16)
437  {
438  }
439 
445  Graph_CSR(size_t n_vertex) :
446  Graph_CSR(n_vertex, 16)
447  {
448  }
449 
455  Graph_CSR(size_t n_vertex, size_t n_slot)
456  :v_slot(n_slot)
457  {
459  v.resize(n_vertex);
461  v_l.resize(n_vertex);
463  v_l.fill(0);
465  e_invalid.resize(1);
466  }
467 
472  {
473  size_t vs_tmp = v_slot;
474  v_slot = g.v_slot;
475  g.v_slot = vs_tmp;
476  swap(g);
477  }
478 
487  template<unsigned int i> auto vertex_p(size_t id) -> decltype( v.template get<i>(id) )
488  {
489  return v.template get<i>(id);
490  }
491 
498  template<unsigned int i> auto vertex_p(grid_key_dx<1> id) -> decltype( v.template get<i>(id) )
499  {
500  return v.template get<i>(id);
501  }
502 
508  auto vertex(size_t id) -> decltype( v.get(id) )
509  {
510  return v.get(id);
511  }
512 
520  auto vertex(grid_key_dx<1> id) -> decltype( v.get(id.get(0)) )
521  {
522  return v.get(id.get(0));
523  }
524 
532  auto vertex(openfpm::vector_key_iterator id) -> decltype( v.get(0) )
533  {
534  return v.get(id.get());
535  }
536 
542  auto vertex(size_t id) const -> const decltype( v.get(id) )
543  {
544  return v.get(id);
545  }
546 
554  auto vertex(grid_key_dx<1> id) const -> const decltype( v.get(id.get(0)) )
555  {
556  return v.get(id.get(0));
557  }
558 
566  auto vertex(openfpm::vector_key_iterator id) const -> const decltype( v.get(0) )
567  {
568  return v.get(id.get());
569  }
570 
577  template<unsigned int i> auto edge_p(grid_key_dx<1> id) -> decltype ( e.template get<i>(id) )
578  {
579  return e.template get<i>(id);
580  }
581 
588  template<unsigned int i> auto edge_p(size_t id) -> decltype ( e.template get<i>(id) )
589  {
590  return e.template get<i>(id);
591  }
592 
598  auto edge(grid_key_dx<1> id) -> decltype ( e.get(id.get(0)) )
599  {
600  return e.get(id.get(0));
601  }
602 
608  auto edge(edge_key ek) -> decltype ( e.get(0) )
609  {
610  return e.get(e_l.template get<e_map::eid>(ek.pos * v_slot + ek.pos_e));
611  }
612 
620  auto edge(size_t id) -> decltype ( e.get(id) )
621  {
622  return e.get(id);
623  }
624 
630  auto edge(grid_key_dx<1> id) const -> const decltype ( e.get(id.get(0)) )
631  {
632  return e.get(id.get(0));
633  }
634 
640  auto edge(edge_key ek) const -> const decltype ( e.get(0) )
641  {
642  return e.get(e_l.template get<e_map::eid>(ek.pos * v_slot + ek.pos_e));
643  }
644 
652  auto edge(size_t id) const -> const decltype ( e.get(id) )
653  {
654  return e.get(id);
655  }
656 
665  inline size_t getNChilds(size_t c) const
666  {
667  // Get the number of childs
668 
669  return v_l.template get<0>(c);
670  }
671 
679  inline size_t getNChilds(typename VertexList<V, Memory, grow_p, openfpm::vect_isel<V>::value>::iterator_key & c)
680  {
681  // Get the number of childs
682 
683  return v_l.template get<0>(c.get());
684  }
685 
692  inline auto getChildEdge(size_t v, size_t v_e) -> decltype(e.get(0))
693  {
694 #ifdef DEBUG
695  if (e >= v_l.template get<0>(v*v_slot))
696  {
697  std::cerr << "Error node " << v << " does not have edge " << v_e << "\n";
698  }
699 
700  if (e.size() >= e_l.template get<e_map::eid>(v * v_slot + v_e))
701  {
702  std::cerr << "Error edge " << v << " does not have edge "<< v_e << "\n";
703  }
704 #endif
705 
706  // Get the edge id
707  return e.get(e_l.template get<e_map::eid>(v * v_slot + v_e));
708  }
709 
719  inline size_t getChild(size_t v, size_t i) const
720  {
721 #ifdef DEBUG
722  if (i >= v_l.template get<0>(v) )
723  {
724  std::cerr << "Error " << __FILE__ << " line: " << __LINE__ << " vertex " << v << " does not have edge " << i << "\n";
725  }
726 
727  if (e.size() <= e_l.template get<e_map::eid>(v * v_slot + i))
728  {
729  std::cerr << "Error " << __FILE__ << " " << __LINE__ << " edge " << v << " does not have edge "<< i << "\n";
730  }
731 #endif
732 
733  // Get the edge id
734  return e_l.template get<e_map::vid>(v * v_slot + i);
735  }
736 
746  inline size_t getChild(typename VertexList<V, Memory, grow_p, openfpm::vect_isel<V>::value>::iterator_key & v, size_t i)
747  {
748 #ifdef DEBUG
749  if (i >= v_l.template get<0>(v.get()) )
750  {
751  std::cerr << "Error " << __FILE__ << " line: " << __LINE__ << " vertex " << v.get() << " does not have edge " << i << "\n";
752  }
753 
754  if (e.size() <= e_l.template get<e_map::eid>(v.get() * v_slot + i))
755  {
756  std::cerr << "Error " << __FILE__ << " " << __LINE__ << " edge " << v.get() << " does not have edge "<< i << "\n";
757  }
758 #endif
759 
760  // Get the edge id
761  return e_l.template get<e_map::vid>(v.get() * v_slot + i);
762  }
763 
770  inline void addVertex(const V & vrt)
771  {
772  v.add(vrt);
773 
774  // Set the number of adjacent vertex for this vertex to 0
775 
776  v_l.add(0ul);
777 
778  // Add a slot for the vertex adjacency list
779 
780  e_l.resize(e_l.size() + v_slot);
781  }
782 
787  inline void addVertex()
788  {
789  v.add();
790 
791  // Set the number of adjacent vertex for this vertex to 0
792 
793  v_l.add(0ul);
794 
795  // Add a slot for the vertex adjacency list
796 
797  e_l.resize(e_l.size() + v_slot);
798  }
799 
806  template<typename CheckPolicy = NoCheck> inline auto addEdge(size_t v1, size_t v2, const E & ed) -> decltype(e.get(0))
807  {
808  long int id_x_end = addEdge_<CheckPolicy>(v1, v2);
809 
810  // If there is not edge return an invalid edge, is a kind of stub object
811  if (id_x_end == NO_EDGE)
812  return e_invalid.get(0);
813 
814  // add in e_l the edge properties
815  e.set(id_x_end, ed);
816 
817  return e.get(id_x_end);
818  }
819 
829  template<typename CheckPolicy = NoCheck> inline auto addEdge(size_t v1, size_t v2) -> decltype(e.get(0))
830  {
832  long int id_x_end = addEdge_<CheckPolicy>(v1, v2);
833  // If there is not edge return an invalid edge, is a kind of stub object
834  if (id_x_end == NO_EDGE)
835  return e_invalid.get(0);
836 
838  return e.get(id_x_end);
839  }
840 
849  {
850  // switch the memory
851 
852  g.v.swap(v);
853  g.e.swap(e);
854  g.v_l.swap(v_l);
855  g.e_l.swap(e_l);
856  g.e_invalid.swap(e_invalid);
857  }
858 
867  inline auto getVertexIterator() const -> decltype(v.getIterator())
868  {
869  return v.getIterator();
870  }
871 
881  {
883  }
884 
891  inline size_t getNVertex() const
892  {
893  return v.size();
894  }
895 
902  inline size_t getNEdge() const
903  {
904  return e.size();
905  }
906 };
907 
932 template<typename V, typename E>
933 class Graph_CSR_s: public Graph_CSR<V, E>
934 {
935 
936 };
937 
938 #endif /* MAP_GRAPH_HPP_ */
edge_iterator< Graph_CSR< V, E, VertexList, EdgeList, Memory > > getEdgeIterator() const
Get the vertex iterator.
Definition: map_graph.hpp:880
auto vertex_p(grid_key_dx< 1 > id) -> decltype(v.template get< i >(id))
Access the vertex.
Definition: map_graph.hpp:498
auto getVertexIterator() const -> decltype(v.getIterator())
Get the vertex iterator.
Definition: map_graph.hpp:867
const Graph & g
Graph.
Definition: map_graph.hpp:152
void swap(Graph_CSR< V, E, VertexList, EdgeList > &g)
swap the memory of g with this graph
Definition: map_graph.hpp:848
Graph_CSR(Graph_CSR< V, E, VertexList, EdgeList, Memory > &&g)
Copy constructor.
Definition: map_graph.hpp:471
EdgeList< E, Memory, grow_p, openfpm::vect_isel< E >::value > e
Structure that store the edge properties.
Definition: map_graph.hpp:296
Grow policy define how the vector should grow every time we exceed the size.
auto edge(grid_key_dx< 1 > id) -> decltype(e.get(id.get(0)))
Access the edge.
Definition: map_graph.hpp:598
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:18
auto edge(size_t id) const -> const decltype(e.get(id))
operator to access the edge
Definition: map_graph.hpp:652
auto edge(edge_key ek) -> decltype(e.get(0))
operator to access the edge
Definition: map_graph.hpp:608
auto edge_p(grid_key_dx< 1 > id) -> decltype(e.template get< i >(id))
Access the edge.
Definition: map_graph.hpp:577
auto getChildEdge(size_t v, size_t v_e) -> decltype(e.get(0))
Get the vertex edge.
Definition: map_graph.hpp:692
VertexList< size_t, Memory, grow_p, openfpm::vect_isel< size_t >::value > v_l
Structure that store the number of adjacent vertex in e_l for each vertex.
Definition: map_graph.hpp:293
EdgeList< e_map, Memory, grow_p, openfpm::vect_isel< e_map >::value > e_l
Structure that store for each vertex the adjacent the vertex id and edge id (for property into e) ...
Definition: map_graph.hpp:299
auto vertex(size_t id) const -> const decltype(v.get(id))
Function to access the vertexes.
Definition: map_graph.hpp:542
bool isNext()
Check if there is the next element.
Definition: map_graph.hpp:209
edge_iterator & operator++()
Get the next element.
Definition: map_graph.hpp:177
edge_iterator(const Graph &g)
Constructor.
Definition: map_graph.hpp:165
auto vertex(size_t id) -> decltype(v.get(id))
Function to access the vertexes.
Definition: map_graph.hpp:508
VertexList< V, Memory, grow_p, openfpm::vect_isel< V >::value > v
Structure that store the vertex properties.
Definition: map_graph.hpp:290
Graph edge iterator.
Definition: map_graph.hpp:149
auto edge(edge_key ek) const -> const decltype(e.get(0))
operator to access the edge
Definition: map_graph.hpp:640
size_t source()
Return the source node.
Definition: map_graph.hpp:239
auto edge(grid_key_dx< 1 > id) const -> const decltype(e.get(id.get(0)))
Access the edge.
Definition: map_graph.hpp:630
auto addEdge(size_t v1, size_t v2, const E &ed) -> decltype(e.get(0))
add edge on the graph
Definition: map_graph.hpp:806
Graph_CSR(size_t n_vertex, size_t n_slot)
Constructor.
Definition: map_graph.hpp:455
size_t getNChilds(typename VertexList< V, Memory, grow_p, openfpm::vect_isel< V >::value >::iterator_key &c)
Return the number of childs of a vertex.
Definition: map_graph.hpp:679
size_t target()
Return the target node.
Definition: map_graph.hpp:249
EdgeList< E, Memory, grow_p, openfpm::vect_isel< E >::value >::container E_container
Object container for the edge, for example can be encap<...> (map_grid or openfpm::vector) ...
Definition: map_graph.hpp:405
auto addEdge(size_t v1, size_t v2) -> decltype(e.get(0))
add edge on the graph
Definition: map_graph.hpp:829
auto vertex(grid_key_dx< 1 > id) -> decltype(v.get(id.get(0)))
operator to access the vertex
Definition: map_graph.hpp:520
size_t & target_t()
Return the target of this edge.
Definition: map_graph.hpp:138
auto edge_p(size_t id) -> decltype(e.template get< i >(id))
Access the edge.
Definition: map_graph.hpp:588
auto vertex(openfpm::vector_key_iterator id) -> decltype(v.get(0))
operator to access the vertex
Definition: map_graph.hpp:532
void addVertex(const V &vrt)
add vertex
Definition: map_graph.hpp:770
auto vertex(grid_key_dx< 1 > id) const -> const decltype(v.get(id.get(0)))
operator to access the vertex
Definition: map_graph.hpp:554
Graph_CSR< V, E, VertexList, EdgeList, Memory, grow_p > duplicate()
It duplicate the graph.
Definition: map_graph.hpp:413
auto vertex_p(size_t id) -> decltype(v.template get< i >(id))
operator to access the vertex
Definition: map_graph.hpp:487
class with no edge
Definition: map_graph.hpp:56
auto edge(size_t id) -> decltype(e.get(id))
operator to access the edge
Definition: map_graph.hpp:620
Structure that store a graph in CSR format or basically in compressed adjacency matrix format...
Definition: map_graph.hpp:70
inter_memc< T >::type type
for each element in the vector interleave memory_c
Definition: memory_conf.hpp:55
EdgeList< E, Memory, grow_p, openfpm::vect_isel< E >::value > e_invalid
invalid edge element, when a function try to create an in valid edge this object is returned ...
Definition: map_graph.hpp:302
void addVertex()
add an empty vertex
Definition: map_graph.hpp:787
size_t getNEdge() const
Return the number of edges.
Definition: map_graph.hpp:902
size_t getNChilds(size_t c) const
Return the number of childs of a vertex.
Definition: map_graph.hpp:665
size_t getChild(typename VertexList< V, Memory, grow_p, openfpm::vect_isel< V >::value >::iterator_key &v, size_t i)
Get the child edge.
Definition: map_graph.hpp:746
Graph_CSR()
Constructor.
Definition: map_graph.hpp:435
Structure used inside GraphCSR an edge.
Definition: map_graph.hpp:79
size_t getNVertex() const
Return the number of the vertex.
Definition: map_graph.hpp:891
size_t v_slot
number of slot per vertex
Definition: map_graph.hpp:287
size_t getChild(size_t v, size_t i) const
Get the child edge.
Definition: map_graph.hpp:719
E E_type
Edge typedef.
Definition: map_graph.hpp:399
This class is a container for the memory interface like HeapMemory CudaMemory.
Definition: memory_c.hpp:32
Simplified implementation of Graph_CSR.
Definition: map_graph.hpp:933
Graph_CSR(size_t n_vertex)
Constructor.
Definition: map_graph.hpp:445
size_t addEdge_(size_t v1, size_t v2)
add edge on the graph
Definition: map_graph.hpp:313
size_t & source()
Get the source id of this edge.
Definition: map_graph.hpp:127
Implementation of 1-D std::vector like structure.
Definition: map_grid.hpp:94
auto vertex(openfpm::vector_key_iterator id) const -> const decltype(v.get(0))
operator to access the vertex
Definition: map_graph.hpp:566
V V_type
Vertex typedef.
Definition: map_graph.hpp:396
VertexList< V, Memory, grow_p, openfpm::vect_isel< V >::value >::container V_container
Object container for the vertex, for example can be encap<...> (map_grid or openfpm::vector) ...
Definition: map_graph.hpp:402