/* call-seq:
 *   graph.transitivity() -> Float
 *
 * Calculates the transitivity (clustering coefficient) of a graph.
 *
 * The transitivity measures the probability that two neighbors of a vertex 
 * are connected. More precisely this is the ratio of the triangles and 
 * connected triples in the graph, the result is a single real number or 
 * NaN (0/0) if there are no connected triples in the graph. Directed graphs 
 * are considered as undirected ones.
 */
VALUE cIGraph_transitivity_local(VALUE self, VALUE vs){

  igraph_t *graph;
  igraph_vs_t vids;
  igraph_vector_t vidv;
  igraph_vector_t res;
  VALUE trans = rb_ary_new();
  int i;

  //vector to hold the results of the calculations
  igraph_vector_init_int(&res,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,vs,&vidv);
  //create vertex selector from the vecotr of ids
  igraph_vs_vector(&vids,&vidv);

  Data_Get_Struct(self, igraph_t, graph);

  igraph_transitivity_local_undirected(graph,&res,vids);

  for(i=0;i<igraph_vector_size(&res);i++){
    rb_ary_push(trans,rb_float_new(VECTOR(res)[i]));
  }

  igraph_vector_destroy(&vidv);
  igraph_vector_destroy(&res);
  igraph_vs_destroy(&vids);

  return trans;

}
Beispiel #2
0
/* 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
  igraph_vector_init_int(&vidv,0);
  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.degree(vs,mode,loops) -> Array
 *
 * Returns an Array of Integers specifying the degree of each of the
 * vertices specified in the vs Array. 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. 
 *
 * Example:
 *
 *   g = IGraph.new([1,2,3,4],true)
 *   g.is_directed? #returns true
 *
 */
VALUE cIGraph_degree(VALUE self, VALUE v, VALUE mode, VALUE loops){
  igraph_t *graph;
  igraph_vs_t vids;
  igraph_vector_t vidv;
  igraph_neimode_t pmode = NUM2INT(mode);
  igraph_bool_t loop_mode = loops ? 1 : 0;
  igraph_vector_t res;
  int i;
  VALUE degree_r = 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
  igraph_vector_init_int(&vidv,0);
  cIGraph_vertex_arr_to_id_vec(self,v,&vidv);
  //create vertex selector from the vecotr of ids
  igraph_vs_vector(&vids,&vidv);

  igraph_degree(graph,&res,vids,pmode,loop_mode);

  for(i=0;i<igraph_vector_size(&res);i++){
    rb_ary_push(degree_r,INT2NUM(VECTOR(res)[i]));
  }

  igraph_vector_destroy(&vidv);
  igraph_vector_destroy(&res);
  igraph_vs_destroy(&vids);

  return degree_r;

}
/* call-seq:
 *   graph.adjacent(vertex,mode) -> Array
 *
 * Returns an Array of the adjacent edge ids to vertex. mode defines 
 * the way adjacent edges are searched for directed graphs. It can have 
 * the following values: IGraph::OUT means only outgoing edges, IGraph::IN 
 * only incoming edges, IGraph::ALL both. This parameter is ignored for 
 * undirected graphs.
 *
 * Example:
 *
 *   g = IGraph.new([1,2,3,4],true)
 *   g.adjacent(1,IGraph::ALL) # returns [1]
 *
 */
VALUE cIGraph_adjacent(VALUE self, VALUE v, VALUE mode){

  igraph_t *graph;
  igraph_integer_t pnode;
  igraph_neimode_t pmode = NUM2INT(mode);
  igraph_vector_t eids;
  int i;
  VALUE eids_r = rb_ary_new();

  igraph_vector_init_int(&eids,0);

  Data_Get_Struct(self, igraph_t, graph);

  pnode = cIGraph_get_vertex_id(self,v);

  igraph_adjacent(graph,&eids,pnode,pmode);

  for(i=0;i<igraph_vector_size(&eids);i++){
    rb_ary_push(eids_r,INT2NUM(VECTOR(eids)[i]));
  }

  igraph_vector_destroy(&eids);

  return eids_r;

}
/* call-seq:
 *   graph.neighbours(vertex,mode) -> Array
 *
 * Returns an Array of the neighbouring vertices to vertex. mode defines 
 * the way adjacent vertices are searched for directed graphs. It can have 
 * the following values: IGraph::OUT, vertices reachable by an edge from the 
 * specified vertex are searched, IGraph::IN, vertices from which the 
 * specified vertex is reachable are searched. IGraph::ALL, both kind of 
 * vertices are searched. This parameter is ignored for undirected graphs.
 *
 * Example:
 *
 *   g = IGraph.new([1,2,3,4],true)
 *   g.neighbours(1,IGraph::ALL) # returns [2]
 *
 */
