This commit is contained in:
parent
f475b5f72b
commit
d5deff9280
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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_vector_size(&neis);i++){
|
||||
rb_ary_push(component,cIGraph_get_vertex_object(self,VECTOR(neis)[i]));
|
||||
|
@ -35,3 +35,120 @@ VALUE cIgraph_subcomponent(VALUE self, VALUE v, VALUE mode){
|
|||
return component;
|
||||
|
||||
}
|
||||
|
||||
/* call-seq:
|
||||
* graph.subgraph(vs) -> 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<no;i++){
|
||||
rb_ary_push(components,rb_ary_new());
|
||||
}
|
||||
|
||||
for(i=0;i<igraph_vector_size(&membership);i++){
|
||||
v = cIGraph_get_vertex_object(self, i);
|
||||
c = rb_ary_entry(components,VECTOR(membership)[i]);
|
||||
rb_ary_push(c,v);
|
||||
}
|
||||
|
||||
igraph_vector_destroy(&membership);
|
||||
|
||||
return components;
|
||||
|
||||
}
|
||||
|
||||
/* call-seq:
|
||||
* graph.decompose(mode,maxcomp=-1,minelem=1) -> 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<igraph_vector_ptr_size(&components); i++){
|
||||
n_graph = VECTOR(components)[i];
|
||||
n_graph_obj = Data_Wrap_Struct(cIGraph, cIGraph_mark, cIGraph_free, n_graph);
|
||||
rb_ary_push(components_a,n_graph_obj);
|
||||
}
|
||||
|
||||
igraph_vector_ptr_destroy(&components);
|
||||
|
||||
return components_a;
|
||||
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ VALUE cIGraph_neighborhood_graphs(VALUE self, VALUE from, VALUE order, VALUE mod
|
|||
|
||||
for(i=0; i<igraph_vector_ptr_size(&res); i++){
|
||||
n_graph = VECTOR(res)[i];
|
||||
n_graph_obj = Data_Wrap_Struct(cIGraph, 0, cIGraph_free, n_graph);
|
||||
n_graph_obj = Data_Wrap_Struct(cIGraph, cIGraph_mark, cIGraph_free, n_graph);
|
||||
rb_ary_push(result,n_graph_obj);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,53 +2,24 @@ require 'test/unit'
|
|||
require 'igraph'
|
||||
|
||||
class TestGraph < Test::Unit::TestCase
|
||||
def test_graph_size
|
||||
assert_equal 4, IGraph.new([1,2,3,4],true).vcount
|
||||
assert_equal 2, IGraph.new([1,2,3,4],true).ecount
|
||||
def test_subcomponent
|
||||
g = IGraph.new([1,2,3,4])
|
||||
assert_equal [1,2], g.subcomponent(1,IGraph::ALL)
|
||||
end
|
||||
|
||||
def test_eid_get_edge
|
||||
assert_nothing_raised do
|
||||
IGraph.new(['A','B','C','D'],true).get_eid('A','B')
|
||||
end
|
||||
graph = IGraph.new(['A','B','C','D'],true)
|
||||
eid1 = graph.get_eid('A','B')
|
||||
eid2 = graph.get_eid('C','D')
|
||||
assert_equal ['A','B'], graph.edge(eid1)
|
||||
assert_equal ['C','D'], graph.edge(eid2);
|
||||
assert_not_equal eid1,eid2
|
||||
def test_subgraph
|
||||
g = IGraph.new([1,2,3,4])
|
||||
h = g.subgraph([1,2])
|
||||
assert_equal 2, h.vcount
|
||||
assert_equal [1,2], h.vertices
|
||||
end
|
||||
|
||||
def test_neighbours
|
||||
assert_nothing_raised do
|
||||
IGraph.new(['A','B','C','D'],true).neighbors('A',IGraph::ALL)
|
||||
end
|
||||
graph = IGraph.new(['A','B','C','D'],true)
|
||||
assert_equal ['B'], graph.neighbors('A',IGraph::ALL)
|
||||
assert_equal ['D'], graph.neighbors('C',IGraph::ALL)
|
||||
def test_clusters
|
||||
g = IGraph.new([1,2,3,4])
|
||||
assert_equal 2, g.clusters(IGraph::WEAK).length
|
||||
assert_equal [1,2], g.clusters(IGraph::WEAK)[0]
|
||||
end
|
||||
|
||||
def test_adjacent
|
||||
assert_nothing_raised do
|
||||
IGraph.new(['A','B','C','D'],true).adjacent('A',IGraph::ALL)
|
||||
end
|
||||
graph = IGraph.new(['A','B','C','D'],true)
|
||||
eid1 = graph.get_eid('A','B')
|
||||
eid2 = graph.adjacent('A',IGraph::ALL)[0]
|
||||
assert_equal eid1, eid2
|
||||
end
|
||||
|
||||
def test_directed
|
||||
assert IGraph.new(['A','B','C','D'],true).is_directed?
|
||||
assert !(IGraph.new(['A','B','C','D'],false).is_directed?)
|
||||
end
|
||||
|
||||
def test_degree
|
||||
graph = IGraph.new(['A','B','C','D'],true)
|
||||
assert_equal [1], graph.degree(['A'], IGraph::ALL,true)
|
||||
assert_equal [1,1],graph.degree(['A','B'],IGraph::ALL,true)
|
||||
assert_raises IGraphError do
|
||||
graph.degree('A',IGraph::ALL,true)
|
||||
end
|
||||
def test_decompose
|
||||
g = IGraph.new([1,2,3,4])
|
||||
assert_equal 2, g.decompose(IGraph::WEAK).length
|
||||
assert_equal [1,2], g.decompose(IGraph::WEAK)[0].vertices
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,6 +9,8 @@ require 'tc_selectors'
|
|||
require 'tc_add_delete'
|
||||
require 'tc_basic_query'
|
||||
require 'tc_basic_properties'
|
||||
require 'tc_centrality'
|
||||
require 'tc_components'
|
||||
require 'tc_copy'
|
||||
require 'tc_error_handling'
|
||||
require 'tc_file_read_write'
|
||||
|
|
Loading…
Reference in New Issue