jumoku 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -0
- data/lib/jumoku.rb +4 -2
- data/lib/jumoku/version.rb +1 -1
- data/spec/raw_tree_spec.rb +353 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/tree_spec.rb +553 -0
- data/vendor/git/graphy/CREDITS.md +31 -0
- data/vendor/git/graphy/LICENSE +35 -0
- data/vendor/git/graphy/README.md +186 -0
- data/vendor/git/graphy/Rakefile +61 -0
- data/vendor/git/graphy/TODO.md +20 -0
- data/vendor/git/graphy/VERSION +1 -0
- data/vendor/git/graphy/examples/graph_self.rb +56 -0
- data/vendor/git/graphy/examples/module_graph.jpg +0 -0
- data/vendor/git/graphy/examples/module_graph.rb +14 -0
- data/vendor/git/graphy/examples/self_graph.jpg +0 -0
- data/vendor/git/graphy/examples/visualize.jpg +0 -0
- data/vendor/git/graphy/examples/visualize.rb +10 -0
- data/vendor/git/graphy/graphy.gemspec +149 -0
- data/vendor/git/graphy/lib/graphy.rb +90 -0
- data/vendor/git/graphy/lib/graphy/adjacency_graph.rb +224 -0
- data/vendor/git/graphy/lib/graphy/arc.rb +65 -0
- data/vendor/git/graphy/lib/graphy/arc_number.rb +52 -0
- data/vendor/git/graphy/lib/graphy/biconnected.rb +84 -0
- data/vendor/git/graphy/lib/graphy/chinese_postman.rb +91 -0
- data/vendor/git/graphy/lib/graphy/classes/graph_classes.rb +28 -0
- data/vendor/git/graphy/lib/graphy/common.rb +63 -0
- data/vendor/git/graphy/lib/graphy/comparability.rb +63 -0
- data/vendor/git/graphy/lib/graphy/directed_graph.rb +76 -0
- data/vendor/git/graphy/lib/graphy/directed_graph/algorithms.rb +92 -0
- data/vendor/git/graphy/lib/graphy/directed_graph/distance.rb +167 -0
- data/vendor/git/graphy/lib/graphy/dot.rb +94 -0
- data/vendor/git/graphy/lib/graphy/edge.rb +37 -0
- data/vendor/git/graphy/lib/graphy/ext.rb +79 -0
- data/vendor/git/graphy/lib/graphy/graph.rb +631 -0
- data/vendor/git/graphy/lib/graphy/graph_api.rb +35 -0
- data/vendor/git/graphy/lib/graphy/labels.rb +113 -0
- data/vendor/git/graphy/lib/graphy/maximum_flow.rb +77 -0
- data/vendor/git/graphy/lib/graphy/ruby_compatibility.rb +17 -0
- data/vendor/git/graphy/lib/graphy/search.rb +511 -0
- data/vendor/git/graphy/lib/graphy/strong_components.rb +93 -0
- data/vendor/git/graphy/lib/graphy/support/support.rb +9 -0
- data/vendor/git/graphy/lib/graphy/undirected_graph.rb +57 -0
- data/vendor/git/graphy/lib/graphy/undirected_graph/algorithms.rb +90 -0
- data/vendor/git/graphy/spec/biconnected_spec.rb +27 -0
- data/vendor/git/graphy/spec/chinese_postman_spec.rb +27 -0
- data/vendor/git/graphy/spec/community_spec.rb +44 -0
- data/vendor/git/graphy/spec/complement_spec.rb +27 -0
- data/vendor/git/graphy/spec/digraph_distance_spec.rb +121 -0
- data/vendor/git/graphy/spec/digraph_spec.rb +339 -0
- data/vendor/git/graphy/spec/dot_spec.rb +48 -0
- data/vendor/git/graphy/spec/edge_spec.rb +159 -0
- data/vendor/git/graphy/spec/inspection_spec.rb +40 -0
- data/vendor/git/graphy/spec/multi_edge_spec.rb +32 -0
- data/vendor/git/graphy/spec/neighborhood_spec.rb +38 -0
- data/vendor/git/graphy/spec/properties_spec.rb +146 -0
- data/vendor/git/graphy/spec/search_spec.rb +227 -0
- data/vendor/git/graphy/spec/spec.opts +4 -0
- data/vendor/git/graphy/spec/spec_helper.rb +56 -0
- data/vendor/git/graphy/spec/strong_components_spec.rb +61 -0
- data/vendor/git/graphy/spec/triangulated_spec.rb +125 -0
- data/vendor/git/graphy/spec/undirected_graph_spec.rb +220 -0
- data/vendor/git/graphy/vendor/priority-queue/CHANGELOG +33 -0
- data/vendor/git/graphy/vendor/priority-queue/Makefile +140 -0
- data/vendor/git/graphy/vendor/priority-queue/README +133 -0
- data/vendor/git/graphy/vendor/priority-queue/benchmark/dijkstra.rb +171 -0
- data/vendor/git/graphy/vendor/priority-queue/compare_comments.rb +49 -0
- data/vendor/git/graphy/vendor/priority-queue/doc/c-vs-rb.png +0 -0
- data/vendor/git/graphy/vendor/priority-queue/doc/compare_big.gp +14 -0
- data/vendor/git/graphy/vendor/priority-queue/doc/compare_big.png +0 -0
- data/vendor/git/graphy/vendor/priority-queue/doc/compare_small.gp +15 -0
- data/vendor/git/graphy/vendor/priority-queue/doc/compare_small.png +0 -0
- data/vendor/git/graphy/vendor/priority-queue/doc/results.csv +37 -0
- data/vendor/git/graphy/vendor/priority-queue/ext/priority_queue/CPriorityQueue/extconf.rb +2 -0
- data/vendor/git/graphy/vendor/priority-queue/ext/priority_queue/CPriorityQueue/priority_queue.c +947 -0
- data/vendor/git/graphy/vendor/priority-queue/lib/priority_queue.rb +14 -0
- data/vendor/git/graphy/vendor/priority-queue/lib/priority_queue/c_priority_queue.rb +1 -0
- data/vendor/git/graphy/vendor/priority-queue/lib/priority_queue/poor_priority_queue.rb +46 -0
- data/vendor/git/graphy/vendor/priority-queue/lib/priority_queue/ruby_priority_queue.rb +526 -0
- data/vendor/git/graphy/vendor/priority-queue/priority_queue.so +0 -0
- data/vendor/git/graphy/vendor/priority-queue/setup.rb +1551 -0
- data/vendor/git/graphy/vendor/priority-queue/test/priority_queue_test.rb +371 -0
- data/vendor/git/graphy/vendor/rdot.rb +360 -0
- metadata +83 -1
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe "Inspection" do # :nodoc:
|
4
|
+
|
5
|
+
before do
|
6
|
+
@dg = DirectedMultiGraph[
|
7
|
+
[0,0,1] => 1,
|
8
|
+
[1,2,2] => 2,
|
9
|
+
[1,3,3] => 4,
|
10
|
+
[1,4,4] => nil,
|
11
|
+
[4,1,5] => 8,
|
12
|
+
[1,2,6] => 16,
|
13
|
+
[3,3,7] => 32,
|
14
|
+
[3,3,8] => 64 ]
|
15
|
+
@dg[3] = 128
|
16
|
+
@dg[0] = 256
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "inspection_without_labels" do
|
20
|
+
it do
|
21
|
+
@dg = Digraph[1,2,3,4,5,6]
|
22
|
+
reflect = eval @dg.inspect
|
23
|
+
reflect.should == @dg
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "inspection_with_labels" do
|
28
|
+
it do
|
29
|
+
inspect = @dg.inspect
|
30
|
+
@dg.vertices.inject(0) {|a,v| a += (@dg[v] || 0)}.should == 384
|
31
|
+
@dg.edges.inject(0) {|a,e| a += (@dg[e] || 0)}.should == 127
|
32
|
+
reflect = eval inspect
|
33
|
+
reflect.should == @dg
|
34
|
+
reflect.edges.inject(0) { |a,e| a += (reflect[e] || 0)}.should == 127
|
35
|
+
reflect.vertices.inject(0) {|a,v| a += (reflect[v] || 0)}.should == 384
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe "MultiArc" do # :nodoc:
|
4
|
+
|
5
|
+
describe "directed_pseudo_graph" do
|
6
|
+
it do
|
7
|
+
dpg = DirectedPseudoGraph[ :a,:b,
|
8
|
+
:a,:b,
|
9
|
+
:a,:b ]
|
10
|
+
dpg.edges.size.should == 3
|
11
|
+
x = 0
|
12
|
+
dpg.edges.each {|e| dpg[e] = (x+=1)}
|
13
|
+
dpg.edges.inject(0) {|a,v| a+=dpg[v]}.should == 6
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "directed_multi_graph" do
|
18
|
+
it do
|
19
|
+
dmg = DirectedMultiGraph[ :a,:a,
|
20
|
+
:a,:a,
|
21
|
+
:a,:b,
|
22
|
+
:a,:b,
|
23
|
+
:b,:b,
|
24
|
+
:b,:b ]
|
25
|
+
dmg.edges.size.should == 6
|
26
|
+
x = 0
|
27
|
+
dmg.edges.each { |e| dmg[e] = (x+=1) }
|
28
|
+
dmg.edges.inject(0) {|a,v| a+=dmg[v]}.should == 21
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe "Neighborhood" do # :nodoc:
|
4
|
+
|
5
|
+
before do
|
6
|
+
@d = Digraph[:a,:b, :a,:f,
|
7
|
+
:b,:g,
|
8
|
+
:c,:b, :c,:g,
|
9
|
+
:d,:c, :d,:g,
|
10
|
+
:e,:d,
|
11
|
+
:f,:e, :f,:g,
|
12
|
+
:g,:a, :g,:e]
|
13
|
+
@w = [:a,:b]
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "open_out_neighborhood" do
|
17
|
+
it do
|
18
|
+
@d.set_neighborhood([:a], :in).should == [:g]
|
19
|
+
([:f,:g] - @d.set_neighborhood(@w, :out)).should == []
|
20
|
+
(@w - @d.open_pth_neighborhood(@w, 0, :out)).should == []
|
21
|
+
([:f, :g] - @d.open_pth_neighborhood(@w, 1, :out)).should == []
|
22
|
+
([:e] - @d.open_pth_neighborhood(@w, 2, :out)).should == []
|
23
|
+
([:d] - @d.open_pth_neighborhood(@w, 3, :out)).should == []
|
24
|
+
([:c] - @d.open_pth_neighborhood(@w, 4, :out)).should == []
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "closed_out_neighborhood" do
|
29
|
+
it do
|
30
|
+
(@w - @d.closed_pth_neighborhood(@w, 0, :out)).should == []
|
31
|
+
([:a,:b,:f,:g] - @d.closed_pth_neighborhood(@w, 1, :out)).should == []
|
32
|
+
([:a,:b,:e,:f,:g] - @d.closed_pth_neighborhood(@w, 2, :out)).should == []
|
33
|
+
([:a,:b,:d,:e,:f,:g] - @d.closed_pth_neighborhood(@w, 3, :out)).should == []
|
34
|
+
([:a,:b,:c,:d,:e,:f,:g] - @d.closed_pth_neighborhood(@w, 4, :out)).should == []
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
|
2
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
3
|
+
require 'graphy/dot'
|
4
|
+
|
5
|
+
# This test runs the classes from Appendix F in
|
6
|
+
# _Algorithmic_Graph_Theory_and_Perfect_Graphs,
|
7
|
+
# by Martin Charles Golumbic
|
8
|
+
describe "Properties" do # :nodoc:
|
9
|
+
|
10
|
+
describe "g1" do
|
11
|
+
it do
|
12
|
+
g1 = UndirectedGraph[ :a,:b, :a,:d, :a,:e, :a,:i, :a,:g, :a,:h,
|
13
|
+
:b,:c, :b,:f,
|
14
|
+
:c,:d, :c,:h,
|
15
|
+
:d,:h, :d,:e,
|
16
|
+
:e,:f,
|
17
|
+
:f,:g, :f,:h, :f,:i,
|
18
|
+
:h,:i ]
|
19
|
+
|
20
|
+
g1.should_not be_triangulated
|
21
|
+
g1.complement.should_not be_triangulated # Disagrees with Golumbic!
|
22
|
+
g1.should_not be_comparability
|
23
|
+
g1.complement.should_not be_comparability
|
24
|
+
g1.should_not be_interval
|
25
|
+
g1.complement.should_not be_interval
|
26
|
+
g1.should_not be_permutation
|
27
|
+
g1.should_not be_split
|
28
|
+
|
29
|
+
# g1.write_to_graphic_file('jpg','g1')
|
30
|
+
# g1.complement.write_to_graphic_file('jpg','g1_complement')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "g2" do
|
35
|
+
it do
|
36
|
+
g2 = UndirectedGraph[ :a,:b, :a,:e,
|
37
|
+
:b,:c, :b,:e, :b,:f,
|
38
|
+
:c,:d, :c,:f, :c,:g,
|
39
|
+
:d,:g,
|
40
|
+
:e,:f,
|
41
|
+
:f,:g]
|
42
|
+
|
43
|
+
g2.should be_triangulated
|
44
|
+
g2.complement.should_not be_triangulated
|
45
|
+
g2.should_not be_comparability
|
46
|
+
g2.complement.should be_comparability
|
47
|
+
g2.should be_interval
|
48
|
+
g2.complement.should_not be_interval
|
49
|
+
g2.should_not be_permutation
|
50
|
+
g2.should_not be_split
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "g3" do
|
55
|
+
it do
|
56
|
+
g3 = UndirectedGraph[ :a,:c,
|
57
|
+
:b,:e,
|
58
|
+
:c,:d, :c,:f,
|
59
|
+
:d,:f, :d,:g, :d,:e,
|
60
|
+
:e,:g,
|
61
|
+
:f,:g ]
|
62
|
+
g3.should be_triangulated
|
63
|
+
g3.complement.should_not be_triangulated
|
64
|
+
g3.should_not be_comparability
|
65
|
+
g3.complement.should be_comparability
|
66
|
+
g3.should be_interval
|
67
|
+
g3.complement.should_not be_interval
|
68
|
+
g3.should_not be_permutation
|
69
|
+
g3.should_not be_split
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "g4" do
|
74
|
+
it do
|
75
|
+
g4 = UndirectedGraph[ :a,:b,
|
76
|
+
:b,:c,
|
77
|
+
:c,:d, :c,:e,
|
78
|
+
:d,:f,
|
79
|
+
:e,:g]
|
80
|
+
g4.should be_triangulated
|
81
|
+
g4.complement.should_not be_triangulated
|
82
|
+
g4.should be_comparability
|
83
|
+
g4.complement.should_not be_comparability
|
84
|
+
g4.should_not be_interval
|
85
|
+
g4.complement.should_not be_interval
|
86
|
+
g4.should_not be_permutation
|
87
|
+
g4.should_not be_split
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "g5" do
|
92
|
+
it do
|
93
|
+
g5 = UndirectedGraph[ :a,:b, :a,:c,
|
94
|
+
:b,:c, :b,:d, :b,:f, :b,:g,
|
95
|
+
:c,:e, :c,:f, :c,:g,
|
96
|
+
:d,:f,
|
97
|
+
:e,:g,
|
98
|
+
:f,:g]
|
99
|
+
g5.should be_triangulated
|
100
|
+
g5.complement.should be_triangulated
|
101
|
+
g5.should be_comparability
|
102
|
+
g5.complement.should_not be_comparability
|
103
|
+
g5.should_not be_interval
|
104
|
+
g5.complement.should be_interval
|
105
|
+
g5.should_not be_permutation
|
106
|
+
g5.should be_split
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "g6" do
|
111
|
+
it do
|
112
|
+
g6 = UndirectedGraph[ :a,:c, :a,:d,
|
113
|
+
:b,:c,
|
114
|
+
:c,:f,
|
115
|
+
:d,:e, :d,:f]
|
116
|
+
g6.should_not be_triangulated
|
117
|
+
g6.complement.should_not be_triangulated
|
118
|
+
g6.should be_comparability
|
119
|
+
g6.complement.should be_comparability
|
120
|
+
g6.should_not be_interval
|
121
|
+
g6.complement.should_not be_interval
|
122
|
+
g6.should be_permutation
|
123
|
+
g6.should_not be_split
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "g7" do
|
128
|
+
it do
|
129
|
+
g7 = UndirectedGraph[ :a,:b, :a,:c,
|
130
|
+
:b,:c, :b,:d, :b,:e,
|
131
|
+
:c,:e, :c,:f,
|
132
|
+
:d,:e,
|
133
|
+
:e,:f]
|
134
|
+
g7.should be_triangulated
|
135
|
+
g7.complement.should be_triangulated
|
136
|
+
g7.should_not be_comparability
|
137
|
+
g7.complement.should_not be_comparability
|
138
|
+
g7.should_not be_interval
|
139
|
+
g7.complement.should_not be_interval
|
140
|
+
g7.should_not be_permutation
|
141
|
+
g7.should be_split
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
@@ -0,0 +1,227 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe "Search" do # :nodoc:
|
4
|
+
|
5
|
+
before do
|
6
|
+
@directed = Digraph[1,2, 2,3, 2,4, 4,5, 1,6, 6,4]
|
7
|
+
@undirected = UndirectedGraph[1,2, 2,3, 2,4, 4,5, 1,6]
|
8
|
+
@tree = Digraph[ 1,2, 1,3, 1,4, 2,5, 2,4, 2,6, 6,7, 23,24 ]
|
9
|
+
end
|
10
|
+
|
11
|
+
# "Algorithmic Graph Theory and Perfect Graphs", Martin Charles
|
12
|
+
# Golumbic, 1980, Academic Press, page 39, Propery (D1) and (D2) of
|
13
|
+
# depth first search
|
14
|
+
describe "dfs_properties" do
|
15
|
+
it do
|
16
|
+
dfs = {}
|
17
|
+
father = {}
|
18
|
+
@directed.each do |vertex|
|
19
|
+
assign_dfsnumber_ancestry(@directed, dfs, father, vertex)
|
20
|
+
# Property (D1)
|
21
|
+
father.keys.each {|v| dfs[father[v]].should be < dfs[v] }
|
22
|
+
# Property (D2)
|
23
|
+
# FIXME: Huh? Doesn't work
|
24
|
+
#@directed.edges.each {|e| related?(father, e.source, e.target).should be_true }
|
25
|
+
#@directed.edges.each {|e| dfs[e.source].should be < dfs[e.target] }
|
26
|
+
end
|
27
|
+
@directed.dfs.size.should == 6
|
28
|
+
@directed.dfs.sort.should == @directed.vertices.sort
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# "Algorithmic Graph Theory and Perfect Graphs", Martin Charles
|
33
|
+
# Golumbic, 1980, Academic Press, page 40, Propery (B1), (B2) and (B3) of
|
34
|
+
# breadth first search
|
35
|
+
describe "bfs_properties" do
|
36
|
+
it do
|
37
|
+
level = {}
|
38
|
+
father = {}
|
39
|
+
bfs = {}
|
40
|
+
@directed.each do |vertex|
|
41
|
+
assign_bfsnumber_ancestry(@directed, bfs, level, father, vertex)
|
42
|
+
# Property (B1)
|
43
|
+
father.keys.each do |v|
|
44
|
+
bfs[father[v]].should be < bfs[v]
|
45
|
+
end
|
46
|
+
# Property (B2)
|
47
|
+
@directed.edges.each do |e|
|
48
|
+
(level[e.source]-level[e.target]).abs.should be < 2
|
49
|
+
end
|
50
|
+
# Property (B3)
|
51
|
+
# FIXME: How can one test this?
|
52
|
+
# @directed.vertex.each { |e| (level[e.source]-level[e.target]).abs.should be < 2 }
|
53
|
+
end
|
54
|
+
@directed.dfs.size.should == 6
|
55
|
+
@directed.dfs.sort.should == @directed.vertices.sort
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "cyclic" do
|
60
|
+
it do
|
61
|
+
@directed.should be_acyclic
|
62
|
+
@undirected.should be_acyclic
|
63
|
+
@directed.should_not be_cyclic
|
64
|
+
@undirected.should_not be_cyclic
|
65
|
+
@undirected.add_edge!(4,6)
|
66
|
+
@directed.add_edge!(3,1)
|
67
|
+
@directed.should_not be_acyclic
|
68
|
+
@undirected.should_not be_acyclic
|
69
|
+
@directed.should be_cyclic
|
70
|
+
@undirected.should be_cyclic
|
71
|
+
|
72
|
+
# Test empty graph
|
73
|
+
x = Digraph.new
|
74
|
+
x.should_not be_cyclic
|
75
|
+
x.should be_acyclic
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "astar" do
|
80
|
+
it do
|
81
|
+
# Graph from "Artificial Intelligence: A Modern Approach" by Stuart
|
82
|
+
# Russell ande Peter Norvig, Prentice-Hall 2nd Edition, pg 63
|
83
|
+
romania = UndirectedGraph.new.
|
84
|
+
add_edge!('Oradea', 'Zerind', 71).
|
85
|
+
add_edge!('Oradea', 'Sibiu', 151).
|
86
|
+
add_edge!('Zerind', 'Arad', 75).
|
87
|
+
add_edge!('Arad', 'Sibiu', 99).
|
88
|
+
add_edge!('Arad', 'Timisoara', 138).
|
89
|
+
add_edge!('Timisoara', 'Lugoj', 111).
|
90
|
+
add_edge!('Lugoj', 'Mehadia', 70).
|
91
|
+
add_edge!('Mehadia', 'Dobreta', 75).
|
92
|
+
add_edge!('Dobreta', 'Craiova', 120).
|
93
|
+
add_edge!('Sibiu', 'Fagaras', 99).
|
94
|
+
add_edge!('Fagaras', 'Bucharest', 211).
|
95
|
+
add_edge!('Sibiu', 'Rimnicu Vilcea', 80).
|
96
|
+
add_edge!('Rimnicu Vilcea', 'Craiova', 146).
|
97
|
+
add_edge!('Rimnicu Vilcea', 'Pitesti', 97).
|
98
|
+
add_edge!('Craiova', 'Pitesti', 138).
|
99
|
+
add_edge!('Pitesti', 'Bucharest', 101).
|
100
|
+
add_edge!('Bucharest', 'Giurgin', 90).
|
101
|
+
add_edge!('Bucharest', 'Urzieni', 85).
|
102
|
+
add_edge!('Urzieni', 'Hirsova', 98).
|
103
|
+
add_edge!('Urzieni', 'Vaslui', 142).
|
104
|
+
add_edge!('Hirsova', 'Eforie', 86).
|
105
|
+
add_edge!('Vaslui', 'Iasi', 92).
|
106
|
+
add_edge!('Iasi', 'Neamt', 87)
|
107
|
+
|
108
|
+
# Heuristic from "Artificial Intelligence: A Modern Approach" by Stuart
|
109
|
+
# Russell ande Peter Norvig, Prentice-Hall 2nd Edition, pg 95
|
110
|
+
straight_line_to_Bucharest =
|
111
|
+
{
|
112
|
+
'Arad' => 366,
|
113
|
+
'Bucharest' => 0,
|
114
|
+
'Craiova' => 160,
|
115
|
+
'Dobreta' => 242,
|
116
|
+
'Eforie' => 161,
|
117
|
+
'Fagaras' => 176,
|
118
|
+
'Giurgiu' => 77,
|
119
|
+
'Hirsova' => 151,
|
120
|
+
'Iasi' => 226,
|
121
|
+
'Lugoj' => 244,
|
122
|
+
'Mehadia' => 241,
|
123
|
+
'Neamt' => 234,
|
124
|
+
'Oradea' => 380,
|
125
|
+
'Pitesti' => 100,
|
126
|
+
'Rimnicu Vilcea' => 193,
|
127
|
+
'Sibiu' => 253,
|
128
|
+
'Timisoara' => 329,
|
129
|
+
'Urziceni' => 80,
|
130
|
+
'Vaslui' => 199,
|
131
|
+
'Zerind' => 374
|
132
|
+
}
|
133
|
+
|
134
|
+
# Heuristic is distance as crow flies, always under estimates costs.
|
135
|
+
h = Proc.new {|v| straight_line_to_Bucharest[v]}
|
136
|
+
|
137
|
+
list = []
|
138
|
+
|
139
|
+
dv = Proc.new {|v| list << "dv #{v}" }
|
140
|
+
ev = Proc.new {|v| list << "ev #{v}" }
|
141
|
+
bt = Proc.new {|v| list << "bt #{v}" }
|
142
|
+
fv = Proc.new {|v| list << "fv #{v}" }
|
143
|
+
er = Proc.new {|e| list << "er #{e}" }
|
144
|
+
enr = Proc.new {|e| list << "enr #{e}" }
|
145
|
+
|
146
|
+
options = { :discover_vertex => dv,
|
147
|
+
:examine_vertex => ev,
|
148
|
+
:black_target => bt,
|
149
|
+
:finish_vertex => fv,
|
150
|
+
:edge_relaxed => er,
|
151
|
+
:edge_not_relaxed => enr }
|
152
|
+
|
153
|
+
result = romania.astar('Arad', 'Bucharest', h, options)
|
154
|
+
|
155
|
+
result.should == ["Arad", "Sibiu", "Rimnicu Vilcea", "Pitesti", "Bucharest"]
|
156
|
+
# This isn't the greatest test since the exact ordering is not
|
157
|
+
# not specified by the algorithm. If someone has a better idea, please fix
|
158
|
+
list.should == ["ev Arad",
|
159
|
+
"er (Arad=Sibiu '99')",
|
160
|
+
"dv Sibiu",
|
161
|
+
"er (Arad=Timisoara '138')",
|
162
|
+
"dv Timisoara",
|
163
|
+
"er (Arad=Zerind '75')",
|
164
|
+
"dv Zerind",
|
165
|
+
"fv Arad",
|
166
|
+
"ev Sibiu",
|
167
|
+
"er (Rimnicu Vilcea=Sibiu '80')",
|
168
|
+
"dv Rimnicu Vilcea",
|
169
|
+
"er (Fagaras=Sibiu '99')",
|
170
|
+
"dv Fagaras",
|
171
|
+
"er (Oradea=Sibiu '151')",
|
172
|
+
"dv Oradea",
|
173
|
+
"enr (Arad=Sibiu '99')",
|
174
|
+
"fv Sibiu",
|
175
|
+
"ev Rimnicu Vilcea",
|
176
|
+
"enr (Rimnicu Vilcea=Sibiu '80')",
|
177
|
+
"er (Craiova=Rimnicu Vilcea '146')",
|
178
|
+
"dv Craiova",
|
179
|
+
"er (Pitesti=Rimnicu Vilcea '97')",
|
180
|
+
"dv Pitesti",
|
181
|
+
"fv Rimnicu Vilcea",
|
182
|
+
"ev Fagaras",
|
183
|
+
"enr (Fagaras=Sibiu '99')",
|
184
|
+
"er (Bucharest=Fagaras '211')",
|
185
|
+
"dv Bucharest",
|
186
|
+
"fv Fagaras",
|
187
|
+
"ev Pitesti",
|
188
|
+
"enr (Pitesti=Rimnicu Vilcea '97')",
|
189
|
+
"er (Bucharest=Pitesti '101')",
|
190
|
+
"enr (Craiova=Pitesti '138')",
|
191
|
+
"fv Pitesti",
|
192
|
+
"ev Bucharest"]
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe "bfs_spanning_forest" do
|
197
|
+
it do
|
198
|
+
predecessor, roots = @tree.bfs_spanning_forest(1)
|
199
|
+
predecessor.should == {2=>1, 3=>1, 4=>1, 5=>2, 6=>2, 7=>6, 24=>23}
|
200
|
+
roots.sort.should == [1,23]
|
201
|
+
predecessor, roots = @tree.bfs_spanning_forest(3)
|
202
|
+
predecessor.should == {7=>6, 24=>23, 2=>1, 4=>1}
|
203
|
+
roots.sort.should == [1,3,5,6,23]
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
describe "dfs_spanning_forest" do
|
208
|
+
it do
|
209
|
+
predecessor, roots = @tree.dfs_spanning_forest(1)
|
210
|
+
predecessor.should == {5=>2, 6=>2, 7=>6, 24=>23, 2=>1, 3=>1, 4=>2}
|
211
|
+
roots.sort.should == [1,23]
|
212
|
+
predecessor, roots = @tree.dfs_spanning_forest(3)
|
213
|
+
predecessor.should == {7=>6, 24=>23, 2=>1, 4=>2}
|
214
|
+
roots.sort.should == [1,3,5,6,23]
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
describe "tree_from_vertex" do
|
219
|
+
it do
|
220
|
+
@tree.bfs_tree_from_vertex(1).should == {5=>2, 6=>2, 7=>6, 2=>1, 3=>1, 4=>1}
|
221
|
+
@tree.bfs_tree_from_vertex(3).should == {}
|
222
|
+
@tree.dfs_tree_from_vertex(1).should == {5=>2, 6=>2, 7=>6, 2=>1, 3=>1, 4=>2}
|
223
|
+
@tree.dfs_tree_from_vertex(3).should == {}
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
end
|