jumoku 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +0 -1
- data/lib/jumoku.rb +2 -3
- data/lib/jumoku/builders/extended.rb +15 -23
- data/lib/jumoku/builders/raw_directed_tree.rb +15 -0
- data/lib/jumoku/builders/raw_undirected_tree.rb +15 -0
- data/lib/jumoku/builders/shared.rb +2 -5
- data/lib/jumoku/support/ruby_compatibility.rb +19 -0
- data/lib/jumoku/version.rb +1 -1
- data/spec/arborescence_spec.rb +14 -0
- data/spec/behaviors/core_tree.rb +281 -0
- data/spec/behaviors/extended.rb +530 -0
- data/spec/raw_directed_tree_spec.rb +14 -0
- data/spec/raw_undirected_tree_spec.rb +9 -310
- data/spec/spec_helper.rb +2 -0
- data/spec/tree_spec.rb +8 -535
- metadata +21 -86
- data/lib/jumoku/tree_api.rb +0 -27
- data/vendor/git/plexus/CREDITS.md +0 -31
- data/vendor/git/plexus/Gemfile +0 -3
- data/vendor/git/plexus/Gemfile.lock +0 -28
- data/vendor/git/plexus/LICENSE +0 -37
- data/vendor/git/plexus/README.md +0 -208
- data/vendor/git/plexus/Rakefile +0 -25
- data/vendor/git/plexus/TODO.md +0 -20
- data/vendor/git/plexus/VERSION +0 -1
- data/vendor/git/plexus/examples/graph_self.rb +0 -56
- data/vendor/git/plexus/examples/module_graph.jpg +0 -0
- data/vendor/git/plexus/examples/module_graph.rb +0 -14
- data/vendor/git/plexus/examples/self_graph.jpg +0 -0
- data/vendor/git/plexus/examples/visualize.jpg +0 -0
- data/vendor/git/plexus/examples/visualize.rb +0 -10
- data/vendor/git/plexus/lib/plexus.rb +0 -90
- data/vendor/git/plexus/lib/plexus/adjacency_graph.rb +0 -224
- data/vendor/git/plexus/lib/plexus/arc.rb +0 -59
- data/vendor/git/plexus/lib/plexus/arc_number.rb +0 -52
- data/vendor/git/plexus/lib/plexus/biconnected.rb +0 -84
- data/vendor/git/plexus/lib/plexus/chinese_postman.rb +0 -91
- data/vendor/git/plexus/lib/plexus/classes/graph_classes.rb +0 -28
- data/vendor/git/plexus/lib/plexus/common.rb +0 -63
- data/vendor/git/plexus/lib/plexus/comparability.rb +0 -63
- data/vendor/git/plexus/lib/plexus/directed_graph.rb +0 -78
- data/vendor/git/plexus/lib/plexus/directed_graph/algorithms.rb +0 -95
- data/vendor/git/plexus/lib/plexus/directed_graph/distance.rb +0 -167
- data/vendor/git/plexus/lib/plexus/dot.rb +0 -94
- data/vendor/git/plexus/lib/plexus/edge.rb +0 -36
- data/vendor/git/plexus/lib/plexus/ext.rb +0 -79
- data/vendor/git/plexus/lib/plexus/graph.rb +0 -626
- data/vendor/git/plexus/lib/plexus/graph_api.rb +0 -35
- data/vendor/git/plexus/lib/plexus/labels.rb +0 -113
- data/vendor/git/plexus/lib/plexus/maximum_flow.rb +0 -77
- data/vendor/git/plexus/lib/plexus/ruby_compatibility.rb +0 -17
- data/vendor/git/plexus/lib/plexus/search.rb +0 -510
- data/vendor/git/plexus/lib/plexus/strong_components.rb +0 -93
- data/vendor/git/plexus/lib/plexus/support/support.rb +0 -9
- data/vendor/git/plexus/lib/plexus/undirected_graph.rb +0 -56
- data/vendor/git/plexus/lib/plexus/undirected_graph/algorithms.rb +0 -90
- data/vendor/git/plexus/lib/plexus/version.rb +0 -6
- data/vendor/git/plexus/plexus.gemspec +0 -24
- data/vendor/git/plexus/spec/biconnected_spec.rb +0 -27
- data/vendor/git/plexus/spec/chinese_postman_spec.rb +0 -27
- data/vendor/git/plexus/spec/community_spec.rb +0 -44
- data/vendor/git/plexus/spec/complement_spec.rb +0 -27
- data/vendor/git/plexus/spec/digraph_distance_spec.rb +0 -121
- data/vendor/git/plexus/spec/digraph_spec.rb +0 -339
- data/vendor/git/plexus/spec/dot_spec.rb +0 -48
- data/vendor/git/plexus/spec/edge_spec.rb +0 -158
- data/vendor/git/plexus/spec/inspection_spec.rb +0 -38
- data/vendor/git/plexus/spec/multi_edge_spec.rb +0 -32
- data/vendor/git/plexus/spec/neighborhood_spec.rb +0 -36
- data/vendor/git/plexus/spec/properties_spec.rb +0 -146
- data/vendor/git/plexus/spec/search_spec.rb +0 -227
- data/vendor/git/plexus/spec/spec.opts +0 -4
- data/vendor/git/plexus/spec/spec_helper.rb +0 -59
- data/vendor/git/plexus/spec/strong_components_spec.rb +0 -61
- data/vendor/git/plexus/spec/triangulated_spec.rb +0 -125
- data/vendor/git/plexus/spec/undirected_graph_spec.rb +0 -220
- data/vendor/git/plexus/vendor/priority-queue/CHANGELOG +0 -33
- data/vendor/git/plexus/vendor/priority-queue/Makefile +0 -140
- data/vendor/git/plexus/vendor/priority-queue/README +0 -133
- data/vendor/git/plexus/vendor/priority-queue/benchmark/dijkstra.rb +0 -171
- data/vendor/git/plexus/vendor/priority-queue/compare_comments.rb +0 -49
- data/vendor/git/plexus/vendor/priority-queue/doc/c-vs-rb.png +0 -0
- data/vendor/git/plexus/vendor/priority-queue/doc/compare_big.gp +0 -14
- data/vendor/git/plexus/vendor/priority-queue/doc/compare_big.png +0 -0
- data/vendor/git/plexus/vendor/priority-queue/doc/compare_small.gp +0 -15
- data/vendor/git/plexus/vendor/priority-queue/doc/compare_small.png +0 -0
- data/vendor/git/plexus/vendor/priority-queue/doc/results.csv +0 -37
- data/vendor/git/plexus/vendor/priority-queue/ext/priority_queue/CPriorityQueue/extconf.rb +0 -2
- data/vendor/git/plexus/vendor/priority-queue/ext/priority_queue/CPriorityQueue/priority_queue.c +0 -947
- data/vendor/git/plexus/vendor/priority-queue/lib/priority_queue.rb +0 -14
- data/vendor/git/plexus/vendor/priority-queue/lib/priority_queue/c_priority_queue.rb +0 -1
- data/vendor/git/plexus/vendor/priority-queue/lib/priority_queue/poor_priority_queue.rb +0 -46
- data/vendor/git/plexus/vendor/priority-queue/lib/priority_queue/ruby_priority_queue.rb +0 -526
- data/vendor/git/plexus/vendor/priority-queue/priority_queue.so +0 -0
- data/vendor/git/plexus/vendor/priority-queue/setup.rb +0 -1551
- data/vendor/git/plexus/vendor/priority-queue/test/priority_queue_test.rb +0 -371
- data/vendor/git/plexus/vendor/rdot.rb +0 -360
@@ -1,93 +0,0 @@
|
|
1
|
-
module Plexus
|
2
|
-
module StrongComponents
|
3
|
-
# strong_components computes the strongly connected components
|
4
|
-
# of a graph using Tarjan's algorithm based on DFS. See: Robert E. Tarjan
|
5
|
-
# _Depth_First_Search_and_Linear_Graph_Algorithms_. SIAM Journal on
|
6
|
-
# Computing, 1(2):146-160, 1972
|
7
|
-
#
|
8
|
-
# The output of the algorithm is an array of components where is
|
9
|
-
# component is an array of vertices
|
10
|
-
#
|
11
|
-
# A strongly connected component of a directed graph G=(V,E) is a maximal
|
12
|
-
# set of vertices U which is in V such that for every pair of
|
13
|
-
# vertices u and v in U, we have both a path from u to v
|
14
|
-
# and path from v to u. That is to say that u and v are reachable
|
15
|
-
# from each other.
|
16
|
-
#
|
17
|
-
def strong_components
|
18
|
-
dfs_num = 0
|
19
|
-
stack = []; result = []; root = {}; comp = {}; number = {}
|
20
|
-
|
21
|
-
# Enter vertex callback
|
22
|
-
enter = Proc.new do |v|
|
23
|
-
root[v] = v
|
24
|
-
comp[v] = :new
|
25
|
-
number[v] = (dfs_num += 1)
|
26
|
-
stack.push(v)
|
27
|
-
end
|
28
|
-
|
29
|
-
# Exit vertex callback
|
30
|
-
exit = Proc.new do |v|
|
31
|
-
adjacent(v).each do |w|
|
32
|
-
if comp[w] == :new
|
33
|
-
root[v] = (number[root[v]] < number[root[w]] ? root[v] : root[w])
|
34
|
-
end
|
35
|
-
end
|
36
|
-
if root[v] == v
|
37
|
-
component = []
|
38
|
-
begin
|
39
|
-
w = stack.pop
|
40
|
-
comp[w] = :assigned
|
41
|
-
component << w
|
42
|
-
end until w == v
|
43
|
-
result << component
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# Execute depth first search
|
48
|
-
dfs({:enter_vertex => enter, :exit_vertex => exit}); result
|
49
|
-
|
50
|
-
end # strong_components
|
51
|
-
|
52
|
-
# Returns a condensation graph of the strongly connected components
|
53
|
-
# Each node is an array of nodes from the original graph
|
54
|
-
def condensation
|
55
|
-
sc = strong_components
|
56
|
-
cg = DirectedMultiGraph.new
|
57
|
-
map = sc.inject({}) do |a,c|
|
58
|
-
c.each {|v| a[v] = c }; a
|
59
|
-
end
|
60
|
-
sc.each do |c|
|
61
|
-
c.each do |v|
|
62
|
-
adjacent(v).each {|v1| cg.add_edge!(c, map[v1]) unless cg.edge?(c, map[v1]) }
|
63
|
-
end
|
64
|
-
end;
|
65
|
-
cg
|
66
|
-
end
|
67
|
-
|
68
|
-
# Compute transitive closure of a graph. That is any node that is reachable
|
69
|
-
# along a path is added as a directed edge.
|
70
|
-
def transitive_closure!
|
71
|
-
cgtc = condensation.plexus_inner_transitive_closure!
|
72
|
-
cgtc.each do |cgv|
|
73
|
-
cgtc.adjacent(cgv).each do |adj|
|
74
|
-
cgv.each do |u|
|
75
|
-
adj.each {|v| add_edge!(u,v)}
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end; self
|
79
|
-
end
|
80
|
-
|
81
|
-
# This returns the transitive closure of a graph. The original graph
|
82
|
-
# is not changed.
|
83
|
-
def transitive_closure() self.class.new(self).transitive_closure!; end
|
84
|
-
|
85
|
-
def plexus_inner_transitive_closure! # :nodoc:
|
86
|
-
sort.reverse.each do |u|
|
87
|
-
adjacent(u).each do |v|
|
88
|
-
adjacent(v).each {|w| add_edge!(u,w) unless edge?(u,w)}
|
89
|
-
end
|
90
|
-
end; self
|
91
|
-
end
|
92
|
-
end # StrongComponents
|
93
|
-
end # Plexus
|
@@ -1,56 +0,0 @@
|
|
1
|
-
module Plexus
|
2
|
-
module UndirectedGraphBuilder
|
3
|
-
autoload :Algorithms, "plexus/undirected_graph/algorithms"
|
4
|
-
|
5
|
-
include Plexus::GraphBuilder
|
6
|
-
extends_host
|
7
|
-
|
8
|
-
module ClassMethods
|
9
|
-
def [](*a)
|
10
|
-
self.new.from_array(*a)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def initialize(*params)
|
15
|
-
args = (params.pop if params.last.kind_of? Hash) || {}
|
16
|
-
args[:algorithmic_category] = Plexus::UndirectedGraphBuilder::Algorithms
|
17
|
-
super *(params << args)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
# This is a Digraph that allows for parallel edges, but does not allow loops.
|
22
|
-
module UndirectedPseudoGraphBuilder
|
23
|
-
include UndirectedGraphBuilder
|
24
|
-
extends_host
|
25
|
-
|
26
|
-
module ClassMethods
|
27
|
-
def [](*a)
|
28
|
-
self.new.from_array(*a)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def initialize(*params)
|
33
|
-
args = (params.pop if params.last.kind_of? Hash) || {}
|
34
|
-
args[:parallel_edges] = true
|
35
|
-
super *(params << args)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
# This is a Digraph that allows for parallel edges and loops.
|
40
|
-
module UndirectedMultiGraphBuilder
|
41
|
-
include UndirectedPseudoGraphBuilder
|
42
|
-
extends_host
|
43
|
-
|
44
|
-
module ClassMethods
|
45
|
-
def [](*a)
|
46
|
-
self.new.from_array(*a)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def initialize(*params)
|
51
|
-
args = (params.pop if params.last.kind_of? Hash) || {}
|
52
|
-
args[:loops] = true
|
53
|
-
super *(params << args)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
@@ -1,90 +0,0 @@
|
|
1
|
-
module Plexus
|
2
|
-
module UndirectedGraphBuilder
|
3
|
-
module Algorithms
|
4
|
-
|
5
|
-
include Search
|
6
|
-
include Biconnected
|
7
|
-
include Comparability
|
8
|
-
|
9
|
-
# UndirectedGraph is by definition undirected, always returns false
|
10
|
-
def directed?() false; end
|
11
|
-
|
12
|
-
# Redefine degree (default was sum)
|
13
|
-
def degree(v) in_degree(v); end
|
14
|
-
|
15
|
-
# A vertex of an undirected graph is balanced by definition
|
16
|
-
def balanced?(v) true; end
|
17
|
-
|
18
|
-
# UndirectedGraph uses Edge for the edge class.
|
19
|
-
def edge_class() @parallel_edges ? Plexus::MultiEdge : Plexus::Edge; end
|
20
|
-
|
21
|
-
def remove_edge!(u, v=nil)
|
22
|
-
unless u.kind_of? Plexus::Arc
|
23
|
-
raise ArgumentError if @parallel_edges
|
24
|
-
u = edge_class[u,v]
|
25
|
-
end
|
26
|
-
super(u.reverse) unless u.source == u.target
|
27
|
-
super(u)
|
28
|
-
end
|
29
|
-
|
30
|
-
# A triangulated graph is an undirected perfect graph that every cycle of length greater than
|
31
|
-
# three possesses a chord. They have also been called chordal, rigid circuit, monotone transitive,
|
32
|
-
# and perfect elimination graphs.
|
33
|
-
#
|
34
|
-
# Implementation taken from Golumbic's, "Algorithmic Graph Theory and
|
35
|
-
# Perfect Graphs" pg. 90
|
36
|
-
def triangulated?
|
37
|
-
a = Hash.new {|h,k| h[k]=Set.new}; sigma=lexicograph_bfs
|
38
|
-
inv_sigma = sigma.inject({}) {|acc,val| acc[val] = sigma.index(val); acc}
|
39
|
-
sigma[0..-2].each do |v|
|
40
|
-
x = adjacent(v).select {|w| inv_sigma[v] < inv_sigma[w] }
|
41
|
-
unless x.empty?
|
42
|
-
u = sigma[x.map {|y| inv_sigma[y]}.min]
|
43
|
-
a[u].merge(x - [u])
|
44
|
-
end
|
45
|
-
return false unless a[v].all? {|z| adjacent?(v,z)}
|
46
|
-
end
|
47
|
-
true
|
48
|
-
end
|
49
|
-
|
50
|
-
def chromatic_number
|
51
|
-
return triangulated_chromatic_number if triangulated?
|
52
|
-
raise NotImplementedError
|
53
|
-
end
|
54
|
-
|
55
|
-
# An interval graph can have its vertices into one-to-one
|
56
|
-
# correspondence with a set of intervals F of a linearly ordered
|
57
|
-
# set (like the real line) such that two vertices are connected
|
58
|
-
# by an edge of G if and only if their corresponding intervals
|
59
|
-
# have nonempty intersection.
|
60
|
-
def interval?() triangulated? and complement.comparability?; end
|
61
|
-
|
62
|
-
# A permutation diagram consists of n points on each of two parallel
|
63
|
-
# lines and n straight line segments matchin the points. The intersection
|
64
|
-
# graph of the line segments is called a permutation graph.
|
65
|
-
def permutation?() comparability? and complement.comparability?; end
|
66
|
-
|
67
|
-
# An undirected graph is defined to be split if there is a partition
|
68
|
-
# V = S + K of its vertex set into a stable set S and a complete set K.
|
69
|
-
def split?() triangulated? and complement.triangulated?; end
|
70
|
-
|
71
|
-
private
|
72
|
-
# Implementation taken from Golumbic's, "Algorithmic Graph Theory and
|
73
|
-
# Perfect Graphs" pg. 99
|
74
|
-
def triangulated_chromatic_number
|
75
|
-
chi = 1; s= Hash.new {|h,k| h[k]=0}
|
76
|
-
sigma=lexicograph_bfs
|
77
|
-
inv_sigma = sigma.inject({}) {|acc,val| acc[val] = sigma.index(val); acc}
|
78
|
-
sigma.each do |v|
|
79
|
-
x = adjacent(v).select {|w| inv_sigma[v] < inv_sigma[w] }
|
80
|
-
unless x.empty?
|
81
|
-
u = sigma[x.map {|y| inv_sigma[y]}.min]
|
82
|
-
s[u] = [s[u], x.size-1].max
|
83
|
-
chi = [chi, x.size+1].max if s[v] < x.size
|
84
|
-
end
|
85
|
-
end; chi
|
86
|
-
end
|
87
|
-
|
88
|
-
end # UndirectedGraphAlgorithms
|
89
|
-
end # UndirectedGraphBuilder
|
90
|
-
end # Plexus
|
@@ -1,24 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
require './lib/plexus/version'
|
3
|
-
|
4
|
-
Gem::Specification.new do |s|
|
5
|
-
s.name = %q{plexus}
|
6
|
-
s.version = Plexus::VERSION
|
7
|
-
s.authors = ["Bruce Williams", "Jean-Denis Vauguet <jd@vauguet.fr>"]
|
8
|
-
s.summary = "A framework for graph data structures and algorithms."
|
9
|
-
s.description = %q{This library is based on GRATR and RGL.
|
10
|
-
|
11
|
-
Graph algorithms currently provided are:
|
12
|
-
|
13
|
-
* Topological Sort
|
14
|
-
* Strongly Connected Components
|
15
|
-
* Transitive Closure
|
16
|
-
* Rural Chinese Postman
|
17
|
-
* Biconnected
|
18
|
-
}
|
19
|
-
s.email = %q{bruce@codefluency.com}
|
20
|
-
s.add_dependency "facets"
|
21
|
-
s.add_development_dependency "rspec"
|
22
|
-
s.add_development_dependency "yard"
|
23
|
-
end
|
24
|
-
|
@@ -1,27 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
-
|
3
|
-
describe "Biconnected" do # :nodoc:
|
4
|
-
describe "tarjan" do
|
5
|
-
it do
|
6
|
-
tarjan = UndirectedGraph[ 1, 2,
|
7
|
-
1, 5,
|
8
|
-
1, 6,
|
9
|
-
1, 7,
|
10
|
-
2, 3,
|
11
|
-
2, 4,
|
12
|
-
3, 4,
|
13
|
-
2, 5,
|
14
|
-
5, 6,
|
15
|
-
7, 8,
|
16
|
-
7, 9,
|
17
|
-
8, 9 ]
|
18
|
-
graphs, articulations = tarjan.biconnected
|
19
|
-
articulations.sort.should == [1,2,7]
|
20
|
-
graphs.size.should == 4
|
21
|
-
graphs.find {|g| g.size == 2}.vertices.sort.should == [1,7]
|
22
|
-
graphs.find {|g| g.size == 4}.vertices.sort.should == [1,2,5,6]
|
23
|
-
graphs.find {|g| g.size == 3 && g.vertex?(2)}.vertices.sort.should == [2,3,4]
|
24
|
-
graphs.find {|g| g.size == 3 && g.vertex?(7)}.vertices.sort.should == [7,8,9]
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
-
|
3
|
-
describe "ChinesePostman" do # :nodoc:
|
4
|
-
|
5
|
-
before do
|
6
|
-
@simple=Digraph[ 0,1, 0,2, 1,2, 1,3, 2,3, 3,0 ]
|
7
|
-
@weight = Proc.new {|e| 1}
|
8
|
-
end
|
9
|
-
|
10
|
-
describe "closed_simple_tour" do
|
11
|
-
it do
|
12
|
-
tour = @simple.closed_chinese_postman_tour(0, @weight)
|
13
|
-
tour.size.should == 11
|
14
|
-
tour[0].should == 0
|
15
|
-
tour[10].should == 0
|
16
|
-
edges = Set.new
|
17
|
-
0.upto(9) do |n|
|
18
|
-
edges << Arc[tour[n],tour[n+1]]
|
19
|
-
@simple.edge?(tour[n],tour[n+1]).should be_true
|
20
|
-
end
|
21
|
-
edges.size.should == @simple.edges.size
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
|
27
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
-
|
3
|
-
describe "Community" do # :nodoc:
|
4
|
-
before do
|
5
|
-
@graph = Digraph[2,1, 3,1, 5,4, 6,5, 7,6, 7,2].add_vertex!(8)
|
6
|
-
end
|
7
|
-
|
8
|
-
describe "ancestors_must_return_ancestors" do
|
9
|
-
it do
|
10
|
-
@graph.ancestors(1).sort.should == [2,3,7]
|
11
|
-
@graph.ancestors(2).sort.should == [7]
|
12
|
-
@graph.ancestors(3).sort.should == []
|
13
|
-
@graph.ancestors(4).sort.should == [5,6,7]
|
14
|
-
@graph.ancestors(5).sort.should == [6,7]
|
15
|
-
@graph.ancestors(6).sort.should == [7]
|
16
|
-
@graph.ancestors(7).sort.should == []
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
describe "descendants_must_return_descendants" do
|
21
|
-
it do
|
22
|
-
@graph.descendants(1).sort.should == []
|
23
|
-
@graph.descendants(2).sort.should == [1]
|
24
|
-
@graph.descendants(3).sort.should == [1]
|
25
|
-
@graph.descendants(4).sort.should == []
|
26
|
-
@graph.descendants(5).sort.should == [4]
|
27
|
-
@graph.descendants(6).sort.should == [4,5]
|
28
|
-
@graph.descendants(7).sort.should == [1,2,4,5,6]
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
describe "family_must_return_family" do
|
33
|
-
it do
|
34
|
-
@graph.family(1).sort.should == [2,3,4,5,6,7]
|
35
|
-
@graph.family(2).sort.should == [1,3,4,5,6,7]
|
36
|
-
@graph.family(3).sort.should == [1,2,4,5,6,7]
|
37
|
-
@graph.family(4).sort.should == [1,2,3,5,6,7]
|
38
|
-
@graph.family(5).sort.should == [1,2,3,4,6,7]
|
39
|
-
@graph.family(6).sort.should == [1,2,3,4,5,7]
|
40
|
-
@graph.family(7).sort.should == [1,2,3,4,5,6]
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
-
|
3
|
-
describe "Complement" do # :nodoc:
|
4
|
-
|
5
|
-
describe "square" do
|
6
|
-
it do
|
7
|
-
x = UndirectedGraph[:a,:b, :b,:c, :c,:d, :d,:a].complement
|
8
|
-
x.edges.size.should == 2
|
9
|
-
x.edges.include?(Edge[:a,:c]).should be_true
|
10
|
-
x.edges.include?(Edge[:b,:d]).should be_true
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
describe "g1" do
|
15
|
-
it do
|
16
|
-
g1 = UndirectedGraph[ :a,:b, :a,:d, :a,:e, :a,:i, :a,:g, :a,:h,
|
17
|
-
:b,:c, :b,:f,
|
18
|
-
:c,:d, :c,:h,
|
19
|
-
:d,:h, :d,:e,
|
20
|
-
:e,:f,
|
21
|
-
:f,:g, :f,:h, :f,:i,
|
22
|
-
:h,:i ].complement
|
23
|
-
g1.edges.size.should == 19
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
@@ -1,121 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
-
|
3
|
-
describe "DigraphDistance" do # :nodoc:
|
4
|
-
|
5
|
-
before do
|
6
|
-
@d = Digraph[ :a,:b, :a,:e,
|
7
|
-
:b,:c, :b,:e,
|
8
|
-
:c,:d,
|
9
|
-
:d,:c,
|
10
|
-
:e,:b, :e,:f,
|
11
|
-
:f,:c, :f,:d, :f,:e ]
|
12
|
-
|
13
|
-
@w = { Arc[:a,:b] => 9,
|
14
|
-
Arc[:a,:e] => 3,
|
15
|
-
Arc[:b,:c] => 2,
|
16
|
-
Arc[:b,:e] => 6,
|
17
|
-
Arc[:c,:d] => 1,
|
18
|
-
Arc[:d,:c] => 2,
|
19
|
-
Arc[:e,:b] => 2,
|
20
|
-
Arc[:e,:f] => 1,
|
21
|
-
Arc[:f,:c] => 2,
|
22
|
-
Arc[:f,:d] => 7,
|
23
|
-
Arc[:f,:e] => 2 }
|
24
|
-
@a = { :a => 0,
|
25
|
-
:b => 5,
|
26
|
-
:c => 6,
|
27
|
-
:d => 7,
|
28
|
-
:e => 3,
|
29
|
-
:f => 4 }
|
30
|
-
@simple_weight = Proc.new {|e| 1}
|
31
|
-
end
|
32
|
-
|
33
|
-
describe "shortest_path" do
|
34
|
-
it do
|
35
|
-
x = Digraph[ :s,:u, :s,:w,
|
36
|
-
:j,:v,
|
37
|
-
:u,:j,
|
38
|
-
:v,:y,
|
39
|
-
:w,:u, :w,:v, :w,:y, :w,:x,
|
40
|
-
:x,:z ]
|
41
|
-
x.should be_acyclic
|
42
|
-
cost, path = x.shortest_path(:s,@simple_weight)
|
43
|
-
cost.should == {:x=>2, :v=>2, :y=>2, :w=>1, :s=>0, :z=>3, :u=>1, :j=> 2}
|
44
|
-
path.should == {:x=>:w, :v=>:w, :y=>:w, :w=>:s, :z=>:x, :u=>:s, :j=>:u}
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
describe "dijkstra_with_proc" do
|
49
|
-
it do
|
50
|
-
p = Proc.new {|e| @w[e]}
|
51
|
-
distance, path = @d.dijkstras_algorithm(:a,p)
|
52
|
-
distance.should == @a
|
53
|
-
path.should == { :d => :c, :c => :f, :f => :e, :b => :e, :e => :a}
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
describe "dijkstra_with_label" do
|
58
|
-
it do
|
59
|
-
@w.keys.each {|e| @d[e] = @w[e]}
|
60
|
-
@d.dijkstras_algorithm(:a)[0].should == @a
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
describe "dijkstra_with_bracket_label" do
|
65
|
-
it do
|
66
|
-
@w.keys.each do |e|
|
67
|
-
@d[e] = {:xyz => (@w[e])}
|
68
|
-
end
|
69
|
-
@d.dijkstras_algorithm(:a, :xyz)[0].should == @a
|
70
|
-
@w.keys.each do |e|
|
71
|
-
@d[e] = [@w[e]]
|
72
|
-
end
|
73
|
-
@d.dijkstras_algorithm(:a, 0)[0].should == @a
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
describe "floyd_warshall" do
|
78
|
-
it do
|
79
|
-
simple = Digraph[ 0,1, 0,2, 1,2, 1,3, 2,3, 3,0 ]
|
80
|
-
|
81
|
-
cost, path, delta = simple.floyd_warshall(@simple_weight)
|
82
|
-
# Costs
|
83
|
-
cost[0].should == {0=>3, 1=>1, 2=>1, 3=>2}
|
84
|
-
cost[1].should == {0=>2, 1=>3, 2=>1, 3=>1}
|
85
|
-
cost[2].should == {0=>2, 1=>3, 2=>3, 3=>1}
|
86
|
-
cost[3].should == {0=>1, 1=>2, 2=>2, 3=>3}
|
87
|
-
|
88
|
-
# Paths
|
89
|
-
path[0].should == {0=>1, 1=>1, 2=>2, 3=>1}
|
90
|
-
path[1].should == {0=>3, 1=>3, 2=>2, 3=>3}
|
91
|
-
path[2].should == {0=>3, 1=>3, 2=>3, 3=>3}
|
92
|
-
path[3].should == {0=>0, 1=>0, 2=>0, 3=>0}
|
93
|
-
|
94
|
-
# Deltas
|
95
|
-
delta[0].should == 1
|
96
|
-
delta[1].should == 1
|
97
|
-
delta[2].should == -1
|
98
|
-
delta[3].should == -1
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
describe "bellman_ford_moore" do
|
103
|
-
it do
|
104
|
-
fig24 = Digraph[ [:s,:e] => 8,
|
105
|
-
[:s,:d] => 4,
|
106
|
-
[:e,:c] => 2,
|
107
|
-
[:e,:d] => -5,
|
108
|
-
[:c,:b] => -2,
|
109
|
-
[:d,:c] => -2,
|
110
|
-
[:d,:a] => 4,
|
111
|
-
[:a,:c] => 10,
|
112
|
-
[:a,:b] => 9,
|
113
|
-
[:b,:c] => 5,
|
114
|
-
[:b,:a] => -3]
|
115
|
-
cost, path = fig24.bellman_ford_moore(:s)
|
116
|
-
cost.should == {:e=>8, :d=>3, :c=>1, :b=>-1, :a=>-4, :s=>0}
|
117
|
-
path.should == {:e=>:s, :d=>:e, :c=>:d, :b=>:c, :a=>:b}
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
end
|