jumoku 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -1
- data/README.md +12 -12
- data/lib/jumoku.rb +2 -2
- data/lib/jumoku/builders/raw_tree.rb +4 -4
- data/lib/jumoku/builders/tree.rb +5 -5
- data/lib/jumoku/support/branch.rb +1 -1
- data/lib/jumoku/tree_api.rb +1 -1
- data/lib/jumoku/version.rb +1 -1
- data/spec/raw_tree_spec.rb +1 -1
- data/vendor/git/{graphy → plexus}/CREDITS.md +0 -0
- data/vendor/git/plexus/Gemfile +3 -0
- data/vendor/git/plexus/Gemfile.lock +28 -0
- data/vendor/git/{graphy → plexus}/LICENSE +3 -1
- data/vendor/git/plexus/README.md +208 -0
- data/vendor/git/plexus/Rakefile +25 -0
- data/vendor/git/{graphy → plexus}/TODO.md +1 -1
- data/vendor/git/{graphy → plexus}/VERSION +0 -0
- data/vendor/git/{graphy → plexus}/examples/graph_self.rb +0 -0
- data/vendor/git/{graphy → plexus}/examples/module_graph.jpg +0 -0
- data/vendor/git/{graphy → plexus}/examples/module_graph.rb +0 -0
- data/vendor/git/{graphy → plexus}/examples/self_graph.jpg +0 -0
- data/vendor/git/{graphy → plexus}/examples/visualize.jpg +0 -0
- data/vendor/git/{graphy → plexus}/examples/visualize.rb +0 -0
- data/vendor/git/plexus/lib/plexus.rb +90 -0
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/adjacency_graph.rb +9 -9
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/arc.rb +16 -22
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/arc_number.rb +2 -2
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/biconnected.rb +2 -2
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/chinese_postman.rb +2 -2
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/classes/graph_classes.rb +10 -10
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/common.rb +6 -6
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/comparability.rb +10 -10
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/directed_graph.rb +15 -13
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/directed_graph/algorithms.rb +21 -18
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/directed_graph/distance.rb +2 -2
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/dot.rb +2 -2
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/edge.rb +8 -9
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/ext.rb +3 -3
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/graph.rb +51 -56
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/graph_api.rb +2 -2
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/labels.rb +8 -8
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/maximum_flow.rb +2 -2
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/ruby_compatibility.rb +0 -0
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/search.rb +43 -44
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/strong_components.rb +4 -4
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/support/support.rb +3 -3
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/undirected_graph.rb +13 -14
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/undirected_graph/algorithms.rb +4 -4
- data/vendor/git/plexus/lib/plexus/version.rb +6 -0
- data/vendor/git/plexus/plexus.gemspec +24 -0
- data/vendor/git/{graphy → plexus}/spec/biconnected_spec.rb +0 -0
- data/vendor/git/{graphy → plexus}/spec/chinese_postman_spec.rb +0 -0
- data/vendor/git/{graphy → plexus}/spec/community_spec.rb +0 -0
- data/vendor/git/{graphy → plexus}/spec/complement_spec.rb +0 -0
- data/vendor/git/{graphy → plexus}/spec/digraph_distance_spec.rb +0 -0
- data/vendor/git/{graphy → plexus}/spec/digraph_spec.rb +0 -0
- data/vendor/git/{graphy → plexus}/spec/dot_spec.rb +0 -0
- data/vendor/git/{graphy → plexus}/spec/edge_spec.rb +17 -18
- data/vendor/git/{graphy → plexus}/spec/inspection_spec.rb +13 -15
- data/vendor/git/{graphy → plexus}/spec/multi_edge_spec.rb +0 -0
- data/vendor/git/{graphy → plexus}/spec/neighborhood_spec.rb +3 -5
- data/vendor/git/{graphy → plexus}/spec/properties_spec.rb +1 -1
- data/vendor/git/{graphy → plexus}/spec/search_spec.rb +45 -45
- data/vendor/git/{graphy → plexus}/spec/spec.opts +0 -0
- data/vendor/git/{graphy → plexus}/spec/spec_helper.rb +13 -10
- data/vendor/git/{graphy → plexus}/spec/strong_components_spec.rb +0 -0
- data/vendor/git/{graphy → plexus}/spec/triangulated_spec.rb +1 -1
- data/vendor/git/{graphy → plexus}/spec/undirected_graph_spec.rb +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/CHANGELOG +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/Makefile +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/README +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/benchmark/dijkstra.rb +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/compare_comments.rb +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/doc/c-vs-rb.png +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/doc/compare_big.gp +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/doc/compare_big.png +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/doc/compare_small.gp +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/doc/compare_small.png +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/doc/results.csv +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/ext/priority_queue/CPriorityQueue/extconf.rb +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/ext/priority_queue/CPriorityQueue/priority_queue.c +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/lib/priority_queue.rb +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/lib/priority_queue/c_priority_queue.rb +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/lib/priority_queue/poor_priority_queue.rb +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/lib/priority_queue/ruby_priority_queue.rb +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/priority_queue.so +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/setup.rb +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/test/priority_queue_test.rb +0 -0
- data/vendor/git/{graphy → plexus}/vendor/rdot.rb +0 -0
- metadata +81 -78
- data/vendor/git/graphy/README.md +0 -186
- data/vendor/git/graphy/Rakefile +0 -61
- data/vendor/git/graphy/graphy.gemspec +0 -149
- data/vendor/git/graphy/lib/graphy.rb +0 -90
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module Plexus
|
2
2
|
|
3
3
|
# This implements a directed graph which does not allow parallel
|
4
4
|
# edges nor loops. That is, only one arc per nodes couple,
|
@@ -6,21 +6,22 @@ module Graphy
|
|
6
6
|
# structure.
|
7
7
|
module DirectedGraphBuilder
|
8
8
|
include GraphBuilder
|
9
|
-
|
10
|
-
autoload :Algorithms, "
|
11
|
-
autoload :Distance, "
|
9
|
+
|
10
|
+
autoload :Algorithms, "plexus/directed_graph/algorithms"
|
11
|
+
autoload :Distance, "plexus/directed_graph/distance"
|
12
12
|
|
13
13
|
# FIXME: DRY this snippet, I didn't find a clever way to
|
14
14
|
# to dit though
|
15
15
|
# TODO: well, extends_host_with do ... end would be cool,
|
16
16
|
# using Module.new.module_eval(&block) in the helper.
|
17
17
|
extends_host
|
18
|
+
|
18
19
|
module ClassMethods
|
19
20
|
def [](*a)
|
20
21
|
self.new.from_array(*a)
|
21
22
|
end
|
22
23
|
end
|
23
|
-
|
24
|
+
|
24
25
|
def initialize(*params)
|
25
26
|
# FIXME/TODO: setting args to the hash or {} while getting rid
|
26
27
|
# on the previous parameters prevents from passing another
|
@@ -30,11 +31,11 @@ module Graphy
|
|
30
31
|
# we should provide a way to handle the graph as a hash
|
31
32
|
# member.
|
32
33
|
args = (params.pop if params.last.kind_of? Hash) || {}
|
33
|
-
args[:algorithmic_category] = DirectedGraphBuilder::Algorithms
|
34
|
+
args[:algorithmic_category] = DirectedGraphBuilder::Algorithms
|
34
35
|
super *(params << args)
|
35
36
|
end
|
36
|
-
end
|
37
|
-
|
37
|
+
end
|
38
|
+
|
38
39
|
# DirectedGraph is just an alias for Digraph should one desire
|
39
40
|
DigraphBuilder = DirectedGraphBuilder
|
40
41
|
|
@@ -43,23 +44,25 @@ module Graphy
|
|
43
44
|
module DirectedPseudoGraphBuilder
|
44
45
|
include DirectedGraphBuilder
|
45
46
|
extends_host
|
47
|
+
|
46
48
|
module ClassMethods
|
47
49
|
def [](*a)
|
48
50
|
self.new.from_array(*a)
|
49
51
|
end
|
50
52
|
end
|
51
|
-
|
53
|
+
|
52
54
|
def initialize(*params)
|
53
55
|
args = (params.pop if params.last.kind_of? Hash) || {}
|
54
56
|
args[:parallel_edges] = true
|
55
57
|
super *(params << args)
|
56
58
|
end
|
57
|
-
end
|
59
|
+
end
|
58
60
|
|
59
61
|
# This is a Digraph that allows for both parallel edges and loops.
|
60
62
|
module DirectedMultiGraphBuilder
|
61
63
|
include DirectedPseudoGraphBuilder
|
62
64
|
extends_host
|
65
|
+
|
63
66
|
module ClassMethods
|
64
67
|
def [](*a)
|
65
68
|
self.new.from_array(*a)
|
@@ -71,6 +74,5 @@ module Graphy
|
|
71
74
|
args[:loops] = true
|
72
75
|
super *(params << args)
|
73
76
|
end
|
74
|
-
end
|
75
|
-
|
76
|
-
end # Graphy
|
77
|
+
end
|
78
|
+
end
|
@@ -1,9 +1,8 @@
|
|
1
|
-
module
|
2
|
-
|
1
|
+
module Plexus
|
3
2
|
# Digraph is a directed graph which is a finite set of vertices
|
4
3
|
# and a finite set of edges connecting vertices. It cannot contain parallel
|
5
4
|
# edges going from the same source vertex to the same target. It also
|
6
|
-
# cannot contain loops, i.e. edges that go have the same vertex for source
|
5
|
+
# cannot contain loops, i.e. edges that go have the same vertex for source
|
7
6
|
# and target.
|
8
7
|
#
|
9
8
|
# DirectedPseudoGraph is a class that allows for parallel edges, and
|
@@ -11,31 +10,33 @@ module Graphy
|
|
11
10
|
# as well.
|
12
11
|
module DirectedGraphBuilder
|
13
12
|
module Algorithms
|
14
|
-
|
15
13
|
include Search
|
16
14
|
include StrongComponents
|
17
15
|
include Distance
|
18
16
|
include ChinesePostman
|
19
17
|
|
20
|
-
# A directed graph is directed by definition
|
18
|
+
# A directed graph is directed by definition.
|
21
19
|
#
|
22
20
|
# @return [Boolean] always true
|
21
|
+
#
|
23
22
|
def directed?
|
24
23
|
true
|
25
24
|
end
|
26
25
|
|
27
|
-
# A digraph uses the Arc class for edges
|
26
|
+
# A digraph uses the Arc class for edges.
|
27
|
+
#
|
28
|
+
# @return [Plexus::MultiArc, Plexus::Arc] `Plexus::MultiArc` if the graph allows for parallel edges,
|
29
|
+
# `Plexus::Arc` otherwise.
|
28
30
|
#
|
29
|
-
# @return [Graphy::MultiArc, Graphy::Arc] `Graphy::MultiArc` if the graph allows for parallel edges,
|
30
|
-
# `Graphy::Arc` otherwise.
|
31
31
|
def edge_class
|
32
|
-
@parallel_edges ?
|
32
|
+
@parallel_edges ? Plexus::MultiArc : Plexus::Arc
|
33
33
|
end
|
34
34
|
|
35
|
-
# Reverse all edges in a graph
|
35
|
+
# Reverse all edges in a graph.
|
36
36
|
#
|
37
37
|
# @return [DirectedGraph] a copy of the receiver for which the direction of edges has
|
38
38
|
# been inverted.
|
39
|
+
#
|
39
40
|
def reversal
|
40
41
|
result = self.class.new
|
41
42
|
edges.inject(result) { |a,e| a << e.reverse}
|
@@ -43,23 +44,26 @@ module Graphy
|
|
43
44
|
result
|
44
45
|
end
|
45
46
|
|
46
|
-
# Check whether the
|
47
|
+
# Check whether the graph is oriented or not.
|
47
48
|
#
|
48
49
|
# @return [Boolean]
|
50
|
+
#
|
49
51
|
def oriented?
|
50
52
|
e = edges
|
51
53
|
re = e.map { |x| x.reverse}
|
52
54
|
not e.any? { |x| re.include?(x)}
|
53
55
|
end
|
54
56
|
|
55
|
-
# Balanced is when the out
|
57
|
+
# Balanced is the state when the out edges count is equal to the in edges count.
|
56
58
|
#
|
57
59
|
# @return [Boolean]
|
60
|
+
#
|
58
61
|
def balanced?(v)
|
59
62
|
out_degree(v) == in_degree(v)
|
60
63
|
end
|
61
64
|
|
62
|
-
# Returns out_degree(v) - in_degree(v)
|
65
|
+
# Returns out_degree(v) - in_degree(v).
|
66
|
+
#
|
63
67
|
def delta(v)
|
64
68
|
out_degree(v) - in_degree(v)
|
65
69
|
end
|
@@ -85,8 +89,7 @@ module Graphy
|
|
85
89
|
|
86
90
|
def family(node)
|
87
91
|
community(node, :all)
|
88
|
-
end
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
end # Graphy
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -1,23 +1,23 @@
|
|
1
|
-
module
|
2
|
-
|
1
|
+
module Plexus
|
3
2
|
# An undirected edge is simply an undirected pair (source, target) used in
|
4
3
|
# undirected graphs. Edge[u,v] == Edge[v,u]
|
5
4
|
class Edge < Arc
|
6
5
|
|
7
6
|
# Equality allows for the swapping of source and target
|
8
|
-
def eql?(other)
|
9
|
-
|
10
|
-
|
7
|
+
def eql?(other)
|
8
|
+
super or (self.class == other.class and target == other.source and source == other.target)
|
9
|
+
end
|
11
10
|
alias == eql?
|
12
11
|
|
13
12
|
# Hash is defined such that source and target can be reversed and the
|
14
13
|
# hash value will be the same
|
15
|
-
def hash
|
14
|
+
def hash
|
15
|
+
source.hash ^ target.hash
|
16
|
+
end
|
16
17
|
|
17
18
|
# Sort support
|
18
19
|
def <=>(rhs)
|
19
|
-
[[source,target].max,[source,target].min] <=>
|
20
|
-
[[rhs.source,rhs.target].max,[rhs.source,rhs.target].min]
|
20
|
+
[[source,target].max, [source,target].min] <=> [[rhs.source,rhs.target].max, [rhs.source,rhs.target].min]
|
21
21
|
end
|
22
22
|
|
23
23
|
# Edge[1,2].to_s == "(1=2 'label)"
|
@@ -33,5 +33,4 @@ module Graphy
|
|
33
33
|
class MultiEdge < Edge
|
34
34
|
include ArcNumber
|
35
35
|
end
|
36
|
-
|
37
36
|
end
|
@@ -28,9 +28,9 @@ class Object
|
|
28
28
|
#
|
29
29
|
# class A; include Digraph; end
|
30
30
|
# a.singleton_class.ancestors
|
31
|
-
# # => [
|
32
|
-
#
|
33
|
-
# a.is_a?
|
31
|
+
# # => [Plexus::GraphAPI, Plexus::DirectedGraph::Algorithms, ...
|
32
|
+
# Plexus::Labels, Enumerable, Object, Plexus, Kernel, BasicObject]
|
33
|
+
# a.is_a? Plexus::Graph
|
34
34
|
# # => true
|
35
35
|
#
|
36
36
|
# @param [Class] klass
|
@@ -1,5 +1,4 @@
|
|
1
|
-
module
|
2
|
-
|
1
|
+
module Plexus
|
3
2
|
# Using the methods required by the {GraphAPI}, it implements all the
|
4
3
|
# *basic* functions of a {Graph} using *only* functions
|
5
4
|
# requested in {GraphAPI}. The process is under the control of the pattern
|
@@ -9,7 +8,6 @@ module Graphy
|
|
9
8
|
# An actual, complete implementation still needs to be done using this cheap result,
|
10
9
|
# hence {Digraph}, {UndirectedGraph} and their roomates.
|
11
10
|
module GraphBuilder
|
12
|
-
|
13
11
|
include Enumerable
|
14
12
|
include Labels
|
15
13
|
include Dot
|
@@ -29,7 +27,7 @@ module Graphy
|
|
29
27
|
|
30
28
|
# Creates a generic graph.
|
31
29
|
#
|
32
|
-
# @param [Hash(
|
30
|
+
# @param [Hash(Plexus::Graph, Array)] *params initialization parameters.
|
33
31
|
# See {AdjacencyGraphBuilder#implementation_initialize} for more details.
|
34
32
|
# @return [Graph]
|
35
33
|
def initialize(*params)
|
@@ -38,7 +36,7 @@ module Graphy
|
|
38
36
|
# and the is_a? redefinition trick (instance_evaling) should be
|
39
37
|
# completed by a clever way to check the actual class of p.
|
40
38
|
# Maybe using ObjectSpace to get the available Graph classes?
|
41
|
-
!(p.is_a?
|
39
|
+
!(p.is_a? Plexus::GraphBuilder or p.is_a? Array or p.is_a? Hash)
|
42
40
|
end
|
43
41
|
|
44
42
|
args = params.last || {}
|
@@ -47,24 +45,24 @@ module Graphy
|
|
47
45
|
self
|
48
46
|
end.module_eval do
|
49
47
|
# These inclusions trigger some validations checks by the way.
|
50
|
-
include(args[:implementation] ? args[:implementation] :
|
51
|
-
include(args[:algorithmic_category] ? args[:algorithmic_category] :
|
52
|
-
include
|
48
|
+
include(args[:implementation] ? args[:implementation] : Plexus::AdjacencyGraphBuilder)
|
49
|
+
include(args[:algorithmic_category] ? args[:algorithmic_category] : Plexus::DigraphBuilder )
|
50
|
+
include Plexus::GraphAPI
|
53
51
|
end
|
54
52
|
|
55
53
|
implementation_initialize(*params)
|
56
|
-
end
|
54
|
+
end
|
57
55
|
|
58
56
|
# Shortcut for creating a Graph.
|
59
57
|
#
|
60
58
|
# Using an arry of implicit {Arc}, specifying the vertices:
|
61
59
|
#
|
62
|
-
#
|
60
|
+
# Plexus::Graph[1,2, 2,3, 2,4, 4,5].edges.to_a.to_s
|
63
61
|
# # => "(1-2)(2-3)(2-4)(4-5)"
|
64
|
-
#
|
62
|
+
#
|
65
63
|
# Using a Hash for specifying labels along the way:
|
66
64
|
#
|
67
|
-
#
|
65
|
+
# Plexus::Graph[ [:a,:b] => 3, [:b,:c] => 4 ] (note: do not use for Multi or Pseudo graphs)
|
68
66
|
#
|
69
67
|
# @param [Array, Hash] *a
|
70
68
|
# @return [Graph]
|
@@ -73,16 +71,16 @@ module Graphy
|
|
73
71
|
# Convert to edge class
|
74
72
|
a[0].each do |k,v|
|
75
73
|
#FIXME, edge class shouldn't be assume here!!!
|
76
|
-
if edge_class.include?
|
74
|
+
if edge_class.include? Plexus::ArcNumber
|
77
75
|
add_edge!(edge_class[k[0],k[1],nil,v])
|
78
76
|
else
|
79
77
|
add_edge!(edge_class[k[0],k[1],v])
|
80
|
-
end
|
78
|
+
end
|
81
79
|
end
|
82
80
|
#FIXME, edge class shouldn't be assume here!!!
|
83
|
-
elsif a[0].is_a?
|
81
|
+
elsif a[0].is_a? Plexus::Arc
|
84
82
|
a.each{ |e| add_edge!(e); self[e] = e.label}
|
85
|
-
elsif a.size % 2 == 0
|
83
|
+
elsif a.size % 2 == 0
|
86
84
|
0.step(a.size-1, 2) {|i| add_edge!(a[i], a[i+1])}
|
87
85
|
else
|
88
86
|
raise ArgumentError
|
@@ -110,7 +108,7 @@ module Graphy
|
|
110
108
|
x = self.class.new(self)
|
111
109
|
x.add_edge!(u, v, l)
|
112
110
|
end
|
113
|
-
alias add_arc add_edge
|
111
|
+
alias add_arc add_edge
|
114
112
|
|
115
113
|
# Non destructive version of {AdjacencyGraphBuilder#remove_vertex!} (works on a copy of the graph).
|
116
114
|
#
|
@@ -130,7 +128,7 @@ module Graphy
|
|
130
128
|
x = self.class.new(self)
|
131
129
|
x.remove_edge!(u, v)
|
132
130
|
end
|
133
|
-
alias remove_arc remove_edge
|
131
|
+
alias remove_arc remove_edge
|
134
132
|
|
135
133
|
# Computes the adjacent portions of the Graph.
|
136
134
|
#
|
@@ -155,7 +153,6 @@ module Graphy
|
|
155
153
|
#FIXME: This is a hack around a serious problem
|
156
154
|
alias graph_adjacent adjacent
|
157
155
|
|
158
|
-
|
159
156
|
# Adds all specified vertices to the vertex set.
|
160
157
|
#
|
161
158
|
# @param [#each] *a an Enumerable vertices set
|
@@ -186,7 +183,7 @@ module Graphy
|
|
186
183
|
a.each { |edge| add_edge!(edge) }
|
187
184
|
self
|
188
185
|
end
|
189
|
-
alias add_arcs! add_edges!
|
186
|
+
alias add_arcs! add_edges!
|
190
187
|
|
191
188
|
# Same as {GraphBuilder#add_egdes! add_edges!} but works on a copy of the receiver.
|
192
189
|
#
|
@@ -274,7 +271,7 @@ module Graphy
|
|
274
271
|
# @return [Boolean]
|
275
272
|
def edge?(*args)
|
276
273
|
edges.include?(edge_convert(*args))
|
277
|
-
end
|
274
|
+
end
|
278
275
|
alias arc? edge?
|
279
276
|
alias has_edge? edge?
|
280
277
|
alias has_arc? edge?
|
@@ -290,9 +287,9 @@ module Graphy
|
|
290
287
|
# @param [vertex] target
|
291
288
|
# @param [Symbol] direction (:all) constraint on the direction of adjacency; may be either `:in`, `:out` or `:all`
|
292
289
|
def adjacent?(source, target, direction = :all)
|
293
|
-
if source.is_a?
|
290
|
+
if source.is_a? Plexus::Arc
|
294
291
|
raise NoArcError unless edge? source
|
295
|
-
if target.is_a?
|
292
|
+
if target.is_a? Plexus::Arc
|
296
293
|
raise NoArcError unless edge? target
|
297
294
|
(direction != :out and source.source == target.target) or (direction != :in and source.target == target.source)
|
298
295
|
else
|
@@ -301,7 +298,7 @@ module Graphy
|
|
301
298
|
end
|
302
299
|
else
|
303
300
|
raise NoVertexError unless vertex? source
|
304
|
-
if target.is_a?
|
301
|
+
if target.is_a? Plexus::Arc
|
305
302
|
raise NoArcError unless edge? target
|
306
303
|
(direction != :out and source == target.target) or (direction != :in and source == target.source)
|
307
304
|
else
|
@@ -343,15 +340,14 @@ module Graphy
|
|
343
340
|
#
|
344
341
|
# @return [Boolean]
|
345
342
|
def empty?
|
346
|
-
puts "yan"
|
347
343
|
vertices.size.zero?
|
348
344
|
end
|
349
345
|
|
350
346
|
# Returns true if the given object is a vertex or an {Arc arc} of the graph.
|
351
|
-
#
|
347
|
+
#
|
352
348
|
# @param [vertex, Arc] x
|
353
349
|
def include?(x)
|
354
|
-
x.is_a?(
|
350
|
+
x.is_a?(Plexus::Arc) ? edge?(x) : vertex?(x)
|
355
351
|
end
|
356
352
|
alias has? include?
|
357
353
|
|
@@ -359,11 +355,11 @@ module Graphy
|
|
359
355
|
#
|
360
356
|
# This is equivalent to {GraphBuilder#adjacent adjacent}, but the type is based on the
|
361
357
|
# type of the specified object.
|
362
|
-
#
|
358
|
+
#
|
363
359
|
# @param [vertex, Arc] x
|
364
360
|
# @param [Symbol] direction (:all) can be either `:all`, `:in` or `:out`
|
365
361
|
def neighborhood(x, direction = :all)
|
366
|
-
adjacent(x, :direction => direction, :type => ((x.is_a?
|
362
|
+
adjacent(x, :direction => direction, :type => ((x.is_a? Plexus::Arc) ? :edges : :vertices ))
|
367
363
|
end
|
368
364
|
|
369
365
|
# Union of all neighborhoods of vertices (or edges) in the Enumerable x minus the contents of x.
|
@@ -373,8 +369,8 @@ module Graphy
|
|
373
369
|
# @param [vertex] x
|
374
370
|
# @param [Symbol] direction can be either `:all`, `:in` or `:out`
|
375
371
|
def set_neighborhood(x, direction = :all)
|
376
|
-
x.inject(Set.new) { |a,v| a.merge(neighborhood(v,
|
377
|
-
end
|
372
|
+
x.inject(Set.new) { |a,v| a.merge(neighborhood(v, direction))}.reject { |v2| x.include?(v2) }
|
373
|
+
end
|
378
374
|
|
379
375
|
# Union of all {GraphBuilder#set_neighborhood set_neighborhoods} reachable
|
380
376
|
# among the specified edges.
|
@@ -387,7 +383,7 @@ module Graphy
|
|
387
383
|
# @param [Symbol] direction can be `:all`, `:in`, or `:out`
|
388
384
|
def closed_pth_neighborhood(w, p, direction = :all)
|
389
385
|
if p <= 0
|
390
|
-
w
|
386
|
+
w
|
391
387
|
elsif p == 1
|
392
388
|
(w + set_neighborhood(w, direction)).uniq
|
393
389
|
else
|
@@ -410,10 +406,10 @@ module Graphy
|
|
410
406
|
x
|
411
407
|
elsif p == 1
|
412
408
|
set_neighborhood(x,direction)
|
413
|
-
else
|
409
|
+
else
|
414
410
|
set_neighborhood(open_pth_neighborhood(x, p-1, direction), direction) -
|
415
411
|
closed_pth_neighborhood(x, p-1, direction)
|
416
|
-
end
|
412
|
+
end
|
417
413
|
end
|
418
414
|
|
419
415
|
# Returns the number of out-edges (for directed graphs) or the number of
|
@@ -451,7 +447,7 @@ module Graphy
|
|
451
447
|
end
|
452
448
|
|
453
449
|
# Minimum out-degree of the graph.
|
454
|
-
#
|
450
|
+
#
|
455
451
|
# @return [Integer, nil] returns `nil` if the graph is empty
|
456
452
|
def min_out_degree
|
457
453
|
return nil if to_a.empty?
|
@@ -529,11 +525,11 @@ module Graphy
|
|
529
525
|
|
530
526
|
# Equality is defined to be same set of edges and directed?
|
531
527
|
def eql?(g)
|
532
|
-
return false unless g.is_a?
|
528
|
+
return false unless g.is_a? Plexus::Graph
|
533
529
|
|
534
|
-
(
|
530
|
+
(directed? == g.directed?) and
|
535
531
|
(vertices.sort == g.vertices.sort) and
|
536
|
-
(
|
532
|
+
(edges.sort == g.edges.sort)
|
537
533
|
end
|
538
534
|
alias == eql?
|
539
535
|
|
@@ -544,8 +540,8 @@ module Graphy
|
|
544
540
|
def merge(other)
|
545
541
|
other.vertices.each { |v| add_vertex!(v) }
|
546
542
|
other.edges.each { |e| add_edge!(e) }
|
547
|
-
other.edges.each { |e| add_edge!(e.reverse) } if directed? and !other.directed?
|
548
|
-
self
|
543
|
+
other.edges.each { |e| add_edge!(e.reverse) } if directed? and !other.directed?
|
544
|
+
self
|
549
545
|
end
|
550
546
|
|
551
547
|
# A synonym for {GraphBuilder#merge merge}, but doesn't modify the current graph.
|
@@ -555,9 +551,9 @@ module Graphy
|
|
555
551
|
def +(other)
|
556
552
|
result = self.class.new(self)
|
557
553
|
case other
|
558
|
-
when
|
554
|
+
when Plexus::Graph
|
559
555
|
result.merge(other)
|
560
|
-
when
|
556
|
+
when Plexus::Arc
|
561
557
|
result.add_edge!(other)
|
562
558
|
else
|
563
559
|
result.add_vertex!(other)
|
@@ -567,12 +563,12 @@ module Graphy
|
|
567
563
|
# Removes all vertices in the specified graph.
|
568
564
|
#
|
569
565
|
# @param [Graph, Arc] other
|
570
|
-
# @return [Graph]
|
566
|
+
# @return [Graph]
|
571
567
|
def -(other)
|
572
568
|
case other
|
573
|
-
when
|
569
|
+
when Plexus::Graph
|
574
570
|
induced_subgraph(vertices - other.vertices)
|
575
|
-
when
|
571
|
+
when Plexus::Arc
|
576
572
|
self.class.new(self).remove_edge!(other)
|
577
573
|
else
|
578
574
|
self.class.new(self).remove_vertex!(other)
|
@@ -599,33 +595,32 @@ module Graphy
|
|
599
595
|
# @param [Array(vertex)] v
|
600
596
|
# @return [Graph]
|
601
597
|
def induced_subgraph(v)
|
602
|
-
edges.inject(self.class.new) do |a,e|
|
598
|
+
edges.inject(self.class.new) do |a,e|
|
603
599
|
(v.include?(e.source) and v.include?(e.target)) ? (a << e) : a
|
604
600
|
end
|
605
601
|
end
|
606
602
|
|
607
|
-
|
603
|
+
def inspect
|
608
604
|
## FIXME: broken, it's not updated. The issue's not with inspect, but it's worth mentionning here.
|
609
605
|
## Example:
|
610
606
|
## dg = Digraph[1,2, 2,3, 2,4, 4,5, 6,4, 1,6]
|
611
607
|
## dg.add_vertices! 1, 5, "yosh"
|
612
|
-
## # =>
|
608
|
+
## # => Plexus::Digraph[Plexus::Arc[1,2,nil], Plexus::Arc[1,6,nil], Plexus::Arc[2,3,nil], Plexus::Arc[2,4,nil], Plexus::Arc[4,5,nil], Plexus::Arc[6,4,nil]]
|
613
609
|
## dg.vertex?("yosh")
|
614
610
|
## # => true
|
615
611
|
## dg
|
616
|
-
## # =>
|
612
|
+
## # =>Plexus::Digraph[Plexus::Arc[1,2,nil], Plexus::Arc[1,6,nil], Plexus::Arc[2,3,nil], Plexus::Arc[2,4,nil], Plexus::Arc[4,5,nil], Plexus::Arc[6,4,nil]]
|
617
613
|
## the new vertex doesn't show up.
|
618
614
|
## Actually this version of inspect is far too verbose IMO :)
|
619
|
-
|
620
|
-
|
621
|
-
|
615
|
+
l = vertices.select { |v| self[v]}.map { |u| "vertex_label_set(#{u.inspect}, #{self[u].inspect})"}.join('.')
|
616
|
+
self.class.to_s + '[' + edges.map {|e| e.inspect}.join(', ') + ']' + (l && l != '' ? '.'+l : '')
|
617
|
+
end
|
622
618
|
|
623
619
|
private
|
624
620
|
|
625
621
|
# ?
|
626
622
|
def edge_convert(*args)
|
627
|
-
args[0].is_a?(
|
623
|
+
args[0].is_a?(Plexus::Arc) ? args[0] : edge_class[*args]
|
628
624
|
end
|
629
|
-
|
630
|
-
|
631
|
-
end # Graphy
|
625
|
+
end
|
626
|
+
end
|