You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

cIGraph_components.c 4.2 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #include "igraph.h"
  2. #include "ruby.h"
  3. #include "cIGraph.h"
  4. /* call-seq:
  5. * graph.subcomponent(v,mode) -> Array
  6. *
  7. * Returns an Array of vertices that are in the same component as the vertex v.
  8. * mode defines the type of the component for directed graphs, possible
  9. * values: IGraph::OUT: the set of vertices reachable from the vertex,
  10. * IGraph::IN the set of vertices from which the vertex is reachable,
  11. * IGraph::ALL the graph is considered as an undirected graph. Note that
  12. * this is not the same as the union of the previous two.
  13. */
  14. VALUE cIGraph_subcomponent(VALUE self, VALUE v, VALUE mode){
  15. igraph_t *graph;
  16. igraph_neimode_t pmode = NUM2INT(mode);
  17. igraph_vector_t neis;
  18. int i;
  19. VALUE component = rb_ary_new();
  20. igraph_vector_init_int(&neis,0);
  21. Data_Get_Struct(self, igraph_t, graph);
  22. igraph_subcomponent(graph, &neis, cIGraph_get_vertex_id(self,v), pmode);
  23. for(i=0;i<igraph_vector_size(&neis);i++){
  24. rb_ary_push(component,cIGraph_get_vertex_object(self,VECTOR(neis)[i]));
  25. }
  26. igraph_vector_destroy(&neis);
  27. return component;
  28. }
  29. /* call-seq:
  30. * graph.subgraph(vs) -> IGraph
  31. *
  32. * Returns an IGraph object containing the vertices defined in the Array vs.
  33. */
  34. VALUE cIGraph_subgraph(VALUE self, VALUE vs){
  35. igraph_t *graph;
  36. igraph_t *n_graph = malloc(sizeof(igraph_t));
  37. igraph_vs_t vids;
  38. igraph_vector_t vidv;
  39. VALUE n_graph_obj;
  40. Data_Get_Struct(self, igraph_t, graph);
  41. //Convert an array of vertices to a vector of vertex ids
  42. igraph_vector_init_int(&vidv,0);
  43. cIGraph_vertex_arr_to_id_vec(self,vs,&vidv);
  44. //create vertex selector from the vecotr of ids
  45. igraph_vs_vector(&vids,&vidv);
  46. igraph_subgraph(graph,n_graph,vids);
  47. n_graph_obj = Data_Wrap_Struct(cIGraph, cIGraph_mark, cIGraph_free, n_graph);
  48. igraph_vector_destroy(&vidv);
  49. igraph_vs_destroy(&vids);
  50. return n_graph_obj;
  51. }
  52. /* call-seq:
  53. * graph.clusters(mode) -> Array
  54. *
  55. * Calculates the (weakly or strongly) connected components in a graph.
  56. * Returns an Array of Arrays of vertices. Each sub-Array is a graph component
  57. */
  58. VALUE cIGraph_clusters(VALUE self, VALUE mode){
  59. igraph_t *graph;
  60. igraph_vector_t membership;
  61. igraph_integer_t no;
  62. VALUE components;
  63. VALUE v,c;
  64. int i;
  65. igraph_vector_init_int(&membership,0);
  66. Data_Get_Struct(self, igraph_t, graph);
  67. igraph_clusters(graph, &membership, NULL, &no, NUM2INT(mode));
  68. components = rb_ary_new();
  69. for(i=0;i<no;i++){
  70. rb_ary_push(components,rb_ary_new());
  71. }
  72. for(i=0;i<igraph_vector_size(&membership);i++){
  73. v = cIGraph_get_vertex_object(self, i);
  74. c = rb_ary_entry(components,VECTOR(membership)[i]);
  75. rb_ary_push(c,v);
  76. }
  77. igraph_vector_destroy(&membership);
  78. return components;
  79. }
  80. /* call-seq:
  81. * graph.decompose(mode,maxcomp=-1,minelem=1) -> Array
  82. *
  83. * Create separate graph for each component of a graph. Returns an Array
  84. * of new IGraph object. mode specifies whether weakly and strongly connected
  85. * components are returned. Right now only the former is implemented. maxcomp
  86. * limits the number of components returned. Leave at the default -1 to return
  87. * all components. minelements specifies the minimum number of vertices a
  88. * component should contain before it is returned. Default 1 returns all
  89. * components.
  90. */
  91. VALUE cIGraph_decompose(int argc, VALUE *argv, VALUE self){
  92. igraph_t *graph;
  93. igraph_t *n_graph;
  94. igraph_vector_ptr_t components;
  95. VALUE mode,maxcomp, minelem, components_a;
  96. VALUE n_graph_obj;
  97. int i;
  98. rb_scan_args(argc,argv,"12", &mode, &maxcomp, &minelem);
  99. if(maxcomp == Qnil)
  100. maxcomp = INT2NUM(-1);
  101. if(minelem == Qnil)
  102. minelem = INT2NUM(1);
  103. igraph_vector_ptr_init(&components,0);
  104. Data_Get_Struct(self, igraph_t, graph);
  105. igraph_decompose(graph, &components, NUM2INT(mode), NUM2INT(maxcomp), NUM2INT(minelem));
  106. components_a = rb_ary_new();
  107. for(i=0; i<igraph_vector_ptr_size(&components); i++){
  108. n_graph = VECTOR(components)[i];
  109. n_graph_obj = Data_Wrap_Struct(cIGraph, cIGraph_mark, cIGraph_free, n_graph);
  110. rb_ary_push(components_a,n_graph_obj);
  111. }
  112. igraph_vector_ptr_destroy(&components);
  113. return components_a;
  114. }

Ruby binding for the igraph library.