iconofthestoneage-doodl 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. data/lib/app/selfrunning.rb +185 -0
  2. data/lib/app/simple_app.rb +49 -0
  3. data/lib/app/simple_controller.rb +584 -0
  4. data/lib/app/simple_model.rb +292 -0
  5. data/lib/app/simple_view.rb +148 -0
  6. data/lib/breadth_first_search.rb +69 -0
  7. data/lib/connected_components.rb +29 -0
  8. data/lib/depth_first_search.rb +73 -0
  9. data/lib/edge.rb +57 -0
  10. data/lib/graph.rb +365 -0
  11. data/lib/graph_canvas.rb +187 -0
  12. data/lib/graph_generator.rb +121 -0
  13. data/lib/jruby/renderer.rb +413 -0
  14. data/lib/layout/collapse_layout.rb +23 -0
  15. data/lib/layout/fr_layout.rb +105 -0
  16. data/lib/layout/isom_layout.rb +77 -0
  17. data/lib/layout/kk_layout.rb +203 -0
  18. data/lib/layout/layout.rb +240 -0
  19. data/lib/layout/morph_layout.rb +65 -0
  20. data/lib/node.rb +57 -0
  21. data/lib/shortest_path/all_pair.rb +35 -0
  22. data/lib/shortest_path/bellman_ford.rb +60 -0
  23. data/lib/shortest_path/dijkstra.rb +74 -0
  24. data/lib/shortest_path/floyd_warshall.rb +68 -0
  25. data/lib/shortest_path/johnson_all_pair.rb +64 -0
  26. data/lib/shortest_path/single_source.rb +32 -0
  27. data/spec/breadth_first_search_spec.rb +145 -0
  28. data/spec/connected_components_spec.rb +50 -0
  29. data/spec/depth_first_search_spec.rb +89 -0
  30. data/spec/edge_spec.rb +58 -0
  31. data/spec/graph_generator_spec.rb +277 -0
  32. data/spec/graph_spec.rb +269 -0
  33. data/spec/jruby/renderer_spec.rb +214 -0
  34. data/spec/layout/layout_spec.rb +146 -0
  35. data/spec/node_spec.rb +179 -0
  36. data/spec/rspec_helper.rb +9 -0
  37. data/spec/rspec_suite.rb +12 -0
  38. data/spec/shortest_path/bellman_ford_spec.rb +101 -0
  39. data/spec/shortest_path/dijkstra_spec.rb +133 -0
  40. data/spec/shortest_path/floyd_warshall_spec.rb +84 -0
  41. data/spec/shortest_path/johnson_all_pair_spec.rb +90 -0
  42. metadata +43 -2
