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,292 @@
1
+ require "observer"
2
+
3
+ require "graph"
4
+ require "layout/morph_layout"
5
+ require "layout/collapse_layout"
6
+ require "layout/fr_layout"
7
+ require "layout/kk_layout"
8
+ require "layout/isom_layout"
9
+ require "layout/layout"
10
+ require "shortest_path/dijkstra"
11
+
12
+ class SimpleModel
13
+ include Observable
14
+
15
+ attr_reader :layout, :graph
16
+
17
+ def initialize
18
+ @graph_type = DirectedGraph
19
+ end
20
+
21
+ def view=(view)
22
+ @view = view
23
+ end
24
+
25
+ #Graph
26
+ def new_graph
27
+ @graph = @graph_type.new
28
+ @graph.add_observer(self)
29
+ @graph.attach_node_data(:is_clicked?, Hash.new(false))
30
+ @graph.attach_edge_data(:is_clicked?, Hash.new(false))
31
+ @layout.graph = @graph
32
+ end
33
+
34
+ def new_empty_graph
35
+ new_graph
36
+ @graph.notify_observers(nil)
37
+ end
38
+
39
+ def new_connected_graph(size)
40
+ $LOG.debug("new_connected_graph called on #{self}")
41
+ self.new_graph
42
+ @graph.gen_connected_graph(size)
43
+ end
44
+
45
+ def new_random_graph(node_number)
46
+ $LOG.debug("new_random_graph called on #{self}")
47
+ self.new_graph
48
+ @graph.gen_random_graph(node_number)
49
+ end
50
+
51
+ def new_ring_graph(node_number)
52
+ $LOG.debug("new_ring_graph called on #{self}")
53
+ self.new_graph
54
+ @graph.gen_ring_graph(node_number)
55
+ end
56
+
57
+ def new_binary_tree(height)
58
+ $LOG.debug("new_bintree_graph called on #{self}")
59
+ self.new_graph
60
+ @graph.gen_binary_tree(height)
61
+ end
62
+
63
+ def new_mesh_graph(rows)
64
+ $LOG.debug("new_mesh_graph called on #{self}")
65
+ self.new_graph
66
+ @graph.gen_mesh_graph(rows)
67
+ end
68
+
69
+ def new_linear_graph(size)
70
+ $LOG.debug("new_linear_graph called on #{self}")
71
+ self.new_graph
72
+ @graph.gen_linear_graph(size)
73
+ end
74
+
75
+
76
+ def add_node_at(x, y)
77
+ $LOG.debug("add_node_at #{x}, #{y} called on #{self}")
78
+ node = @graph.add_node(false)
79
+ @layout.set_location(node, x, y, true)
80
+ return node
81
+ end
82
+
83
+ def get_nearest_node(x, y)
84
+ $LOG.debug("get_nearest_node #{x}, #{y} called on #{self}")
85
+ @layout.get_nearest_node(x, y)
86
+ end
87
+
88
+ def set_location(node, x, y)
89
+ @layout.set_location(node, x, y, true)
90
+ end
91
+
92
+ def del_node(node)
93
+ @layout.delete(node)
94
+ @graph.del_node(node, true)
95
+ end
96
+
97
+ def add_edge(source, target)
98
+ @graph.add_edge(source, target, true)
99
+ end
100
+
101
+ def get_edge(source, target)
102
+ edge = nil
103
+ @graph.each_adjacent_edge(source) do |e|
104
+ if e.target == target
105
+ edge = e
106
+ elsif (not e.directed?) and e.source == target and e.target == source
107
+ edge = e
108
+ end
109
+ end
110
+ return edge
111
+ end
112
+
113
+ def del_edge(edge)
114
+ @graph.del_edge(edge, true)
115
+ end
116
+
117
+ def select_node(node)
118
+ end
119
+
120
+ def deselect_node(node)
121
+ end
122
+
123
+ def select(edge)
124
+ end
125
+
126
+ def deselect(edge)
127
+ end
128
+
129
+ #Layout
130
+ def new_layout(layout)
131
+ @layout = layout
132
+ @layout.add_observer(self)
133
+ if @graph
134
+ @layout.graph = @graph
135
+ end
136
+ end
137
+
138
+ def set_random_layout
139
+ self.new_layout(RandomLayout.new(@view.canvas))
140
+ end
141
+
142
+ def set_circle_layout
143
+ self.new_layout(CircleLayout.new(@view.canvas))
144
+ end
145
+
146
+ def set_fr_layout
147
+ self.new_layout(FRLayout.new(@view.canvas))
148
+ end
149
+
150
+ def set_kk_layout
151
+ self.new_layout(KKLayout.new(@view.canvas))
152
+ end
153
+
154
+ def set_morph_layout(target_layout)
155
+ if target_layout
156
+ self.new_layout(MorphLayout.new(@view.canvas, Kernel.const_get(target_layout)))
157
+ else
158
+ self.new_layout(MorphLayout.new(@view.canvas))
159
+ end
160
+ end
161
+
162
+ def set_collapse_layout
163
+ new_layout(CollapseLayout.new(@view.canvas))
164
+ end
165
+
166
+ def set_directed
167
+ @graph_type = DirectedGraph
168
+ end
169
+
170
+ def set_undirected
171
+ @graph_type = UndirectedGraph
172
+ end
173
+
174
+ def set_isom_layout
175
+ self.new_layout(ISOMLayout.new(@view.canvas))
176
+ end
177
+
178
+ def click(node)
179
+ @graph.node_data(:is_clicked?)[node] = true
180
+ changed
181
+ notify_observers(nil)
182
+ end
183
+
184
+ def unclick(node)
185
+ @graph.node_data(:is_clicked?)[node] = false
186
+ changed
187
+ notify_observers(nil)
188
+ end
189
+
190
+ def click_edge(edge)
191
+ @graph.edge_data(:is_clicked?)[edge] = true
192
+ changed
193
+ notify_observers(nil)
194
+ end
195
+
196
+ def unclick_edge(edge)
197
+ @graph.edge_data(:is_clicked?)[edge] = false
198
+ changed
199
+ notify_observers(nil)
200
+ end
201
+
202
+ def dsp(source, target)
203
+ stdata = @graph.attach_node_data(:start)
204
+ stdata[source] = true
205
+ endata = @graph.attach_node_data(:end)
206
+ endata[target] = true
207
+
208
+ dsp = DijkstraShortestPath.new(@graph, source)
209
+ npath = dsp.node_path_to(target)
210
+ epath = dsp.edge_path_to(target)
211
+
212
+ edata = @graph.attach_edge_data(:path)
213
+ epath.each do |edge|
214
+ edata[edge] = true
215
+ end
216
+ ndata = @graph.attach_node_data(:path)
217
+ npath.each do |node|
218
+ ndata[node] = true
219
+ end
220
+ end
221
+
222
+ def dspt(source)
223
+ @graph.attach_node_data(:start)[source] = true
224
+ path = []
225
+ edata = @graph.attach_edge_data(:path)
226
+ ndata = @graph.attach_node_data(:end)
227
+ dijk = DijkstraShortestPath.new(@graph, source)
228
+ @graph.each_node do |node|
229
+ if (node != source)
230
+ dijk.edge_path_to(node).each { |edge| edata[edge] = true }
231
+ dijk.node_path_to(node).each { |node| ndata[node] = true }
232
+ end
233
+ end
234
+ end
235
+
236
+ def count_nodes
237
+ index = 0
238
+ data = @graph.attach_node_data(:text)
239
+ @graph.each_node do |node|
240
+ data[node] = index.to_s
241
+ index += 1
242
+ end
243
+ index = 0
244
+ data = @graph.attach_edge_data(:text)
245
+ @graph.each_edge do |edge|
246
+ data[edge] = index.to_s
247
+ index += 1
248
+ end
249
+ changed
250
+ notify_observers(nil)
251
+ end
252
+
253
+ def rotate_layout(theta)
254
+ @layout.rotate(theta)
255
+ changed
256
+ notify_observers(nil)
257
+ end
258
+
259
+ def move_layout(x, y)
260
+ @layout.move(x, y)
261
+ changed
262
+ notify_observers(nil)
263
+ end
264
+
265
+ def center_x
266
+ @layout.center_x
267
+ changed
268
+ notify_observers(nil)
269
+ end
270
+
271
+ def center_y
272
+ @layout.center_y
273
+ changed
274
+ notify_observers(nil)
275
+ end
276
+
277
+ def center_xy
278
+ @layout.center_x
279
+ @layout.center_y
280
+ changed
281
+ notify_observers(nil)
282
+ end
283
+
284
+ #being a listener
285
+ def update(observable)
286
+ $LOG.debug("Observer #{self} being updated by #{observable}")
287
+ observable = nil if observable.is_a?(Graph)
288
+ changed
289
+ notify_observers(observable)
290
+ end
291
+
292
+ end
@@ -0,0 +1,148 @@
1
+ require "logger"
2
+
3
+ require "../lib/jruby/renderer"
4
+
5
+ include_class 'java.awt.geom.Rectangle2D'
6
+ include_class 'java.awt.BasicStroke'
7
+ include_class 'java.awt.Color'
8
+
9
+ class SimpleView
10
+
11
+ attr_writer :frame
12
+ attr_reader :canvas
13
+
14
+ def initialize
15
+
16
+ end
17
+
18
+ def canvas=(canvas)
19
+ @canvas = canvas
20
+ # @canvas.node_shape_function { |g, l, n| Rectangle2D::Double.new(l[n].x-10, l[n].y-10, 20, 20) }
21
+ @canvas.edge_stroke_function do |g, l, e|
22
+ if (g.has_edge_data_key?(:path) and g.edge_data(:path)[e])
23
+ BasicStroke.new(3)
24
+ else
25
+ BasicStroke.new(2)
26
+ end
27
+ end
28
+ @canvas.node_stroke_function do |g, l, n|
29
+ if (g.has_node_data_key?(:path) and g.node_data(:path)[n])
30
+ BasicStroke.new(3)
31
+ else
32
+ BasicStroke.new(2)
33
+ end
34
+ end
35
+ @canvas.node_stroke_color_function do |g, l, n|
36
+ if g.node_data(:is_clicked?) and g.node_data(:is_clicked?)[n]
37
+ Color::BLUE
38
+ elsif g.node_data(:start) and g.node_data(:start)[n]
39
+ Color::GREEN
40
+ elsif g.node_data(:end) and g.node_data(:end)[n]
41
+ Color::YELLOW
42
+ else
43
+ Color::WHITE
44
+ end
45
+ end
46
+ @canvas.edge_stroke_color_function do |g, l, e|
47
+ if g.edge_data(:is_clicked?) and g.edge_data(:is_clicked?)[e]
48
+ Color::BLUE
49
+ else
50
+ Color::WHITE
51
+ end
52
+ end
53
+ @canvas.instance_variable_set(:@arrow_head_stroke_color_function, @canvas.instance_variable_get(:@edge_stroke_color_function))
54
+ @canvas.instance_variable_set(:@arrow_head_fill_color_function, @canvas.instance_variable_get(:@edge_stroke_color_function))
55
+ @canvas.instance_variable_set(:@edge_stroke_function, @canvas.instance_variable_get(:@arrow_head_stroke_function))
56
+ @canvas.instance_variable_set(:@node_label_color_function, @canvas.instance_variable_get(:@node_stroke_color_function))
57
+ @canvas.requestFocusInWindow
58
+ end
59
+
60
+ def add_key_listener(key_listener)
61
+ $LOG.debug("adding key_listener #{key_listener} on #{self}")
62
+ @canvas.addKeyListener(key_listener)
63
+ end
64
+
65
+ def add_mouse_listener(mouse_listener)
66
+ $LOG.debug("adding mouse_listener #{mouse_listener} on #{self}")
67
+ @canvas.addMouseListener(mouse_listener)
68
+ end
69
+
70
+ def add_mouse_motion_listener(mouse_motion_listener)
71
+ $LOG.debug("adding mouse_motion_listener #{mouse_motion_listener} on #{self}")
72
+ @canvas.addMouseMotionListener(mouse_motion_listener)
73
+ end
74
+
75
+ def remove_mouse_listener(mouse_listener)
76
+ $LOG.debug("removing mouse_listener #{mouse_listener} on #{self}")
77
+ @canvas.removeMouseListener(mouse_listener)
78
+ end
79
+
80
+ def remove_mouse_motion_listener(mouse_motion_listener)
81
+ $LOG.debug("removing mouse_motion_listener #{mouse_motion_listener} on #{self}")
82
+ @canvas.removeMouseMotionListener(mouse_motion_listener)
83
+ end
84
+
85
+ def add_info_panel(info_text)
86
+ $LOG.debug("adding info panel with text: #{info_text}")
87
+ if (@frame.isAncestorOf(@infopanel))
88
+ @frame.getContentPane.remove(@infopanel)
89
+ end
90
+ @infopanel = javax.swing.JLabel.new(info_text)
91
+ @infopanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(2, 4, 2, 2))
92
+ @frame.getContentPane().add(@infopanel, java.awt.BorderLayout::NORTH)
93
+ @frame.validate
94
+ end
95
+
96
+ def remove_info_panel
97
+ @frame.getContentPane().remove(@infopanel)
98
+ @infopanel = nil
99
+ @frame.validate
100
+ end
101
+
102
+ def add_text_field(action_listener)
103
+ $LOG.debug("adding text field with action listener: #{action_listener}")
104
+ @textfield = javax.swing.JTextField.new
105
+ @textfield.addActionListener(action_listener)
106
+ @frame.getContentPane().add(@textfield, java.awt.BorderLayout::SOUTH)
107
+ @frame.validate
108
+ @textfield.requestFocusInWindow
109
+ end
110
+
111
+ def remove_text_field
112
+ $LOG.debug("removing text field")
113
+ @frame.remove(@textfield)
114
+ @textfield = nil
115
+ @frame.validate
116
+ @canvas.requestFocusInWindow
117
+ end
118
+
119
+ def toggle_paint_iterations
120
+ if @canvas.paint_iterations?
121
+ @canvas.paint_iterations = false
122
+ else
123
+ @canvas.paint_iterations = true
124
+ end
125
+ end
126
+
127
+ def width
128
+ @canvas.width
129
+ end
130
+
131
+ def height
132
+ @canvas.height
133
+ end
134
+
135
+ def update(layout)
136
+ $LOG.debug("Observer #{self} being updated with #{layout}")
137
+ if (layout)
138
+ @canvas.update_layout(layout)
139
+ else
140
+ @canvas.repaint
141
+ end
142
+ end
143
+
144
+ def repaint
145
+ @canvas.repaint
146
+ end
147
+
148
+ end
@@ -0,0 +1,69 @@
1
+ # encoding: utf-8
2
+
3
+ require "graph"
4
+
5
+ require "facets/infinity"
6
+
7
+ module Doodl
8
+
9
+ class BreadthFirstSearch
10
+
11
+ attr_reader :dist, :prev, :list
12
+
13
+ def initialize(graph, source, visitor = nil)
14
+ raise ArgumentError unless (graph.is_a?(Graph) and graph.contains_node?(source))
15
+ @graph, @visitor = graph, visitor
16
+ @dist, @prev, @color = {}, {}, {}
17
+ @queue, @list = [], []
18
+ init_maps
19
+ main_algorithm(source)
20
+ end
21
+
22
+ private
23
+
24
+ def init_maps
25
+ @graph.each_node do |node|
26
+ visit(:init, @graph, node)
27
+ @color[node] = :white
28
+ @dist[node] = INFINITY
29
+ @prev[node] = node
30
+ end
31
+ end
32
+
33
+ def visit_edge(edge)
34
+ visit(:examine_edge, @graph, edge)
35
+ if (@color[edge.target] == :white)
36
+ @color[edge.target] = :gray
37
+ @dist[edge.target] = @dist[edge.source] + 1
38
+ @prev[edge.target] = edge.source
39
+ @queue.push(edge.target)
40
+ visit(:discover, @graph, edge.target)
41
+ @list.push(edge.target)
42
+ end
43
+ end
44
+
45
+ def main_algorithm(source)
46
+ @color[source] = :gray
47
+ @dist[source] = 0
48
+ @queue.push(source)
49
+ visit(:discover, @graph, source)
50
+ @list.push(source)
51
+ until (@queue.empty?)
52
+ node = @queue.shift
53
+ visit(:examine_node, @graph, node)
54
+ @graph.each_adjacent_edge(node) do |edge|
55
+ visit_edge(edge)
56
+ end
57
+ @color[node] = :black
58
+ end
59
+ end
60
+
61
+ def visit(position, *arg)
62
+ if @visitor.respond_to?(position)
63
+ @visitor.send(position, *arg)
64
+ end
65
+ end
66
+
67
+ end
68
+
69
+ end