This commit is contained in:
parent
d6ff8c61fc
commit
9a8dbfa7fa
|
@ -256,6 +256,9 @@ void Init_igraph(){
|
|||
rb_define_method(cIGraph, "diameter", cIGraph_diameter, 2); /* in cIGraph_shortest_paths.c */
|
||||
rb_define_method(cIGraph, "girth", cIGraph_girth, 0); /* in cIGraph_shortest_paths.c */
|
||||
|
||||
|
||||
rb_define_method(cIGraph, "dijkstra_shortest_paths", cIGraph_dijkstra_shortest_paths, 3);
|
||||
|
||||
rb_define_method(cIGraph, "neighbourhood_size", cIGraph_neighborhood_size, 3); /* in cIGraph_vertex_neighbourhood.c */
|
||||
rb_define_method(cIGraph, "neighbourhood", cIGraph_neighborhood, 3); /* in cIGraph_vertex_neighbourhood.c */
|
||||
rb_define_method(cIGraph, "neighbourhood_graphs", cIGraph_neighborhood_graphs, 3); /* in cIGraph_vertex_neighbourhood.c */
|
||||
|
@ -301,6 +304,21 @@ void Init_igraph(){
|
|||
rb_define_method(cIGraph, "maximal_cliques", cIGraph_maximal_cliques, 0); /* in cIGraph_cliques.c */
|
||||
rb_define_method(cIGraph, "clique_number", cIGraph_clique_number, 0); /* in cIGraph_cliques.c */
|
||||
|
||||
rb_define_method(cIGraph, "independent_vertex_sets", cIGraph_independent_vertex_sets, 2); /* in cIGraph_independent_vertex_sets.c */
|
||||
rb_define_method(cIGraph, "largest_independent_vertex_sets", cIGraph_largest_independent_vertex_sets, 0); /* in cIGraph_independent_vertex_sets.c */
|
||||
rb_define_method(cIGraph, "maximal_independent_vertex_sets", cIGraph_maximal_independent_vertex_sets, 0); /* in cIGraph_independent_vertex_sets.c */
|
||||
rb_define_method(cIGraph, "independence_number", cIGraph_independence_number, 0); /* in cIGraph_independent_vertex_sets.c */
|
||||
|
||||
rb_define_method(cIGraph, "isomorphic", cIGraph_isomorphic, 1); /* in cIGraph_isomorphic.c */
|
||||
rb_define_method(cIGraph, "isomorphic_vf2", cIGraph_isomorphic_vf2, 1); /* in cIGraph_isomorphic.c */
|
||||
rb_define_method(cIGraph, "isoclass", cIGraph_isoclass, 0); /* in cIGraph_isomorphic.c */
|
||||
rb_define_method(cIGraph, "isoclass_subgraph", cIGraph_isoclass_subgraph, 1); /* in cIGraph_isomorphic.c */
|
||||
rb_define_singleton_method(cIGraph, "isoclass_create", cIGraph_isoclass_create, 3); /* in cIGraph_isomorphic.c */
|
||||
|
||||
rb_define_method(cIGraph, "motifs_randesu", cIGraph_motifs_randesu, 2); /* in cIGraph_motif.c */
|
||||
rb_define_method(cIGraph, "motifs_randesu_no", cIGraph_motifs_randesu_no, 2); /* in cIGraph_motif.c */
|
||||
rb_define_method(cIGraph, "motifs_randesu_estimate", cIGraph_motifs_randesu_estimate, 4); /* in cIGraph_motif.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 */
|
||||
|
|
|
@ -81,6 +81,13 @@ VALUE cIGraph_average_path_length (VALUE self, VALUE directed, VALUE unconn);
|
|||
VALUE cIGraph_diameter (VALUE self, VALUE directed, VALUE unconn);
|
||||
VALUE cIGraph_girth (VALUE self);
|
||||
|
||||
VALUE cIGraph_dijkstra_shortest_paths(VALUE self, VALUE from, VALUE weights, VALUE mode);
|
||||
int igraph_dijkstra_shortest_paths(const igraph_t *graph,
|
||||
igraph_matrix_t *res,
|
||||
const igraph_vs_t from,
|
||||
const igraph_vector_t *wghts,
|
||||
igraph_neimode_t mode);
|
||||
|
||||
//Vertex neighbourhood functions
|
||||
VALUE cIGraph_neighborhood_size (VALUE self, VALUE from, VALUE order, VALUE mode);
|
||||
VALUE cIGraph_neighborhood (VALUE self, VALUE from, VALUE order, VALUE mode);
|
||||
|
@ -136,6 +143,25 @@ VALUE cIGraph_largest_cliques(VALUE self);
|
|||
VALUE cIGraph_maximal_cliques(VALUE self);
|
||||
VALUE cIGraph_clique_number(VALUE self);
|
||||
|
||||
//Independent vertex sets
|
||||
VALUE cIGraph_independent_vertex_sets(VALUE self, VALUE min, VALUE max);
|
||||
VALUE cIGraph_largest_independent_vertex_sets(VALUE self);
|
||||
VALUE cIGraph_maximal_independent_vertex_sets(VALUE self);
|
||||
VALUE cIGraph_independence_number(VALUE self);
|
||||
|
||||
//Graph isomorphism
|
||||
VALUE cIGraph_isomorphic (VALUE self, VALUE g);
|
||||
VALUE cIGraph_isomorphic_vf2 (VALUE self, VALUE g);
|
||||
VALUE cIGraph_isoclass (VALUE self);
|
||||
VALUE cIGraph_isoclass_subgraph(VALUE self, VALUE vs);
|
||||
VALUE cIGraph_isoclass_create (VALUE self, VALUE vn, VALUE iso, VALUE dir);
|
||||
|
||||
//Motifs
|
||||
VALUE cIGraph_motifs_randesu (VALUE self, VALUE size, VALUE cuts);
|
||||
VALUE cIGraph_motifs_randesu_no (VALUE self, VALUE size, VALUE cuts);
|
||||
VALUE cIGraph_motifs_randesu_estimate(VALUE self, VALUE size, VALUE cuts,
|
||||
VALUE samplen, VALUE samplev);
|
||||
|
||||
//File handling
|
||||
VALUE cIGraph_read_graph_edgelist (VALUE self, VALUE file, VALUE mode);
|
||||
VALUE cIGraph_write_graph_edgelist(VALUE self, VALUE file);
|
||||
|
|
|
@ -189,6 +189,7 @@ int cIGraph_attribute_add_vertices(igraph_t *graph, long int nv, igraph_vector_p
|
|||
VALUE values;
|
||||
|
||||
if(attr){
|
||||
|
||||
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;
|
||||
|
@ -234,6 +235,11 @@ int cIGraph_attribute_add_vertices(igraph_t *graph, long int nv, igraph_vector_p
|
|||
rb_ary_push(vertex_array,record);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//Default: Add numbered vertices.
|
||||
for(i=0;i<nv;i++){
|
||||
rb_ary_push(vertex_array,INT2NUM(i));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -0,0 +1,258 @@
|
|||
#include "igraph.h"
|
||||
#include "ruby.h"
|
||||
#include "cIGraph.h"
|
||||
|
||||
/* call-seq:
|
||||
* graph.dijkstra_shortest_paths(varray,weights,mode) -> Array
|
||||
*
|
||||
* Calculates the length of the shortest paths from each of the vertices in
|
||||
* the varray Array to all of the other vertices in the graph given a set of
|
||||
* edge weights given in the weights Array. The result
|
||||
* is returned as an Array of Array. Each top-level Array contains the results
|
||||
* for a vertex in the varray Array. Each entry in the Array is the path length
|
||||
* to another vertex in the graph in vertex order (the order the vertices were
|
||||
* added to the graph. (This should probalby be changed to give a Hash of Hash
|
||||
* to allow easier look up.)
|
||||
*/
|
||||
VALUE cIGraph_dijkstra_shortest_paths(VALUE self, VALUE from, VALUE weights, VALUE mode){
|
||||
|
||||
igraph_t *graph;
|
||||
igraph_vs_t vids;
|
||||
igraph_vector_t vidv;
|
||||
igraph_vector_t wghts;
|
||||
igraph_neimode_t pmode = NUM2INT(mode);
|
||||
igraph_matrix_t res;
|
||||
int i;
|
||||
int j;
|
||||
VALUE row;
|
||||
VALUE path_length;
|
||||
VALUE matrix = rb_ary_new();
|
||||
int n_row;
|
||||
int n_col;
|
||||
|
||||
Data_Get_Struct(self, igraph_t, graph);
|
||||
|
||||
n_row = NUM2INT(rb_funcall(from,rb_intern("length"),0));
|
||||
n_col = igraph_vcount(graph);
|
||||
|
||||
//matrix to hold the results of the calculations
|
||||
igraph_matrix_init(&res,n_row,n_col);
|
||||
|
||||
igraph_vector_init(&wghts,RARRAY(weights)->len);
|
||||
|
||||
for(i=0;i<RARRAY(weights)->len;i++){
|
||||
VECTOR(wghts)[i] = NUM2DBL(RARRAY(weights)->ptr[i]);
|
||||
}
|
||||
|
||||
//Convert an array of vertices to a vector of vertex ids
|
||||
igraph_vector_init_int(&vidv,0);
|
||||
cIGraph_vertex_arr_to_id_vec(self,from,&vidv);
|
||||
//create vertex selector from the vecotr of ids
|
||||
igraph_vs_vector(&vids,&vidv);
|
||||
|
||||
igraph_dijkstra_shortest_paths(graph,&res,vids,&wghts,pmode);
|
||||
|
||||
for(i=0; i<igraph_matrix_nrow(&res); i++){
|
||||
row = rb_ary_new();
|
||||
rb_ary_push(matrix,row);
|
||||
for(j=0; j<igraph_matrix_ncol(&res); j++){
|
||||
path_length = MATRIX(res,i,j) == n_col ? Qnil : rb_float_new(MATRIX(res,i,j));
|
||||
rb_ary_push(row,path_length);
|
||||
}
|
||||
}
|
||||
|
||||
igraph_vector_destroy(&vidv);
|
||||
igraph_matrix_destroy(&res);
|
||||
igraph_vs_destroy(&vids);
|
||||
|
||||
return matrix;
|
||||
|
||||
}
|
||||
|
||||
/* call-seq:
|
||||
* graph.get_shortest_paths(from,to_array,mode) -> Array
|
||||
*
|
||||
* Calculates the paths from the vertex specified as from to each vertex in the
|
||||
* to_array Array. Returns an Array of Arrays. Each top level Array represents
|
||||
* a path and each entry in each Array is a vertex on the path. mode
|
||||
* represents the type of shortest paths to be calculated: IGraph::OUT
|
||||
* the outgoing paths are calculated. IGraph::IN the incoming paths are
|
||||
* calculated. IGraph::ALL the directed graph is considered as an undirected
|
||||
* one for the computation.
|
||||
*/
|
||||
VALUE cIGraph_get_dijkstra_shortest_paths(VALUE self, VALUE from, VALUE to, VALUE mode){
|
||||
|
||||
igraph_t *graph;
|
||||
|
||||
igraph_integer_t from_vid;
|
||||
igraph_vs_t to_vids;
|
||||
igraph_vector_t to_vidv;
|
||||
|
||||
igraph_neimode_t pmode = NUM2INT(mode);
|
||||
|
||||
igraph_vector_ptr_t res;
|
||||
igraph_vector_t *path_v;
|
||||
|
||||
int i;
|
||||
int j;
|
||||
VALUE path;
|
||||
VALUE matrix = rb_ary_new();
|
||||
int n_paths;
|
||||
|
||||
Data_Get_Struct(self, igraph_t, graph);
|
||||
|
||||
n_paths = RARRAY(to)->len;
|
||||
|
||||
//vector to hold the results of the calculations
|
||||
igraph_vector_ptr_init(&res,0);
|
||||
for(i=0;i<n_paths;i++){
|
||||
path_v = malloc(sizeof(igraph_vector_t));
|
||||
igraph_vector_init(path_v,0);
|
||||
igraph_vector_ptr_push_back(&res,path_v);
|
||||
}
|
||||
|
||||
//Convert an array of vertices to a vector of vertex ids
|
||||
igraph_vector_init_int(&to_vidv,0);
|
||||
cIGraph_vertex_arr_to_id_vec(self,to,&to_vidv);
|
||||
//create vertex selector from the vecotr of ids
|
||||
igraph_vs_vector(&to_vids,&to_vidv);
|
||||
|
||||
//The id of the vertex from where we are counting
|
||||
from_vid = cIGraph_get_vertex_id(self, from);
|
||||
|
||||
igraph_get_shortest_paths(graph,&res,from_vid,to_vids,pmode);
|
||||
|
||||
for(i=0; i<n_paths; i++){
|
||||
path = rb_ary_new();
|
||||
rb_ary_push(matrix,path);
|
||||
path_v = VECTOR(res)[i];
|
||||
for(j=0; j<igraph_vector_size(VECTOR(res)[i]); j++){
|
||||
rb_ary_push(path,cIGraph_get_vertex_object(self,VECTOR(*path_v)[j]));
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0;i<n_paths;i++){
|
||||
igraph_vector_destroy(VECTOR(res)[i]);
|
||||
free(VECTOR(res)[i]);
|
||||
}
|
||||
|
||||
igraph_vector_destroy(&to_vidv);
|
||||
igraph_vector_ptr_destroy(&res);
|
||||
igraph_vs_destroy(&to_vids);
|
||||
|
||||
return matrix;
|
||||
|
||||
}
|
||||
|
||||
int igraph_dijkstra_shortest_paths(const igraph_t *graph,
|
||||
igraph_matrix_t *res,
|
||||
const igraph_vs_t from,
|
||||
const igraph_vector_t *wghts,
|
||||
igraph_neimode_t mode) {
|
||||
|
||||
long int no_of_nodes=igraph_vcount(graph);
|
||||
long int no_of_from;
|
||||
igraph_real_t *shortest;
|
||||
igraph_real_t min,alt;
|
||||
|
||||
int i, j, uj, included;
|
||||
igraph_integer_t eid, u,v;
|
||||
igraph_vector_t q;
|
||||
igraph_vit_t fromvit;
|
||||
igraph_vector_t neis;
|
||||
|
||||
IGRAPH_CHECK(igraph_vit_create(graph, from, &fromvit));
|
||||
IGRAPH_FINALLY(igraph_vit_destroy, &fromvit);
|
||||
|
||||
no_of_from=IGRAPH_VIT_SIZE(fromvit);
|
||||
|
||||
if (mode != IGRAPH_OUT && mode != IGRAPH_IN &&
|
||||
mode != IGRAPH_ALL) {
|
||||
IGRAPH_ERROR("Invalid mode argument", IGRAPH_EINVMODE);
|
||||
}
|
||||
shortest=calloc(no_of_nodes, sizeof(igraph_real_t));
|
||||
if (shortest==0) {
|
||||
IGRAPH_ERROR("shortest paths failed", IGRAPH_ENOMEM);
|
||||
}
|
||||
IGRAPH_FINALLY(free, shortest);
|
||||
|
||||
IGRAPH_CHECK(igraph_matrix_resize(res, no_of_from, no_of_nodes));
|
||||
igraph_matrix_null(res);
|
||||
|
||||
for (IGRAPH_VIT_RESET(fromvit), i=0;
|
||||
!IGRAPH_VIT_END(fromvit);
|
||||
IGRAPH_VIT_NEXT(fromvit), i++) {
|
||||
|
||||
//Start shortest and previous
|
||||
for(j=0;j<no_of_nodes;j++){
|
||||
shortest[j] = INFINITY;
|
||||
//memset(previous,NAN, no_of_nodes);
|
||||
}
|
||||
|
||||
shortest[(int)IGRAPH_VIT_GET(fromvit)] = 0;
|
||||
igraph_vector_init_seq(&q,0,no_of_nodes-1);
|
||||
|
||||
while(igraph_vector_size(&q) != 0){
|
||||
|
||||
min = INFINITY;
|
||||
u = no_of_nodes;
|
||||
uj = igraph_vector_size(&q);
|
||||
for(j=0;j<igraph_vector_size(&q);j++){
|
||||
v = VECTOR(q)[j];
|
||||
if(shortest[(int)v] < min){
|
||||
min = shortest[(int)v];
|
||||
u = v;
|
||||
uj = j;
|
||||
}
|
||||
}
|
||||
|
||||
if(min == INFINITY)
|
||||
break;
|
||||
|
||||
igraph_vector_remove(&q,uj);
|
||||
|
||||
igraph_vector_init(&neis,0);
|
||||
igraph_neighbors(graph,&neis,u,mode);
|
||||
|
||||
for(j=0;j<igraph_vector_size(&neis);j++){
|
||||
|
||||
v = VECTOR(neis)[j];
|
||||
|
||||
//v must be in Q
|
||||
included = 0;
|
||||
for(j=0;j<igraph_vector_size(&q);j++){
|
||||
if(v == VECTOR(q)[j]){
|
||||
included = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!included)
|
||||
continue;
|
||||
|
||||
igraph_get_eid(graph,&eid,u,v,1);
|
||||
|
||||
alt = shortest[(int)u] + VECTOR(*wghts)[(int)eid];
|
||||
|
||||
if(alt < shortest[(int)v]){
|
||||
shortest[(int)v] = alt;
|
||||
}
|
||||
}
|
||||
igraph_vector_destroy(&neis);
|
||||
}
|
||||
|
||||
for(j=0;j<no_of_nodes;j++){
|
||||
MATRIX(*res,i,j) = shortest[j];
|
||||
}
|
||||
|
||||
igraph_vector_destroy(&q);
|
||||
|
||||
}
|
||||
|
||||
/* Clean */
|
||||
free(shortest);
|
||||
igraph_vit_destroy(&fromvit);
|
||||
IGRAPH_FINALLY_CLEAN(2);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,182 @@
|
|||
#include "igraph.h"
|
||||
#include "ruby.h"
|
||||
#include "cIGraph.h"
|
||||
|
||||
/* call-seq:
|
||||
* graph.independent_vertex_sets(min_size,max_size) -> Array
|
||||
*
|
||||
* Find all independent vertex sets in a graph
|
||||
*
|
||||
* A vertex set is considered independent if there are no edges between them.
|
||||
*
|
||||
* If you are interested in the size of the largest independent vertex set,
|
||||
* use IGraph#independence_number() instead.
|
||||
*/
|
||||
|
||||
VALUE cIGraph_independent_vertex_sets(VALUE self, VALUE min, VALUE max){
|
||||
|
||||
igraph_t *graph;
|
||||
igraph_vector_ptr_t res;
|
||||
igraph_vector_t *vec;
|
||||
int i;
|
||||
int j;
|
||||
VALUE independent_vertex_set;
|
||||
VALUE object;
|
||||
VALUE independent_vertex_sets = rb_ary_new();
|
||||
|
||||
Data_Get_Struct(self, igraph_t, graph);
|
||||
|
||||
igraph_vector_ptr_init(&res,0);
|
||||
|
||||
igraph_independent_vertex_sets(graph, &res, NUM2INT(min), NUM2INT(max));
|
||||
|
||||
for(i=0; i<igraph_vector_ptr_size(&res); i++){
|
||||
independent_vertex_set = rb_ary_new();
|
||||
rb_ary_push(independent_vertex_sets,independent_vertex_set);
|
||||
vec = VECTOR(res)[i];
|
||||
for(j=0; j<igraph_vector_size(vec); j++){
|
||||
vec = VECTOR(res)[i];
|
||||
object = cIGraph_get_vertex_object(self,VECTOR(*vec)[j]);
|
||||
rb_ary_push(independent_vertex_set,object);
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0;i<igraph_vector_ptr_size(&res);i++){
|
||||
igraph_vector_destroy(VECTOR(res)[i]);
|
||||
free(VECTOR(res)[i]);
|
||||
}
|
||||
|
||||
igraph_vector_ptr_destroy(&res);
|
||||
|
||||
return independent_vertex_sets;
|
||||
|
||||
}
|
||||
|
||||
/* call-seq:
|
||||
* graph.largest_independent_vertex_sets() -> Array
|
||||
*
|
||||
* Finds the largest independent vertex set(s) in a graph.
|
||||
|
||||
* An independent vertex set is largest if there is no other independent
|
||||
* vertex set with more vertices in the graph.
|
||||
*/
|
||||
|
||||
VALUE cIGraph_largest_independent_vertex_sets(VALUE self){
|
||||
|
||||
igraph_t *graph;
|
||||
igraph_vector_ptr_t res;
|
||||
igraph_vector_t *vec;
|
||||
int i;
|
||||
int j;
|
||||
VALUE independent_vertex_set;
|
||||
VALUE object;
|
||||
VALUE independent_vertex_sets = rb_ary_new();
|
||||
|
||||
Data_Get_Struct(self, igraph_t, graph);
|
||||
|
||||
igraph_vector_ptr_init(&res,0);
|
||||
|
||||
igraph_largest_independent_vertex_sets(graph, &res);
|
||||
|
||||
for(i=0; i<igraph_vector_ptr_size(&res); i++){
|
||||
independent_vertex_set = rb_ary_new();
|
||||
rb_ary_push(independent_vertex_sets,independent_vertex_set);
|
||||
vec = VECTOR(res)[i];
|
||||
for(j=0; j<igraph_vector_size(vec); j++){
|
||||
vec = VECTOR(res)[i];
|
||||
object = cIGraph_get_vertex_object(self,VECTOR(*vec)[j]);
|
||||
rb_ary_push(independent_vertex_set,object);
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0;i<igraph_vector_ptr_size(&res);i++){
|
||||
igraph_vector_destroy(VECTOR(res)[i]);
|
||||
free(VECTOR(res)[i]);
|
||||
}
|
||||
|
||||
igraph_vector_ptr_destroy(&res);
|
||||
|
||||
return independent_vertex_sets;
|
||||
|
||||
}
|
||||
|
||||
/* call-seq:
|
||||
* graph.maximal_independent_vertex_sets() -> Array
|
||||
*
|
||||
* Find all maximal independent vertex sets of a graph
|
||||
*
|
||||
* A maximal independent vertex set is an independent vertex set which can't
|
||||
* be extended any more by adding a new vertex to it.
|
||||
*
|
||||
* The algorithm used here is based on the following paper: S. Tsukiyama,
|
||||
* M. Ide, H. Ariyoshi and I. Shirawaka. A new algorithm for generating all
|
||||
* the maximal independent sets. SIAM J Computing, 6:505--517, 1977.
|
||||
*
|
||||
* The implementation was originally written by Kevin O'Neill and modified
|
||||
* by K M Briggs in the Very Nauty Graph Library. I simply re-wrote it to
|
||||
* use igraph's data structures.
|
||||
*
|
||||
* If you are interested in the size of the largest independent vertex set,
|
||||
* use IGraph#independence_number() instead.
|
||||
*/
|
||||
|
||||
VALUE cIGraph_maximal_independent_vertex_sets(VALUE self){
|
||||
|
||||
igraph_t *graph;
|
||||
igraph_vector_ptr_t res;
|
||||
igraph_vector_t *vec;
|
||||
int i;
|
||||
int j;
|
||||
VALUE independent_vertex_set;
|
||||
VALUE object;
|
||||
VALUE independent_vertex_sets = rb_ary_new();
|
||||
|
||||
Data_Get_Struct(self, igraph_t, graph);
|
||||
|
||||
igraph_vector_ptr_init(&res,0);
|
||||
|
||||
igraph_maximal_independent_vertex_sets(graph, &res);
|
||||
|
||||
for(i=0; i<igraph_vector_ptr_size(&res); i++){
|
||||
independent_vertex_set = rb_ary_new();
|
||||
rb_ary_push(independent_vertex_sets,independent_vertex_set);
|
||||
vec = VECTOR(res)[i];
|
||||
for(j=0; j<igraph_vector_size(vec); j++){
|
||||
vec = VECTOR(res)[i];
|
||||
object = cIGraph_get_vertex_object(self,VECTOR(*vec)[j]);
|
||||
rb_ary_push(independent_vertex_set,object);
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0;i<igraph_vector_ptr_size(&res);i++){
|
||||
igraph_vector_destroy(VECTOR(res)[i]);
|
||||
free(VECTOR(res)[i]);
|
||||
}
|
||||
|
||||
igraph_vector_ptr_destroy(&res);
|
||||
|
||||
return independent_vertex_sets;
|
||||
|
||||
}
|
||||
|
||||
/* call-seq:
|
||||
* graph.independence_number() -> Integer
|
||||
*
|
||||
* Find the independence number of the graph
|
||||
*
|
||||
* The independence number of a graph is the cardinality of the largest
|
||||
* independent vertex set.
|
||||
*/
|
||||
|
||||
VALUE cIGraph_independence_number(VALUE self){
|
||||
|
||||
igraph_t *graph;
|
||||
igraph_integer_t res;
|
||||
|
||||
Data_Get_Struct(self, igraph_t, graph);
|
||||
|
||||
igraph_independence_number(graph, &res);
|
||||
|
||||
return INT2NUM(res);
|
||||
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
#include "igraph.h"
|
||||
#include "ruby.h"
|
||||
#include "cIGraph.h"
|
||||
|
||||
/* call-seq:
|
||||
* graph.isomorphic(graph) -> True/False
|
||||
*
|
||||
* Decides whether two graphs are isomorphic
|
||||
*
|
||||
* From Wikipedia: The graph isomorphism problem or GI problem is the graph
|
||||
* theory problem of determining whether, given two graphs G1 and G2, it is
|
||||
* possible to permute (or relabel) the vertices of one graph so that it is
|
||||
* equal to the other. Such a permutation is called a graph isomorphism.
|
||||
*/
|
||||
VALUE cIGraph_isomorphic(VALUE self, VALUE g){
|
||||
|
||||
igraph_bool_t res = 0;
|
||||
igraph_t *graph;
|
||||
igraph_t *graph2;
|
||||
|
||||
Data_Get_Struct(self, igraph_t, graph);
|
||||
Data_Get_Struct(g, igraph_t, graph2);
|
||||
|
||||
IGRAPH_CHECK(igraph_isomorphic(graph,graph2,&res));
|
||||
|
||||
return res == 0 ? Qfalse : Qtrue;
|
||||
|
||||
}
|
||||
|
||||
/* call-seq:
|
||||
* graph.isomorphic_vf2(graph) -> True/False
|
||||
*
|
||||
* Decides whether two graphs are isomorphic
|
||||
*
|
||||
* This function is an implementation of the VF2 isomorphism algorithm,
|
||||
* see P. Foggia, C. Sansone, M. Vento, An Improved algorithm for matching
|
||||
* large graphs, Prof. of the 3rd IAPR-TC-15 International Workshop on
|
||||
* Graph-based Representations, Italy, 2001.
|
||||
*/
|
||||
VALUE cIGraph_isomorphic_vf2(VALUE self, VALUE g){
|
||||
|
||||
igraph_bool_t res = 0;
|
||||
igraph_t *graph;
|
||||
igraph_t *graph2;
|
||||
|
||||
Data_Get_Struct(self, igraph_t, graph);
|
||||
Data_Get_Struct(g, igraph_t, graph2);
|
||||
|
||||
IGRAPH_CHECK(igraph_isomorphic_vf2(graph,graph2,&res));
|
||||
|
||||
return res == 0 ? Qfalse : Qtrue;
|
||||
|
||||
}
|
||||
|
||||
/* call-seq:
|
||||
* graph.isoclass() -> Integer
|
||||
*
|
||||
* Determine the isomorphism class of a graph
|
||||
*
|
||||
* All graphs with a given number of vertices belong to a number of
|
||||
* isomorpism classes, with every graph in a given class being isomorphic
|
||||
* to each other.
|
||||
*
|
||||
* This function gives the isomorphism class (a number) of a graph. Two
|
||||
* graphs have the same isomorphism class if and only if they are isomorphic.
|
||||
*
|
||||
* The first isomorphism class is numbered zero and it is the empty graph,
|
||||
* the last isomorphism class is the full graph. The number of isomorphism
|
||||
* class for directed graphs with three vertices is 16 (between 0 and 15),
|
||||
* for undirected graph it is only 4. For graphs with four vertices it is
|
||||
* 218 (directed) and 11 (undirected).
|
||||
*/
|
||||
VALUE cIGraph_isoclass(VALUE self){
|
||||
|
||||
int res = 0;
|
||||
igraph_t *graph;
|
||||
|
||||
Data_Get_Struct(self, igraph_t, graph);
|
||||
|
||||
IGRAPH_CHECK(igraph_isoclass(graph,&res));
|
||||
|
||||
return INT2NUM(res);
|
||||
|
||||
}
|
||||
|
||||
/* call-seq:
|
||||
* graph.isoclass_subgraph(vs) -> Integer
|
||||
*
|
||||
* Determine the isomorphism class of a subgraph given by the vertices given
|
||||
* in the Array vs.
|
||||
*
|
||||
*/
|
||||
VALUE cIGraph_isoclass_subgraph(VALUE self, VALUE vs){
|
||||
|
||||
int res = 0;
|
||||
igraph_t *graph;
|
||||
igraph_vector_t vidv;
|
||||
|
||||
Data_Get_Struct(self, igraph_t, graph);
|
||||
|
||||
//Convert an array of vertices to a vector of vertex ids
|
||||
igraph_vector_init_int(&vidv,0);
|
||||
cIGraph_vertex_arr_to_id_vec(self,vs,&vidv);
|
||||
|
||||
IGRAPH_CHECK(igraph_isoclass_subgraph(graph,&vidv,&res));
|
||||
|
||||
igraph_vector_destroy(&vidv);
|
||||
|
||||
return INT2NUM(res);
|
||||
|
||||
}
|
||||
|
||||
/* call-seq:
|
||||
* IGraph.isoclass_create(vn,iso,dir) -> IGraph
|
||||
*
|
||||
* Creates a graph with the number of vertices given by vn from the given
|
||||
* isomorphism class iso and the direction boolean dir.
|
||||
*
|
||||
* This function is implemented only for graphs with three or four vertices.
|
||||
*/
|
||||
VALUE cIGraph_isoclass_create(VALUE self, VALUE vn, VALUE iso, VALUE dir){
|
||||
|
||||
igraph_t *graph;
|
||||
VALUE new_graph;
|
||||
igraph_bool_t dir_b = 0;
|
||||
|
||||
if(dir)
|
||||
dir_b = 1;
|
||||
|
||||
new_graph = cIGraph_alloc(cIGraph);
|
||||
Data_Get_Struct(new_graph, igraph_t, graph);
|
||||
|
||||
IGRAPH_CHECK(igraph_isoclass_create(graph,NUM2INT(vn),NUM2INT(iso),dir_b));
|
||||
|
||||
return new_graph;
|
||||
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
#include "igraph.h"
|
||||
#include "ruby.h"
|
||||
#include "cIGraph.h"
|
||||
|
||||
/* call-seq:
|
||||
* igraph.motifs_randesu(size,cut)
|
||||
*
|
||||
*/
|
||||
VALUE cIGraph_motifs_randesu(VALUE self, VALUE size, VALUE cuts){
|
||||
|
||||
igraph_t *graph;
|
||||
igraph_vector_t cutsv;
|
||||
igraph_vector_t res;
|
||||
int i;
|
||||
VALUE hist = rb_ary_new();
|
||||
|
||||
Data_Get_Struct(self, igraph_t, graph);
|
||||
|
||||
igraph_vector_init(&res,0);
|
||||
|
||||
//Convert an array of vertices to a vector of vertex ids
|
||||
igraph_vector_init(&cutsv,0);
|
||||
for(i=0;i<RARRAY(cuts)->len;i++){
|
||||
igraph_vector_push_back(&cutsv,NUM2DBL(RARRAY(cuts)->ptr[i]));
|
||||
}
|
||||
|
||||
igraph_motifs_randesu(graph,&res,NUM2INT(size),&cutsv);
|
||||
|
||||
for(i=0; i<igraph_vector_size(&res); i++){
|
||||
rb_ary_push(hist,INT2NUM(VECTOR(res)[i]));
|
||||
}
|
||||
|
||||
igraph_vector_destroy(&cutsv);
|
||||
igraph_vector_destroy(&res);
|
||||
|
||||
return hist;
|
||||
|
||||
}
|
||||
|
||||
/* call-seq:
|
||||
* igraph.motifs_randesu_no(size,cut)
|
||||
*
|
||||
*/
|
||||
VALUE cIGraph_motifs_randesu_no(VALUE self, VALUE size, VALUE cuts){
|
||||
|
||||
igraph_t *graph;
|
||||
igraph_vector_t cutsv;
|
||||
igraph_integer_t res;
|
||||
int i;
|
||||
|
||||
Data_Get_Struct(self, igraph_t, graph);
|
||||
|
||||
//Convert an array of vertices to a vector of vertex ids
|
||||
igraph_vector_init(&cutsv,0);
|
||||
for(i=0;i<RARRAY(cuts)->len;i++){
|
||||
igraph_vector_push_back(&cutsv,NUM2DBL(RARRAY(cuts)->ptr[i]));
|
||||
}
|
||||
|
||||
igraph_motifs_randesu_no(graph,&res,NUM2INT(size),&cutsv);
|
||||
|
||||
igraph_vector_destroy(&cutsv);
|
||||
|
||||
return INT2NUM(res);
|
||||
|
||||
}
|
||||
|
||||
/* call-seq:
|
||||
* igraph.motifs_randesu_estimate(size,cut,samplen,samplev)
|
||||
*
|
||||
*/
|
||||
VALUE cIGraph_motifs_randesu_estimate(VALUE self, VALUE size, VALUE cuts,
|
||||
VALUE samplen, VALUE samplev){
|
||||
|
||||
igraph_t *graph;
|
||||
igraph_vector_t cutsv;
|
||||
igraph_vector_t vidv;
|
||||
igraph_integer_t res;
|
||||
int i;
|
||||
|
||||
if(samplev != Qnil){
|
||||
igraph_vector_init(&vidv,0);
|
||||
//Convert an array of vertices to a vector of vertex ids
|
||||
igraph_vector_init_int(&vidv,0);
|
||||
cIGraph_vertex_arr_to_id_vec(self,samplev,&vidv);
|
||||
}
|
||||
|
||||
Data_Get_Struct(self, igraph_t, graph);
|
||||
|
||||
igraph_vector_init(&cutsv,0);
|
||||
for(i=0;i<RARRAY(cuts)->len;i++){
|
||||
igraph_vector_push_back(&cutsv,NUM2DBL(RARRAY(cuts)->ptr[i]));
|
||||
}
|
||||
|
||||
if(samplev == Qnil){
|
||||
igraph_motifs_randesu_estimate(graph,&res,NUM2INT(size),
|
||||
&cutsv,NUM2INT(samplen),NULL);
|
||||
} else {
|
||||
igraph_motifs_randesu_estimate(graph,&res,NUM2INT(size),
|
||||
&cutsv,NUM2INT(samplen),&vidv);
|
||||
}
|
||||
|
||||
igraph_vector_destroy(&cutsv);
|
||||
if(samplev != Qnil){
|
||||
igraph_vector_destroy(&vidv);
|
||||
}
|
||||
|
||||
return INT2NUM(res);
|
||||
|
||||
}
|
|
@ -31,7 +31,7 @@ VALUE cIGraph_laplacian(VALUE self, VALUE mode){
|
|||
VALUE val;
|
||||
VALUE matrix = rb_ary_new();
|
||||
|
||||
if(mode = Qtrue)
|
||||
if(mode == Qtrue)
|
||||
pmode = 1;
|
||||
|
||||
Data_Get_Struct(self, igraph_t, graph);
|
||||
|
|
|
@ -12,12 +12,16 @@ require 'tc_centrality'
|
|||
require 'tc_components'
|
||||
require 'tc_copy'
|
||||
require 'tc_cores'
|
||||
require 'tc_dijkstra'
|
||||
require 'tc_directedness'
|
||||
require 'tc_error_handling'
|
||||
require 'tc_file_read_write'
|
||||
require 'tc_independent_vertex_sets'
|
||||
require 'tc_isomorphic'
|
||||
require 'tc_iterators'
|
||||
require 'tc_layout'
|
||||
require 'tc_matrix'
|
||||
require 'tc_motif'
|
||||
require 'tc_other_ops'
|
||||
require 'tc_selectors'
|
||||
require 'tc_shortest_paths'
|
||||
|
|
Loading…
Reference in New Issue