VALUE cIGraph_neighbors(VALUE self, VALUE v, VALUE mode){

  igraph_t *graph;
  igraph_integer_t pnode;
  igraph_neimode_t pmode = NUM2INT(mode);
  igraph_vector_t neis;
  int i;
  VALUE neighbors = rb_ary_new();

  igraph_vector_init_int(&neis,0);

  Data_Get_Struct(self, igraph_t, graph);

  pnode = cIGraph_get_vertex_id(self,v);

  igraph_neighbors(graph,&neis,pnode,pmode);

  for(i=0;i<igraph_vector_size(&neis);i++){
    rb_ary_push(neighbors,cIGraph_get_vertex_object(self,VECTOR(neis)[i]));
  }

  igraph_vector_destroy(&neis);

  return neighbors;

}
/* 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
  igraph_vector_init_int(&vidv,0);
  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;

}
Beispiel #7
0
/* 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
  igraph_vector_init_int(&vidv,0);
  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);

}
Beispiel #8
0
/* 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.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;

}
Beispiel #10
0
/* 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_LEN(weights));

  for(i=0;i<RARRAY_LEN(weights);i++){
    VECTOR(wghts)[i] = NUM2DBL(RARRAY_PTR(weights)[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);
  igraph_vector_destroy(&wghts);
  return matrix;

}
Beispiel #11
0
/* 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;
  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_FINALLY(igraph_vector_destroy, &res);
  IGRAPH_FINALLY(igraph_vector_destroy, &wght);
  IGRAPH_FINALLY(igraph_vector_destroy, &vidv);
  IGRAPH_CHECK(igraph_vector_init(&res,0));
  IGRAPH_CHECK(igraph_vector_init(&wght,0));

  Data_Get_Struct(self, igraph_t, graph);

  //Convert an array of vertices to a vector of vertex ids
  IGRAPH_CHECK(igraph_vector_init_int(&vidv,0));
  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_CHECK(igraph_constraint(graph,&res,vids,NULL));
  } else {
    for(i=0;i<RARRAY_LEN(weights);i++){
      IGRAPH_CHECK(igraph_vector_push_back(&wght,NUM2DBL(RARRAY_PTR(weights)[i])));
    }
    IGRAPH_CHECK(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);
  igraph_vector_destroy(&wght);
  igraph_vs_destroy(&vids);

  IGRAPH_FINALLY_CLEAN(3);

  return constraints;

}
Beispiel #12
0
/* 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
  igraph_vector_init_int(&vidv,0);
  cIGraph_vertex_arr_to_id_vec(self,vs,&vidv);
  //create vertex selector from the vecotr of ids
  igraph_vs_vector(&vids,&vidv);

  igraph_pagerank_old(graph,&res,vids,dir,
		  NUM2INT(niter),NUM2DBL(eps),NUM2DBL(damping),0);

  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.cocitation(varray) -> Array
 *
 * Cocitation coupling.
 *
 * Two vertices are cocited if there is another vertex citing both of them. 
 * igraph_cocitation() simply counts how many types two vertices are cocited. 
 * The cocitation score for each given vertex and all other vertices in the 
 * graph will be calculated. 
 *
 */
