rgl 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/ChangeLog +19 -10
  2. data/Gemfile +3 -0
  3. data/{README → README.rdoc} +70 -98
  4. data/Rakefile +44 -150
  5. data/examples/canvas.rb +63 -64
  6. data/examples/examples.rb +42 -42
  7. data/examples/graph.dot +46 -0
  8. data/examples/images/example.jpg +0 -0
  9. data/examples/images/module_graph.jpg +0 -0
  10. data/examples/images/rgl_modules.png +0 -0
  11. data/examples/{insel-der-tausend-gefahren.rb → insel_der_tausend_gefahren.rb} +18 -19
  12. data/examples/north.rb +2 -2
  13. data/examples/north2.rb +11 -11
  14. data/examples/rdep-rgl.rb +218 -222
  15. data/lib/rgl/adjacency.rb +78 -74
  16. data/lib/rgl/base.rb +160 -78
  17. data/lib/rgl/bellman_ford.rb +115 -0
  18. data/lib/rgl/bidirectional.rb +17 -10
  19. data/lib/rgl/bipartite.rb +87 -0
  20. data/lib/rgl/condensation.rb +13 -4
  21. data/lib/rgl/connected_components.rb +38 -30
  22. data/lib/rgl/dijkstra.rb +158 -0
  23. data/lib/rgl/dijkstra_visitor.rb +42 -0
  24. data/lib/rgl/dot.rb +40 -32
  25. data/lib/rgl/edge_properties_map.rb +55 -0
  26. data/lib/rgl/edmonds_karp.rb +136 -0
  27. data/lib/rgl/enumerable_ext.rb +4 -1
  28. data/lib/rgl/graph_iterator.rb +15 -0
  29. data/lib/rgl/graph_visitor.rb +138 -0
  30. data/lib/rgl/graph_wrapper.rb +15 -0
  31. data/lib/rgl/graphxml.rb +20 -10
  32. data/lib/rgl/implicit.rb +68 -66
  33. data/lib/rgl/mutable.rb +37 -31
  34. data/lib/rgl/path_builder.rb +40 -0
  35. data/lib/rgl/prim.rb +52 -0
  36. data/lib/rgl/rdot.rb +411 -374
  37. data/lib/rgl/topsort.rb +23 -16
  38. data/lib/rgl/transitivity.rb +29 -27
  39. data/lib/rgl/traversal.rb +67 -205
  40. data/rakelib/dep_graph.rake +4 -3
  41. data/test/bellman_ford_test.rb +187 -0
  42. data/test/bipartite_test.rb +47 -0
  43. data/test/components_test.rb +80 -0
  44. data/test/cycles_test.rb +60 -0
  45. data/test/dijkstra_test.rb +148 -0
  46. data/test/directed_graph_test.rb +118 -0
  47. data/test/dot_test.rb +26 -0
  48. data/test/edge_properties_map_test.rb +63 -0
  49. data/test/edge_test.rb +35 -0
  50. data/test/edmonds_karp_test.rb +105 -0
  51. data/{tests/TestGraph.rb → test/graph_test.rb} +6 -6
  52. data/test/graph_xml_test.rb +57 -0
  53. data/test/implicit_test.rb +53 -0
  54. data/test/prim_test.rb +98 -0
  55. data/{tests/TestRdot.rb → test/rdot_test.rb} +309 -308
  56. data/{tests → test}/test_helper.rb +4 -1
  57. data/{tests/TestTransitivity.rb → test/transitivity_test.rb} +43 -43
  58. data/test/traversal_test.rb +221 -0
  59. data/test/undirected_graph_test.rb +103 -0
  60. metadata +226 -145
  61. data/examples/example.jpg +0 -0
  62. data/examples/module_graph.jpg +0 -0
  63. data/install.rb +0 -49
  64. data/tests/TestComponents.rb +0 -65
  65. data/tests/TestCycles.rb +0 -61
  66. data/tests/TestDirectedGraph.rb +0 -125
  67. data/tests/TestDot.rb +0 -18
  68. data/tests/TestEdge.rb +0 -34
  69. data/tests/TestGraphXML.rb +0 -57
  70. data/tests/TestImplicit.rb +0 -52
  71. data/tests/TestTraversal.rb +0 -220
  72. data/tests/TestUnDirectedGraph.rb +0 -102
@@ -13,9 +13,10 @@ end
13
13
  desc "Generate dependency graph of rake tasks"
14
14
  task :dep_graph do |task|
