igraph 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,14 +10,20 @@ ext/cIGraph_attribute_handler.c
10
10
  ext/cIGraph_basic_properties.c
11
11
  ext/cIGraph_basic_query.c
12
12
  ext/cIGraph_centrality.c
13
+ ext/cIGraph_cliques.c
13
14
  ext/cIGraph_components.c
15
+ ext/cIGraph_dijkstra.c
14
16
  ext/cIGraph_direction.c
15
17
  ext/cIGraph_error_handlers.c
16
18
  ext/cIGraph_file.c
19
+ ext/cIGraph_generators_random.c
20
+ ext/cIGraph_independent_vertex_sets.c
21
+ ext/cIGraph_isomorphism.c
17
22
  ext/cIGraph_iterators.c
18
23
  ext/cIGraph_kcores.c
19
24
  ext/cIGraph_layout.c
20
25
  ext/cIGraph_matrix.c
26
+ ext/cIGraph_motif.c
21
27
  ext/cIGraph_operators.c
22
28
  ext/cIGraph_other_ops.c
23
29
  ext/cIGraph_selectors.c
@@ -30,20 +36,27 @@ ext/cIGraph_utility.c
30
36
  ext/cIGraph_vertex_neighbourhood.c
31
37
  ext/extconf.rb
32
38
  test/tc_add_delete.rb
39
+ test/tc_adj_to_distance.rb
33
40
  test/tc_attributes.rb
34
41
  test/tc_basic_properties.rb
35
42
  test/tc_basic_query.rb
36
43
  test/tc_centrality.rb
44
+ test/tc_cliques.rb
37
45
  test/tc_components.rb
38
46
  test/tc_copy.rb
39
47
  test/tc_cores.rb
40
48
  test/tc_create.rb
49
+ test/tc_dijkstra.rb
41
50
  test/tc_directedness.rb
42
51
  test/tc_error_handling.rb
43
52
  test/tc_file_read_write.rb
53
+ test/tc_generators_random.rb
54
+ test/tc_independent_vertex_sets.rb
55
+ test/tc_isomorphic.rb
44
56
  test/tc_iterators.rb
45
57
  test/tc_layout.rb
46
58
  test/tc_matrix.rb
59
+ test/tc_motif.rb
47
60
  test/tc_other_ops.rb
48
61
  test/tc_selectors.rb
49
62
  test/tc_shortest_paths.rb
@@ -54,3 +67,4 @@ test/tc_topological_sort.rb
54
67
  test/tc_transitivity.rb
55
68
  test/tc_vertex_neighbourhood.rb
56
69
  test/test_all.rb
70
+ test/test_draw.rb
@@ -3,7 +3,7 @@ require 'hoe'
3
3
  $LOAD_PATH.unshift("./ext")
4
4
 
5
5
  class IGraph
6
- VERSION = "0.0"
6
+ VERSION = "0.3.3"
7
7
  end
8
8
 
9
9
  begin