VALUE cIGraph_cocitation(VALUE self, VALUE vs){

  igraph_t *graph;
  igraph_vs_t vids;
  igraph_vector_t vidv;
  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(vs,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);

  //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);
  //create vertex selector from the vecotr of ids
  igraph_vs_vector(&vids,&vidv);

  igraph_cocitation(graph,&res,vids);

  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 = INT2NUM(MATRIX(res,i,j));
      rb_ary_push(row,path_length);
    }
  }

  igraph_vector_destroy(&vidv);
  igraph_matrix_destroy(&res);
  igraph_vs_destroy(&vids);

  return matrix;

}
Beispiel #14
0
/* 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_FINALLY(igraph_vector_destroy, &res);
  IGRAPH_FINALLY(igraph_vector_destroy, &vidv);
  IGRAPH_FINALLY(igraph_vs_destroy,&vids);
   
  IGRAPH_CHECK(igraph_vector_init(&res,0));

  Data_Get_Struct(self, igraph_t, graph);

  //Convert an array of vertices to a vector of vertex ids
  IGRAPH_CHECK(igraph_vector_init_int(&vidv,0));
  cIGraph_vertex_arr_to_id_vec(self,vs,&vidv);
  //create vertex selector from the vecotr of ids
  IGRAPH_CHECK(igraph_vs_vector(&vids,&vidv));

  IGRAPH_CHECK(igraph_betweenness(graph,&res,vids,dir));

  for(i=0;i<igraph_vector_size(&res);i++){
    rb_ary_push(betweenness,rb_float_new((float)VECTOR(res)[i]));
  }

  igraph_vector_destroy(&vidv);
  igraph_vector_destroy(&res);
  igraph_vs_destroy(&vids);

  IGRAPH_FINALLY_CLEAN(3);

  return betweenness;

}
Beispiel #15
0
/* 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_LEN(cuts);i++){
    igraph_vector_push_back(&cutsv,NUM2DBL(RARRAY_PTR(cuts)[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);

}
/* 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,v), 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;  

}
/* 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;

}
Beispiel #18
0
/* 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 weights, VALUE mode){

    igraph_t *graph;

  igraph_integer_t from_vid;
  igraph_vs_t to_vids;
  igraph_vector_t to_vidv;
  igraph_vector_t wghts;

  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_LEN(to);

  //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);
  }

  igraph_vector_init(&wghts,RARRAY_LEN(weights));

  for(i=0;i<RARRAY_LEN(weights);i++){
    VECTOR(wghts)[i] = NUM2DBL(RARRAY_PTR(weights)[i]);
  }

  //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);
  igraph_get_shortest_paths_dijkstra(graph,&res,from_vid,to_vids,igraph_vector_size(&wghts) > 0 ? &wghts : NULL,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);
  igraph_vector_destroy(&wghts);

  return matrix;

  /*
  igraph_t *graph;

  igraph_integer_t from_vid;
  igraph_vs_t to_vids;
  igraph_vector_t to_vidv;
  igraph_vector_t wghts;

  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 = 0;

  Data_Get_Struct(self, igraph_t, graph);

  n_paths = RARRAY_LEN(to);

  //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);
  }


  igraph_vector_init(&wghts,RARRAY_LEN(weights));

  for(i=0;i<RARRAY_LEN(weights);i++){
    VECTOR(wghts)[i] = NUM2DBL(RARRAY_PTR(weights)[i]);
  }

  //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);
  //igraph_get_shortest_paths_dijkstra(graph,&res,from_vid,to_vids,igraph_vector_size(&wghts) > 0 ? &wghts : NULL,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);
  igraph_vector_destroy(&wghts);

  return matrix;
    */
}
Beispiel #19
0
VALUE cIGraph_initialize(int argc, VALUE *argv, VALUE self){

  igraph_t *graph;
  igraph_vector_t edge_v;
  VALUE vertex;
  VALUE directed;
  VALUE edges;
  VALUE attrs;
  VALUE v_ary;
  int vertex_n = 0;
  int current_vertex_id;
  int i;

  igraph_vector_ptr_t vertex_attr;
  igraph_vector_ptr_t edge_attr;

  igraph_i_attribute_record_t v_attr_rec;
  v_attr_rec.name  = "__RUBY__";
  v_attr_rec.type  = IGRAPH_ATTRIBUTE_PY_OBJECT;
  v_attr_rec.value = (void*)rb_ary_new();

  igraph_i_attribute_record_t e_attr_rec;
  e_attr_rec.name  = "__RUBY__";
  e_attr_rec.type  = IGRAPH_ATTRIBUTE_PY_OBJECT;
  e_attr_rec.value = (void*)rb_ary_new();

  rb_scan_args(argc,argv,"12", &edges, &directed, &attrs);

  //Initialize edge vector
  IGRAPH_FINALLY(igraph_vector_destroy,&edge_v);
  IGRAPH_FINALLY(igraph_vector_ptr_destroy,&vertex_attr);
  IGRAPH_FINALLY(igraph_vector_ptr_destroy,&edge_attr);

  IGRAPH_CHECK(igraph_vector_init_int(&edge_v,0));

  IGRAPH_CHECK(igraph_vector_ptr_init(&vertex_attr,0));
  IGRAPH_CHECK(igraph_vector_ptr_init(&edge_attr,0));

  Data_Get_Struct(self, igraph_t, graph);

  v_ary = rb_ary_new();

  if(!directed)
    IGRAPH_CHECK(igraph_to_undirected(graph,IGRAPH_TO_UNDIRECTED_COLLAPSE));

  //Loop through objects in edge Array
  for (i=0; i<RARRAY_LEN(edges); i++) {
    vertex = RARRAY_PTR(edges)[i];
    if(rb_ary_includes(v_ary,vertex)){
      //If @vertices includes this vertex then look up the vertex number
      current_vertex_id = NUM2INT(rb_funcall(v_ary,rb_intern("index"),1,vertex));
    } else {
      //Otherwise add to the list of vertices
      rb_ary_push(v_ary,vertex);
      current_vertex_id = vertex_n;
      vertex_n++;
      
      //Add object to list of vertex attributes
      rb_ary_push((VALUE)v_attr_rec.value,vertex);
      
    }
    IGRAPH_CHECK(igraph_vector_push_back(&edge_v,current_vertex_id));
    if (i % 2){
      if (attrs != Qnil){
	rb_ary_push((VALUE)e_attr_rec.value,RARRAY_PTR(attrs)[i/2]);
      } else {
	rb_ary_push((VALUE)e_attr_rec.value,Qnil);
      }
    }
  }

  IGRAPH_CHECK(igraph_vector_ptr_push_back(&vertex_attr, &v_attr_rec));
  IGRAPH_CHECK(igraph_vector_ptr_push_back(&edge_attr,   &e_attr_rec));

  if(igraph_vector_size(&edge_v) > 0){
    IGRAPH_CHECK(igraph_add_vertices(graph,vertex_n,&vertex_attr));
    IGRAPH_CHECK(igraph_add_edges(graph,&edge_v,&edge_attr));
  }

  igraph_vector_destroy(&edge_v);
  igraph_vector_ptr_destroy(&vertex_attr);
  igraph_vector_ptr_destroy(&edge_attr);

  IGRAPH_FINALLY_CLEAN(3);

  return self;

}