15
15
  this_task = task.name
16
- dep = RGL::ImplicitGraph.new { |g|
16
+
17
+ dep = RGL::ImplicitGraph.new do |g|
17
18
  # vertices of the graph are all defined tasks without this task
18
- g.vertex_iterator do |b|
19
+ g.vertex_iterator do |b|
19
20
  Rake::Task.tasks.each do |t|
20
21
  b.call(t) unless t.name == this_task
21
22
  end
@@ -23,7 +24,7 @@ task :dep_graph do |task|
23
24
  # neighbors of task t are its prerequisites
24
25
  g.adjacent_iterator { |t, b| t.prerequisites.each(&b) }
25
26
  g.directed = true
26
- }
27
+ end
27
28
 
28
29
  dep.write_to_graphic_file('png', this_task)
29
30
  puts "Wrote dependency graph to #{this_task}.png."
@@ -0,0 +1,187 @@
1
+ require 'test_helper'
2
+
3
+ require 'rgl/bellman_ford'
4
+ require 'rgl/adjacency'
5
+
6
+ include RGL
7
+
8
+ class TestBellmanFord < Test::Unit::TestCase
9
+
10
+ def setup
11
+ @graph = AdjacencyGraph[1,2, 1,3, 2,3, 2,4, 3,4]
12
+
13
+ @edge_weights = {
14
+ [1, 2] => 10,
15
+ [1, 3] => 1,
16
+ [2, 3] => 1,
17
+ [2, 4] => 1,
18
+ [3, 4] => 10
19
+ }
20
+
21
+ @edge_weights_lambda = lambda { |edge| @edge_weights[edge] }
22
+ end
23
+
24
+ def test_shortest_paths_search
25
+ assert_equal(
26
+ {
27
+ 1 => [1],
28
+ 2 => [1, 3, 2],
29
+ 3 => [1, 3],
30
+ 4 => [1, 3, 2, 4]
31
+ },
32
+ shortest_paths(1)
33
+ )
34
+ end
35
+
36
+ def test_shortest_paths_search_with_lambda
37
+ assert_equal(
38
+ {
39
+ 1 => [1],
40
+ 2 => [1, 3, 2],
41
+ 3 => [1, 3],
42
+ 4 => [1, 3, 2, 4]
43
+ },
44
+ shortest_paths(1, @edge_weights_lambda)
45
+ )
46
+ end
47
+
48
+ def test_shortest_paths_search_with_unreachable_vertex
49
+ @graph.add_vertex(5)
50
+
51
+ assert_equal(
52
+ {
53
+ 1 => [1],
54
+ 2 => [1, 3, 2],
55
+ 3 => [1, 3],
56
+ 4 => [1, 3, 2, 4],
57
+ 5 => nil
58
+ },
59
+ shortest_paths(1)
60
+ )
61
+ end
62
+
63
+ def test_shortest_paths_with_negative_weights
64
+ # can't use an undirected graph with a negative weighted edge here, because a negative weighted undirected edge is
65
+ # already a negative weighted cycle and therefore Bellman-Ford can't be applied for such graph
66
+ @graph = DirectedAdjacencyGraph[1,2, 1,3, 2,3, 2,4, 3,2, 3,4]
67
+ @edge_weights[[3, 2]] = 1
68
+ @edge_weights[[3, 4]] = -1
69
+
70
+ assert_equal(
71
+ {
72
+ 1 => [1],
73
+ 2 => [1, 3, 2],
74
+ 3 => [1, 3],
75
+ 4 => [1, 3, 4]
76
+ },
77
+ shortest_paths(1)
78
+ )
79
+ end
80
+
81
+ def test_missing_edge_weight
82
+ @edge_weights.delete([2, 3])
83
+ assert_raises(ArgumentError, 'weight of edge (2, 3) is not defined') { shortest_paths(1) }
84
+ end
85
+
86
+ def test_negative_cycles
87
+ @graph = DirectedAdjacencyGraph[1,2, 1,3, 2,3, 2,4, 3,4, 4,2]
88
+ @edge_weights[[4, 2]] = 1
89
+ @edge_weights[[3, 4]] = -3 # cycle 2-3-4-2 has negative weight
90
+
91
+ assert_raises(ArgumentError, 'there is a negative-weight cycle including edge (3, 4)') { shortest_paths(1) }
92
+ end
93
+
94
+ def test_visitor
95
+ visitor = BellmanFordVisitor.new(@graph)
96
+
97
+ events = []
98
+
99
+ %w[examine_edge edge_relaxed edge_not_relaxed edge_minimized edge_not_minimized].each do |event|
100
+ visitor.send("set_#{event}_event_handler") { |*args| events << { event.to_sym => args } }
101
+ end
102
+
103
+ @graph.bellman_ford_shortest_paths(@edge_weights, 1, visitor)
104
+
105
+ assert_equal(
106
+ [
107
+ # first iteration
108
+ { :examine_edge => [1, 2] },
109
+ { :edge_relaxed => [1, 2] },
110
+ { :examine_edge => [2, 1] },
111
+ { :edge_not_relaxed => [2, 1] },
112
+ { :examine_edge => [1, 3] },
113
+ { :edge_relaxed => [1, 3] },
114
+ { :examine_edge => [3, 1] },
115
+ { :edge_not_relaxed => [3, 1] },
116
+ { :examine_edge => [2, 3] },
117
+ { :edge_not_relaxed => [2, 3] },
118
+ { :examine_edge => [3, 2] },
119
+ { :edge_relaxed => [3, 2] },
120
+ { :examine_edge => [2, 4] },
121
+ { :edge_relaxed => [2, 4] },
122
+ { :examine_edge => [4, 2] },
123
+ { :edge_not_relaxed => [4, 2] },
124
+ { :examine_edge => [3, 4] },
125
+ { :edge_not_relaxed => [3, 4] },
126
+ { :examine_edge => [4, 3] },
127
+ { :edge_not_relaxed => [4, 3] },
128
+ # second iteration
129
+ { :examine_edge => [1, 2] },
130
+ { :edge_not_relaxed => [1, 2] },
131
+ { :examine_edge => [2, 1] },
132
+ { :edge_not_relaxed => [2, 1] },
133
+ { :examine_edge => [1, 3] },
134
+ { :edge_not_relaxed => [1, 3] },
135
+ { :examine_edge => [3, 1] },
136
+ { :edge_not_relaxed => [3, 1] },
137
+ { :examine_edge => [2, 3] },
138
+ { :edge_not_relaxed => [2, 3] },
139
+ { :examine_edge => [3, 2] },
140
+ { :edge_not_relaxed => [3, 2] },
141
+ { :examine_edge => [2, 4] },
142
+ { :edge_not_relaxed => [2, 4] },
143
+ { :examine_edge => [4, 2] },
144
+ { :edge_not_relaxed => [4, 2] },
145
+ { :examine_edge => [3, 4] },
146
+ { :edge_not_relaxed => [3, 4] },
147
+ { :examine_edge => [4, 3] },
148
+ { :edge_not_relaxed => [4, 3] },
149
+ # thirds iteration
150
+ { :examine_edge => [1, 2] },
151
+ { :edge_not_relaxed => [1, 2] },
152
+ { :examine_edge => [2, 1] },
153
+ { :edge_not_relaxed => [2, 1] },
154
+ { :examine_edge => [1, 3] },
155
+ { :edge_not_relaxed => [1, 3] },
156
+ { :examine_edge => [3, 1] },
157
+ { :edge_not_relaxed => [3, 1] },
158
+ { :examine_edge => [2, 3] },
159
+ { :edge_not_relaxed => [2, 3] },
160
+ { :examine_edge => [3, 2] },
161
+ { :edge_not_relaxed => [3, 2] },
162
+ { :examine_edge => [2, 4] },
163
+ { :edge_not_relaxed => [2, 4] },
164
+ { :examine_edge => [4, 2] },
165
+ { :edge_not_relaxed => [4, 2] },
166
+ { :examine_edge => [3, 4] },
167
+ { :edge_not_relaxed => [3, 4] },
168
+ { :examine_edge => [4, 3] },
169
+ { :edge_not_relaxed => [4, 3] },
170
+ # post-iteration check
171
+ { :edge_minimized => [1, 2] },
172
+ { :edge_minimized => [1, 3] },
173
+ { :edge_minimized => [2, 3] },
174
+ { :edge_minimized => [2, 4] },
175
+ { :edge_minimized => [3, 4] }
176
+ ],
177
+ events
178
+ )
179
+ end
180
+
181
+ private
182
+
183
+ def shortest_paths(source, edge_weights = @edge_weights)
184
+ @graph.bellman_ford_shortest_paths(edge_weights, source)
185
+ end
186
+
187
+ end
@@ -0,0 +1,47 @@
1
+ require 'test_helper'
2
+
3
+ require 'rgl/bipartite'
4
+ require 'rgl/adjacency'
5
+
6
+ include RGL
7
+
8
+ class TestBipartite < Test::Unit::TestCase
9
+
10
+ def test_bipartite_sets
11
+ assert_equal([[1, 2, 3], [4, 5, 6]], bipartite_sets(AdjacencyGraph[1,5, 1,6, 2,4, 2,5, 3,4, 3,5, 3,6]))
12
+ end
13
+
14
+ def test_bipartite_sets_for_non_bipartite_graph
15
+ assert_equal(nil, bipartite_sets(AdjacencyGraph[1,4, 1,5, 2,3, 2,4, 2,5, 3,5]))
16
+ end
17
+
18
+ def test_bipartite_sets_for_directed_graph
19
+ assert_raise(NotUndirectedError, 'bipartite sets can only be found for an undirected graph') do
20
+ DirectedAdjacencyGraph.new.bipartite_sets
21
+ end
22
+ end
23
+
24
+ def test_bipartite_sets_for_bipartite_disconnected_graph
25
+ assert_equal([[1, 3], [2, 4]], bipartite_sets(AdjacencyGraph[1,2, 3,4]))
26
+ end
27
+
28
+ def test_bipartite_sets_for_non_bipartite_disconnected_graph
29
+ assert_equal(nil, bipartite_sets(AdjacencyGraph[1,2, 3,4, 4,5, 5,3]))
30
+ end
31
+
32
+ def test_bipartite
33
+ assert(AdjacencyGraph[1,2, 2,3].bipartite?)
34
+ end
35
+
36
+ def test_not_bipartite
37
+ assert(!AdjacencyGraph[1,2, 2,3, 3,1].bipartite?)
38
+ end
39
+
40
+ private
41
+
42
+ def bipartite_sets(graph)
43
+ sets = graph.bipartite_sets
44
+ sets && sets.map { |set| set.sort }.sort
45
+ end
46
+
47
+ end
@@ -0,0 +1,80 @@
1
+ require 'test_helper'
2
+
3
+ require 'rgl/connected_components'
4
+ require 'rgl/adjacency'
5
+
6
+ include RGL
7
+
8
+ def graph_from_string(s)
9
+ g = DirectedAdjacencyGraph.new(Array)
10
+ s.split(/\n/).collect { |x| x.split(/->/) }.each do |a|
11
+ from = a[0].strip
12
+ a[1].split.each do |to|
13
+ g.add_edge from, to
14
+ end
15
+ end
16
+ g
17
+ end
18
+
19
+ class TestComponents < Test::Unit::TestCase
20
+
21
+ def setup
22
+ @dg = DirectedAdjacencyGraph.new(Array)
23
+ edges = [[1, 2], [2, 3], [2, 4], [4, 5], [1, 6], [6, 4]]
24
+ edges.each do |(src, target)|
25
+ @dg.add_edge(src, target)
26
+ end
27
+ @bfs = @dg.bfs_iterator(1)
28
+ @dfs = @dg.dfs_iterator(1)
29
+
30
+ @ug = AdjacencyGraph.new(Array)
31
+ @ug.add_edges(*edges)
32
+
33
+ @dg2 = graph_from_string(<<-END
34
+ a -> b f h
35
+ b -> c a
36
+ c -> d b
37
+ d -> e
38
+ e -> d
39
+ f -> g
40
+ g -> f d
41
+ h -> i
42
+ i -> h j e c
43
+ END
44
+ )
45
+ end
46
+
47
+ def test_connected_components
48
+ ccs = []
49
+ @ug.each_connected_component { |c| ccs << c }
50
+ assert_equal(1, ccs.size)
51
+
52
+ ccs = []
53
+ @ug.add_edge 10, 11
54
+ @ug.add_edge 33, 44
55
+ @ug.each_connected_component { |c| ccs << c.sort }
56
+ assert_equal([[10, 11], [1, 2, 3, 4, 5, 6], [33, 44]].sort, ccs.sort)
57
+ end
58
+
59
+ def test_strong_components
60
+ vis = @dg2.strongly_connected_components
61
+
62
+ assert_equal(4, vis.num_comp)
63
+
64
+ res = vis.comp_map.to_a.sort.reduce({}) { |res, a|
65
+ if res.key?(a[1])
66
+ res[a[1]] << a[0]
67
+ else
68
+ res[a[1]] = [a[0]]
69
+ end
70
+ res
71
+ }
72
+
73
+ std_res = res.to_a.map {
74
+ |a|
75
+ [a[1][0], a[1]]
76
+ }.sort
77
+
78
+ assert_equal([["a", ["a", "b", "c", "h", "i"]], ["d", ["d", "e"]], ["f", ["f", "g"]], ["j", ["j"]]], std_res)
79
+ end
80
+ end
@@ -0,0 +1,60 @@
1
+ require 'test_helper'
2
+
3
+ require 'rgl/adjacency'
4
+
5
+ include RGL
6
+
7
+ class TestCycles < Test::Unit::TestCase
8
+
9
+ def setup
10
+ @dg = DirectedAdjacencyGraph.new(Array)
11
+ edges = [[1, 2], [2, 2], [2, 3], [3, 4], [4, 5], [5, 1], [6, 4], [6, 6], [1, 4], [7, 7], [7, 7]]
12
+ edges.each do |(src, target)|
13
+ @dg.add_edge(src, target)
14
+ end
15
+
16
+ @ug = AdjacencyGraph.new(Array)
17
+ @ug.add_edges(*edges)
18
+ end
19
+
20
+ # Helper for testing for different permutations of a cycle
21
+ def contains_cycle?(cycles, cycle)
22
+ cycle.size.times do |i|
23
+ return true if cycles.include?(cycle)
24
+ cycle = cycle[1..-1] + [cycle[0]]
25
+ end
26
+ end
27
+
28
+ def test_cycles
29
+ d_cycles = @dg.cycles
30
+ assert_equal 6, d_cycles.size
31
+ assert d_cycles.include?([6])
32
+ assert d_cycles.include?([7])
33
+ assert d_cycles.include?([2])
34
+ assert contains_cycle?(d_cycles, [1, 4, 5])
35
+ assert contains_cycle?(d_cycles, [1, 2, 3, 4, 5])
36
+
37
+ assert_equal 5, DirectedAdjacencyGraph.new(Set, @dg).cycles.size
38
+
39
+ u_cycles = AdjacencyGraph.new(Set, @dg).cycles.sort
40
+
41
+ assert u_cycles.include?([2])
42
+ assert u_cycles.include?([6])
43
+ assert u_cycles.include?([7])
44
+ assert contains_cycle?(u_cycles, [1, 2, 3, 4, 5])
45
+ assert contains_cycle?(u_cycles, [1, 5, 4, 3, 2])
46
+ assert contains_cycle?(u_cycles, [1, 4, 3, 2])
47
+ assert contains_cycle?(u_cycles, [1, 4, 5])
48
+ assert contains_cycle?(u_cycles, [1, 5, 4])
49
+ assert contains_cycle?(u_cycles, [1, 5])
50
+ assert contains_cycle?(u_cycles, [1, 2])
51
+ assert contains_cycle?(u_cycles, [1, 2, 3, 4])
52
+ assert contains_cycle?(u_cycles, [2, 3])
53
+ assert contains_cycle?(u_cycles, [1, 4])
54
+ assert contains_cycle?(u_cycles, [3, 4])
55
+ assert contains_cycle?(u_cycles, [4, 5])
56
+ assert contains_cycle?(u_cycles, [4, 6])
57
+ assert_equal 16, u_cycles.size
58
+ end
59
+
60
+ end
@@ -0,0 +1,148 @@
1
+ require 'test_helper'
2
+
3
+ require 'rgl/dijkstra'
4
+ require 'rgl/adjacency'
5
+
6
+ include RGL
7
+
8
+ class TestDijkstra < Test::Unit::TestCase
9
+
10
+ def setup
11
+ @graph = AdjacencyGraph[1,2, 1,3, 2,3, 2,4, 3,4]
12
+
13
+ @edge_weights = {
14
+ [1, 2] => 10,
15
+ [1, 3] => 1,
16
+ [2, 3] => 1,
17
+ [2, 4] => 1,
18
+ [3, 4] => 10
19
+ }
20
+
21
+ @edge_weights_lambda = lambda { |edge| @edge_weights[edge] }
22
+ end
23
+
24
+ def test_shortest_path_search
25
+ assert_equal([1, 3, 2, 4], shortest_path(1, 4))
26
+ end
27
+
28
+ def test_shortest_path_search_with_lambda
29
+ assert_equal([1, 3, 2, 4], shortest_path(1, 4, @edge_weights_lambda))
30
+ end
31
+
32
+ def test_shortest_path_to_the_source
33
+ assert_equal([1], shortest_path(1, 1))
34
+ end
35
+
36
+ def test_path_for_unreachable_vertex
37
+ @graph.add_vertex(5)
38
+ assert_equal(nil, shortest_path(1, 5))
39
+ end
40
+
41
+ def test_shortest_paths_search
42
+ assert_equal(
43
+ {
44
+ 1 => [1],
45
+ 2 => [1, 3, 2],
46
+ 3 => [1, 3],
47
+ 4 => [1, 3, 2, 4]
48
+ },
49
+ shortest_paths(1)
50
+ )
51
+ end
52
+
53
+ def test_shortest_paths_search_with_lambda
54
+ assert_equal(
55
+ {
56
+ 1 => [1],
57
+ 2 => [1, 3, 2],
58
+ 3 => [1, 3],
59
+ 4 => [1, 3, 2, 4]
60
+ },
61
+ shortest_paths(1, @edge_weights_lambda)
62
+ )
63
+ end
64
+
65
+ def test_shortest_paths_search_with_unreachable_vertex
66
+ @graph.add_vertex(5)
67
+
68
+ assert_equal(
69
+ {
70
+ 1 => [1],
71
+ 2 => [1, 3, 2],
72
+ 3 => [1, 3],
73
+ 4 => [1, 3, 2, 4],
74
+ 5 => nil
75
+ },
76
+ shortest_paths(1)
77
+ )
78
+ end
79
+
80
+ def test_visitor
81
+ visitor = DijkstraVisitor.new(@graph)
82
+
83
+ events = []
84
+
85
+ %w[examine_vertex examine_edge edge_relaxed edge_not_relaxed finish_vertex].each do |event|
86
+ visitor.send("set_#{event}_event_handler") { |*args| events << { event.to_sym => args } }
87
+ end
88
+
89
+ @graph.dijkstra_shortest_paths(@edge_weights, 1, visitor)
90
+
91
+ assert_equal(
92
+ [
93
+ { :examine_vertex => [1] },
94
+ { :examine_edge => [1, 2] },
95
+ { :edge_relaxed => [1, 2] },
96
+ { :examine_edge => [1, 3] },
97
+ { :edge_relaxed => [1, 3] },
98
+ { :finish_vertex => [1] },
99
+ { :examine_vertex => [3] },
100
+ { :examine_edge => [3, 2] },
101
+ { :edge_relaxed => [3, 2] },
102
+ { :examine_edge => [3, 4] },
103
+ { :edge_relaxed => [3, 4] },
104
+ { :finish_vertex => [3] },
105
+ { :examine_vertex => [2] },
106
+ { :examine_edge => [2, 4] },
107
+ { :edge_relaxed => [2, 4] },
108
+ { :finish_vertex => [2] },
109
+ { :examine_vertex => [4] },
110
+ { :finish_vertex => [4] },
111
+ ],
112
+ events
113
+ )
114
+ end
115
+
116
+ def test_negative_edge_weight
117
+ @edge_weights[[2, 3]] = -7
118
+ assert_raises(ArgumentError, 'weight of edge (2, 3) is negative') { shortest_path(1, 5) }
119
+ end
120
+
121
+ def test_negative_edge_weight_with_lambda
122
+ @edge_weights[[2, 3]] = -7
123
+ assert_raises(ArgumentError, 'weight of edge (2, 3) is negative') { shortest_path(1, 5, @edge_weights_lambda) }
124
+ end
125
+
126
+ def test_missing_edge_weight
127
+ @edge_weights.delete([2, 3])
128
+ assert_raises(ArgumentError, 'weight of edge (2, 3) is not defined') { shortest_path(1, 5) }
129
+ end
130
+
131
+ def test_edge_weights_map_object_in_argument
132
+ weights_map = EdgePropertiesMap.new(@edge_weights, @graph.directed?)
133
+ dijkstra = DijkstraAlgorithm.new(@graph, weights_map, DijkstraVisitor.new(@graph))
134
+
135
+ assert_equal([1, 3, 2, 4], dijkstra.shortest_path(1, 4))
136
+ end
137
+
138
+ private
139
+
140
+ def shortest_path(source, target, edge_weights = @edge_weights)
141
+ @graph.dijkstra_shortest_path(edge_weights, source, target)
142
+ end
143
+
144
+ def shortest_paths(source, edge_weights = @edge_weights)
145
+ @graph.dijkstra_shortest_paths(edge_weights, source)
146
+ end
147
+
148
+ end