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.
- data/Manifest.txt +14 -0
- data/Rakefile.rb +1 -1
- data/ext/cIGraph.c +40 -4
- data/ext/cIGraph.h +70 -2
- data/ext/cIGraph_attribute_handler.c +6 -0
- data/ext/cIGraph_cliques.c +178 -0
- data/ext/cIGraph_dijkstra.c +258 -0
- data/ext/cIGraph_generators_random.c +72 -0
- data/ext/cIGraph_independent_vertex_sets.c +182 -0
- data/ext/cIGraph_isomorphism.c +137 -0
- data/ext/cIGraph_layout.c +174 -2
- data/ext/cIGraph_motif.c +109 -0
- data/ext/cIGraph_spectral.c +1 -1
- data/test/tc_adj_to_distance.rb +24 -0
- data/test/tc_cliques.rb +21 -0
- data/test/tc_dijkstra.rb +11 -0
- data/test/tc_generators_random.rb +26 -0
- data/test/tc_independent_vertex_sets.rb +21 -0
- data/test/tc_isomorphic.rb +33 -0
- data/test/tc_layout.rb +35 -0
- data/test/tc_motif.rb +19 -0
- data/test/test_all.rb +8 -2
- data/test/test_draw.rb +61 -0
- metadata +16 -2
data/Manifest.txt
CHANGED
@@ -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
|
data/Rakefile.rb
CHANGED
data/ext/cIGraph.c
CHANGED
@@ -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.
|
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",
|
309
|
-
rb_define_method(cIGraph, "layout_circle",
|
310
|
-
rb_define_method(cIGraph, "layout_fruchterman_reingold",
|
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);
|
data/ext/cIGraph.h
CHANGED
@@ -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
|
+
}
|