graphs 0.1.3-x86-linux → 0.1.4-x86-linux
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/graph.rb +175 -68
- data/tests/tests_graph.rb +294 -60
- metadata +2 -2
data/lib/graph.rb
CHANGED
@@ -3,80 +3,47 @@
|
|
3
3
|
require 'yaml'
|
4
4
|
|
5
5
|
# A graph with nodes and edges
|
6
|
+
# @!attribute [rw] nodes
|
7
|
+
# @return [NodeArray] array of current Graph's nodes
|
8
|
+
# @!attribute [rw] edges
|
9
|
+
# @return [EdgeArray] array of current Graph's edges
|
10
|
+
# @!attribute [rw] attrs
|
11
|
+
# @return [Hash] attributes of the current Graph (e.g. author, description, …)
|
6
12
|
class Graph
|
7
13
|
|
8
|
-
# Return a new Graph which is the intersection of every given
|
14
|
+
# Return a new Graph which is the intersection of every given graph.
|
9
15
|
# Each node of the intersection is in every given graph (idem for edges).
|
10
16
|
# The last argument may be a hash of options.
|
11
17
|
# @option options [Boolean] :same_fields use only fields which are in every
|
12
|
-
# graph to perform the intersection
|
18
|
+
# graph to compare nodes/edges to perform the intersection
|
13
19
|
# @see Graph#&
|
20
|
+
# @see Graph::union
|
21
|
+
# @see Graph::xor
|
14
22
|
def Graph::intersection(*graphs)
|
15
|
-
|
16
|
-
|
17
|
-
opts = {}
|
18
|
-
|
19
|
-
if graphs[-1].is_a?(Hash)
|
20
|
-
return nil if graphs.length == 1
|
21
|
-
opts.update(graphs.pop)
|
22
|
-
end
|
23
|
-
|
24
|
-
graphs.each {|g|
|
25
|
-
if (!g.is_a?(Graph))
|
26
|
-
return nil
|
27
|
-
end
|
28
|
-
}
|
29
|
-
|
30
|
-
if opts[:same_fields]
|
31
|
-
graphs.map! {|g| g.clone}
|
32
|
-
|
33
|
-
# every first node of every graphs
|
34
|
-
nodes_ref = graphs.map {|g| g.nodes[0] || {}}
|
35
|
-
# every first edge of every graphs
|
36
|
-
edges_ref = graphs.map {|g| g.edges[0] || {}}
|
37
|
-
|
38
|
-
nodes_keys_ref = nodes_ref.map {|n| n.keys}
|
39
|
-
edges_keys_ref = edges_ref.map {|e| e.keys}
|
40
|
-
|
41
|
-
# keep only same keys
|
42
|
-
nodes_keys_uniq = nodes_keys_ref.inject {|i,e| i &= e}
|
43
|
-
edges_keys_uniq = edges_keys_ref.inject {|i,e| i &= e}
|
44
|
-
|
45
|
-
graphs.map! {|g|
|
46
|
-
g.nodes.map! { |n|
|
47
|
-
|
48
|
-
newnode = {}
|
49
|
-
|
50
|
-
n.each_key { |k|
|
51
|
-
newnode[k] = n[k] if nodes_keys_uniq.include?(k)
|
52
|
-
}
|
53
|
-
|
54
|
-
newnode
|
55
|
-
}
|
56
|
-
g.edges.map! { |n|
|
57
|
-
|
58
|
-
newedge = {}
|
59
|
-
|
60
|
-
n.each_key { |k|
|
61
|
-
newedge[k] = n[k] if edges_keys_uniq.include?(k)
|
62
|
-
}
|
63
|
-
|
64
|
-
newedge
|
65
|
-
}
|
66
|
-
g
|
67
|
-
}
|
68
|
-
|
69
|
-
elsif graphs.length == 2
|
70
|
-
return graphs[0] & graphs[1]
|
71
|
-
end
|
72
|
-
|
73
|
-
graph = graphs.shift.clone
|
23
|
+
perform_graphs_group_op(*graphs, &:&)
|
24
|
+
end
|
74
25
|
|
75
|
-
|
76
|
-
|
77
|
-
|
26
|
+
# Return a new Graph which is the union of every given graph.
|
27
|
+
# Each node of the union is in one or more given graph(s) (idem for edges).
|
28
|
+
# The last argument may be a hash of options.
|
29
|
+
# @option options [Boolean] :same_fields use only fields which are in every
|
30
|
+
# graph to compare nodes/edges to perform the union
|
31
|
+
# @see Graph#|
|
32
|
+
# @see Graph::intersection
|
33
|
+
# @see Graph::xor
|
34
|
+
def Graph::union(*graphs)
|
35
|
+
perform_graphs_group_op(*graphs, &:|)
|
36
|
+
end
|
78
37
|
|
79
|
-
|
38
|
+
# Perform a XOR operation on all given graphs, and returns the result.
|
39
|
+
# The last argument may be a hash of options.
|
40
|
+
# @option options [Boolean] :same_fields use only fields which are in every
|
41
|
+
# graph to compare nodes/edges to perform the XOR operation
|
42
|
+
# @see Graph#^
|
43
|
+
# @see Graph::union
|
44
|
+
# @see Graph::intersection
|
45
|
+
def Graph::xor(*graphs)
|
46
|
+
perform_graphs_group_op(*graphs, &:^)
|
80
47
|
end
|
81
48
|
|
82
49
|
# An array of nodes, each node is an hash of label/value paires
|
@@ -96,6 +63,8 @@ class Graph
|
|
96
63
|
self.map! { |e| e.update(@defaults) }
|
97
64
|
end
|
98
65
|
|
66
|
+
# Add the given node at the end of the list
|
67
|
+
# @param o [Node]
|
99
68
|
def push(o)
|
100
69
|
if (!o.is_a?(Hash))
|
101
70
|
raise TypeError.new "#{o.inspect} is not an Hash!"
|
@@ -110,13 +79,14 @@ class Graph
|
|
110
79
|
class EdgeArray < NodeArray
|
111
80
|
end
|
112
81
|
|
113
|
-
attr_accessor :nodes, :edges
|
82
|
+
attr_accessor :nodes, :edges, :attrs
|
114
83
|
|
115
84
|
# @param nodes [Array] Nodes of the graph
|
116
85
|
# @param edges [Array] Edges of the graph
|
117
86
|
def initialize(nodes=nil, edges=nil)
|
118
87
|
@nodes = NodeArray.new(nodes || [])
|
119
88
|
@edges = EdgeArray.new(edges || [])
|
89
|
+
@attrs = {}
|
120
90
|
end
|
121
91
|
|
122
92
|
# Test if current graph has same nodes and edges as the other
|
@@ -126,13 +96,15 @@ class Graph
|
|
126
96
|
if (!other.is_a?(Graph))
|
127
97
|
return false
|
128
98
|
end
|
129
|
-
(self.nodes === other.nodes) && (self.edges
|
99
|
+
(self.nodes === other.nodes) && (self.edges === other.edges)
|
130
100
|
end
|
131
101
|
|
132
102
|
# Perform an intersection between the current graph and the other.
|
133
103
|
# Returns a new Graph which nodes are both in the current graph and
|
134
104
|
# the other (idem for edges).
|
135
105
|
# @param other [Graph]
|
106
|
+
# @see Graph#^
|
107
|
+
# @see Graph::intersection
|
136
108
|
def &(other)
|
137
109
|
if (!other.is_a?(Graph))
|
138
110
|
return nil
|
@@ -144,7 +116,70 @@ class Graph
|
|
144
116
|
Graph.new(nodes, edges)
|
145
117
|
end
|
146
118
|
|
147
|
-
#
|
119
|
+
# Perform a XOR operation between the current graph and the other. Returns a
|
120
|
+
# new Graph which nodes are in the current graph or in the other, but not in
|
121
|
+
# both (idem for edges).
|
122
|
+
# @param other [Graph]
|
123
|
+
# @see Graph#&
|
124
|
+
def ^(other)
|
125
|
+
if (!other.is_a?(Graph))
|
126
|
+
return nil
|
127
|
+
end
|
128
|
+
|
129
|
+
nodes = (@nodes + other.nodes) - (@nodes & other.nodes)
|
130
|
+
edges = (@edges + other.edges) - (@edges & other.edges)
|
131
|
+
|
132
|
+
Graph.new(nodes, edges)
|
133
|
+
end
|
134
|
+
|
135
|
+
# Add two graphs, keeping duplicate nodes and edges
|
136
|
+
# @param other [Graph]
|
137
|
+
def +(other)
|
138
|
+
if (!other.is_a?(Graph))
|
139
|
+
return nil
|
140
|
+
end
|
141
|
+
|
142
|
+
nodes = @nodes + other.nodes
|
143
|
+
edges = @edges + other.edges
|
144
|
+
|
145
|
+
Graph.new(nodes, edges)
|
146
|
+
end
|
147
|
+
|
148
|
+
# Perform an OR operation on the current Graph and the given one. Returns a
|
149
|
+
# new graph which every node is in the current Graph and/or the other
|
150
|
+
# (idem for edges).
|
151
|
+
def |(other)
|
152
|
+
if (!other.is_a?(Graph))
|
153
|
+
return nil
|
154
|
+
end
|
155
|
+
|
156
|
+
nodes = @nodes | other.nodes
|
157
|
+
edges = @edges | other.edges
|
158
|
+
|
159
|
+
Graph.new(nodes, edges)
|
160
|
+
end
|
161
|
+
|
162
|
+
# Returns a new Graph, which is a copy of the current graph without nodes
|
163
|
+
# and edges which are in the given Graph.
|
164
|
+
# @param other [Graph]
|
165
|
+
def -(other)
|
166
|
+
if (!other.is_a?(Graph))
|
167
|
+
return nil
|
168
|
+
end
|
169
|
+
|
170
|
+
nodes = @nodes - other.nodes
|
171
|
+
edges = @edges - other.edges
|
172
|
+
|
173
|
+
Graph.new(nodes, edges)
|
174
|
+
end
|
175
|
+
|
176
|
+
# @see Graph#-
|
177
|
+
def not(other)
|
178
|
+
self - other
|
179
|
+
end
|
180
|
+
|
181
|
+
# Clone the current graph. All nodes and edges are also cloned. A new Graph
|
182
|
+
# is returned.
|
148
183
|
def clone()
|
149
184
|
g = Graph.new
|
150
185
|
g.nodes = self.nodes.clone
|
@@ -184,4 +219,76 @@ class Graph
|
|
184
219
|
end
|
185
220
|
|
186
221
|
end
|
222
|
+
|
223
|
+
# return the provided set of graphs, from which every node/edge label which
|
224
|
+
# is not in all graphs has been removed. So every returned graph has same
|
225
|
+
# node/edge labels than each other
|
226
|
+
def Graph::keep_only_same_fields(*graphs)
|
227
|
+
graphs.map! {|g| g.clone}
|
228
|
+
|
229
|
+
# every first node of every graphs
|
230
|
+
nodes_ref = graphs.map {|g| g.nodes[0] || {}}
|
231
|
+
# every first edge of every graphs
|
232
|
+
edges_ref = graphs.map {|g| g.edges[0] || {}}
|
233
|
+
|
234
|
+
nodes_keys_ref = nodes_ref.map {|n| n.keys}
|
235
|
+
edges_keys_ref = edges_ref.map {|e| e.keys}
|
236
|
+
|
237
|
+
# keep only same keys
|
238
|
+
nodes_keys_uniq = nodes_keys_ref.inject {|i,e| i &= e}
|
239
|
+
edges_keys_uniq = edges_keys_ref.inject {|i,e| i &= e}
|
240
|
+
|
241
|
+
graphs.map {|g|
|
242
|
+
g.nodes.map! { |n|
|
243
|
+
|
244
|
+
newnode = {}
|
245
|
+
|
246
|
+
n.each_key { |k|
|
247
|
+
newnode[k] = n[k] if nodes_keys_uniq.include?(k)
|
248
|
+
}
|
249
|
+
|
250
|
+
newnode
|
251
|
+
}
|
252
|
+
g.edges.map! { |n|
|
253
|
+
|
254
|
+
newedge = {}
|
255
|
+
|
256
|
+
n.each_key { |k|
|
257
|
+
newedge[k] = n[k] if edges_keys_uniq.include?(k)
|
258
|
+
}
|
259
|
+
|
260
|
+
newedge
|
261
|
+
}
|
262
|
+
g
|
263
|
+
}
|
264
|
+
end
|
265
|
+
|
266
|
+
# Perform an operation on a graphs group
|
267
|
+
# @param block [Block] operation
|
268
|
+
def Graph::perform_graphs_group_op(*graphs, &block)
|
269
|
+
return nil if graphs.length == 0
|
270
|
+
|
271
|
+
# options
|
272
|
+
opts = {}
|
273
|
+
|
274
|
+
# if the last arg is an hash, use it as a set of options and remove it
|
275
|
+
# from the arguments
|
276
|
+
if graphs[-1].is_a?(Hash)
|
277
|
+
return nil if graphs.length == 1
|
278
|
+
opts.update(graphs.pop)
|
279
|
+
end
|
280
|
+
|
281
|
+
# return nil if one argument is not a graph
|
282
|
+
graphs.each {|g|
|
283
|
+
return nil if (!g.is_a?(Graph))
|
284
|
+
}
|
285
|
+
|
286
|
+
# if :same_fields option is set, call `keep_only_same_fields` function
|
287
|
+
*graphs = keep_only_same_fields(*graphs) if opts[:same_fields]
|
288
|
+
|
289
|
+
# perform an and operation on all graph list
|
290
|
+
graphs.inject(&block)
|
291
|
+
end
|
292
|
+
|
293
|
+
private_class_method :keep_only_same_fields, :perform_graphs_group_op
|
187
294
|
end
|
data/tests/tests_graph.rb
CHANGED
@@ -7,32 +7,49 @@ require 'graph'
|
|
7
7
|
|
8
8
|
class Graph_test < Test::Unit::TestCase
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
10
|
+
def setup
|
11
|
+
@@sample_graph = Graph.new(
|
12
|
+
[
|
13
|
+
{'label'=>'foo', 'id'=>2},
|
14
|
+
{'label'=>'bar', 'id'=>1},
|
15
|
+
{'label'=>'chuck', 'id'=>3}
|
16
|
+
],
|
17
|
+
[
|
18
|
+
{'node1'=>'foo', 'node2'=>'bar'},
|
19
|
+
{'node1'=>'bar', 'node2'=>'foo'},
|
20
|
+
{'node1'=>'bar', 'node2'=>'chuck'},
|
21
|
+
{'node1'=>'foo', 'node2'=>'chuck'}
|
22
|
+
]
|
23
|
+
)
|
24
|
+
|
25
|
+
@@sample_graph_1 = Graph.new(
|
26
|
+
[
|
27
|
+
{'label'=>'bar', 'num'=>3},
|
28
|
+
{'label'=>'foo', 'num'=>42},
|
29
|
+
{'label'=>'chuck', 'num'=>78}
|
30
|
+
],
|
31
|
+
[
|
32
|
+
{'node1'=>'foo', 'node2'=>'bar', 'time'=>1.0},
|
33
|
+
{'node1'=>'bar', 'node2'=>'foo', 'time'=>2.5},
|
34
|
+
{'node1'=>'foo', 'node2'=>'chuck', 'time'=>3.1}
|
35
|
+
]
|
36
|
+
)
|
37
|
+
|
38
|
+
@@empty = Graph.new
|
39
|
+
end
|
40
|
+
|
41
|
+
# == Graph#attrs == #
|
42
|
+
|
43
|
+
def test_graph_attrs
|
44
|
+
g = @@empty
|
45
|
+
assert_equal({}, g.attrs)
|
46
|
+
|
47
|
+
g.attrs['mode'] = 'static'
|
48
|
+
g.attrs['defaultedgetype'] = 'directed'
|
49
|
+
|
50
|
+
assert_equal('static', g.attrs['mode'])
|
51
|
+
assert_equal('directed', g.attrs['defaultedgetype'])
|
52
|
+
end
|
36
53
|
|
37
54
|
# == Graph::intersection == #
|
38
55
|
|
@@ -42,14 +59,14 @@ class Graph_test < Test::Unit::TestCase
|
|
42
59
|
end
|
43
60
|
|
44
61
|
def test_intersection_2_empty_graphs
|
45
|
-
g =
|
62
|
+
g = @@empty
|
46
63
|
h = g.clone
|
47
64
|
|
48
65
|
assert_equal(h, Graph::intersection(g, g))
|
49
66
|
end
|
50
67
|
|
51
68
|
def test_intersection_4_empty_graphs_intersection
|
52
|
-
g =
|
69
|
+
g = @@empty
|
53
70
|
h = g.clone
|
54
71
|
|
55
72
|
assert_equal(h, Graph::intersection(g, g, g, g))
|
@@ -57,10 +74,8 @@ class Graph_test < Test::Unit::TestCase
|
|
57
74
|
|
58
75
|
def test_intersection_one_node_graph_and_empty_graph
|
59
76
|
g = Graph.new([{'label'=>'foo'}])
|
60
|
-
empty = Graph.new
|
61
|
-
empty2 = empty.clone
|
62
77
|
|
63
|
-
assert_equal(
|
78
|
+
assert_equal(@@empty, Graph::intersection(g, @@empty))
|
64
79
|
end
|
65
80
|
|
66
81
|
def test_intersection_sample_graph_and_itself_5_times
|
@@ -72,18 +87,15 @@ class Graph_test < Test::Unit::TestCase
|
|
72
87
|
|
73
88
|
def test_intersection_sample_graph_and_itself_5_times_and_empty_graph
|
74
89
|
g = @@sample_graph
|
75
|
-
empty = Graph.new
|
76
|
-
empty2 = empty.clone
|
77
90
|
|
78
|
-
assert_equal(
|
91
|
+
assert_equal(@@empty, Graph::intersection(g, g, @@empty, g, g, g))
|
79
92
|
end
|
80
93
|
|
81
94
|
def test_intersection_one_node_graph_and_one_other_node_graph
|
82
95
|
g = Graph.new([{'label'=>'foo'}])
|
83
96
|
h = Graph.new([{'label'=>'bar'}])
|
84
|
-
|
85
|
-
|
86
|
-
assert_equal(empty, Graph::intersection(g, h))
|
97
|
+
|
98
|
+
assert_equal(@@empty, Graph::intersection(g, h))
|
87
99
|
end
|
88
100
|
|
89
101
|
def test_intersection_sample_graph_and_no_graph
|
@@ -99,9 +111,8 @@ class Graph_test < Test::Unit::TestCase
|
|
99
111
|
def test_intersection_2_graphs_same_nodes_different_fields
|
100
112
|
g1 = @@sample_graph.clone
|
101
113
|
g2 = @@sample_graph_1.clone
|
102
|
-
|
103
|
-
|
104
|
-
assert_equal(empty, Graph::intersection(g1, g2))
|
114
|
+
|
115
|
+
assert_equal(@@empty, Graph::intersection(g1, g2))
|
105
116
|
# test for side effects
|
106
117
|
assert_equal(@@sample_graph, g1)
|
107
118
|
assert_equal(@@sample_graph_1, g2)
|
@@ -130,11 +141,10 @@ class Graph_test < Test::Unit::TestCase
|
|
130
141
|
assert_equal(@@sample_graph_1, g2)
|
131
142
|
end
|
132
143
|
|
133
|
-
|
134
144
|
# == Graph#new == #
|
135
145
|
|
136
146
|
def test_new_empty_graph
|
137
|
-
g =
|
147
|
+
g = @@empty
|
138
148
|
|
139
149
|
assert_equal([], g.nodes)
|
140
150
|
assert_equal([], g.edges)
|
@@ -143,7 +153,7 @@ class Graph_test < Test::Unit::TestCase
|
|
143
153
|
# == Graph#clone == #
|
144
154
|
|
145
155
|
def test_empty_graph_clone
|
146
|
-
g =
|
156
|
+
g = @@empty
|
147
157
|
h = g.clone
|
148
158
|
|
149
159
|
assert_equal(g, h)
|
@@ -209,9 +219,8 @@ class Graph_test < Test::Unit::TestCase
|
|
209
219
|
end
|
210
220
|
|
211
221
|
def test_edgearray_set_default_existing_property
|
212
|
-
g = Graph.new([],
|
213
|
-
|
214
|
-
{'node1'=>'bar', 'node2'=>'foo'}])
|
222
|
+
g = Graph.new([], [{'node1'=>'foo', 'node2'=>'bar', 'directed'=>true},
|
223
|
+
{'node1'=>'bar', 'node2'=>'foo'}])
|
215
224
|
g.edges.set_default 'directed' => false
|
216
225
|
|
217
226
|
assert_equal(false, g.edges[0]['directed'])
|
@@ -238,25 +247,22 @@ class Graph_test < Test::Unit::TestCase
|
|
238
247
|
|
239
248
|
# == Graph#& == #
|
240
249
|
|
241
|
-
def
|
242
|
-
g1 =
|
243
|
-
g2 = Graph.new
|
250
|
+
def test_AND_2_empty_graphs
|
251
|
+
g1 = g2 = @@empty
|
244
252
|
|
245
253
|
assert_equal(g1, g1 & g2)
|
246
254
|
end
|
247
255
|
|
248
256
|
def test_one_node_graph_AND_empty_graph
|
249
257
|
g = Graph.new([{'label'=>'foo'}])
|
250
|
-
|
251
|
-
|
252
|
-
assert_equal(empty, g & empty)
|
258
|
+
|
259
|
+
assert_equal(@@empty, g & @@empty)
|
253
260
|
end
|
254
261
|
|
255
262
|
def test_empty_graph_AND_one_node_graph
|
256
263
|
g = Graph.new([{'label'=>'foo'}])
|
257
|
-
|
258
|
-
|
259
|
-
assert_equal(empty, empty & g)
|
264
|
+
|
265
|
+
assert_equal(@@empty, @@empty & g)
|
260
266
|
end
|
261
267
|
|
262
268
|
def test_sample_graph_AND_itself
|
@@ -268,9 +274,8 @@ class Graph_test < Test::Unit::TestCase
|
|
268
274
|
def test_one_node_graph_AND_one_other_node_graph
|
269
275
|
g = Graph.new([{'label'=>'foo'}])
|
270
276
|
h = Graph.new([{'label'=>'bar'}])
|
271
|
-
|
272
|
-
|
273
|
-
assert_equal(empty, g & h)
|
277
|
+
|
278
|
+
assert_equal(@@empty, g & h)
|
274
279
|
end
|
275
280
|
|
276
281
|
def test_sample_graph_AND_no_graph
|
@@ -287,9 +292,238 @@ class Graph_test < Test::Unit::TestCase
|
|
287
292
|
def test_AND_2_graphs_same_nodes_different_labels
|
288
293
|
g1 = @@sample_graph
|
289
294
|
g2 = @@sample_graph_1
|
290
|
-
|
295
|
+
|
296
|
+
assert_equal(@@empty, g1 & g2)
|
297
|
+
end
|
298
|
+
|
299
|
+
# == Graph#^ == #
|
300
|
+
|
301
|
+
def test_XOR_2_empty_graphs
|
302
|
+
g = @@empty
|
303
|
+
assert_equal(g, g ^ g)
|
304
|
+
end
|
305
|
+
|
306
|
+
def test_one_node_graph_XOR_empty_graph
|
307
|
+
g = Graph.new([{'label'=>'foo'}])
|
308
|
+
|
309
|
+
assert_equal(g, g ^ @@empty)
|
310
|
+
end
|
311
|
+
|
312
|
+
def test_empty_graph_XOR_one_node_graph
|
313
|
+
g = Graph.new([{'label'=>'foo'}])
|
314
|
+
|
315
|
+
assert_equal(g, @@empty ^ g)
|
316
|
+
end
|
317
|
+
|
318
|
+
def test_sample_graph_XOR_itself
|
319
|
+
g = @@sample_graph
|
320
|
+
|
321
|
+
assert_equal(@@empty, g ^ g)
|
322
|
+
end
|
323
|
+
|
324
|
+
def test_one_node_graph_XOR_one_other_node_graph
|
325
|
+
g1 = Graph.new([{'label'=>'foo'}])
|
326
|
+
g2 = Graph.new([{'label'=>'bar'}])
|
327
|
+
g3 = Graph.new(g1.nodes+g2.nodes)
|
328
|
+
g4 = Graph.new(g2.nodes+g1.nodes)
|
329
|
+
|
330
|
+
assert_equal(g3, g1 ^ g2)
|
331
|
+
assert_equal(g4, g2 ^ g1)
|
332
|
+
end
|
333
|
+
|
334
|
+
def test_sample_graph_XOR_no_graph
|
335
|
+
g = @@sample_graph
|
336
|
+
|
337
|
+
assert_equal(nil, g ^ 2)
|
338
|
+
assert_equal(nil, g ^ true)
|
339
|
+
assert_equal(nil, g ^ false)
|
340
|
+
assert_equal(nil, g ^ ['foo', 'bar'])
|
341
|
+
assert_equal(nil, g ^ {'foo'=>'bar'})
|
342
|
+
assert_equal(nil, g ^ 'foo')
|
343
|
+
end
|
344
|
+
|
345
|
+
def test_XOR_2_graphs_same_nodes_different_labels
|
346
|
+
g1 = @@sample_graph
|
347
|
+
g2 = @@sample_graph_1
|
348
|
+
g3 = Graph.new(g1.nodes+g2.nodes, g1.edges+g2.edges)
|
349
|
+
|
350
|
+
assert_equal(g3, g1 ^ g2)
|
351
|
+
end
|
352
|
+
|
353
|
+
# == Graph#+ == #
|
354
|
+
|
355
|
+
def test_empty_graph_plus_empty_graph
|
356
|
+
assert_equal(@@empty, @@empty+@@empty)
|
357
|
+
end
|
358
|
+
|
359
|
+
def test_empty_graph_plus_sample_graph
|
360
|
+
g = @@sample_graph
|
361
|
+
|
362
|
+
assert_equal(g, @@empty+g)
|
363
|
+
assert_equal(g, g+@@empty)
|
364
|
+
end
|
365
|
+
|
366
|
+
def test_sample_graph_plus_itself
|
367
|
+
g = @@sample_graph
|
368
|
+
g2 = Graph.new(g.nodes+g.nodes, g.edges+g.edges)
|
369
|
+
|
370
|
+
assert_equal(g2, g+g)
|
371
|
+
end
|
372
|
+
|
373
|
+
# == Graph#| == #
|
374
|
+
|
375
|
+
def test_empty_graph_OR_empty_graph
|
376
|
+
assert_equal(@@empty, @@empty|@@empty)
|
377
|
+
end
|
378
|
+
|
379
|
+
def test_empty_graph_OR_sample_graph
|
380
|
+
g = @@sample_graph
|
381
|
+
|
382
|
+
assert_equal(g, @@empty|g)
|
383
|
+
assert_equal(g, g|@@empty)
|
384
|
+
end
|
385
|
+
|
386
|
+
def test_sample_graph_OR_itself
|
387
|
+
g = @@sample_graph
|
388
|
+
|
389
|
+
assert_equal(g, g|g)
|
390
|
+
end
|
391
|
+
|
392
|
+
def test_sample_graph_OR_other_sample_graph
|
393
|
+
g1 = @@sample_graph
|
394
|
+
g2 = @@sample_graph_1
|
395
|
+
g3 = Graph.new(g1.nodes|g2.nodes, g1.edges|g2.edges)
|
396
|
+
g4 = Graph.new(g2.nodes|g1.nodes, g2.edges|g1.edges)
|
397
|
+
|
398
|
+
assert_equal(g3, g1|g2)
|
399
|
+
assert_equal(g4, g2|g1)
|
400
|
+
end
|
401
|
+
|
402
|
+
# == Graph#- == #
|
403
|
+
|
404
|
+
def test_empty_graph_minus_empty_graph
|
405
|
+
assert_equal(@@empty, @@empty-@@empty)
|
406
|
+
end
|
407
|
+
|
408
|
+
def test_empty_graph_minus_sample_graph
|
409
|
+
g = @@sample_graph
|
410
|
+
|
411
|
+
assert_equal(@@empty, @@empty-g)
|
412
|
+
end
|
413
|
+
|
414
|
+
def test_sample_graph_minus_empty_graph
|
415
|
+
g = @@sample_graph
|
416
|
+
|
417
|
+
assert_equal(g, g-@@empty)
|
418
|
+
end
|
419
|
+
|
420
|
+
def test_sample_graph_minus_itself
|
421
|
+
g = @@sample_graph
|
422
|
+
|
423
|
+
assert_equal(@@empty, g-g)
|
424
|
+
end
|
425
|
+
|
426
|
+
# == Graph#not == #
|
427
|
+
|
428
|
+
def test_empty_graph_NOT_empty_graph
|
429
|
+
assert_equal(@@empty, @@empty.not(@@empty))
|
430
|
+
end
|
431
|
+
|
432
|
+
def test_empty_graph_NOT_sample_graph
|
433
|
+
g = @@sample_graph
|
434
|
+
|
435
|
+
assert_equal(@@empty, @@empty.not(g))
|
436
|
+
end
|
437
|
+
|
438
|
+
def test_sample_graph_NOT_empty_graph
|
439
|
+
g = @@sample_graph
|
440
|
+
|
441
|
+
assert_equal(g, g.not(@@empty))
|
442
|
+
end
|
443
|
+
|
444
|
+
def test_sample_graph_NOT_itself
|
445
|
+
g = @@sample_graph
|
446
|
+
|
447
|
+
assert_equal(@@empty, g.not(g))
|
448
|
+
end
|
449
|
+
|
450
|
+
# == Graph::union == #
|
451
|
+
|
452
|
+
def test_union_one_empty_graph
|
453
|
+
assert_equal(@@empty, Graph::union(@@empty))
|
454
|
+
end
|
455
|
+
|
456
|
+
def test_union_3_empty_graph
|
457
|
+
assert_equal(@@empty, Graph::union(@@empty, @@empty, @@empty))
|
458
|
+
end
|
459
|
+
|
460
|
+
def test_union_empty_graph_and_sample_graph
|
461
|
+
g = @@sample_graph
|
462
|
+
|
463
|
+
assert_equal(g, Graph::union(@@empty, g))
|
464
|
+
assert_equal(g, Graph::union(g, @@empty))
|
465
|
+
end
|
466
|
+
|
467
|
+
def test_union_sample_graph_and_itself
|
468
|
+
g = @@sample_graph
|
469
|
+
|
470
|
+
assert_equal(g, Graph::intersection(g, g))
|
471
|
+
assert_equal(g, Graph::intersection(g, g, g, g))
|
472
|
+
end
|
473
|
+
|
474
|
+
def test_union_sample_graph_and_other_sample_graph
|
475
|
+
g1 = @@sample_graph
|
476
|
+
g2 = @@sample_graph_1
|
477
|
+
g3 = Graph.new(g1.nodes|g2.nodes, g1.edges|g2.edges)
|
478
|
+
g4 = Graph.new(g2.nodes|g1.nodes, g2.edges|g1.edges)
|
479
|
+
|
480
|
+
assert_equal(g3, Graph::union(g1, g2))
|
481
|
+
assert_equal(g3, Graph::union(g1, g1, g2))
|
482
|
+
assert_equal(g3, Graph::union(g1, g2, g2))
|
483
|
+
|
484
|
+
assert_equal(g4, Graph::union(g2, g1))
|
485
|
+
assert_equal(g4, Graph::union(g2, g2, g1))
|
486
|
+
assert_equal(g4, Graph::union(g2, g1, g1))
|
487
|
+
end
|
488
|
+
|
489
|
+
# == Graph::xor == #
|
490
|
+
|
491
|
+
def test_xor_one_empty_graph
|
492
|
+
assert_equal(@@empty, Graph::xor(@@empty))
|
493
|
+
end
|
494
|
+
|
495
|
+
def test_xor_3_empty_graph
|
496
|
+
assert_equal(@@empty, Graph::xor(@@empty, @@empty, @@empty))
|
497
|
+
end
|
498
|
+
|
499
|
+
def test_xor_empty_graph_and_sample_graph
|
500
|
+
g = @@sample_graph
|
501
|
+
|
502
|
+
assert_equal(g, Graph::xor(@@empty, g))
|
503
|
+
assert_equal(g, Graph::xor(g, @@empty))
|
504
|
+
end
|
505
|
+
|
506
|
+
def test_xor_sample_graph_and_itself
|
507
|
+
g = @@sample_graph
|
508
|
+
|
509
|
+
assert_equal(@@empty, Graph::xor(g, g))
|
510
|
+
assert_equal(@@empty, Graph::xor(g, g, g, g))
|
511
|
+
end
|
512
|
+
|
513
|
+
def test_xor_sample_graph_and_other_sample_graph
|
514
|
+
g1 = @@sample_graph
|
515
|
+
g2 = @@sample_graph_1
|
516
|
+
|
517
|
+
def _xor(g,h)
|
518
|
+
[(g.nodes|h.nodes)-(g.nodes&h.nodes),
|
519
|
+
(g.edges|h.edges)-(g.edges&h.edges)]
|
520
|
+
end
|
521
|
+
|
522
|
+
g_1_2 = Graph.new(*_xor(g1,g2))
|
523
|
+
g_2_1 = Graph.new(*_xor(g2,g1))
|
291
524
|
|
292
|
-
assert_equal(
|
525
|
+
assert_equal(g_1_2, Graph::xor(g1, g2))
|
526
|
+
assert_equal(g_2_1, Graph::xor(g2, g1))
|
293
527
|
end
|
294
528
|
|
295
529
|
# == Graph#write == #
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
prerelease:
|
6
6
|
platform: x86-linux
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-05-
|
12
|
+
date: 2012-05-06 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Provide functions to (un)parse GDF files and generate graphs
|
15
15
|
email: batifon@yahoo.fr
|