@@ -0,0 +1,146 @@
1
+ require 'rspec_helper'
2
+ require 'layout/layout'
3
+
4
+ include Doodl
5
+
6
+ describe Location do
7
+ before(:each) do
8
+ @v = Location.new(3, 3)
9
+ end
10
+ it "should be initialized using two fixnums" do
11
+ lambda { Location.new(0, 0) }.should_not raise_error(Exception)
12
+ lambda { Location.new(0.0, 0.0) }.should_not raise_error(Exception)
13
+ v = Location.new(1, 0)
14
+ v.x.should == 1
15
+ v.y.should == 0
16
+ v = Location.new(1.1, 0.1)
17
+ v.x.should == 1.1
18
+ v.y.should == 0.1
19
+ end
20
+
21
+ it "should be initialized with two points" do
22
+ lambda { Location.new(Location.new(0,0), Location.new(0,0)) }.should_not raise_error(Exception)
23
+ v = Location.new(Location.new(1, 1), Location.new(2, 2))
24
+ v.x.should == 1
25
+ v.y.should == 1
26
+ end
27
+
28
+ it "should return have an unary - operator" do
29
+ v = Location.new(1, 4)
30
+ w = -v
31
+ w.x.should == -1
32
+ w.y.should == -4
33
+ v.should_not == w
34
+ end
35
+
36
+ it "should have a / operator" do
37
+ x = @v / 2.0
38
+ x.x.should == 1.5
39
+ x.y.should == 1.5
40
+ x.should_not == @v
41
+ @v.x.should == 3
42
+ @v.y.should == 3
43
+ y = @v
44
+ y /= 3
45
+ y.x == 1
46
+ @v.should_not == y
47
+ end
48
+
49
+ it "should have a * operator" do
50
+ x = @v * 2.0
51
+ x.x.should == 6.0
52
+ x.y.should == 6.0
53
+ x.should_not == @v
54
+ @v.y.should == 3
55
+ @v.y.should == 3
56
+ y = @v
57
+ y *= 3
58
+ y.x.should == 9
59
+ @v.should_not == y
60
+ end
61
+
62
+ it "should have an + operator" do
63
+ x = @v + @v
64
+ x.x.should == 6.0
65
+ x.y.should == 6.0
66
+ x.should_not == @v
67
+ @v.x.should == 3
68
+ @v.y.should == 3
69
+ y = @v
70
+ y += x
71
+ y.x.should == 9
72
+ @v.should_not == y
73
+ end
74
+
75
+ it "should have an binary - operator" do
76
+ x = @v - @v
77
+ x.x.should == 0.0
78
+ x.y.should == 0.0
79
+ x.should_not == @v
80
+ @v.x.should == 3
81
+ @v.y.should == 3
82
+ end
83
+
84
+ it "should have a #div! method which alters and returns the vector" do
85
+ @v.div!(2.0).should == @v
86
+ @v.x.should == 1.5
87
+ @v.y.should == 1.5
88
+ end
89
+
90
+ it "should have a #mul! method which multiplies and retruns the vector" do
91
+ @v.mul!(2).should == @v
92
+ @v.x.should == 6
93
+ @v.y.should == 6
94
+ end
95
+
96
+ it "should have a #add! method which adds two scalars and returns the vector" do
97
+ @v.add!(1, 2).should == @v
98
+ @v.x.should == 4
99
+ @v.y.should == 5
100
+ end
101
+
102
+ it "should have a #add! method which adds an other vector returns the vector" do
103
+ @v.add!(Location.new(1, 2)).should == @v
104
+ @v.x.should == 4
105
+ @v.y.should == 5
106
+ end
107
+
108
+ it "should have a #sub! method which subtracts two scalars and returns the vector" do
109
+ @v.sub!(1, 2).should == @v
110
+ @v.x.should == 2
111
+ @v.y.should == 1
112
+ end
113
+
114
+ it "should have a #add! method which subtracts an other vector returns the vector" do
115
+ @v.sub!(Location.new(1, 2)).should == @v
116
+ @v.x.should == 2
117
+ @v.y.should == 1
118
+ end
119
+
120
+ it "should return the length of the vector when sent #length" do
121
+ @v.length.should == Math.sqrt(18)
122
+ end
123
+
124
+ it "should have the length of 1 when altered by sending #normalize!" do
125
+ v = Location.new(3.0, 4.0)
126
+ length = v.length
127
+ v.normalize!.should == v
128
+ v.length.should == 1
129
+ (v.x / v.y).should be_close(3.0/4.0, Float::EPSILON)
130
+ end
131
+
132
+ it "should have a rotate_radians! method" do
133
+ v = Location.new(1.0, 0.0)
134
+ v.rotate_radians!(Math::PI).should == v
135
+ v.x.should be_close(-1.0, Float::EPSILON)
136
+ v.y.should be_close(0.0, Float::EPSILON)
137
+ end
138
+
139
+ it "should have a rotate! method" do
140
+ v = Location.new(1.0, 0.0)
141
+ v.rotate!(180).should == v
142
+ v.x.should be_close(-1.0, Float::EPSILON)
143
+ v.y.should be_close(0.0, Float::EPSILON)
144
+ end
145
+
146
+ end
@@ -0,0 +1,179 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rspec_helper'
4
+
5
+ require 'enumerator'
6
+ require "node"
7
+
8
+ include Doodl
9
+
10
+ describe "DirectedNode" do
11
+
12
+ before(:each) do
13
+ @node = DirectedNode.new
14
+ end
15
+
16
+ it "should add an edge when sent #add_edge" do
17
+ @node.should respond_to(:add_out_edge)
18
+ lambda { @node.add_out_edge(:edge) }.should_not raise_error(Exception)
19
+ end
20
+
21
+ it "should return whether it includes an added edge when sent #include_edge?(edge)" do
22
+ @node.should respond_to(:includes_out_edge?)
23
+ @node.add_out_edge(:edge)
24
+ @node.includes_out_edge?(:edge).should == true
25
+ @node.includes_out_edge?(:else).should == false
26
+ end
27
+
28
+ it "should return a Iterator that iterates over the added edge when sent #each_edge" do
29
+ @node.should respond_to(:each_out_edge)
30
+ @node.add_out_edge(:edge)
31
+ @node.add_out_edge(:other)
32
+ enum = Enumerable::Enumerator.new(@node, :each_out_edge)
33
+ enum.to_a.should == [:edge, :other]
34
+ end
35
+
36
+ it "should return the number of included nodes when sent #degree" do
37
+ @node.should respond_to(:out_degree)
38
+ @node.out_degree.should == 0
39
+ @node.add_out_edge(:edge1)
40
+ @node.out_degree.should == 1
41
+ end
42
+
43
+ it "should delete an included edge when sent delete_edge(edge)" do
44
+ @node.should respond_to(:del_out_edge)
45
+ @node.add_out_edge(:edge)
46
+ @node.del_out_edge(:edge)
47
+ @node.out_degree.should == 0
48
+ @node.add_out_edge(:edge)
49
+ @node.del_out_edge(:other)
50
+ @node.out_degree.should == 1
51
+ end
52
+ end
53
+
54
+ describe "UndirectedNode" do
55
+
56
+ before(:each) do
57
+ @node = UndirectedNode.new
58
+ end
59
+
60
+ it "should add an edge when sent #add_edge" do
61
+ @node.should respond_to(:add_edge)
62
+ lambda { @node.add_edge(:edge) }.should_not raise_error(Exception)
63
+ end
64
+
65
+ it "should return whether it includes an added edge when sent #include_edge?(edge)" do
66
+ @node.should respond_to(:includes_edge?)
67
+ @node.add_edge(:edge)
68
+ @node.includes_edge?(:edge).should == true
69
+ @node.includes_edge?(:else).should == false
70
+ end
71
+
72
+ it "should return a Iterator that iterates over the added edge when sent #each_edge" do
73
+ @node.should respond_to(:each_edge)
74
+ @node.add_edge(:edge)
75
+ @node.add_edge(:other)
76
+ enum = Enumerable::Enumerator.new(@node, :each_edge)
77
+ enum.to_a.should == [:edge, :other]
78
+ end
79
+
80
+ it "should return the number of included nodes when sent #degree" do
81
+ @node.should respond_to(:degree)
82
+ @node.degree.should == 0
83
+ @node.add_edge(:edge1)
84
+ @node.degree.should == 1
85
+ end
86
+
87
+ it "should delete an included edge when sent delete_edge(edge)" do
88
+ @node.should respond_to(:del_edge)
89
+ @node.add_edge(:edge)
90
+ @node.del_edge(:edge)
91
+ @node.degree.should == 0
92
+ @node.add_edge(:edge)
93
+ @node.del_edge(:other)
94
+ @node.degree.should == 1
95
+ end
96
+
97
+ end
98
+
99
+ describe "SimpleBidirectionalNode" do
100
+
101
+ before(:each) do
102
+ @node = SimpleBidirectionalNode.new
103
+ end
104
+
105
+ it "should add an edge when sent #add_in_edge" do
106
+ @node.should respond_to(:add_in_edge)
107
+ lambda { @node.add_in_edge(:edge) }.should_not raise_error(Exception)
108
+ end
109
+
110
+ it "should return whether it includes an added edge when sent #include_in_edge?(edge)" do
111
+ @node.should respond_to(:includes_in_edge?)
112
+ @node.add_in_edge(:edge)
113
+ @node.includes_in_edge?(:edge).should == true
114
+ @node.includes_in_edge?(:else).should == false
115
+ end
116
+
117
+ it "should return a Iterator that iterates over the added edge when sent #each_in_edge" do
118
+ @node.should respond_to(:each_in_edge)
119
+ @node.add_in_edge(:edge)
120
+ @node.add_in_edge(:other)
121
+ enum = Enumerable::Enumerator.new(@node, :each_in_edge)
122
+ enum.to_a.should == [:edge, :other]
123
+ end
124
+
125
+ it "should return the number of included nodes when sent #in_degree" do
126
+ @node.should respond_to(:in_degree)
127
+ @node.in_degree.should == 0
128
+ @node.add_in_edge(:edge1)
129
+ @node.in_degree.should == 1
130
+ end
131
+
132
+ it "should delete an included edge when sent delete_in_edge(edge)" do
133
+ @node.should respond_to(:del_in_edge)
134
+ @node.add_in_edge(:edge)
135
+ @node.del_in_edge(:edge)
136
+ @node.in_degree.should == 0
137
+ @node.add_in_edge(:edge)
138
+ @node.del_in_edge(:other)
139
+ @node.in_degree.should == 1
140
+ end
141
+
142
+ it "should add an edge when sent #add_out_edge" do
143
+ @node.should respond_to(:add_out_edge)
144
+ lambda { @node.add_out_edge(:edge) }.should_not raise_error(Exception)
145
+ end
146
+
147
+ it "should return whether it includes an added edge when sent #include_out_edge?(edge)" do
148
+ @node.should respond_to(:includes_out_edge?)
149
+ @node.add_out_edge(:edge)
150
+ @node.includes_out_edge?(:edge).should == true
151
+ @node.includes_out_edge?(:else).should == false
152
+ end
153
+
154
+ it "should return a Iterator that iterates over the added edge when sent #each_out_edge" do
155
+ @node.should respond_to(:each_out_edge)
156
+ @node.add_out_edge(:edge)
157
+ @node.add_out_edge(:other)
158
+ enum = Enumerable::Enumerator.new(@node, :each_out_edge)
159
+ enum.to_a.should == [:edge, :other]
160
+ end
161
+
162
+ it "should return the number of included nodes when sent #out_degree" do
163
+ @node.should respond_to(:out_degree)
164
+ @node.out_degree.should == 0
165
+ @node.add_out_edge(:edge1)
166
+ @node.out_degree.should == 1
167
+ end
168
+
169
+ it "should delete an included edge when sent delete_out_edge(edge)" do
170
+ @node.should respond_to(:del_out_edge)
171
+ @node.add_out_edge(:edge)
172
+ @node.del_out_edge(:edge)
173
+ @node.out_degree.should == 0
174
+ @node.add_out_edge(:edge)
175
+ @node.del_out_edge(:other)
176
+ @node.out_degree.should == 1
177
+ end
178
+
179
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+
3
+ require "rubygems"
4
+ require "spec"
5
+
6
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), 'lib')
7
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), 'spec')
8
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '../lib')
9
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '../spec')
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ dir = File.dirname(__FILE__)
4
+ files = Dir.glob("#{dir}/**/*_spec.rb")
5
+ begin
6
+ require 'java'
7
+ rescue LoadError => e
8
+ files -= Dir.glob("#{dir}/jruby/**/*_spec.rb")
9
+ end
10
+ files.each do |file|
11
+ require file
12
+ end
@@ -0,0 +1,101 @@
1
+ require "rspec_helper"
2
+ require "graph"
3
+ require "shortest_path/bellman_ford"
4
+
5
+ include Doodl
6
+
7
+ describe "BellbanFord" do
8
+
9
+ before(:each) do
10
+ @graph = DirectedGraph.new
11
+ @u = @graph.add_node
12
+ @v = @graph.add_node
13
+ @w = @graph.add_node
14
+ @x = @graph.add_node
15
+ @y = @graph.add_node
16
+ @z = @graph.add_node
17
+
18
+ @uv = @graph.add_edge(@u, @v)
19
+ @uw = @graph.add_edge(@u, @w)
20
+ @ux = @graph.add_edge(@u, @x)
21
+ @vx = @graph.add_edge(@v, @x)
22
+ @xz = @graph.add_edge(@x, @z)
23
+ @wy = @graph.add_edge(@w, @y)
24
+ @yz = @graph.add_edge(@y, @z)
25
+
26
+ @weight = @graph.attach_edge_data(:weight)
27
+ @weight[@uv] = 1
28
+ @weight[@uw] = 1
29
+ @weight[@ux] = 1
30
+ @weight[@vx] = 1
31
+ @weight[@xz] = 1
32
+ @weight[@wy] = 1
33
+ @weight[@yz] = 1
34
+ end
35
+
36
+ it "should raise an ArgumentError when not initialized a graph and a start node" do
37
+ lambda { BellmanFord.new(Object.new, :node) }.should raise_error(ArgumentError)
38
+ end
39
+
40
+ it "should raise an ArgumentError when not initialized with a start_node that is a graph member" do
41
+ lambda { BellmanFord.new(Graph.new, :node) }.should raise_error(ArgumentError)
42
+ end
43
+
44
+ it "should NOT raise an ArgumentError when initialized with a weighted graph, a contained node" do
45
+ graph = DirectedGraph.new
46
+ node = graph.add_node
47
+ lambda { BellmanFord.new(graph, node, Hash.new(1)) }.should_not raise_error(ArgumentError)
48
+ end
49
+
50
+ it "should return the distance 0 for the start node" do
51
+ bf = BellmanFord.new(@graph, @u, @weight)
52
+ bf.dist[@u].should == 0
53
+ end
54
+
55
+ it "should return the shortest distance d(u,x) with u being the source and x being a node of the graph when sent #dist[x]" do
56
+ bf = BellmanFord.new(@graph, @u, @weight)
57
+ bf.dist[@v].should == 1
58
+ bf.dist[@x].should == 1
59
+ bf.dist[@w].should == 1
60
+ bf.dist[@y].should == 2
61
+ bf.dist[@z].should == 2
62
+ end
63
+
64
+ it "should return INFINITY when sent #dist[x] if x is not reachable" do
65
+ bf = BellmanFord.new(@graph, @z, @weight)
66
+ bf.dist[@u].should == INFINITY
67
+ end
68
+
69
+ it "should return the previous node of x in the shortes path tree when sent #prev[x]" do
70
+ bf = BellmanFord.new(@graph, @u, @weight)
71
+ bf.prev[@u].should == nil
72
+ bf.prev[@v].should == @u
73
+ bf.prev[@x].should == @u
74
+ bf.prev[@y].should == @w
75
+ bf.prev[@z].should == @x
76
+ end
77
+
78
+ it "should return nil when sent #prev[x] and x is not reachable" do
79
+ fw = BellmanFord.new(@graph, @z, @weight)
80
+ fw.prev[@u].should == nil
81
+ end
82
+
83
+ it "should return an array containing the nodes of the shortest path when sent node_path_to(x)" do
84
+ bf = BellmanFord.new(@graph, @u, @weight)
85
+ bf.node_path_to(@u).should == [@u]
86
+ bf.node_path_to(@v).should == [@u, @v]
87
+ bf.node_path_to(@z).should == [@u, @x, @z]
88
+ end
89
+
90
+ it "should return an array of edge representing the shortest path, when sent edge_path_to" do
91
+ bf = BellmanFord.new(@graph, @u, @weight)
92
+ bf.edge_path_to(@u).should == []
93
+ bf.edge_path_to(@v).should == [@graph.get_edge(@u, @v)]
94
+ bf.edge_path_to(@z).should == [@graph.get_edge(@u, @x), @graph.get_edge(@x, @z)]
95
+ bf = BellmanFord.new(@graph, @u, Hash.new(1))
96
+ bf.edge_path_to(@u).should == []
97
+ bf.edge_path_to(@v).should == [@graph.get_edge(@u, @v)]
98
+ bf.edge_path_to(@z).should == [@graph.get_edge(@u, @x), @graph.get_edge(@x, @z)]
99
+ end
100
+
101
+ end