From 1e0e9aa08ddb6bf7524f60e9bf1cf7527761e82c Mon Sep 17 00:00:00 2001 From: alexgutteridge Date: Wed, 15 Aug 2007 06:01:35 +0000 Subject: [PATCH] git-svn-id: http://igraph.rubyforge.org/svn/trunk@29 71f48855-0bbf-4aa5-930d-4df415e86613 --- ext/cIGraph.c | 6 ++ ext/cIGraph.h | 6 ++ ext/cIGraph_components.c | 121 ++++++++++++++++++++++++++++- ext/cIGraph_vertex_neighbourhood.c | 2 +- test/tc_components.rb | 61 ++++----------- test/test_all.rb | 2 + 6 files changed, 150 insertions(+), 48 deletions(-) diff --git a/ext/cIGraph.c b/ext/cIGraph.c index ab02281..52c0126 100644 --- a/ext/cIGraph.c +++ b/ext/cIGraph.c @@ -188,6 +188,9 @@ void Init_igraph(){ rb_define_const(cIGraph, "ALL", INT2NUM(3)); rb_define_const(cIGraph, "TOTAL", INT2NUM(4)); + rb_define_const(cIGraph, "WEAK", INT2NUM(1)); + rb_define_const(cIGraph, "STRONG", INT2NUM(2)); + rb_define_method(cIGraph, "[]", cIGraph_get_edge_attr, 2); /* in cIGraph_attribute_handler.c */ rb_define_method(cIGraph, "[]=", cIGraph_set_edge_attr, 3); /* in cIGraph_attribute_handler.c */ rb_define_alias (cIGraph, "get_edge_attr", "[]"); @@ -245,6 +248,9 @@ void Init_igraph(){ rb_define_alias (cIGraph, "neighborhood_graphs", "neighbourhood_graphs"); rb_define_method(cIGraph, "subcomponent", cIGraph_subcomponent, 2); /* in cIGraph_components.c */ + rb_define_method(cIGraph, "subgraph", cIGraph_subgraph, 1); /* in cIGraph_components.c */ + rb_define_method(cIGraph, "clusters", cIGraph_clusters, 1); /* in cIGraph_components.c */ + rb_define_method(cIGraph, "decompose", cIGraph_decompose, -1); /* in cIGraph_decompose.c */ rb_define_method(cIGraph, "topological_sorting", cIGraph_topological_sorting, 1); /* in cIGraph_topological_sort.c */ diff --git a/ext/cIGraph.h b/ext/cIGraph.h index fd0e8f5..8902973 100644 --- a/ext/cIGraph.h +++ b/ext/cIGraph.h @@ -86,6 +86,12 @@ VALUE cIGraph_neighborhood_size (VALUE self, VALUE from, VALUE order, VALUE mod VALUE cIGraph_neighborhood (VALUE self, VALUE from, VALUE order, VALUE mode); VALUE cIGraph_neighborhood_graphs(VALUE self, VALUE from, VALUE order, VALUE mode); +//Component functions +VALUE cIGraph_subcomponent(VALUE self, VALUE v, VALUE mode); +VALUE cIGraph_subgraph (VALUE self, VALUE vs); +VALUE cIGraph_clusters (VALUE self, VALUE mode); +VALUE cIGraph_decompose(int argc, VALUE *argv, VALUE self); + //Topological sorting VALUE cIGraph_topological_sorting(VALUE self, VALUE mode); diff --git a/ext/cIGraph_components.c b/ext/cIGraph_components.c index 2ef22ab..4199d1e 100644 --- a/ext/cIGraph_components.c +++ b/ext/cIGraph_components.c @@ -12,7 +12,7 @@ * IGraph::ALL the graph is considered as an undirected graph. Note that * this is not the same as the union of the previous two. */ -VALUE cIgraph_subcomponent(VALUE self, VALUE v, VALUE mode){ +VALUE cIGraph_subcomponent(VALUE self, VALUE v, VALUE mode){ igraph_t *graph; igraph_neimode_t pmode = NUM2INT(mode); @@ -24,7 +24,7 @@ VALUE cIgraph_subcomponent(VALUE self, VALUE v, VALUE mode){ Data_Get_Struct(self, igraph_t, graph); - igraph_subcomponent(graph, &neis, cIGraph_get_vertex_id(self,from), pmode); + igraph_subcomponent(graph, &neis, cIGraph_get_vertex_id(self,v), pmode); for(i=0;i IGraph + * + * Returns an IGraph object containing the vertices defined in the Array vs. + */ +VALUE cIGraph_subgraph(VALUE self, VALUE vs){ + + igraph_t *graph; + igraph_t *n_graph = malloc(sizeof(igraph_t)); + igraph_vs_t vids; + igraph_vector_t vidv; + + VALUE n_graph_obj; + + Data_Get_Struct(self, igraph_t, graph); + + //Convert an array of vertices to a vector of vertex ids + cIGraph_vertex_arr_to_id_vec(self,vs,&vidv); + //create vertex selector from the vecotr of ids + igraph_vs_vector(&vids,&vidv); + + igraph_subgraph(graph,n_graph,vids); + + n_graph_obj = Data_Wrap_Struct(cIGraph, cIGraph_mark, cIGraph_free, n_graph); + + igraph_vector_destroy(&vidv); + igraph_vs_destroy(&vids); + + return n_graph_obj; + +} + +/* call-seq: + * graph.clusters(mode) -> Array + * + * Calculates the (weakly or strongly) connected components in a graph. + * Returns an Array of Arrays of vertices. Each sub-Array is a graph component + */ +VALUE cIGraph_clusters(VALUE self, VALUE mode){ + + igraph_t *graph; + igraph_vector_t membership; + igraph_integer_t no; + VALUE components; + VALUE v,c; + int i; + + igraph_vector_init_int(&membership,0); + + Data_Get_Struct(self, igraph_t, graph); + + igraph_clusters(graph, &membership, NULL, &no, NUM2INT(mode)); + + components = rb_ary_new(); + for(i=0;i Array + * + * Create separate graph for each component of a graph. Returns an Array + * of new IGraph object. mode specifies whether weakly and strongly connected + * components are returned. Right now only the former is implemented. maxcomp + * limits the number of components returned. Leave at the default -1 to return + * all components. minelements specifies the minimum number of vertices a + * component should contain before it is returned. Default 1 returns all + * components. + */ +VALUE cIGraph_decompose(int argc, VALUE *argv, VALUE self){ + + igraph_t *graph; + igraph_t *n_graph; + igraph_vector_ptr_t components; + VALUE mode,maxcomp, minelem, components_a; + VALUE n_graph_obj; + int i; + + rb_scan_args(argc,argv,"12", &mode, &maxcomp, &minelem); + + if(maxcomp == Qnil) + maxcomp = INT2NUM(-1); + if(minelem == Qnil) + minelem = INT2NUM(1); + + igraph_vector_ptr_init(&components,0); + + Data_Get_Struct(self, igraph_t, graph); + + igraph_decompose(graph, &components, NUM2INT(mode), NUM2INT(maxcomp), NUM2INT(minelem)); + + components_a = rb_ary_new(); + + for(i=0; i