@@ -184,7 +184,7 @@ void Init_igraph(){
184
184
 
185
185
  rb_include_module(cIGraph, rb_mEnumerable);
186
186
 
187
- rb_define_const(cIGraph, "VERSION", rb_str_new2("0.3.2"));
187
+ rb_define_const(cIGraph, "VERSION", rb_str_new2("0.3.3"));
188
188
 
189
189
  rb_define_const(cIGraph, "EDGEORDER_ID", INT2NUM(1));
190
190
  rb_define_const(cIGraph, "EDGEORDER_FROM", INT2NUM(2));
@@ -207,6 +207,14 @@ void Init_igraph(){
207
207
  rb_define_const(cIGraph, "GET_ADJACENCY_LOWER", INT2NUM(1));
208
208
  rb_define_const(cIGraph, "GET_ADJACENCY_BOTH", INT2NUM(2));
209
209
 
210
+ rb_define_const(cIGraph, "ERDOS_RENYI_GNP", INT2NUM(0));
211
+ rb_define_const(cIGraph, "ERDOS_RENYI_GNM", INT2NUM(1));
212
+
213
+ rb_define_singleton_method(cIGraph, "grg_game", cIGraph_grg_game, 3); /* in cIGraph_generators_random.c */
214
+ rb_define_singleton_method(cIGraph, "barabasi_game", cIGraph_barabasi_game, 4); /* in cIGraph_generators_random.c */
215
+ rb_define_singleton_method(cIGraph, "nonlinear_barabasi_game", cIGraph_nonlinear_barabasi_game, 6); /* in cIGraph_generators_random.c */
216
+ rb_define_singleton_method(cIGraph, "erdos_renyi_game", cIGraph_erdos_renyi_game, 5); /* in cIGraph_generators_random.c */
217
+
210
218
  rb_define_method(cIGraph, "[]", cIGraph_get_edge_attr, 2); /* in cIGraph_attribute_handler.c */
211
219
  rb_define_method(cIGraph, "[]=", cIGraph_set_edge_attr, 3); /* in cIGraph_attribute_handler.c */
212
220
  rb_define_alias (cIGraph, "get_edge_attr", "[]");
@@ -256,6 +264,9 @@ void Init_igraph(){
256
264
  rb_define_method(cIGraph, "diameter", cIGraph_diameter, 2); /* in cIGraph_shortest_paths.c */
257
265
  rb_define_method(cIGraph, "girth", cIGraph_girth, 0); /* in cIGraph_shortest_paths.c */
258
266
 
267
+
268
+ rb_define_method(cIGraph, "dijkstra_shortest_paths", cIGraph_dijkstra_shortest_paths, 3);
269
+
259
270
  rb_define_method(cIGraph, "neighbourhood_size", cIGraph_neighborhood_size, 3); /* in cIGraph_vertex_neighbourhood.c */
260
271
  rb_define_method(cIGraph, "neighbourhood", cIGraph_neighborhood, 3); /* in cIGraph_vertex_neighbourhood.c */
261
272
  rb_define_method(cIGraph, "neighbourhood_graphs", cIGraph_neighborhood_graphs, 3); /* in cIGraph_vertex_neighbourhood.c */
@@ -296,6 +307,26 @@ void Init_igraph(){
296
307
  rb_define_method(cIGraph, "cocitation", cIGraph_cocitation, 1); /* in cIGraph_other_ops.c */
297
308
  rb_define_method(cIGraph, "get_adjacency", cIGraph_get_adjacency, 1); /* in cIGraph_other_ops.c */
298
309
 
310
+ rb_define_method(cIGraph, "cliques", cIGraph_cliques, 2); /* in cIGraph_cliques.c */
311
+ rb_define_method(cIGraph, "largest_cliques", cIGraph_largest_cliques, 0); /* in cIGraph_cliques.c */
312
+ rb_define_method(cIGraph, "maximal_cliques", cIGraph_maximal_cliques, 0); /* in cIGraph_cliques.c */
313
+ rb_define_method(cIGraph, "clique_number", cIGraph_clique_number, 0); /* in cIGraph_cliques.c */
314
+
315
+ rb_define_method(cIGraph, "independent_vertex_sets", cIGraph_independent_vertex_sets, 2); /* in cIGraph_independent_vertex_sets.c */
316
+ rb_define_method(cIGraph, "largest_independent_vertex_sets", cIGraph_largest_independent_vertex_sets, 0); /* in cIGraph_independent_vertex_sets.c */
317
+ rb_define_method(cIGraph, "maximal_independent_vertex_sets", cIGraph_maximal_independent_vertex_sets, 0); /* in cIGraph_independent_vertex_sets.c */
318
+ rb_define_method(cIGraph, "independence_number", cIGraph_independence_number, 0); /* in cIGraph_independent_vertex_sets.c */
319
+
320
+ rb_define_method(cIGraph, "isomorphic", cIGraph_isomorphic, 1); /* in cIGraph_isomorphism.c */
321
+ rb_define_method(cIGraph, "isomorphic_vf2", cIGraph_isomorphic_vf2, 1); /* in cIGraph_isomorphism.c */
322
+ rb_define_method(cIGraph, "isoclass", cIGraph_isoclass, 0); /* in cIGraph_isomorphism.c */
323
+ rb_define_method(cIGraph, "isoclass_subgraph", cIGraph_isoclass_subgraph, 1); /* in cIGraph_isomorphism.c */
324
+ rb_define_singleton_method(cIGraph, "isoclass_create", cIGraph_isoclass_create, 3); /* in cIGraph_isomorphism.c */
325
+
326
+ rb_define_method(cIGraph, "motifs_randesu", cIGraph_motifs_randesu, 2); /* in cIGraph_motif.c */
327
+ rb_define_method(cIGraph, "motifs_randesu_no", cIGraph_motifs_randesu_no, 2); /* in cIGraph_motif.c */
328
+ rb_define_method(cIGraph, "motifs_randesu_estimate", cIGraph_motifs_randesu_estimate, 4); /* in cIGraph_motif.c */
329
+
299
330
  rb_define_method(cIGraph, "topological_sorting", cIGraph_topological_sorting, 1); /* in cIGraph_topological_sort.c */
300
331
 
301
332
  rb_define_singleton_method(cIGraph, "read_graph_edgelist", cIGraph_read_graph_edgelist, 2); /* in cIGraph_file.c */
@@ -305,9 +336,14 @@ void Init_igraph(){
305
336
  rb_define_method(cIGraph, "write_graph_graphml", cIGraph_write_graph_graphml, 1); /* in cIGraph_file.c */
306
337
  rb_define_method(cIGraph, "write_graph_pajek", cIGraph_write_graph_pajek, 1); /* in cIGraph_file.c */
307
338
 
308
- rb_define_method(cIGraph, "layout_random", cIGraph_layout_random, 0); /* in cIGraph_layout.c */
309
- rb_define_method(cIGraph, "layout_circle", cIGraph_layout_circle, 0); /* in cIGraph_layout.c */
310
- rb_define_method(cIGraph, "layout_fruchterman_reingold", cIGraph_layout_fruchterman_reingold, 6); /* in cIGraph_layout.c */
339
+ rb_define_method(cIGraph, "layout_random", cIGraph_layout_random, 0); /* in cIGraph_layout.c */
340
+ rb_define_method(cIGraph, "layout_circle", cIGraph_layout_circle, 0); /* in cIGraph_layout.c */
341
+ rb_define_method(cIGraph, "layout_fruchterman_reingold", cIGraph_layout_fruchterman_reingold, 6); /* in cIGraph_layout.c */
342
+ rb_define_method(cIGraph, "layout_kamada_kawai", cIGraph_layout_kamada_kawai, 5); /* in cIGraph_layout.c */
343
+ rb_define_method(cIGraph, "layout_reingold_tilford", cIGraph_layout_reingold_tilford, 1); /* in cIGraph_layout.c */
344
+ rb_define_method(cIGraph, "layout_reingold_tilford_circular", cIGraph_layout_reingold_tilford_circular, 1); /* in cIGraph_layout.c */
345
+ rb_define_method(cIGraph, "layout_grid_fruchterman_reingold", cIGraph_layout_grid_fruchterman_reingold, 7); /* in cIGraph_layout.c */
346
+ rb_define_method(cIGraph, "layout_lgl", cIGraph_layout_lgl, 7); /* in cIGraph_layout.c */
311
347
 
312
348
  //Matrix class
313
349
  cIGraphMatrix = rb_define_class("IGraphMatrix", rb_cObject);
@@ -30,6 +30,15 @@ VALUE cIGraph_alloc(VALUE klass);
30
30
  VALUE cIGraph_initialize(int argc, VALUE *argv, VALUE self);
31
31
  VALUE cIGraph_init_copy(VALUE copy, VALUE orig);
32
32
 
33
+ //Random graph generators
34
+ VALUE cIGraph_grg_game (VALUE self, VALUE nodes,
35
+ VALUE radius, VALUE torus);
36
+ VALUE cIGraph_barabasi_game(VALUE self, VALUE nodes,
37
+ VALUE m, VALUE outpref, VALUE directed);
38
+ VALUE cIGraph_nonlinear_barabasi_game(VALUE self, VALUE nodes, VALUE power,
39
+ VALUE m, VALUE outpref, VALUE zeroappeal, VALUE directed);
40
+ VALUE cIGraph_erdos_renyi_game (VALUE self, VALUE type, VALUE nodes, VALUE mp, VALUE directed, VALUE loops);
41
+
33
42
  //Attribute accessors
34
43
  int replace_i(VALUE key, VALUE val, VALUE hash);
35
44
  VALUE cIGraph_get_edge_attr(VALUE self, VALUE from, VALUE to);
@@ -81,6 +90,13 @@ VALUE cIGraph_average_path_length (VALUE self, VALUE directed, VALUE unconn);
81
90
  VALUE cIGraph_diameter (VALUE self, VALUE directed, VALUE unconn);
82
91
  VALUE cIGraph_girth (VALUE self);
83
92
 
93
+ VALUE cIGraph_dijkstra_shortest_paths(VALUE self, VALUE from, VALUE weights, VALUE mode);
94
+ int igraph_dijkstra_shortest_paths(const igraph_t *graph,
95
+ igraph_matrix_t *res,
96
+ const igraph_vs_t from,
97
+ const igraph_vector_t *wghts,
98
+ igraph_neimode_t mode);
99
+
84
100
  //Vertex neighbourhood functions
85
101
  VALUE cIGraph_neighborhood_size (VALUE self, VALUE from, VALUE order, VALUE mode);
86
102
  VALUE cIGraph_neighborhood (VALUE self, VALUE from, VALUE order, VALUE mode);
@@ -130,6 +146,31 @@ VALUE cIGraph_bibcoupling (VALUE self, VALUE vs);
130
146
  VALUE cIGraph_cocitation (VALUE self, VALUE vs);
131
147
  VALUE cIGraph_get_adjacency(VALUE self, VALUE mode);
132
148
 
149
+ //Cliques
150
+ VALUE cIGraph_cliques(VALUE self, VALUE min, VALUE max);
151
+ VALUE cIGraph_largest_cliques(VALUE self);
152
+ VALUE cIGraph_maximal_cliques(VALUE self);
153
+ VALUE cIGraph_clique_number(VALUE self);
154
+
155
+ //Independent vertex sets
156
+ VALUE cIGraph_independent_vertex_sets(VALUE self, VALUE min, VALUE max);
157
+ VALUE cIGraph_largest_independent_vertex_sets(VALUE self);
158
+ VALUE cIGraph_maximal_independent_vertex_sets(VALUE self);
159
+ VALUE cIGraph_independence_number(VALUE self);
160
+
161
+ //Graph isomorphism
162
+ VALUE cIGraph_isomorphic (VALUE self, VALUE g);
163
+ VALUE cIGraph_isomorphic_vf2 (VALUE self, VALUE g);
164
+ VALUE cIGraph_isoclass (VALUE self);
165
+ VALUE cIGraph_isoclass_subgraph(VALUE self, VALUE vs);
166
+ VALUE cIGraph_isoclass_create (VALUE self, VALUE vn, VALUE iso, VALUE dir);
167
+
168
+ //Motifs
169
+ VALUE cIGraph_motifs_randesu (VALUE self, VALUE size, VALUE cuts);
170
+ VALUE cIGraph_motifs_randesu_no (VALUE self, VALUE size, VALUE cuts);
171
+ VALUE cIGraph_motifs_randesu_estimate(VALUE self, VALUE size, VALUE cuts,
172
+ VALUE samplen, VALUE samplev);
173
+
133
174
  //File handling
134
175
  VALUE cIGraph_read_graph_edgelist (VALUE self, VALUE file, VALUE mode);
135
176
  VALUE cIGraph_write_graph_edgelist(VALUE self, VALUE file);
@@ -139,8 +180,8 @@ VALUE cIGraph_read_graph_pajek (VALUE self, VALUE file);
139
180
  VALUE cIGraph_write_graph_pajek (VALUE self, VALUE file);
140
181
 
141
182
  //Layouts
142
- VALUE cIGraph_layout_random(VALUE self);
143
- VALUE cIGraph_layout_circle(VALUE self);
183
+ VALUE cIGraph_layout_random (VALUE self);
184
+ VALUE cIGraph_layout_circle (VALUE self);
144
185
  VALUE cIGraph_layout_fruchterman_reingold(VALUE self,
145
186
  VALUE niter,
146
187
  VALUE maxdelta,
@@ -148,6 +189,33 @@ VALUE cIGraph_layout_fruchterman_reingold(VALUE self,
148
189
  VALUE coolexp,
149
190
  VALUE repulserad,
150
191
  VALUE use_seed);
192
+ VALUE cIGraph_layout_kamada_kawai (VALUE self,
193
+ VALUE niter,
194
+ VALUE sigma,
195
+ VALUE initemp,
196
+ VALUE coolexp,
197
+ VALUE kkconst);
198
+ VALUE cIGraph_layout_reingold_tilford (VALUE self,
199
+ VALUE root);
200
+ VALUE cIGraph_layout_reingold_tilford_circular(VALUE self,
201
+ VALUE root);
202
+ VALUE cIGraph_layout_grid_fruchterman_reingold(VALUE self,
203
+ VALUE niter,
204
+ VALUE maxdelta,
205
+ VALUE area,
206
+ VALUE coolexp,
207
+ VALUE repulserad,
208
+ VALUE cellsize,
209
+ VALUE use_seed);
210
+ VALUE cIGraph_layout_lgl(VALUE self,
211
+ VALUE maxit,
212
+ VALUE maxdelta,
213
+ VALUE area,
214
+ VALUE coolexp,
215
+ VALUE repulserad,
216
+ VALUE cellsize,
217
+ VALUE proot);
218
+
151
219
 
152
220
  //Attributes
153
221
  int cIGraph_attribute_init(igraph_t *graph,
@@ -189,6 +189,7 @@ int cIGraph_attribute_add_vertices(igraph_t *graph, long int nv, igraph_vector_p
189
189
  VALUE values;
190
190
 
191
191
  if(attr){
192
+
192
193
  if(igraph_vector_ptr_size(attr) > 0 && ((igraph_i_attribute_record_t*)VECTOR(*attr)[0])->type == IGRAPH_ATTRIBUTE_PY_OBJECT){
193
194
 
194
195
  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
234
235
  rb_ary_push(vertex_array,record);
235
236
  }
236
237
  }
238
+ } else {
239
+ //Default: Add numbered vertices.
240
+ for(i=0;i<nv;i++){
241
+ rb_ary_push(vertex_array,INT2NUM(i));
242
+ }
237
243
  }
238
244
 
239
245
  #ifdef DEBUG
@@ -0,0 +1,178 @@
1
+ #include "igraph.h"
2
+ #include "ruby.h"
3
+ #include "cIGraph.h"
4
+
5
+ /* call-seq:
6
+ * graph.cliques(min_size,max_size) -> Array
7
+ *
8
+ * Find all or some cliques in a graph
9
+ *
10
+ * Cliques are fully connected subgraphs of a graph.
11
+ *
12
+ * If you are only interested in the size of the largest clique in the
13
+ * graph, use IGraph#clique_number instead.
14
+ */
15
+
16
+ VALUE cIGraph_cliques(VALUE self, VALUE min, VALUE max){
17
+
18
+ igraph_t *graph;
19
+ igraph_vector_ptr_t res;
20
+ igraph_vector_t *vec;
21
+ int i;
22
+ int j;
23
+ VALUE clique;
24
+ VALUE object;
25
+ VALUE cliques = rb_ary_new();
26
+
27
+ Data_Get_Struct(self, igraph_t, graph);
28
+
29
+ igraph_vector_ptr_init(&res,0);
30
+
31
+ igraph_cliques(graph, &res, NUM2INT(min), NUM2INT(max));
32
+
33
+ for(i=0; i<igraph_vector_ptr_size(&res); i++){
34
+ clique = rb_ary_new();
35
+ rb_ary_push(cliques,clique);
36
+ vec = VECTOR(res)[i];
37
+ for(j=0; j<igraph_vector_size(vec); j++){
38
+ vec = VECTOR(res)[i];
39
+ object = cIGraph_get_vertex_object(self,VECTOR(*vec)[j]);
40
+ rb_ary_push(clique,object);
41
+ }
42
+ }
43
+
44
+ for(i=0;i<igraph_vector_ptr_size(&res);i++){
45
+ igraph_vector_destroy(VECTOR(res)[i]);
46
+ free(VECTOR(res)[i]);
47
+ }
48
+
49
+ igraph_vector_ptr_destroy(&res);
50
+
51
+ return cliques;
52
+
53
+ }
54
+
55
+ /* call-seq:
56
+ * graph.largest_cliques() -> Array
57
+ *
58
+ * Finds the largest clique(s) in a graph.
59
+ *
60
+ * A clique is largest (quite intuitively) if there is no other clique in
61
+ * the graph which contains more vertices.
62
+ *
63
+ * Note that this is not neccessarily the same as a maximal clique, ie.
64
+ * the largest cliques are always maximal but a maximal clique is not always
65
+ * largest.
66
+ */
67
+
68
+ VALUE cIGraph_largest_cliques(VALUE self){
69
+
70
+ igraph_t *graph;
71
+ igraph_vector_ptr_t res;
72
+ igraph_vector_t *vec;
73
+ int i;
74
+ int j;
75
+ VALUE clique;
76
+ VALUE object;
77
+ VALUE cliques = rb_ary_new();
78
+
79
+ Data_Get_Struct(self, igraph_t, graph);
80
+
81
+ igraph_vector_ptr_init(&res,0);
82
+
83
+ igraph_largest_cliques(graph, &res);
84
+
85
+ for(i=0; i<igraph_vector_ptr_size(&res); i++){
86
+ clique = rb_ary_new();
87
+ rb_ary_push(cliques,clique);
88
+ vec = VECTOR(res)[i];
89
+ for(j=0; j<igraph_vector_size(vec); j++){
90
+ vec = VECTOR(res)[i];
91
+ object = cIGraph_get_vertex_object(self,VECTOR(*vec)[j]);
92
+ rb_ary_push(clique,object);
93
+ }
94
+ }
95
+
96
+ for(i=0;i<igraph_vector_ptr_size(&res);i++){
97
+ igraph_vector_destroy(VECTOR(res)[i]);
98
+ free(VECTOR(res)[i]);
99
+ }
100
+
101
+ igraph_vector_ptr_destroy(&res);
102
+
103
+ return cliques;
104
+
105
+ }
106
+
107
+ /* call-seq:
108
+ * graph.maximal_cliques() -> Array
109
+ *
110
+ * Find all maximal cliques of a graph
111
+ *
112
+ * A maximal clique is a clique which can't be extended any more by adding a
113
+ * new vertex to it. This is actually implemented by looking for a maximal
114
+ * independent vertex set in the complementer of the graph.
115
+ *
116
+ * If you are only interested in the size of the largest clique in the
117
+ * graph, use IGraph#clique_number instead.
118
+ */
119
+
120
+ VALUE cIGraph_maximal_cliques(VALUE self){
121
+
122
+ igraph_t *graph;
123
+ igraph_vector_ptr_t res;
124
+ igraph_vector_t *vec;
125
+ int i;
126
+ int j;
127
+ VALUE clique;
128
+ VALUE object;
129
+ VALUE cliques = rb_ary_new();
130
+
131
+ Data_Get_Struct(self, igraph_t, graph);
132
+
133
+ igraph_vector_ptr_init(&res,0);
134
+
135
+ igraph_maximal_cliques(graph, &res);
136
+
137
+ for(i=0; i<igraph_vector_ptr_size(&res); i++){
138
+ clique = rb_ary_new();
139
+ rb_ary_push(cliques,clique);
140
+ vec = VECTOR(res)[i];
141
+ for(j=0; j<igraph_vector_size(vec); j++){
142
+ vec = VECTOR(res)[i];
143
+ object = cIGraph_get_vertex_object(self,VECTOR(*vec)[j]);
144
+ rb_ary_push(clique,object);
145
+ }
146
+ }
147
+
148
+ for(i=0;i<igraph_vector_ptr_size(&res);i++){
149
+ igraph_vector_destroy(VECTOR(res)[i]);
150
+ free(VECTOR(res)[i]);
151
+ }
152
+
153
+ igraph_vector_ptr_destroy(&res);
154
+
155
+ return cliques;
156
+
157
+ }
158
+
159
+ /* call-seq:
160
+ * graph.clique_number() -> Integer
161
+ *
162
+ * Find the clique number of the graph
163
+ *
164
+ * The clique number of a graph is the size of the largest clique.
165
+ */
166
+
167
+ VALUE cIGraph_clique_number(VALUE self){
168
+
169
+ igraph_t *graph;
170
+ igraph_integer_t res;
171
+
172
+ Data_Get_Struct(self, igraph_t, graph);
173
+
174
+ igraph_clique_number(graph, &res);
175
+
176
+ return INT2NUM(res);
177
+
178
+ }
@@ -0,0 +1,258 @@
1
+ #include "igraph.h"
2
+ #include "ruby.h"
3
+ #include "cIGraph.h"
4
+
5
+ /* call-seq:
6
+ * graph.dijkstra_shortest_paths(varray,weights,mode) -> Array
7
+ *
8
+ * Calculates the length of the shortest paths from each of the vertices in
9
+ * the varray Array to all of the other vertices in the graph given a set of
10
+ * edge weights given in the weights Array. The result
11
+ * is returned as an Array of Array. Each top-level Array contains the results
12
+ * for a vertex in the varray Array. Each entry in the Array is the path length
13
+ * to another vertex in the graph in vertex order (the order the vertices were
14
+ * added to the graph. (This should probalby be changed to give a Hash of Hash
15
+ * to allow easier look up.)
16
+ */
17
+ VALUE cIGraph_dijkstra_shortest_paths(VALUE self, VALUE from, VALUE weights, VALUE mode){
18
+
19
+ igraph_t *graph;
20
+ igraph_vs_t vids;
21
+ igraph_vector_t vidv;
22
+ igraph_vector_t wghts;
23
+ igraph_neimode_t pmode = NUM2INT(mode);
24
+ igraph_matrix_t res;
25
+ int i;
26
+ int j;
27
+ VALUE row;
28
+ VALUE path_length;
29
+ VALUE matrix = rb_ary_new();
30
+ int n_row;
31
+ int n_col;
32
+
33
+ Data_Get_Struct(self, igraph_t, graph);
34
+
35
+ n_row = NUM2INT(rb_funcall(from,rb_intern("length"),0));
36
+ n_col = igraph_vcount(graph);
37
+
38
+ //matrix to hold the results of the calculations
39
+ igraph_matrix_init(&res,n_row,n_col);
40
+
41
+ igraph_vector_init(&wghts,RARRAY(weights)->len);
42
+
43
+ for(i=0;i<RARRAY(weights)->len;i++){
44
+ VECTOR(wghts)[i] = NUM2DBL(RARRAY(weights)->ptr[i]);
45
+ }
46
+
47
+ //Convert an array of vertices to a vector of vertex ids
48
+ igraph_vector_init_int(&vidv,0);
49
+ cIGraph_vertex_arr_to_id_vec(self,from,&vidv);
50
+ //create vertex selector from the vecotr of ids
51
+ igraph_vs_vector(&vids,&vidv);
52
+
53
+ igraph_dijkstra_shortest_paths(graph,&res,vids,&wghts,pmode);
54
+
55
+ for(i=0; i<igraph_matrix_nrow(&res); i++){
56
+ row = rb_ary_new();
57
+ rb_ary_push(matrix,row);
58
+ for(j=0; j<igraph_matrix_ncol(&res); j++){
59
+ path_length = MATRIX(res,i,j) == n_col ? Qnil : rb_float_new(MATRIX(res,i,j));
60
+ rb_ary_push(row,path_length);
61
+ }
62
+ }
63
+
64
+ igraph_vector_destroy(&vidv);
65
+ igraph_matrix_destroy(&res);
66
+ igraph_vs_destroy(&vids);
67
+
68
+ return matrix;
69
+
70
+ }
71
+
72
+ /* call-seq:
73
+ * graph.get_shortest_paths(from,to_array,mode) -> Array
74
+ *
75
+ * Calculates the paths from the vertex specified as from to each vertex in the
76
+ * to_array Array. Returns an Array of Arrays. Each top level Array represents
77
+ * a path and each entry in each Array is a vertex on the path. mode
78
+ * represents the type of shortest paths to be calculated: IGraph::OUT
79
+ * the outgoing paths are calculated. IGraph::IN the incoming paths are
80
+ * calculated. IGraph::ALL the directed graph is considered as an undirected
81
+ * one for the computation.
82
+ */
83
+ VALUE cIGraph_get_dijkstra_shortest_paths(VALUE self, VALUE from, VALUE to, VALUE mode){
84
+
85
+ igraph_t *graph;
86
+
87
+ igraph_integer_t from_vid;
88
+ igraph_vs_t to_vids;
89
+ igraph_vector_t to_vidv;
90
+
91
+ igraph_neimode_t pmode = NUM2INT(mode);
92
+
93
+ igraph_vector_ptr_t res;
94
+ igraph_vector_t *path_v;
95
+
96
+ int i;
97
+ int j;
98
+ VALUE path;
99
+ VALUE matrix = rb_ary_new();
100
+ int n_paths;
101
+
102
+ Data_Get_Struct(self, igraph_t, graph);
103
+
104
+ n_paths = RARRAY(to)->len;
105
+
106
+ //vector to hold the results of the calculations
107
+ igraph_vector_ptr_init(&res,0);
108
+ for(i=0;i<n_paths;i++){
109
+ path_v = malloc(sizeof(igraph_vector_t));
110
+ igraph_vector_init(path_v,0);
111
+ igraph_vector_ptr_push_back(&res,path_v);
112
+ }
113
+
114
+ //Convert an array of vertices to a vector of vertex ids
115
+ igraph_vector_init_int(&to_vidv,0);
116
+ cIGraph_vertex_arr_to_id_vec(self,to,&to_vidv);
117
+ //create vertex selector from the vecotr of ids
118
+ igraph_vs_vector(&to_vids,&to_vidv);
119
+
120
+ //The id of the vertex from where we are counting
121
+ from_vid = cIGraph_get_vertex_id(self, from);
122
+
123
+ igraph_get_shortest_paths(graph,&res,from_vid,to_vids,pmode);
124
+
125
+ for(i=0; i<n_paths; i++){
126
+ path = rb_ary_new();
127
+ rb_ary_push(matrix,path);
128
+ path_v = VECTOR(res)[i];
129
+ for(j=0; j<igraph_vector_size(VECTOR(res)[i]); j++){
130
+ rb_ary_push(path,cIGraph_get_vertex_object(self,VECTOR(*path_v)[j]));
131
+ }
132
+ }
133
+
134
+ for(i=0;i<n_paths;i++){
135
+ igraph_vector_destroy(VECTOR(res)[i]);
136
+ free(VECTOR(res)[i]);
137
+ }
138
+
139
+ igraph_vector_destroy(&to_vidv);
140
+ igraph_vector_ptr_destroy(&res);
141
+ igraph_vs_destroy(&to_vids);
142
+
143
+ return matrix;
144
+
145
+ }
146
+
147
+ int igraph_dijkstra_shortest_paths(const igraph_t *graph,
148
+ igraph_matrix_t *res,
149
+ const igraph_vs_t from,
150
+ const igraph_vector_t *wghts,
151
+ igraph_neimode_t mode) {
152
+
153
+ long int no_of_nodes=igraph_vcount(graph);
154
+ long int no_of_from;
155
+ igraph_real_t *shortest;
156
+ igraph_real_t min,alt;
157
+
158
+ int i, j, uj, included;
159
+ igraph_integer_t eid, u,v;
160
+ igraph_vector_t q;
161
+ igraph_vit_t fromvit;
162
+ igraph_vector_t neis;
163
+
164
+ IGRAPH_CHECK(igraph_vit_create(graph, from, &fromvit));
165
+ IGRAPH_FINALLY(igraph_vit_destroy, &fromvit);
166
+
167
+ no_of_from=IGRAPH_VIT_SIZE(fromvit);
168
+
169
+ if (mode != IGRAPH_OUT && mode != IGRAPH_IN &&
170
+ mode != IGRAPH_ALL) {
171
+ IGRAPH_ERROR("Invalid mode argument", IGRAPH_EINVMODE);
172
+ }
173
+ shortest=calloc(no_of_nodes, sizeof(igraph_real_t));
174
+ if (shortest==0) {
175
+ IGRAPH_ERROR("shortest paths failed", IGRAPH_ENOMEM);
176
+ }
177
+ IGRAPH_FINALLY(free, shortest);
178
+
179
+ IGRAPH_CHECK(igraph_matrix_resize(res, no_of_from, no_of_nodes));
180
+ igraph_matrix_null(res);
181
+
182
+ for (IGRAPH_VIT_RESET(fromvit), i=0;
183
+ !IGRAPH_VIT_END(fromvit);
184
+ IGRAPH_VIT_NEXT(fromvit), i++) {
185
+
186
+ //Start shortest and previous
187
+ for(j=0;j<no_of_nodes;j++){
188
+ shortest[j] = INFINITY;
189
+ //memset(previous,NAN, no_of_nodes);
190
+ }
191
+
192
+ shortest[(int)IGRAPH_VIT_GET(fromvit)] = 0;
193
+ igraph_vector_init_seq(&q,0,no_of_nodes-1);
194
+
195
+ while(igraph_vector_size(&q) != 0){
196
+
197
+ min = INFINITY;
198
+ u = no_of_nodes;
199
+ uj = igraph_vector_size(&q);
200
+ for(j=0;j<igraph_vector_size(&q);j++){
201
+ v = VECTOR(q)[j];
202
+ if(shortest[(int)v] < min){
203
+ min = shortest[(int)v];
204
+ u = v;
205
+ uj = j;
206
+ }
207
+ }
208
+
209
+ if(min == INFINITY)
210
+ break;
211
+
212
+ igraph_vector_remove(&q,uj);
213
+
214
+ igraph_vector_init(&neis,0);
215
+ igraph_neighbors(graph,&neis,u,mode);
216
+
217
+ for(j=0;j<igraph_vector_size(&neis);j++){
218
+
219
+ v = VECTOR(neis)[j];
220
+
221
+ //v must be in Q
222
+ included = 0;
223
+ for(j=0;j<igraph_vector_size(&q);j++){
224
+ if(v == VECTOR(q)[j]){
225
+ included = 1;
226
+ break;
227
+ }
228
+ }
229
+
230
+ if(!included)
231
+ continue;
232
+
233
+ igraph_get_eid(graph,&eid,u,v,1);
234
+
235
+ alt = shortest[(int)u] + VECTOR(*wghts)[(int)eid];
236
+
237
+ if(alt < shortest[(int)v]){
238
+ shortest[(int)v] = alt;
239
+ }
240
+ }
241
+ igraph_vector_destroy(&neis);
242
+ }
243
+
244
+ for(j=0;j<no_of_nodes;j++){
245
+ MATRIX(*res,i,j) = shortest[j];
246
+ }
247
+
248
+ igraph_vector_destroy(&q);
249
+
250
+ }
251
+
252
+ /* Clean */
253
+ free(shortest);
254
+ igraph_vit_destroy(&fromvit);
255
+ IGRAPH_FINALLY_CLEAN(2);
256
+
257
+ return 0;
258
+ }