git-svn-id: http://igraph.rubyforge.org/svn/trunk@28 71f48855-0bbf-4aa5-930d-4df415e86613
This commit is contained in:
parent
6daa70a03f
commit
1a93b67a24
|
@ -244,6 +244,8 @@ void Init_igraph(){
|
||||||
rb_define_alias (cIGraph, "neighborhood", "neighbourhood");
|
rb_define_alias (cIGraph, "neighborhood", "neighbourhood");
|
||||||
rb_define_alias (cIGraph, "neighborhood_graphs", "neighbourhood_graphs");
|
rb_define_alias (cIGraph, "neighborhood_graphs", "neighbourhood_graphs");
|
||||||
|
|
||||||
|
rb_define_method(cIGraph, "subcomponent", cIGraph_subcomponent, 2); /* in cIGraph_components.c */
|
||||||
|
|
||||||
rb_define_method(cIGraph, "topological_sorting", cIGraph_topological_sorting, 1); /* in cIGraph_topological_sort.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 */
|
rb_define_singleton_method(cIGraph, "read_graph_edgelist", cIGraph_read_graph_edgelist, 2); /* in cIGraph_file.c */
|
||||||
|
|
|
@ -181,7 +181,7 @@ int cIGraph_attribute_add_vertices(igraph_t *graph, long int nv, igraph_vector_p
|
||||||
VALUE values;
|
VALUE values;
|
||||||
|
|
||||||
if(attr){
|
if(attr){
|
||||||
if(((igraph_i_attribute_record_t*)VECTOR(*attr)[0])->type == IGRAPH_ATTRIBUTE_PY_OBJECT){
|
if(igraph_vector_ptr_size(attr) > 0 && ((igraph_i_attribute_record_t*)VECTOR(*attr)[0])->type == IGRAPH_ATTRIBUTE_PY_OBJECT){
|
||||||
|
|
||||||
values = (VALUE)((igraph_i_attribute_record_t*)VECTOR(*attr)[0])->value;
|
values = (VALUE)((igraph_i_attribute_record_t*)VECTOR(*attr)[0])->value;
|
||||||
Check_Type(values, T_ARRAY);
|
Check_Type(values, T_ARRAY);
|
||||||
|
@ -196,6 +196,12 @@ int cIGraph_attribute_add_vertices(igraph_t *graph, long int nv, igraph_vector_p
|
||||||
igraph_i_attribute_record_t *attr_rec;
|
igraph_i_attribute_record_t *attr_rec;
|
||||||
char *s;
|
char *s;
|
||||||
record = rb_hash_new();
|
record = rb_hash_new();
|
||||||
|
|
||||||
|
//For when no attributes are given
|
||||||
|
if(igraph_vector_ptr_size(attr) == 0){
|
||||||
|
record = INT2NUM(i+1);
|
||||||
|
}
|
||||||
|
|
||||||
for (j=0; j<igraph_vector_ptr_size(attr); j++) {
|
for (j=0; j<igraph_vector_ptr_size(attr); j++) {
|
||||||
VALUE key;
|
VALUE key;
|
||||||
VALUE value;
|
VALUE value;
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
#include "igraph.h"
|
||||||
|
#include "ruby.h"
|
||||||
|
#include "cIGraph.h"
|
||||||
|
|
||||||
|
/* call-seq:
|
||||||
|
* graph.subcomponent(v,mode) -> Array
|
||||||
|
*
|
||||||
|
* Returns an Array of vertices that are in the same component as the vertex v.
|
||||||
|
* mode defines the type of the component for directed graphs, possible
|
||||||
|
* values: IGraph::OUT: the set of vertices reachable from the vertex,
|
||||||
|
* IGraph::IN the set of vertices from which the vertex is reachable,
|
||||||
|
* 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){
|
||||||
|
|
||||||
|
igraph_t *graph;
|
||||||
|
igraph_neimode_t pmode = NUM2INT(mode);
|
||||||
|
igraph_vector_t neis;
|
||||||
|
int i;
|
||||||
|
VALUE component = rb_ary_new();
|
||||||
|
|
||||||
|
igraph_vector_init_int(&neis,0);
|
||||||
|
|
||||||
|
Data_Get_Struct(self, igraph_t, graph);
|
||||||
|
|
||||||
|
igraph_subcomponent(graph, &neis, cIGraph_get_vertex_id(self,from), pmode);
|
||||||
|
|
||||||
|
for(i=0;i<igraph_vector_size(&neis);i++){
|
||||||
|
rb_ary_push(component,cIGraph_get_vertex_object(self,VECTOR(neis)[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
igraph_vector_destroy(&neis);
|
||||||
|
|
||||||
|
return component;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,176 @@
|
||||||
|
#include "igraph.h"
|
||||||
|
#include "ruby.h"
|
||||||
|
#include "cIGraph.h"
|
||||||
|
|
||||||
|
/* call-seq:
|
||||||
|
* IGraph.read_graph_edgelist(file,mode) -> IGraph
|
||||||
|
*
|
||||||
|
* Reads an edge list from a File (or any IO) and creates a graph.
|
||||||
|
*
|
||||||
|
* This format is simply a series of even number integers separated by
|
||||||
|
* whitespace. The one edge (ie. two integers) per line format is thus not
|
||||||
|
* required (but recommended for readability). Edges of directed graphs are
|
||||||
|
* assumed to be in from, to order.
|
||||||
|
*/
|
||||||
|
VALUE cIGraph_read_graph_edgelist(VALUE self, VALUE file, VALUE directed){
|
||||||
|
|
||||||
|
VALUE string;
|
||||||
|
FILE *stream;
|
||||||
|
VALUE new_graph;
|
||||||
|
VALUE v_ary;
|
||||||
|
igraph_t *graph;
|
||||||
|
igraph_bool_t directed_b = 0;
|
||||||
|
|
||||||
|
igraph_vs_t vs;
|
||||||
|
igraph_vit_t vit;
|
||||||
|
|
||||||
|
int vid;
|
||||||
|
|
||||||
|
if(directed)
|
||||||
|
directed_b = 1;
|
||||||
|
|
||||||
|
new_graph = cIGraph_alloc(cIGraph);
|
||||||
|
Data_Get_Struct(new_graph, igraph_t, graph);
|
||||||
|
|
||||||
|
string = rb_funcall(file, rb_intern("read"), 0);
|
||||||
|
stream = fmemopen(RSTRING(string)->ptr,RSTRING(string)->len, "r");
|
||||||
|
|
||||||
|
igraph_read_graph_edgelist(graph, stream, 0, directed_b);
|
||||||
|
|
||||||
|
fclose(stream);
|
||||||
|
|
||||||
|
igraph_vs_all(&vs);
|
||||||
|
igraph_vit_create(graph, vs, &vit);
|
||||||
|
|
||||||
|
v_ary = ((VALUE*)graph->attr)[0];
|
||||||
|
|
||||||
|
while (!IGRAPH_VIT_END(vit)) {
|
||||||
|
vid = IGRAPH_VIT_GET(vit);
|
||||||
|
rb_ary_push(v_ary,INT2NUM(vid));
|
||||||
|
IGRAPH_VIT_NEXT(vit);
|
||||||
|
}
|
||||||
|
|
||||||
|
igraph_vit_destroy(&vit);
|
||||||
|
igraph_vs_destroy(&vs);
|
||||||
|
|
||||||
|
return new_graph;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* call-seq:
|
||||||
|
* graph.write_graph_edgelist(file) -> Integer
|
||||||
|
*
|
||||||
|
* Writes an edge list to an IO
|
||||||
|
*
|
||||||
|
* This format is simply a series of even number integers separated by
|
||||||
|
* whitespace. The one edge (ie. two integers) per line format is thus not
|
||||||
|
* required (but recommended for readability). Edges of directed graphs are
|
||||||
|
* assumed to be in from, to order.
|
||||||
|
*/
|
||||||
|
VALUE cIGraph_write_graph_edgelist(VALUE self, VALUE file){
|
||||||
|
|
||||||
|
char *buf;
|
||||||
|
size_t size;
|
||||||
|
FILE *stream;
|
||||||
|
igraph_t *graph;
|
||||||
|
int e;
|
||||||
|
|
||||||
|
Data_Get_Struct(self, igraph_t, graph);
|
||||||
|
|
||||||
|
stream = open_memstream(&buf,&size);
|
||||||
|
e = igraph_write_graph_edgelist(graph, stream);
|
||||||
|
fflush(stream);
|
||||||
|
|
||||||
|
rb_funcall(file, rb_intern("write"), 1, rb_str_new(buf,size));
|
||||||
|
|
||||||
|
fclose(stream);
|
||||||
|
|
||||||
|
return e;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE cIGraph_read_graph_graphml(VALUE self, VALUE file, VALUE index){
|
||||||
|
|
||||||
|
VALUE string;
|
||||||
|
FILE *stream;
|
||||||
|
VALUE new_graph;
|
||||||
|
igraph_t *graph;
|
||||||
|
|
||||||
|
new_graph = cIGraph_alloc(cIGraph);
|
||||||
|
Data_Get_Struct(new_graph, igraph_t, graph);
|
||||||
|
|
||||||
|
string = rb_funcall(file, rb_intern("read"), 0);
|
||||||
|
stream = fmemopen(RSTRING(string)->ptr,RSTRING(string)->len, "r");
|
||||||
|
|
||||||
|
igraph_read_graph_graphml(graph, stream, NUM2INT(index));
|
||||||
|
|
||||||
|
fclose(stream);
|
||||||
|
|
||||||
|
return new_graph;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE cIGraph_write_graph_graphml(VALUE self, VALUE file){
|
||||||
|
|
||||||
|
char *buf;
|
||||||
|
size_t size;
|
||||||
|
FILE *stream;
|
||||||
|
igraph_t *graph;
|
||||||
|
int e;
|
||||||
|
|
||||||
|
Data_Get_Struct(self, igraph_t, graph);
|
||||||
|
|
||||||
|
stream = open_memstream(&buf,&size);
|
||||||
|
e = igraph_write_graph_graphml(graph, stream);
|
||||||
|
fflush(stream);
|
||||||
|
|
||||||
|
rb_funcall(file, rb_intern("write"), 1, rb_str_new(buf,size));
|
||||||
|
|
||||||
|
fclose(stream);
|
||||||
|
|
||||||
|
return e;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE cIGraph_read_graph_pajek(VALUE self, VALUE file){
|
||||||
|
|
||||||
|
VALUE string;
|
||||||
|
FILE *stream;
|
||||||
|
VALUE new_graph;
|
||||||
|
igraph_t *graph;
|
||||||
|
|
||||||
|
new_graph = cIGraph_alloc(cIGraph);
|
||||||
|
Data_Get_Struct(new_graph, igraph_t, graph);
|
||||||
|
|
||||||
|
string = rb_funcall(file, rb_intern("read"), 0);
|
||||||
|
stream = fmemopen(RSTRING(string)->ptr,RSTRING(string)->len, "r");
|
||||||
|
|
||||||
|
igraph_read_graph_pajek(graph, stream);
|
||||||
|
|
||||||
|
fclose(stream);
|
||||||
|
|
||||||
|
return new_graph;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE cIGraph_write_graph_pajek(VALUE self, VALUE file){
|
||||||
|
|
||||||
|
char *buf;
|
||||||
|
size_t size;
|
||||||
|
FILE *stream;
|
||||||
|
igraph_t *graph;
|
||||||
|
int e;
|
||||||
|
|
||||||
|
Data_Get_Struct(self, igraph_t, graph);
|
||||||
|
|
||||||
|
stream = open_memstream(&buf,&size);
|
||||||
|
e = igraph_write_graph_pajek(graph, stream);
|
||||||
|
fflush(stream);
|
||||||
|
|
||||||
|
rb_funcall(file, rb_intern("write"), 1, rb_str_new(buf,size));
|
||||||
|
|
||||||
|
fclose(stream);
|
||||||
|
|
||||||
|
return e;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
#include "igraph.h"
|
||||||
|
#include "ruby.h"
|
||||||
|
#include "cIGraph.h"
|
||||||
|
|
||||||
|
/* call-seq:
|
||||||
|
* graph.layout_random -> IGraphMatrix
|
||||||
|
*
|
||||||
|
* Returns a random layout
|
||||||
|
*/
|
||||||
|
VALUE cIGraph_layout_random(VALUE self){
|
||||||
|
|
||||||
|
igraph_t *graph;
|
||||||
|
igraph_matrix_t *res = malloc(sizeof(igraph_matrix_t));
|
||||||
|
|
||||||
|
Data_Get_Struct(self, igraph_t, graph);
|
||||||
|
|
||||||
|
igraph_matrix_init(res,0,0);
|
||||||
|
igraph_layout_random(graph,res);
|
||||||
|
|
||||||
|
return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE cIGraph_layout_circle(VALUE self){
|
||||||
|
|
||||||
|
igraph_t *graph;
|
||||||
|
igraph_matrix_t *res = malloc(sizeof(igraph_matrix_t));
|
||||||
|
|
||||||
|
Data_Get_Struct(self, igraph_t, graph);
|
||||||
|
|
||||||
|
igraph_matrix_init(res,0,0);
|
||||||
|
igraph_layout_circle(graph,res);
|
||||||
|
|
||||||
|
return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE cIGraph_layout_fruchterman_reingold(VALUE self,
|
||||||
|
VALUE niter,
|
||||||
|
VALUE maxdelta,
|
||||||
|
VALUE area,
|
||||||
|
VALUE coolexp,
|
||||||
|
VALUE repulserad,
|
||||||
|
VALUE use_seed){
|
||||||
|
|
||||||
|
igraph_t *graph;
|
||||||
|
igraph_matrix_t *res = malloc(sizeof(igraph_matrix_t));
|
||||||
|
|
||||||
|
Data_Get_Struct(self, igraph_t, graph);
|
||||||
|
|
||||||
|
igraph_matrix_init(res,0,0);
|
||||||
|
igraph_layout_fruchterman_reingold(graph,res,
|
||||||
|
NUM2INT(niter),
|
||||||
|
NUM2DBL(maxdelta),
|
||||||
|
NUM2DBL(area),
|
||||||
|
NUM2DBL(coolexp),
|
||||||
|
NUM2DBL(repulserad),
|
||||||
|
use_seed == Qtrue ? 1: 0);
|
||||||
|
|
||||||
|
return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,199 @@
|
||||||
|
#include "igraph.h"
|
||||||
|
#include "ruby.h"
|
||||||
|
#include "cIGraph.h"
|
||||||
|
|
||||||
|
//Classes
|
||||||
|
VALUE cIGraphMatrix;
|
||||||
|
|
||||||
|
void cIGraph_matrix_free(void *p){
|
||||||
|
igraph_matrix_destroy(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE cIGraph_matrix_alloc(VALUE klass){
|
||||||
|
|
||||||
|
igraph_matrix_t *m = malloc(sizeof(igraph_matrix_t));
|
||||||
|
VALUE obj;
|
||||||
|
|
||||||
|
igraph_matrix_init(m, 0, 0);
|
||||||
|
|
||||||
|
obj = Data_Wrap_Struct(klass, 0, cIGraph_matrix_free, m);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Document-method: initialize_copy
|
||||||
|
*
|
||||||
|
* Internal method for copying IGraph objects.
|
||||||
|
*/
|
||||||
|
VALUE cIGraph_matrix_init_copy(VALUE copy, VALUE orig){
|
||||||
|
|
||||||
|
igraph_matrix_t *orig_m;
|
||||||
|
igraph_matrix_t *copy_m;
|
||||||
|
|
||||||
|
if (copy == orig)
|
||||||
|
return copy;
|
||||||
|
|
||||||
|
if(TYPE(orig) != T_DATA || RDATA(orig)->dfree != (RUBY_DATA_FUNC)cIGraph_free){
|
||||||
|
rb_raise(rb_eTypeError, "Wrong argument type.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Data_Get_Struct(copy, igraph_matrix_t, copy_m);
|
||||||
|
Data_Get_Struct(orig, igraph_matrix_t, orig_m);
|
||||||
|
|
||||||
|
igraph_matrix_copy(copy_m,orig_m);
|
||||||
|
|
||||||
|
return copy;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* call-seq:
|
||||||
|
* IGraphMatrix[[x,y,...],...] -> IGraphMatrix
|
||||||
|
*
|
||||||
|
* IGraphMatrix[[1,2],[3,4]]
|
||||||
|
*
|
||||||
|
* Creates a graph with four vertices. Vertex 1 is connected to vertex 2.
|
||||||
|
* Vertex 3 is connected to vertex 4.
|
||||||
|
*/
|
||||||
|
|
||||||
|
VALUE cIGraph_matrix_initialize(int argc, VALUE *argv, VALUE self){
|
||||||
|
|
||||||
|
igraph_matrix_t *m;
|
||||||
|
VALUE rows;
|
||||||
|
int nrows;
|
||||||
|
int ncols;
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
rb_scan_args(argc,argv,"0*", &rows);
|
||||||
|
|
||||||
|
Data_Get_Struct(self, igraph_matrix_t, m);
|
||||||
|
|
||||||
|
nrows = RARRAY(rows)->len;
|
||||||
|
ncols = RARRAY(RARRAY(rows)->ptr[0])->len;
|
||||||
|
|
||||||
|
igraph_matrix_resize(m, nrows, ncols);
|
||||||
|
|
||||||
|
//Loop through rows
|
||||||
|
for (i=0; i<nrows; i++) {
|
||||||
|
for (j=0; j<ncols; j++){
|
||||||
|
MATRIX(*m,i,j) = NUM2DBL(RARRAY(RARRAY(rows)->ptr[i])->ptr[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE cIGraph_matrix_get(VALUE self, VALUE i, VALUE j){
|
||||||
|
|
||||||
|
igraph_matrix_t *m;
|
||||||
|
|
||||||
|
Data_Get_Struct(self, igraph_matrix_t, m);
|
||||||
|
return rb_float_new(MATRIX(*m,NUM2INT(i),NUM2INT(j)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE cIGraph_matrix_set(VALUE self, VALUE i, VALUE j, VALUE x){
|
||||||
|
|
||||||
|
igraph_matrix_t *m;
|
||||||
|
|
||||||
|
Data_Get_Struct(self, igraph_matrix_t, m);
|
||||||
|
MATRIX(*m,NUM2INT(i),NUM2INT(j)) = NUM2DBL(x);
|
||||||
|
return x;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE cIGraph_matrix_each(VALUE self){
|
||||||
|
|
||||||
|
igraph_matrix_t *m;
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
Data_Get_Struct(self, igraph_matrix_t, m);
|
||||||
|
|
||||||
|
for(i=0;i < m->nrow;i++){
|
||||||
|
for(j=0;j < m->ncol;j++){
|
||||||
|
rb_yield(rb_float_new(MATRIX(*m,i,j)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE cIGraph_matrix_size(VALUE self){
|
||||||
|
|
||||||
|
igraph_matrix_t *m;
|
||||||
|
|
||||||
|
Data_Get_Struct(self, igraph_matrix_t, m);
|
||||||
|
return LONG2FIX(igraph_matrix_size(m));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE cIGraph_matrix_nrow(VALUE self){
|
||||||
|
|
||||||
|
igraph_matrix_t *m;
|
||||||
|
|
||||||
|
Data_Get_Struct(self, igraph_matrix_t, m);
|
||||||
|
return LONG2FIX(igraph_matrix_nrow(m));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE cIGraph_matrix_ncol(VALUE self){
|
||||||
|
|
||||||
|
igraph_matrix_t *m;
|
||||||
|
|
||||||
|
Data_Get_Struct(self, igraph_matrix_t, m);
|
||||||
|
return LONG2FIX(igraph_matrix_ncol(m));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE cIGraph_matrix_max(VALUE self){
|
||||||
|
|
||||||
|
igraph_matrix_t *m;
|
||||||
|
|
||||||
|
Data_Get_Struct(self, igraph_matrix_t, m);
|
||||||
|
return rb_float_new(igraph_matrix_max(m));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE cIGraph_matrix_multiply(VALUE self, VALUE x){
|
||||||
|
|
||||||
|
igraph_matrix_t *m;
|
||||||
|
igraph_matrix_t *n = malloc(sizeof(igraph_matrix_t));
|
||||||
|
VALUE nobj;
|
||||||
|
|
||||||
|
Data_Get_Struct(self, igraph_matrix_t, m);
|
||||||
|
|
||||||
|
igraph_matrix_copy(n,m);
|
||||||
|
igraph_matrix_multiply(n, NUM2DBL(x));
|
||||||
|
|
||||||
|
nobj = Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, n);
|
||||||
|
|
||||||
|
return nobj;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE cIGraph_matrix_toa(VALUE self){
|
||||||
|
|
||||||
|
igraph_matrix_t *m;
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
VALUE a = rb_ary_new();
|
||||||
|
VALUE row;
|
||||||
|
|
||||||
|
Data_Get_Struct(self, igraph_matrix_t, m);
|
||||||
|
|
||||||
|
for(i=0;i < m->nrow;i++){
|
||||||
|
row = rb_ary_new();
|
||||||
|
for(j=0;j < m->ncol;j++){
|
||||||
|
rb_ary_push(row,rb_float_new(MATRIX(*m,i,j)));
|
||||||
|
}
|
||||||
|
rb_ary_push(a,row);
|
||||||
|
}
|
||||||
|
|
||||||
|
return a;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
#include "igraph.h"
|
||||||
|
#include "ruby.h"
|
||||||
|
#include "cIGraph.h"
|
||||||
|
|
||||||
|
/* call-seq:
|
||||||
|
* graph.topological_sorting(mode) -> Array
|
||||||
|
*
|
||||||
|
* Calculate a possible topological sorting of the graph. A topological
|
||||||
|
* sorting of a directed acyclic graph is a linear ordering of its nodes
|
||||||
|
* where each node comes before all nodes to which it has edges. Every DAG
|
||||||
|
* has at least one topological sort, and may have many. This function
|
||||||
|
* returns a possible topological sort among them. If the graph is not
|
||||||
|
* acyclic (it has at least one cycle), a partial topological sort is
|
||||||
|
* returned and a warning is issued. mode specifies how to use the direction
|
||||||
|
* of the edges. For IGRAPH_OUT, the sorting order ensures that each node
|
||||||
|
* comes before all nodes to which it has edges, so nodes with no incoming
|
||||||
|
* edges go first. For IGRAPH_IN, it is quite the opposite: each node comes
|
||||||
|
* before all nodes from which it receives edges. Nodes with no outgoing
|
||||||
|
* edges go first.
|
||||||
|
*/
|
||||||
|
VALUE cIGraph_topological_sorting(VALUE self, VALUE mode){
|
||||||
|
|
||||||
|
igraph_t *graph;
|
||||||
|
igraph_vector_t res;
|
||||||
|
igraph_neimode_t pmode = NUM2INT(mode);
|
||||||
|
VALUE result = rb_ary_new();
|
||||||
|
int i;
|
||||||
|
|
||||||
|
igraph_vector_init_int(&res,0);
|
||||||
|
|
||||||
|
Data_Get_Struct(self, igraph_t, graph);
|
||||||
|
|
||||||
|
igraph_topological_sorting(graph, &res, pmode);
|
||||||
|
|
||||||
|
for(i=0;i<igraph_vector_size(&res);i++){
|
||||||
|
rb_ary_push(result,cIGraph_get_vertex_object(self,VECTOR(res)[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
igraph_vector_destroy(&res);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
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
|
||||||
|
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
|
||||||
|
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)
|
||||||
|
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
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,13 @@
|
||||||
|
require 'test/unit'
|
||||||
|
require 'igraph'
|
||||||
|
|
||||||
|
class TestGraph < Test::Unit::TestCase
|
||||||
|
def test_copy
|
||||||
|
g = IGraph.new(['A','B','C','D'],true,[1,2]);
|
||||||
|
h = g.dup
|
||||||
|
assert g.vcount == h.vcount
|
||||||
|
assert g['A','B'] == h['A','B']
|
||||||
|
h['A','B'] = g['A','B'] + 1
|
||||||
|
assert g['A','B'] != h['A','B']
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,10 @@
|
||||||
|
require 'test/unit'
|
||||||
|
require 'igraph'
|
||||||
|
|
||||||
|
class TestGraph < Test::Unit::TestCase
|
||||||
|
def test_adj
|
||||||
|
graph = IGraph.new(['A','B','C','D'],true)
|
||||||
|
assert_equal ['B'], graph.adjacent_vertices('A',IGraph::ALL)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -0,0 +1,161 @@
|
||||||
|
require 'test/unit'
|
||||||
|
require 'igraph'
|
||||||
|
require 'stringio'
|
||||||
|
|
||||||
|
class TestGraph < Test::Unit::TestCase
|
||||||
|
def test_edgelist_read
|
||||||
|
g = nil
|
||||||
|
assert_nothing_raised{
|
||||||
|
g = IGraph.read_graph_edgelist(StringIO.new("0 1 2 3"),true)
|
||||||
|
}
|
||||||
|
assert_instance_of IGraph, g
|
||||||
|
assert_equal 4, g.vcount
|
||||||
|
assert g.are_connected?(0,1)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_edgelist_write
|
||||||
|
g = IGraph.new([0,1,2,3])
|
||||||
|
s = StringIO.new("")
|
||||||
|
str = g.write_graph_edgelist(s)
|
||||||
|
s.rewind
|
||||||
|
assert_equal "0 1\n2 3\n", s.read
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_graphml_read
|
||||||
|
g = nil
|
||||||
|
g = IGraph.read_graph_graphml(StringIO.new(Graphml),0)
|
||||||
|
assert_instance_of IGraph, g
|
||||||
|
assert_equal '2006-11-12', g.attributes['date']
|
||||||
|
h = g.dup
|
||||||
|
assert_equal g.to_a,h.to_a
|
||||||
|
assert_equal g.attributes['date'], h.attributes['date']
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_graphml_write
|
||||||
|
g = IGraph.new([{'id'=>0,'name'=>'a','type' => 4.0},
|
||||||
|
{'id'=>1,'name'=>'b','type' => 5},
|
||||||
|
{'id'=>2,'type' => 6},
|
||||||
|
{'id'=>3,'name'=>'d'}],
|
||||||
|
true,
|
||||||
|
[{'eid'=>'e1'},
|
||||||
|
{'eid'=>'e2'}])
|
||||||
|
g.attributes['date'] = 'Friday'
|
||||||
|
s = StringIO.new("")
|
||||||
|
str = g.write_graph_graphml(s)
|
||||||
|
s.rewind
|
||||||
|
assert_equal Graphml_out, s.read
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_pajek_read_write
|
||||||
|
g = nil
|
||||||
|
g = IGraph.read_graph_pajek(StringIO.new(Pajek),0)
|
||||||
|
assert_instance_of IGraph, g
|
||||||
|
assert_equal 4, g.vcount
|
||||||
|
assert_equal 1, g[4,1]['weight']
|
||||||
|
h = g.dup
|
||||||
|
s = StringIO.new('')
|
||||||
|
h.write_graph_pajek(s)
|
||||||
|
s.rewind
|
||||||
|
str = s.read
|
||||||
|
str.gsub!(/\r/,'')
|
||||||
|
assert_equal Pajek, str
|
||||||
|
end
|
||||||
|
|
||||||
|
Graphml = %q{<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- This file was written by the JAVA GraphML Library.-->
|
||||||
|
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3
|
||||||
|
.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdr
|
||||||
|
awing.org/xmlns/1.0/graphml.xsd">
|
||||||
|
<key id="d0" for="node" attr.name="color" attr.type="string">yellow</key>
|
||||||
|
<key id="d1" for="edge" attr.name="weight" attr.type="double"/>
|
||||||
|
<key id="d2" for="graph" attr.name="date" attr.type="string"></key>
|
||||||
|
<graph id="G" edgedefault="undirected">
|
||||||
|
<data key="d2">2006-11-12</data>
|
||||||
|
<node id="n0">
|
||||||
|
<data key="d0">green</data>
|
||||||
|
<data key="d3">incorrect</data>
|
||||||
|
<!-- incorrect attribute key, should issue a warning -->
|
||||||
|
</node>
|
||||||
|
<node id="n1"/>
|
||||||
|
<node id="n2">
|
||||||
|
<data key="d0">blue</data>
|
||||||
|
</node>
|
||||||
|
<node id="n3">
|
||||||
|
<data key="d0">red</data>
|
||||||
|
</node>
|
||||||
|
<node id="n4"/>
|
||||||
|
<node id="n5">
|
||||||
|
<data key="d0">turquoise</data>
|
||||||
|
</node>
|
||||||
|
<edge id="e0" source="n0" target="n2">
|
||||||
|
<data key="d1">1.0</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e1" source="n0" target="n1">
|
||||||
|
<data key="d1">1.0</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e2" source="n1" target="n3">
|
||||||
|
<data key="d1">2.0</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e3" source="n3" target="n2"/>
|
||||||
|
<edge id="e4" source="n2" target="n4"/>
|
||||||
|
<edge id="e5" source="n3" target="n5"/>
|
||||||
|
<edge id="e6" source="n5" target="n4">
|
||||||
|
<data key="d1">1.1</data>
|
||||||
|
</edge>
|
||||||
|
</graph>
|
||||||
|
</graphml>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Graphml_out = %q{<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
|
||||||
|
http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
|
||||||
|
<!-- Created by igraph -->
|
||||||
|
<key id="date" for="graph" attr.name="date" attr.type="string"/>
|
||||||
|
<key id="name" for="node" attr.name="name" attr.type="string"/>
|
||||||
|
<key id="type" for="node" attr.name="type" attr.type="double"/>
|
||||||
|
<key id="id" for="node" attr.name="id" attr.type="double"/>
|
||||||
|
<key id="eid" for="edge" attr.name="eid" attr.type="string"/>
|
||||||
|
<graph id="G" edgedefault="directed">
|
||||||
|
<data key="date">Friday</data>
|
||||||
|
<node id="n0">
|
||||||
|
<data key="name">a</data>
|
||||||
|
<data key="type">4</data>
|
||||||
|
<data key="id">0</data>
|
||||||
|
</node>
|
||||||
|
<node id="n1">
|
||||||
|
<data key="name">b</data>
|
||||||
|
<data key="type">5</data>
|
||||||
|
<data key="id">1</data>
|
||||||
|
</node>
|
||||||
|
<node id="n2">
|
||||||
|
<data key="name"></data>
|
||||||
|
<data key="type">6</data>
|
||||||
|
<data key="id">2</data>
|
||||||
|
</node>
|
||||||
|
<node id="n3">
|
||||||
|
<data key="name">d</data>
|
||||||
|
<data key="id">3</data>
|
||||||
|
</node>
|
||||||
|
<edge source="n0" target="n1">
|
||||||
|
<data key="eid">e1</data>
|
||||||
|
</edge>
|
||||||
|
<edge source="n2" target="n3">
|
||||||
|
<data key="eid">e2</data>
|
||||||
|
</edge>
|
||||||
|
</graph>
|
||||||
|
</graphml>
|
||||||
|
}
|
||||||
|
|
||||||
|
Pajek = %q{*Vertices 4
|
||||||
|
*Edges
|
||||||
|
4 1 1
|
||||||
|
1 2 4
|
||||||
|
1 3 2
|
||||||
|
2 3 2
|
||||||
|
}
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,26 @@
|
||||||
|
require 'test/unit'
|
||||||
|
require 'igraph'
|
||||||
|
|
||||||
|
class TestGraph < Test::Unit::TestCase
|
||||||
|
def test_random
|
||||||
|
g = IGraph.new([1,2,3,4],true)
|
||||||
|
l = g.layout_random
|
||||||
|
assert_instance_of IGraphMatrix, l
|
||||||
|
assert_equal g.vcount, l.nrow
|
||||||
|
assert_equal 2, l.ncol
|
||||||
|
end
|
||||||
|
def test_circle
|
||||||
|
g = IGraph.new([1,2,3,4],true)
|
||||||
|
l = g.layout_circle
|
||||||
|
assert_instance_of IGraphMatrix, l
|
||||||
|
assert_equal g.vcount, l.nrow
|
||||||
|
assert_equal 2, l.ncol
|
||||||
|
end
|
||||||
|
def test_fruchterman_reingold
|
||||||
|
g = IGraph.new([1,2,3,4],true)
|
||||||
|
l = g.layout_fruchterman_reingold(10,1,1,2,1,false)
|
||||||
|
assert_instance_of IGraphMatrix, l
|
||||||
|
assert_equal g.vcount, l.nrow
|
||||||
|
assert_equal 2, l.ncol
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,32 @@
|
||||||
|
require 'test/unit'
|
||||||
|
require 'igraph'
|
||||||
|
|
||||||
|
class TestGraph < Test::Unit::TestCase
|
||||||
|
def test_matrix
|
||||||
|
m = IGraphMatrix.new([1,2],[3,4])
|
||||||
|
assert_equal 1, m[0,0]
|
||||||
|
assert_equal 3, m[1,0]
|
||||||
|
end
|
||||||
|
def test_set
|
||||||
|
m = IGraphMatrix.new([1,2],[3,4])
|
||||||
|
m[0,0] = 6
|
||||||
|
assert_equal 6, m[0,0]
|
||||||
|
end
|
||||||
|
def test_prop
|
||||||
|
m = IGraphMatrix.new([1,2],[3,4])
|
||||||
|
assert_equal 4, m.size
|
||||||
|
assert_equal 2, m.nrow
|
||||||
|
assert_equal 2, m.ncol
|
||||||
|
assert_equal 4, m.max
|
||||||
|
end
|
||||||
|
def test_op
|
||||||
|
m = IGraphMatrix.new([1,2],[3,4])
|
||||||
|
n = m * 2
|
||||||
|
assert_equal 1, m[0,0]
|
||||||
|
assert_equal 2, n[0,0]
|
||||||
|
end
|
||||||
|
def test_to_a
|
||||||
|
m = IGraphMatrix.new([1,2],[3,4])
|
||||||
|
assert_equal [[1,2],[3,4]], m.to_a
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,10 @@
|
||||||
|
require 'test/unit'
|
||||||
|
require 'igraph'
|
||||||
|
|
||||||
|
class TestGraph < Test::Unit::TestCase
|
||||||
|
def test_top_sort
|
||||||
|
g = IGraph.new([1,2,2,3,3,4])
|
||||||
|
assert_equal [1,2,3,4], g.topological_sorting(IGraph::OUT)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in New Issue