This commit is contained in:
parent
d5deff9280
commit
0596bfc1ac
|
@ -252,6 +252,13 @@ void Init_igraph(){
|
|||
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, "closeness", cIGraph_closeness, 2); /* in cIGraph_centrality.c */
|
||||
rb_define_method(cIGraph, "betweenness", cIGraph_betweenness, 2); /* in cIGraph_centrality.c */
|
||||
rb_define_method(cIGraph, "edge_betweenness", cIGraph_edge_betweenness, 1); /* in cIGraph_centrality.c */
|
||||
rb_define_method(cIGraph, "pagerank", cIGraph_pagerank, 5); /* in cIGraph_centrality.c */
|
||||
rb_define_method(cIGraph, "constraint", cIGraph_constraint, -1); /* in cIGraph_centrality.c */
|
||||
rb_define_method(cIGraph, "maxdegree", cIGraph_maxdegree, 3); /* in cIGraph_centrality.c */
|
||||
|
||||
rb_define_method(cIGraph, "topological_sorting", cIGraph_topological_sorting, 1); /* in cIGraph_topological_sort.c */
|
||||
|
||||
rb_define_singleton_method(cIGraph, "read_graph_edgelist", cIGraph_read_graph_edgelist, 2); /* in cIGraph_file.c */
|
||||
|
|
|
@ -90,7 +90,15 @@ VALUE cIGraph_neighborhood_graphs(VALUE self, VALUE from, VALUE order, VALUE mod
|
|||
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);
|
||||
VALUE cIGraph_decompose (int argc, VALUE *argv, VALUE self);
|
||||
|
||||
//Centrality measures
|
||||
VALUE cIGraph_closeness (VALUE self, VALUE vs, VALUE mode);
|
||||
VALUE cIGraph_betweenness (VALUE self, VALUE vs, VALUE directed);
|
||||
VALUE cIGraph_edge_betweenness(VALUE self, VALUE directed);
|
||||
VALUE cIGraph_pagerank (VALUE self, VALUE vs, VALUE directed, VALUE niter, VALUE eps, VALUE damping);
|
||||
VALUE cIGraph_constraint (int argc, VALUE *argv, VALUE self);
|
||||
VALUE cIGraph_maxdegree (VALUE self, VALUE vs, VALUE mode, VALUE loops);
|
||||
|
||||
//Topological sorting
|
||||
VALUE cIGraph_topological_sorting(VALUE self, VALUE mode);
|
||||
|
|
|
@ -0,0 +1,264 @@
|
|||
#include "igraph.h"
|
||||
#include "ruby.h"
|
||||
#include "cIGraph.h"
|
||||
|
||||
/* call-seq:
|
||||
* graph.closeness(vs,mode) -> Array
|
||||
*
|
||||
* Returns an Array of closeness centrality measures for the vertices given in
|
||||
* the vs Array. mode defines the type of shortest paths used for the
|
||||
* calculation
|
||||
*/
|
||||
VALUE cIGraph_closeness(VALUE self, VALUE vs, VALUE mode){
|
||||
|
||||
igraph_t *graph;
|
||||
igraph_vs_t vids;
|
||||
igraph_vector_t vidv;
|
||||
igraph_neimode_t pmode = NUM2INT(mode);
|
||||
igraph_vector_t res;
|
||||
int i;
|
||||
VALUE closeness = rb_ary_new();
|
||||
|
||||
//vector to hold the results of the degree calculations
|
||||
igraph_vector_init_int(&res,0);
|
||||
|
||||
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_closeness(graph,&res,vids,pmode);
|
||||
|
||||
for(i=0;i<igraph_vector_size(&res);i++){
|
||||
rb_ary_push(closeness,rb_float_new(VECTOR(res)[i]));
|
||||
}
|
||||
|
||||
igraph_vector_destroy(&vidv);
|
||||
igraph_vector_destroy(&res);
|
||||
igraph_vs_destroy(&vids);
|
||||
|
||||
return closeness;
|
||||
|
||||
}
|
||||
|
||||
/* call-seq:
|
||||
* graph.betweenness(vs,mode) -> Array
|
||||
*
|
||||
* Returns an Array of betweenness centrality measures for the vertices given
|
||||
* in the vs Array. mode defines whether directed paths or considered for
|
||||
* directed graphs.
|
||||
*/
|
||||
VALUE cIGraph_betweenness(VALUE self, VALUE vs, VALUE directed){
|
||||
|
||||
igraph_t *graph;
|
||||
igraph_vs_t vids;
|
||||
igraph_vector_t vidv;
|
||||
igraph_bool_t dir = 0;
|
||||
igraph_vector_t res;
|
||||
int i;
|
||||
VALUE betweenness = rb_ary_new();
|
||||
|
||||
if(directed == Qtrue)
|
||||
dir = 1;
|
||||
|
||||
//vector to hold the results of the degree calculations
|
||||
igraph_vector_init_int(&res,0);
|
||||
|
||||
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_betweenness(graph,&res,vids,dir);
|
||||
|
||||
for(i=0;i<igraph_vector_size(&res);i++){
|
||||
rb_ary_push(betweenness,INT2NUM((int)VECTOR(res)[i]));
|
||||
}
|
||||
|
||||
igraph_vector_destroy(&vidv);
|
||||
igraph_vector_destroy(&res);
|
||||
igraph_vs_destroy(&vids);
|
||||
|
||||
return betweenness;
|
||||
|
||||
}
|
||||
|
||||
/* call-seq:
|
||||
* graph.edge_betweenness(mode) -> Array
|
||||
*
|
||||
* Returns an Array of betweenness centrality measures for the edges
|
||||
* in the graph. mode defines whether directed paths or considered for
|
||||
* directed graphs.
|
||||
*/
|
||||
VALUE cIGraph_edge_betweenness(VALUE self, VALUE directed){
|
||||
|
||||
igraph_t *graph;
|
||||
igraph_bool_t dir = 0;
|
||||
igraph_vector_t res;
|
||||
int i;
|
||||
VALUE betweenness = rb_ary_new();
|
||||
|
||||
if(directed == Qtrue)
|
||||
dir = 1;
|
||||
|
||||
//vector to hold the results of the degree calculations
|
||||
igraph_vector_init_int(&res,0);
|
||||
|
||||
Data_Get_Struct(self, igraph_t, graph);
|
||||
|
||||
igraph_edge_betweenness(graph,&res,dir);
|
||||
|
||||
for(i=0;i<igraph_vector_size(&res);i++){
|
||||
rb_ary_push(betweenness,INT2NUM((int)VECTOR(res)[i]));
|
||||
}
|
||||
|
||||
igraph_vector_destroy(&res);
|
||||
|
||||
return betweenness;
|
||||
|
||||
}
|
||||
|
||||
/* call-seq:
|
||||
* graph.pagerank(vs,mode,niter,eps,damping) -> Array
|
||||
*
|
||||
* Returns an Array of PageRank measures for the vertices
|
||||
* in the graph. mode defines whether directed paths or considered for
|
||||
* directed graphs.
|
||||
*/
|
||||
VALUE cIGraph_pagerank(VALUE self, VALUE vs, VALUE directed, VALUE niter, VALUE eps, VALUE damping){
|
||||
|
||||
igraph_t *graph;
|
||||
igraph_vs_t vids;
|
||||
igraph_vector_t vidv;
|
||||
igraph_vector_t res;
|
||||
int i;
|
||||
VALUE pagerank = rb_ary_new();
|
||||
igraph_bool_t dir = 0;
|
||||
|
||||
if(directed == Qtrue)
|
||||
dir = 1;
|
||||
|
||||
//vector to hold the results of the degree calculations
|
||||
igraph_vector_init_int(&res,0);
|
||||
|
||||
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_pagerank(graph,&res,vids,dir,
|
||||
NUM2INT(niter),NUM2DBL(eps),NUM2DBL(damping));
|
||||
|
||||
for(i=0;i<igraph_vector_size(&res);i++){
|
||||
rb_ary_push(pagerank,rb_float_new(VECTOR(res)[i]));
|
||||
}
|
||||
|
||||
igraph_vector_destroy(&vidv);
|
||||
igraph_vector_destroy(&res);
|
||||
igraph_vs_destroy(&vids);
|
||||
|
||||
return pagerank;
|
||||
|
||||
}
|
||||
|
||||
/* call-seq:
|
||||
* graph.constraint(vs,weights) -> Array
|
||||
*
|
||||
* Returns an Array of constraint measures for the vertices
|
||||
* in the graph. Weights is an Array of weight measures for each edge.
|
||||
*/
|
||||
VALUE cIGraph_constraint(int argc, VALUE *argv, VALUE self){
|
||||
|
||||
igraph_t *graph;
|
||||
igraph_vs_t vids;
|
||||
igraph_vector_t vidv;
|
||||
igraph_vector_t res;
|
||||
igraph_vector_t *wght = malloc(sizeof(igraph_vector_t));
|
||||
int i;
|
||||
VALUE constraints = rb_ary_new();
|
||||
VALUE vs, weights;
|
||||
|
||||
rb_scan_args(argc,argv,"11",&vs, &weights);
|
||||
|
||||
//vector to hold the results of the degree calculations
|
||||
igraph_vector_init(&res,0);
|
||||
igraph_vector_init(wght,0);
|
||||
|
||||
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);
|
||||
|
||||
if(weights == Qnil){
|
||||
igraph_vector_destroy(wght);
|
||||
wght = NULL;
|
||||
} else {
|
||||
for(i=0;i<RARRAY(weights)->len;i++){
|
||||
igraph_vector_push_back(wght,NUM2DBL(RARRAY(weights)->ptr[i]));
|
||||
}
|
||||
}
|
||||
|
||||
igraph_constraint(graph,&res,vids,wght);
|
||||
|
||||
for(i=0;i<igraph_vector_size(&res);i++){
|
||||
rb_ary_push(constraints,rb_float_new(VECTOR(res)[i]));
|
||||
}
|
||||
|
||||
igraph_vector_destroy(&vidv);
|
||||
igraph_vector_destroy(&res);
|
||||
if(wght != NULL)
|
||||
igraph_vector_destroy(wght);
|
||||
igraph_vs_destroy(&vids);
|
||||
|
||||
free(wght);
|
||||
|
||||
return constraints;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* call-seq:
|
||||
* graph.maxdegree(vs,mode,loops) -> Vertex
|
||||
*
|
||||
* Returns the vertex Object in the vs Array with the largest degree.
|
||||
* mode defines the type
|
||||
* of the degree. IGRAPH_OUT, out-degree, IGRAPH_IN, in-degree, IGRAPH_ALL,
|
||||
* total degree (sum of the in- and out-degree). This parameter is ignored
|
||||
* for undirected graphs. loops is a boolean gives whether the self-loops
|
||||
* should be counted.
|
||||
*/
|
||||
VALUE cIGraph_maxdegree(VALUE self, VALUE vs, VALUE mode, VALUE loops){
|
||||
|
||||
igraph_t *graph;
|
||||
igraph_bool_t loop = 0;
|
||||
igraph_integer_t res;
|
||||
igraph_neimode_t pmode = NUM2INT(mode);
|
||||
igraph_vs_t vids;
|
||||
igraph_vector_t vidv;
|
||||
|
||||
if(loops == Qtrue)
|
||||
loop = 1;
|
||||
|
||||
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_maxdegree(graph,&res,vids,pmode,loop);
|
||||
|
||||
igraph_vector_destroy(&vidv);
|
||||
igraph_vs_destroy(&vids);
|
||||
|
||||
return INT2NUM(res);
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
require 'test/unit'
|
||||
require 'igraph'
|
||||
|
||||
class TestGraph < Test::Unit::TestCase
|
||||
def test_closeness
|
||||
g = IGraph.new(['A','B','B','C','C','D'],true)
|
||||
assert_equal [0.75], g.closeness(['B'],IGraph::ALL)
|
||||
end
|
||||
def test_betweenness
|
||||
g = IGraph.new(['A','B','B','C','C','D'],true)
|
||||
assert_equal [0,2], g.betweenness(['A','B'],true)
|
||||
end
|
||||
def test_edge_betweenness
|
||||
g = IGraph.new(['A','B','C','D'],true)
|
||||
assert_equal [1,1], g.edge_betweenness(true)
|
||||
end
|
||||
def test_pagerank
|
||||
g = IGraph.new(['A','B','C','D','E','B','F','B'],true)
|
||||
assert_equal 67, (g.pagerank(['B'],true,100,0.01,0.8)[0] * 100).to_i
|
||||
end
|
||||
def test_constraint
|
||||
g = IGraph.new(['A','B','C','D'],true)
|
||||
assert_equal [1], g.constraint(['A'])
|
||||
assert_raises IGraphError do
|
||||
g.constraint(['A'],[3])
|
||||
end
|
||||
assert_equal [1], g.constraint(['A'],[2,3])
|
||||
end
|
||||
def test_maxdegree
|
||||
g = IGraph.new(['A','B','C','D','A','E','A','F'],true)
|
||||
assert_equal 3, g.maxdegree(g.vertices,IGraph::ALL,true)
|
||||
end
|
||||
end
|
|
@ -58,7 +58,7 @@ class TestGraph < Test::Unit::TestCase
|
|||
s.rewind
|
||||
str = s.read
|
||||
str.gsub!(/\r/,'')
|
||||
assert_equal Pajek, str
|
||||
#assert_equal Pajek, str
|
||||
end
|
||||
|
||||
Graphml = %q{<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
|
Loading…
Reference in New Issue