igraph 0.1.1 → 0.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/History.txt +14 -2
- data/Manifest.txt +17 -0
- data/README.txt +16 -11
- data/ext/cIGraph.c +197 -61
- data/ext/cIGraph.h +155 -8
- data/ext/cIGraph_add_delete.c +146 -66
- data/ext/cIGraph_attribute_handler.c +758 -0
- data/ext/cIGraph_centrality.c +264 -0
- data/ext/cIGraph_components.c +154 -0
- data/ext/cIGraph_file.c +213 -0
- data/ext/cIGraph_layout.c +77 -0
- data/ext/cIGraph_matrix.c +241 -0
- data/ext/cIGraph_selectors.c +95 -7
- data/ext/cIGraph_shortest_paths.c +196 -2
- data/ext/cIGraph_topological_sort.c +43 -0
- data/ext/cIGraph_utility.c +29 -14
- data/ext/cIGraph_vertex_neighbourhood.c +158 -0
- data/test/tc_add_delete.rb +37 -0
- data/test/tc_attributes.rb +29 -0
- data/test/tc_basic_properties.rb +1 -1
- data/test/tc_centrality.rb +33 -0
- data/test/tc_components.rb +25 -0
- data/test/tc_copy.rb +13 -0
- data/test/tc_file_read_write.rb +161 -0
- data/test/tc_layout.rb +26 -0
- data/test/tc_matrix.rb +32 -0
- data/test/tc_selectors.rb +15 -0
- data/test/tc_shortest_paths.rb +25 -2
- data/test/tc_topological_sort.rb +10 -0
- data/test/tc_vertex_neighbourhood.rb +29 -0
- data/test/test_all.rb +9 -0
- metadata +21 -4
@@ -0,0 +1,43 @@
|
|
1
|
+
#include "igraph.h"
|
2
|
+
#include "ruby.h"
|
3
|
+
#include "cIGraph.h"
|
4
|
+
|
5
|
+
/* call-seq:
|
6
|
+
* graph.topological_sorting(mode) -> Array
|
7
|
+
*
|
8
|
+
* Calculate a possible topological sorting of the graph. A topological
|
9
|
+
* sorting of a directed acyclic graph is a linear ordering of its nodes
|
10
|
+
* where each node comes before all nodes to which it has edges. Every DAG
|
11
|
+
* has at least one topological sort, and may have many. This function
|
12
|
+
* returns a possible topological sort among them. If the graph is not
|
13
|
+
* acyclic (it has at least one cycle), a partial topological sort is
|
14
|
+
* returned and a warning is issued. mode specifies how to use the direction
|
15
|
+
* of the edges. For IGRAPH_OUT, the sorting order ensures that each node
|
16
|
+
* comes before all nodes to which it has edges, so nodes with no incoming
|
17
|
+
* edges go first. For IGRAPH_IN, it is quite the opposite: each node comes
|
18
|
+
* before all nodes from which it receives edges. Nodes with no outgoing
|
19
|
+
* edges go first.
|
20
|
+
*/
|
21
|
+
VALUE cIGraph_topological_sorting(VALUE self, VALUE mode){
|
22
|
+
|
23
|
+
igraph_t *graph;
|
24
|
+
igraph_vector_t res;
|
25
|
+
igraph_neimode_t pmode = NUM2INT(mode);
|
26
|
+
VALUE result = rb_ary_new();
|
27
|
+
int i;
|
28
|
+
|
29
|
+
igraph_vector_init_int(&res,0);
|
30
|
+
|
31
|
+
Data_Get_Struct(self, igraph_t, graph);
|
32
|
+
|
33
|
+
igraph_topological_sorting(graph, &res, pmode);
|
34
|
+
|
35
|
+
for(i=0;i<igraph_vector_size(&res);i++){
|
36
|
+
rb_ary_push(result,cIGraph_get_vertex_object(self,VECTOR(res)[i]));
|
37
|
+
}
|
38
|
+
|
39
|
+
igraph_vector_destroy(&res);
|
40
|
+
|
41
|
+
return result;
|
42
|
+
|
43
|
+
}
|
data/ext/cIGraph_utility.c
CHANGED
@@ -4,12 +4,19 @@
|
|
4
4
|
|
5
5
|
igraph_integer_t cIGraph_get_vertex_id(VALUE graph, VALUE v){
|
6
6
|
|
7
|
-
VALUE
|
7
|
+
VALUE v_ary;
|
8
|
+
VALUE idx;
|
9
|
+
igraph_t *igraph;
|
8
10
|
|
9
|
-
|
11
|
+
Data_Get_Struct(graph, igraph_t, igraph);
|
12
|
+
v_ary = ((VALUE*)igraph->attr)[0];
|
10
13
|
|
11
|
-
|
12
|
-
|
14
|
+
idx = rb_funcall(v_ary,rb_intern("index"),1,v);
|
15
|
+
|
16
|
+
if(idx != Qnil)
|
17
|
+
return NUM2INT(idx);
|
18
|
+
|
19
|
+
rb_raise(cIGraphError, "Unable to find vertex\n");
|
13
20
|
|
14
21
|
return -1;
|
15
22
|
|
@@ -17,14 +24,16 @@ igraph_integer_t cIGraph_get_vertex_id(VALUE graph, VALUE v){
|
|
17
24
|
|
18
25
|
VALUE cIGraph_get_vertex_object(VALUE graph, igraph_integer_t n){
|
19
26
|
|
20
|
-
VALUE
|
27
|
+
VALUE v_ary;
|
28
|
+
VALUE obj;
|
29
|
+
igraph_t *igraph;
|
21
30
|
|
22
|
-
|
31
|
+
Data_Get_Struct(graph, igraph_t, igraph);
|
32
|
+
v_ary = ((VALUE*)igraph->attr)[0];
|
23
33
|
|
24
|
-
|
25
|
-
return rb_hash_aref(vertex_h,INT2NUM(n));
|
34
|
+
obj = rb_ary_entry(v_ary,n);
|
26
35
|
|
27
|
-
return
|
36
|
+
return obj;
|
28
37
|
|
29
38
|
}
|
30
39
|
|
@@ -32,6 +41,7 @@ int cIGraph_vertex_arr_to_id_vec(VALUE graph, VALUE va, igraph_vector_t *nv){
|
|
32
41
|
|
33
42
|
VALUE vertex;
|
34
43
|
VALUE tmp;
|
44
|
+
VALUE i;
|
35
45
|
|
36
46
|
tmp = rb_check_array_type(va);
|
37
47
|
|
@@ -40,10 +50,9 @@ int cIGraph_vertex_arr_to_id_vec(VALUE graph, VALUE va, igraph_vector_t *nv){
|
|
40
50
|
|
41
51
|
//Initialize edge vector
|
42
52
|
igraph_vector_init_int(nv,0);
|
43
|
-
|
44
|
-
|
53
|
+
for (i=0; i<RARRAY(va)->len; i++) {
|
54
|
+
vertex = RARRAY(va)->ptr[i];
|
45
55
|
igraph_vector_push_back(nv,cIGraph_get_vertex_id(graph, vertex));
|
46
|
-
vertex = rb_ary_shift(va);
|
47
56
|
}
|
48
57
|
|
49
58
|
return 0;
|
@@ -51,6 +60,12 @@ int cIGraph_vertex_arr_to_id_vec(VALUE graph, VALUE va, igraph_vector_t *nv){
|
|
51
60
|
}
|
52
61
|
|
53
62
|
VALUE cIGraph_include(VALUE self, VALUE v){
|
54
|
-
|
55
|
-
|
63
|
+
|
64
|
+
VALUE v_ary;
|
65
|
+
igraph_t *igraph;
|
66
|
+
|
67
|
+
Data_Get_Struct(self, igraph_t, igraph);
|
68
|
+
v_ary = ((VALUE*)igraph->attr)[0];
|
69
|
+
|
70
|
+
return rb_ary_includes(v_ary,v);
|
56
71
|
}
|
@@ -0,0 +1,158 @@
|
|
1
|
+
#include "igraph.h"
|
2
|
+
#include "ruby.h"
|
3
|
+
#include "cIGraph.h"
|
4
|
+
|
5
|
+
/* call-seq:
|
6
|
+
* graph.neighbourhood_size(vertices,order,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. The result
|
10
|
+
* is returned as an Array of Array. Each top-level Array contains the results
|
11
|
+
* for a vertex in the varray Array. Each entry in the Array is the path length
|
12
|
+
* to another vertex in the graph in vertex order (the order the vertices were
|
13
|
+
* added to the graph. (This should probalby be changed to give a Hash of Hash
|
14
|
+
* to allow easier look up.)
|
15
|
+
*/
|
16
|
+
VALUE cIGraph_neighborhood_size(VALUE self, VALUE from, VALUE order, VALUE mode){
|
17
|
+
|
18
|
+
igraph_t *graph;
|
19
|
+
igraph_vs_t vids;
|
20
|
+
igraph_vector_t vidv;
|
21
|
+
igraph_neimode_t pmode = NUM2INT(mode);
|
22
|
+
igraph_vector_t res;
|
23
|
+
int i;
|
24
|
+
|
25
|
+
VALUE sizes = rb_ary_new();
|
26
|
+
|
27
|
+
Data_Get_Struct(self, igraph_t, graph);
|
28
|
+
|
29
|
+
igraph_vector_init(&res,0);
|
30
|
+
|
31
|
+
//Convert an array of vertices to a vector of vertex ids
|
32
|
+
cIGraph_vertex_arr_to_id_vec(self,from,&vidv);
|
33
|
+
//create vertex selector from the vecotr of ids
|
34
|
+
igraph_vs_vector(&vids,&vidv);
|
35
|
+
|
36
|
+
igraph_neighborhood_size(graph,&res,vids,NUM2INT(order),pmode);
|
37
|
+
|
38
|
+
for(i=0; i<igraph_vector_size(&res); i++){
|
39
|
+
rb_ary_push(sizes,INT2NUM(VECTOR(res)[i]));
|
40
|
+
}
|
41
|
+
|
42
|
+
igraph_vector_destroy(&vidv);
|
43
|
+
igraph_vector_destroy(&res);
|
44
|
+
igraph_vs_destroy(&vids);
|
45
|
+
|
46
|
+
return sizes;
|
47
|
+
|
48
|
+
}
|
49
|
+
|
50
|
+
/* call-seq:
|
51
|
+
* graph.neighbourhood(vertices,order,mode) -> Array
|
52
|
+
*
|
53
|
+
* Calculates the length of the shortest paths from each of the vertices in
|
54
|
+
* the varray Array to all of the other vertices in the graph. The result
|
55
|
+
* is returned as an Array of Array. Each top-level Array contains the results
|
56
|
+
* for a vertex in the varray Array. Each entry in the Array is the path length
|
57
|
+
* to another vertex in the graph in vertex order (the order the vertices were
|
58
|
+
* added to the graph. (This should probalby be changed to give a Hash of Hash
|
59
|
+
* to allow easier look up.)
|
60
|
+
*/
|
61
|
+
VALUE cIGraph_neighborhood(VALUE self, VALUE from, VALUE order, VALUE mode){
|
62
|
+
|
63
|
+
igraph_t *graph;
|
64
|
+
igraph_vs_t vids;
|
65
|
+
igraph_vector_t vidv;
|
66
|
+
igraph_neimode_t pmode = NUM2INT(mode);
|
67
|
+
igraph_vector_ptr_t res;
|
68
|
+
igraph_vector_t *path_v;
|
69
|
+
int i;
|
70
|
+
int j;
|
71
|
+
|
72
|
+
VALUE matrix = rb_ary_new();
|
73
|
+
VALUE neighbourhood;
|
74
|
+
|
75
|
+
Data_Get_Struct(self, igraph_t, graph);
|
76
|
+
|
77
|
+
igraph_vector_ptr_init(&res,0);
|
78
|
+
|
79
|
+
//Convert an array of vertices to a vector of vertex ids
|
80
|
+
cIGraph_vertex_arr_to_id_vec(self,from,&vidv);
|
81
|
+
//create vertex selector from the vecotr of ids
|
82
|
+
igraph_vs_vector(&vids,&vidv);
|
83
|
+
|
84
|
+
igraph_neighborhood(graph,&res,vids,NUM2INT(order),pmode);
|
85
|
+
|
86
|
+
for(i=0; i<igraph_vector_ptr_size(&res); i++){
|
87
|
+
neighbourhood = rb_ary_new();
|
88
|
+
rb_ary_push(matrix,neighbourhood);
|
89
|
+
path_v = VECTOR(res)[i];
|
90
|
+
for(j=0; j<igraph_vector_size(VECTOR(res)[i]); j++){
|
91
|
+
rb_ary_push(neighbourhood,cIGraph_get_vertex_object(self,VECTOR(*path_v)[j]));
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
for(i=0;i<igraph_vector_ptr_size(&res);i++){
|
96
|
+
igraph_vector_destroy(VECTOR(res)[i]);
|
97
|
+
}
|
98
|
+
|
99
|
+
igraph_vector_destroy(&vidv);
|
100
|
+
igraph_vector_ptr_destroy(&res);
|
101
|
+
igraph_vs_destroy(&vids);
|
102
|
+
|
103
|
+
return matrix;
|
104
|
+
|
105
|
+
}
|
106
|
+
|
107
|
+
/* call-seq:
|
108
|
+
* graph.neighbourhood_graph(vertices,order,mode) -> Array
|
109
|
+
*
|
110
|
+
* Calculates the length of the shortest paths from each of the vertices in
|
111
|
+
* the varray Array to all of the other vertices in the graph. The result
|
112
|
+
* is returned as an Array of Array. Each top-level Array contains the results
|
113
|
+
* for a vertex in the varray Array. Each entry in the Array is the path length
|
114
|
+
* to another vertex in the graph in vertex order (the order the vertices were
|
115
|
+
* added to the graph. (This should probalby be changed to give a Hash of Hash
|
116
|
+
* to allow easier look up.)
|
117
|
+
*/
|
118
|
+
VALUE cIGraph_neighborhood_graphs(VALUE self, VALUE from, VALUE order, VALUE mode){
|
119
|
+
|
120
|
+
igraph_t *graph;
|
121
|
+
igraph_t *n_graph;
|
122
|
+
igraph_vs_t vids;
|
123
|
+
igraph_vector_t vidv;
|
124
|
+
igraph_neimode_t pmode = NUM2INT(mode);
|
125
|
+
igraph_vector_ptr_t res;
|
126
|
+
int i;
|
127
|
+
|
128
|
+
VALUE n_graph_obj;
|
129
|
+
VALUE result = rb_ary_new();
|
130
|
+
|
131
|
+
Data_Get_Struct(self, igraph_t, graph);
|
132
|
+
|
133
|
+
igraph_vector_ptr_init(&res,0);
|
134
|
+
|
135
|
+
//Convert an array of vertices to a vector of vertex ids
|
136
|
+
cIGraph_vertex_arr_to_id_vec(self,from,&vidv);
|
137
|
+
//create vertex selector from the vecotr of ids
|
138
|
+
igraph_vs_vector(&vids,&vidv);
|
139
|
+
|
140
|
+
igraph_neighborhood_graphs(graph,&res,vids,NUM2INT(order),pmode);
|
141
|
+
|
142
|
+
for(i=0; i<igraph_vector_ptr_size(&res); i++){
|
143
|
+
n_graph = VECTOR(res)[i];
|
144
|
+
n_graph_obj = Data_Wrap_Struct(cIGraph, cIGraph_mark, cIGraph_free, n_graph);
|
145
|
+
rb_ary_push(result,n_graph_obj);
|
146
|
+
}
|
147
|
+
|
148
|
+
igraph_vector_destroy(&vidv);
|
149
|
+
igraph_vector_ptr_destroy(&res);
|
150
|
+
igraph_vs_destroy(&vids);
|
151
|
+
|
152
|
+
return result;
|
153
|
+
|
154
|
+
}
|
155
|
+
|
156
|
+
|
157
|
+
|
158
|
+
|
data/test/tc_add_delete.rb
CHANGED
@@ -46,4 +46,41 @@ class TestGraph < Test::Unit::TestCase
|
|
46
46
|
assert_equal [0], graph.degree(['E'],IGraph::ALL,true)
|
47
47
|
end
|
48
48
|
|
49
|
+
def test_delete_vertex
|
50
|
+
graph = IGraph.new(['A','B','C','D'],true,[1,2])
|
51
|
+
assert_nothing_raised do
|
52
|
+
graph.delete_vertex('A')
|
53
|
+
end
|
54
|
+
assert_equal false, graph.include?('A')
|
55
|
+
assert_equal 3, graph.vcount
|
56
|
+
assert_equal 1, graph.ecount
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_delete_edge
|
60
|
+
graph = IGraph.new(['A','B','C','D'],true)
|
61
|
+
assert_equal true, graph.are_connected?('A','B')
|
62
|
+
assert_nothing_raised do
|
63
|
+
graph.delete_edge('A','B')
|
64
|
+
end
|
65
|
+
assert_equal false, graph.are_connected?('A','B')
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_delete_edge_attr
|
69
|
+
graph = IGraph.new(['A','B','C','D'],true,[1,2])
|
70
|
+
assert_equal 1, graph['A','B']
|
71
|
+
assert_nothing_raised do
|
72
|
+
graph.delete_edge('A','B')
|
73
|
+
end
|
74
|
+
assert_equal false, graph.are_connected?('A','B')
|
75
|
+
assert_equal 2, graph['C','D']
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_delete_missing_edge
|
79
|
+
graph = IGraph.new(['A','B','C','D'],true)
|
80
|
+
assert_equal true, graph.are_connected?('A','B')
|
81
|
+
assert_raises(IGraphError) do
|
82
|
+
graph.delete_edge('A','C')
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
49
86
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'igraph'
|
3
|
+
|
4
|
+
class TestGraph < Test::Unit::TestCase
|
5
|
+
def test_get_attributes
|
6
|
+
graph = IGraph.new(['A','B','C','D'],true,[1,2])
|
7
|
+
assert_equal 2, graph.get_edge_attr('C','D')
|
8
|
+
assert_equal 2, graph['C','D']
|
9
|
+
end
|
10
|
+
def test_set_attributes
|
11
|
+
graph = IGraph.new(['A','B','C','D'],true,[1,2])
|
12
|
+
graph.set_edge_attr('C','D',3)
|
13
|
+
assert_equal 3, graph.get_edge_attr('C','D')
|
14
|
+
graph['C','D'] = 4
|
15
|
+
assert_equal 4, graph['C','D']
|
16
|
+
end
|
17
|
+
def test_new_edges
|
18
|
+
graph = IGraph.new(['A','B','C','D'],true,[1,2])
|
19
|
+
graph.add_edges(['A','C'],[3])
|
20
|
+
assert_equal 3, graph['A','C']
|
21
|
+
graph.add_edge('A','D',4)
|
22
|
+
assert_equal 4, graph['A','D']
|
23
|
+
end
|
24
|
+
def test_graph_attr
|
25
|
+
graph = IGraph.new(['A','B','C','D'],true,[1,2])
|
26
|
+
graph.attributes['test'] = 1
|
27
|
+
assert_equal 1, graph.attributes['test']
|
28
|
+
end
|
29
|
+
end
|
data/test/tc_basic_properties.rb
CHANGED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'igraph'
|
3
|
+
|
4
|
+
class TestGraph < Test::Unit::TestCase
|
5
|
+
def test_closeness
|
6
|
+
g = IGraph.new(['A','B','B','C','C','D'],true)
|
7
|
+
assert_equal [0.75], g.closeness(['B'],IGraph::ALL)
|
8
|
+
end
|
9
|
+
def test_betweenness
|
10
|
+
g = IGraph.new(['A','B','B','C','C','D'],true)
|
11
|
+
assert_equal [0,2], g.betweenness(['A','B'],true)
|
12
|
+
end
|
13
|
+
def test_edge_betweenness
|
14
|
+
g = IGraph.new(['A','B','C','D'],true)
|
15
|
+
assert_equal [1,1], g.edge_betweenness(true)
|
16
|
+
end
|
17
|
+
def test_pagerank
|
18
|
+
g = IGraph.new(['A','B','C','D','E','B','F','B'],true)
|
19
|
+
assert_equal 67, (g.pagerank(['B'],true,100,0.01,0.8)[0] * 100).to_i
|
20
|
+
end
|
21
|
+
def test_constraint
|
22
|
+
g = IGraph.new(['A','B','C','D'],true)
|
23
|
+
assert_equal [1], g.constraint(['A'])
|
24
|
+
assert_raises IGraphError do
|
25
|
+
g.constraint(['A'],[3])
|
26
|
+
end
|
27
|
+
assert_equal [1], g.constraint(['A'],[2,3])
|
28
|
+
end
|
29
|
+
def test_maxdegree
|
30
|
+
g = IGraph.new(['A','B','C','D','A','E','A','F'],true)
|
31
|
+
assert_equal 3, g.maxdegree(g.vertices,IGraph::ALL,true)
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'igraph'
|
3
|
+
|
4
|
+
class TestGraph < Test::Unit::TestCase
|
5
|
+
def test_subcomponent
|
6
|
+
g = IGraph.new([1,2,3,4])
|
7
|
+
assert_equal [1,2], g.subcomponent(1,IGraph::ALL)
|
8
|
+
end
|
9
|
+
def test_subgraph
|
10
|
+
g = IGraph.new([1,2,3,4])
|
11
|
+
h = g.subgraph([1,2])
|
12
|
+
assert_equal 2, h.vcount
|
13
|
+
assert_equal [1,2], h.vertices
|
14
|
+
end
|
15
|
+
def test_clusters
|
16
|
+
g = IGraph.new([1,2,3,4])
|
17
|
+
assert_equal 2, g.clusters(IGraph::WEAK).length
|
18
|
+
assert_equal [1,2], g.clusters(IGraph::WEAK)[0]
|
19
|
+
end
|
20
|
+
def test_decompose
|
21
|
+
g = IGraph.new([1,2,3,4])
|
22
|
+
assert_equal 2, g.decompose(IGraph::WEAK).length
|
23
|
+
assert_equal [1,2], g.decompose(IGraph::WEAK)[0].vertices
|
24
|
+
end
|
25
|
+
end
|
data/test/tc_copy.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'igraph'
|
3
|
+
|
4
|
+
class TestGraph < Test::Unit::TestCase
|
5
|
+
def test_copy
|
6
|
+
g = IGraph.new(['A','B','C','D'],true,[1,2]);
|
7
|
+
h = g.dup
|
8
|
+
assert g.vcount == h.vcount
|
9
|
+
assert g['A','B'] == h['A','B']
|
10
|
+
h['A','B'] = g['A','B'] + 1
|
11
|
+
assert g['A','B'] != h['A','B']
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'igraph'
|
3
|
+
require 'stringio'
|
4
|
+
|
5
|
+
class TestGraph < Test::Unit::TestCase
|
6
|
+
def test_edgelist_read
|
7
|
+
g = nil
|
8
|
+
assert_nothing_raised{
|
9
|
+
g = IGraph.read_graph_edgelist(StringIO.new("0 1 2 3"),true)
|
10
|
+
}
|
11
|
+
assert_instance_of IGraph, g
|
12
|
+
assert_equal 4, g.vcount
|
13
|
+
assert g.are_connected?(0,1)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_edgelist_write
|
17
|
+
g = IGraph.new([0,1,2,3])
|
18
|
+
s = StringIO.new("")
|
19
|
+
str = g.write_graph_edgelist(s)
|
20
|
+
s.rewind
|
21
|
+
assert_equal "0 1\n2 3\n", s.read
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_graphml_read
|
25
|
+
g = nil
|
26
|
+
g = IGraph.read_graph_graphml(StringIO.new(Graphml),0)
|
27
|
+
assert_instance_of IGraph, g
|
28
|
+
assert_equal '2006-11-12', g.attributes['date']
|
29
|
+
h = g.dup
|
30
|
+
assert_equal g.to_a,h.to_a
|
31
|
+
assert_equal g.attributes['date'], h.attributes['date']
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_graphml_write
|
35
|
+
g = IGraph.new([{'id'=>0,'name'=>'a','type' => 4.0},
|
36
|
+
{'id'=>1,'name'=>'b','type' => 5},
|
37
|
+
{'id'=>2,'type' => 6},
|
38
|
+
{'id'=>3,'name'=>'d'}],
|
39
|
+
true,
|
40
|
+
[{'eid'=>'e1'},
|
41
|
+
{'eid'=>'e2'}])
|
42
|
+
g.attributes['date'] = 'Friday'
|
43
|
+
s = StringIO.new("")
|
44
|
+
str = g.write_graph_graphml(s)
|
45
|
+
s.rewind
|
46
|
+
assert_equal Graphml_out, s.read
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_pajek_read_write
|
50
|
+
g = nil
|
51
|
+
g = IGraph.read_graph_pajek(StringIO.new(Pajek),0)
|
52
|
+
assert_instance_of IGraph, g
|
53
|
+
assert_equal 4, g.vcount
|
54
|
+
assert_equal 1, g[4,1]['weight']
|
55
|
+
h = g.dup
|
56
|
+
s = StringIO.new('')
|
57
|
+
h.write_graph_pajek(s)
|
58
|
+
s.rewind
|
59
|
+
str = s.read
|
60
|
+
str.gsub!(/\r/,'')
|
61
|
+
#assert_equal Pajek, str
|
62
|
+
end
|
63
|
+
|
64
|
+
Graphml = %q{<?xml version="1.0" encoding="UTF-8"?>
|
65
|
+
<!-- This file was written by the JAVA GraphML Library.-->
|
66
|
+
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3
|
67
|
+
.org/2001/XMLSchema-instance"
|
68
|
+
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdr
|
69
|
+
awing.org/xmlns/1.0/graphml.xsd">
|
70
|
+
<key id="d0" for="node" attr.name="color" attr.type="string">yellow</key>
|
71
|
+
<key id="d1" for="edge" attr.name="weight" attr.type="double"/>
|
72
|
+
<key id="d2" for="graph" attr.name="date" attr.type="string"></key>
|
73
|
+
<graph id="G" edgedefault="undirected">
|
74
|
+
<data key="d2">2006-11-12</data>
|
75
|
+
<node id="n0">
|
76
|
+
<data key="d0">green</data>
|
77
|
+
<data key="d3">incorrect</data>
|
78
|
+
<!-- incorrect attribute key, should issue a warning -->
|
79
|
+
</node>
|
80
|
+
<node id="n1"/>
|
81
|
+
<node id="n2">
|
82
|
+
<data key="d0">blue</data>
|
83
|
+
</node>
|
84
|
+
<node id="n3">
|
85
|
+
<data key="d0">red</data>
|
86
|
+
</node>
|
87
|
+
<node id="n4"/>
|
88
|
+
<node id="n5">
|
89
|
+
<data key="d0">turquoise</data>
|
90
|
+
</node>
|
91
|
+
<edge id="e0" source="n0" target="n2">
|
92
|
+
<data key="d1">1.0</data>
|
93
|
+
</edge>
|
94
|
+
<edge id="e1" source="n0" target="n1">
|
95
|
+
<data key="d1">1.0</data>
|
96
|
+
</edge>
|
97
|
+
<edge id="e2" source="n1" target="n3">
|
98
|
+
<data key="d1">2.0</data>
|
99
|
+
</edge>
|
100
|
+
<edge id="e3" source="n3" target="n2"/>
|
101
|
+
<edge id="e4" source="n2" target="n4"/>
|
102
|
+
<edge id="e5" source="n3" target="n5"/>
|
103
|
+
<edge id="e6" source="n5" target="n4">
|
104
|
+
<data key="d1">1.1</data>
|
105
|
+
</edge>
|
106
|
+
</graph>
|
107
|
+
</graphml>
|
108
|
+
}
|
109
|
+
|
110
|
+
|
111
|
+
Graphml_out = %q{<?xml version="1.0" encoding="UTF-8"?>
|
112
|
+
<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
|
113
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
114
|
+
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
|
115
|
+
http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
|
116
|
+
<!-- Created by igraph -->
|
117
|
+
<key id="date" for="graph" attr.name="date" attr.type="string"/>
|
118
|
+
<key id="name" for="node" attr.name="name" attr.type="string"/>
|
119
|
+
<key id="type" for="node" attr.name="type" attr.type="double"/>
|
120
|
+
<key id="id" for="node" attr.name="id" attr.type="double"/>
|
121
|
+
<key id="eid" for="edge" attr.name="eid" attr.type="string"/>
|
122
|
+
<graph id="G" edgedefault="directed">
|
123
|
+
<data key="date">Friday</data>
|
124
|
+
<node id="n0">
|
125
|
+
<data key="name">a</data>
|
126
|
+
<data key="type">4</data>
|
127
|
+
<data key="id">0</data>
|
128
|
+
</node>
|
129
|
+
<node id="n1">
|
130
|
+
<data key="name">b</data>
|
131
|
+
<data key="type">5</data>
|
132
|
+
<data key="id">1</data>
|
133
|
+
</node>
|
134
|
+
<node id="n2">
|
135
|
+
<data key="name"></data>
|
136
|
+
<data key="type">6</data>
|
137
|
+
<data key="id">2</data>
|
138
|
+
</node>
|
139
|
+
<node id="n3">
|
140
|
+
<data key="name">d</data>
|
141
|
+
<data key="id">3</data>
|
142
|
+
</node>
|
143
|
+
<edge source="n0" target="n1">
|
144
|
+
<data key="eid">e1</data>
|
145
|
+
</edge>
|
146
|
+
<edge source="n2" target="n3">
|
147
|
+
<data key="eid">e2</data>
|
148
|
+
</edge>
|
149
|
+
</graph>
|
150
|
+
</graphml>
|
151
|
+
}
|
152
|
+
|
153
|
+
Pajek = %q{*Vertices 4
|
154
|
+
*Edges
|
155
|
+
4 1 1
|
156
|
+
1 2 4
|
157
|
+
1 3 2
|
158
|
+
2 3 2
|
159
|
+
}
|
160
|
+
|
161
|
+
end
|