silicium 0.0.20 → 0.0.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +3 -3
  3. data/.gitignore +13 -13
  4. data/.rakeTasks +8 -0
  5. data/.travis.yml +28 -25
  6. data/CODE_OF_CONDUCT.md +74 -74
  7. data/Gemfile +8 -8
  8. data/LICENSE.txt +21 -21
  9. data/Makefile +269 -269
  10. data/README.md +588 -46
  11. data/Rakefile +16 -16
  12. data/bin/console +14 -14
  13. data/bin/setup +8 -8
  14. data/docs/Object.html +117 -117
  15. data/docs/README_md.html +142 -142
  16. data/docs/Silicium/Combinatorics.html +270 -270
  17. data/docs/Silicium/Dice/Polyhedron.html +315 -315
  18. data/docs/Silicium/Dice/PolyhedronSet.html +321 -321
  19. data/docs/Silicium/Dice.html +99 -99
  20. data/docs/Silicium/Error.html +106 -106
  21. data/docs/Silicium/Geometry/Line2dCanon.html +243 -243
  22. data/docs/Silicium/Geometry/VariablesOrderException.html +106 -106
  23. data/docs/Silicium/Geometry.html +940 -940
  24. data/docs/Silicium/GraphVisualizer.html +226 -0
  25. data/docs/Silicium/Graphs/GraphError.html +106 -106
  26. data/docs/Silicium/Graphs/OrientedGraph.html +901 -775
  27. data/docs/Silicium/Graphs/UnorientedGraph.html +237 -284
  28. data/docs/Silicium/Graphs.html +374 -164
  29. data/docs/Silicium/IntegralDoesntExistError.html +106 -106
  30. data/docs/Silicium/NumericalIntegration.html +521 -521
  31. data/docs/Silicium/Optimization.html +629 -639
  32. data/docs/Silicium/Plotter/Image.html +297 -297
  33. data/docs/Silicium/Plotter.html +186 -186
  34. data/docs/Silicium.html +101 -101
  35. data/docs/created.rid +9 -9
  36. data/docs/css/fonts.css +167 -167
  37. data/docs/css/rdoc.css +619 -619
  38. data/docs/index.html +134 -132
  39. data/docs/js/darkfish.js +84 -84
  40. data/docs/js/navigation.js +105 -105
  41. data/docs/js/search.js +110 -110
  42. data/docs/js/search_index.js +1 -1
  43. data/docs/js/search_index.js.gz +0 -0
  44. data/docs/js/searcher.js +229 -229
  45. data/docs/table_of_contents.html +697 -608
  46. data/lib/algebra.rb +452 -0
  47. data/lib/algebra_diff.rb +258 -0
  48. data/lib/geometry/figure.rb +62 -0
  49. data/lib/geometry.rb +290 -236
  50. data/lib/geometry3d.rb +270 -0
  51. data/lib/graph/dfs.rb +42 -0
  52. data/lib/graph/kruskal.rb +36 -0
  53. data/lib/graph/scc.rb +97 -0
  54. data/lib/graph.rb +350 -164
  55. data/lib/graph_visualizer.rb +287 -0
  56. data/lib/ml_algorithms.rb +181 -0
  57. data/lib/numerical_integration.rb +184 -147
  58. data/lib/optimization.rb +209 -144
  59. data/lib/plotter.rb +256 -96
  60. data/lib/polynomial_division.rb +132 -0
  61. data/lib/polynomial_interpolation.rb +94 -0
  62. data/lib/regression.rb +120 -0
  63. data/lib/silicium/adding.rb +37 -0
  64. data/lib/silicium/conversions.rb +23 -0
  65. data/lib/silicium/multi.rb +82 -0
  66. data/lib/silicium/sparse.rb +76 -0
  67. data/lib/silicium/sugar.rb +37 -0
  68. data/lib/silicium/trans.rb +26 -0
  69. data/lib/silicium/version.rb +3 -3
  70. data/lib/silicium.rb +5 -5
  71. data/lib/theory_of_probability.rb +240 -226
  72. data/lib/topological_sort.rb +50 -0
  73. data/oriented_graph.png +0 -0
  74. data/plot.png +0 -0
  75. data/silicium.gemspec +38 -39
  76. metadata +38 -16
data/lib/graph.rb CHANGED
@@ -1,164 +1,350 @@
1
- #require 'set'
2
- #require 'silicium'
3
-
4
- module Silicium
5
- module Graphs
6
- Pair = Struct.new(:first, :second)
7
-
8
- class GraphError < Error
9
-
10
- end
11
-
12
- class OrientedGraph
13
- def initialize(initializer = [])
14
- @vertices = {}
15
- @edge_labels = {}
16
- @vertex_labels = {}
17
- initializer.each do |v|
18
- add_vertex!(v[:v])
19
- v[:i].each { |iv| add_edge_force!(v[:v], iv)}
20
- end
21
- end
22
-
23
- def add_vertex!(vertex_id)
24
- if @vertices.has_key?(vertex_id)
25
- return
26
- end
27
- @vertices[vertex_id] = [].to_set
28
- end
29
-
30
- def add_edge!(from, to)
31
- if @vertices.has_key?(from) && @vertices.has_key?(to)
32
- @vertices[from] << to
33
- end
34
- end
35
-
36
- # should only be used in constructor
37
- def add_edge_force!(from, to)
38
- add_vertex!(from)
39
- add_vertex!(to)
40
- add_edge!(from, to)
41
- end
42
-
43
- def adjacted_with(vertex)
44
- unless @vertices.has_key?(vertex)
45
- raise GraphError.new("Graph does not contain vertex #{vertex}")
46
- end
47
-
48
- @vertices[vertex].clone
49
- end
50
-
51
- def label_edge!(from, to, label)
52
- unless @vertices.has_key?(from) && @vertices[from].include?(to)
53
- raise GraphError.new("Graph does not contain edge (#{from}, #{to})")
54
- end
55
-
56
- @edge_labels[Pair.new(from, to)] = label
57
- end
58
-
59
- def label_vertex!(vertex, label)
60
- unless @vertices.has_key?(vertex)
61
- raise GraphError.new("Graph does not contain vertex #{vertex}")
62
- end
63
-
64
- @vertex_labels[vertex] = label
65
- end
66
-
67
- def get_edge_label(from, to)
68
- if !@vertices.has_key?(from) || ! @vertices[from].include?(to)
69
- raise GraphError.new("Graph does not contain edge (#{from}, #{to})")
70
- end
71
-
72
- @edge_labels[Pair.new(from, to)]
73
- end
74
-
75
- def get_vertex_label(vertex)
76
- unless @vertices.has_key?(vertex)
77
- raise GraphError.new("Graph does not contain vertex #{vertex}")
78
- end
79
-
80
- @vertex_labels[vertex]
81
- end
82
-
83
- def vertex_number
84
- @vertices.count
85
- end
86
-
87
- def edge_number
88
- res = 0
89
- @vertices.values.each do |item|
90
- res += item.count
91
- end
92
- res
93
- end
94
-
95
- def vertex_label_number
96
- @vertex_labels.count
97
- end
98
-
99
- def edge_label_number
100
- @edge_labels.count
101
- end
102
-
103
- def has_vertex?(vertex)
104
- @vertices.has_key?(vertex)
105
- end
106
-
107
- def has_edge?(from, to)
108
- @vertices.has_key?(from) && @vertices[from].include?(to)
109
- end
110
-
111
- def delete_vertex!(vertex)
112
- if has_vertex?(vertex)
113
- @vertices.keys.each do |key|
114
- delete_edge!(key, vertex)
115
- end
116
- @vertices.delete(vertex)
117
- @vertex_labels.delete(vertex)
118
-
119
- @vertices.keys.each do |key|
120
- @edge_labels.delete(Pair.new(vertex, key))
121
- end
122
- end
123
- end
124
-
125
- def delete_edge!(from, to)
126
- if has_edge?(from, to)
127
- @vertices[from].delete(to)
128
- @edge_labels.delete(Pair.new(from, to))
129
- end
130
- end
131
-
132
- end
133
-
134
- class UnorientedGraph < OrientedGraph
135
- def add_edge!(from, to)
136
- super(from, to)
137
- super(to, from)
138
- end
139
-
140
- def label_edge!(from, to, label)
141
- super(from, to, label)
142
- super(to, from, label)
143
- end
144
-
145
- def delete_edge!(from, to)
146
- super(from, to)
147
- super(to, from)
148
- end
149
-
150
- def edge_number
151
- res = 0
152
- @vertices.each do |from, tos|
153
- tos.each {|to| res += (to == from ? 2 : 1)}
154
- end
155
- res / 2
156
- end
157
- end
158
-
159
- def dijkstra_algorythm(graph, starting_vertex)
160
- #
161
- end
162
- end
163
-
164
- end
1
+ require_relative 'graph/dfs'
2
+ require_relative 'graph/scc'
3
+ require_relative 'graph/kruskal'
4
+
5
+ module Silicium
6
+ module Graphs
7
+ Pair = Struct.new(:first, :second)
8
+
9
+ class GraphError < Error
10
+ end
11
+
12
+ ##
13
+ # Class represents oriented graph
14
+ class OrientedGraph
15
+ def initialize(initializer = [])
16
+ @vertices = {}; @vertex_labels = {}
17
+ @edge_labels = {}; @edge_number = 0
18
+ initializer.each do |v|
19
+ add_vertex!(v[:v])
20
+ v[:i].each do |iv|
21
+ add_vertex!(v[:v])
22
+ add_vertex!(iv)
23
+ add_edge!(v[:v], iv)
24
+ end
25
+ end
26
+ end
27
+
28
+ ##
29
+ # Adds vertex to graph
30
+ def add_vertex!(vertex_id)
31
+ if @vertices.has_key?(vertex_id); return end
32
+ @vertices[vertex_id] = [].to_set
33
+ end
34
+
35
+ ##
36
+ # Adds edge to graph
37
+ def add_edge!(from, to)
38
+ protected_add_edge!(from, to)
39
+ @edge_number += 1
40
+ end
41
+
42
+ # should only be used in constructor
43
+ def add_edge_force!(from, to)
44
+ add_vertex!(from)
45
+ add_vertex!(to)
46
+ add_edge!(from, to)
47
+ end
48
+
49
+ ##
50
+ # Returns array of vertices which adjacted with vertex
51
+ # @raise [GraphError] if graph does not contain vertex
52
+ def adjacted_with(vertex)
53
+ raise GraphError.new("Graph does not contain vertex #{vertex}") unless @vertices.has_key?(vertex)
54
+ @vertices[vertex].clone
55
+ end
56
+
57
+ ##
58
+ # Adds label to edge
59
+ # @raise [GraphError] if graph does not contain edge
60
+ def label_edge!(from, to, label)
61
+ unless @vertices.has_key?(from) && @vertices[from].include?(to)
62
+ raise GraphError.new("Graph does not contain edge (#{from}, #{to})")
63
+ end
64
+ @edge_labels[Pair.new(from, to)] = label
65
+ end
66
+
67
+ ##
68
+ # Adds label to vertex
69
+ # @raise [GraphError] if graph does not contain vertex
70
+ def label_vertex!(vertex, label)
71
+ unless @vertices.has_key?(vertex)
72
+ raise GraphError.new("Graph does not contain vertex #{vertex}")
73
+ end
74
+ @vertex_labels[vertex] = label
75
+ end
76
+
77
+ ##
78
+ # Returns edge label
79
+ # @raise [GraphError] if graph does not contain edge
80
+ def get_edge_label(from, to)
81
+ if !@vertices.has_key?(from) || ! @vertices[from].include?(to)
82
+ raise GraphError.new("Graph does not contain edge (#{from}, #{to})")
83
+ end
84
+ @edge_labels[Pair.new(from, to)]
85
+ end
86
+
87
+ ##
88
+ # Returns vertex label
89
+ # @raise [GraphError] if graph does not contain vertex
90
+ def get_vertex_label(vertex)
91
+ unless @vertices.has_key?(vertex)
92
+ raise GraphError.new("Graph does not contain vertex #{vertex}")
93
+ end
94
+
95
+ @vertex_labels[vertex]
96
+ end
97
+ ##
98
+ # Returns number of vertices
99
+ def vertex_number
100
+ @vertices.count
101
+ end
102
+ ##
103
+ # Returns number of edges
104
+ def edge_number
105
+ @edge_number
106
+ end
107
+ ##
108
+ # Returns number of vertex labels
109
+ def vertex_label_number
110
+ @vertex_labels.count
111
+ end
112
+ ##
113
+ # Returns number of edge labels
114
+ def edge_label_number
115
+ @edge_labels.count
116
+ end
117
+ ##
118
+ # Checks if graph contains vertex
119
+ def has_vertex?(vertex)
120
+ @vertices.has_key?(vertex)
121
+ end
122
+ ##
123
+ # Checks if graph contains edge
124
+ def has_edge?(from, to)
125
+ @vertices.has_key?(from) && @vertices[from].include?(to)
126
+ end
127
+ ##
128
+ # Deletes vertex from graph
129
+ def delete_vertex!(vertex)
130
+ if has_vertex?(vertex)
131
+ @vertices.keys.each { |key| delete_edge!(key, vertex) }
132
+ @vertices.delete(vertex)
133
+ @vertex_labels.delete(vertex)
134
+ @vertices.keys.each { |key| @edge_labels.delete(Pair.new(vertex, key)) }
135
+ end
136
+ end
137
+ ##
138
+ # Deletes edge from graph
139
+ def delete_edge!(from, to)
140
+ protected_delete_edge!(from, to)
141
+ @edge_number -= 1
142
+ end
143
+ ##
144
+ # Reverses graph
145
+ def reverse!
146
+ l = {}; v = {}
147
+ @vertices.keys.each { |from| v[from] = [].to_set }
148
+ @vertices.keys.each do |from|
149
+ @vertices[from].each do |to|
150
+ v[to] << from
151
+ if @edge_labels.include?(Pair.new(from, to))
152
+ l[Pair.new(to, from)] = @edge_labels[Pair.new(from, to)]
153
+ end
154
+ end
155
+ end
156
+ @vertices = v; @edge_labels = l
157
+ end
158
+
159
+
160
+ # Returns array of vertices
161
+ def vertices
162
+ @vertices
163
+ end
164
+
165
+ # Returns labels of edges
166
+ def edge_labels
167
+ @edge_labels
168
+ end
169
+
170
+
171
+ # Returns labels of vertices
172
+ def vertex_labels
173
+ @vertex_labels
174
+ end
175
+
176
+ protected
177
+ ##
178
+ # Adds edge to graph
179
+ def protected_add_edge!(from, to)
180
+ @vertices[from] << to if @vertices.has_key?(from) && @vertices.has_key?(to)
181
+ end
182
+ ##
183
+ # Deletes edge from graph
184
+ def protected_delete_edge!(from, to)
185
+ if has_edge?(from, to)
186
+ @vertices[from].delete(to)
187
+ @edge_labels.delete(Pair.new(from, to))
188
+ end
189
+ end
190
+
191
+ end
192
+ ##
193
+ # Class represents unoriented graph
194
+ class UnorientedGraph < OrientedGraph
195
+ ##
196
+ # Adds edge to graph
197
+ def add_edge!(from, to)
198
+ protected_add_edge!(from, to)
199
+ protected_add_edge!(to, from)
200
+ @edge_number += 1
201
+ end
202
+ ##
203
+ # Adds label to edge
204
+ def label_edge!(from, to, label)
205
+ super(from, to, label)
206
+ super(to, from, label)
207
+ end
208
+ ##
209
+ # Deletes edge from graph
210
+ def delete_edge!(from, to)
211
+ protected_delete_edge!(from, to)
212
+ protected_delete_edge!(to, from)
213
+ @edge_number -= 1
214
+ end
215
+
216
+ end
217
+ ##
218
+ # Implements breadth-first search (BFS)
219
+ def breadth_first_search?(graph, start, goal)
220
+ visited = Hash.new(false)
221
+ queue = Queue.new
222
+ queue.push(start)
223
+ visited[start] = true
224
+ until queue.empty? do
225
+ node = queue.pop
226
+ return true if node == goal
227
+ add_to_queue(graph, queue, node, visited)
228
+ end
229
+ false
230
+ end
231
+ ##
232
+ # Adds to queue not visited vertices
233
+ def add_to_queue(graph, queue, node, visited)
234
+ graph.vertices[node].each do |child|
235
+ unless visited[child]
236
+ queue.push(child)
237
+ visited[child] = true
238
+ end
239
+ end
240
+ end
241
+ ##
242
+ # Checks if graph is connected
243
+ def connected?(graph)
244
+ start = graph.vertices.keys[0]
245
+ goal = graph.vertices.keys[graph.vertex_number - 1]
246
+ pred = breadth_first_search?(graph, start, goal)
247
+ graph.reverse!
248
+ pred = pred and breadth_first_search?(graph, goal, start)
249
+ graph.reverse!
250
+ pred
251
+ end
252
+ ##
253
+ # Returns number of connected vertices
254
+ def number_of_connected(graph)
255
+ visited = Hash.new(false)
256
+ res = 0
257
+ graph.vertices.keys.each do |v|
258
+ unless visited[v]
259
+ dfu(graph, v, visited)
260
+ res += 1
261
+ end
262
+ end
263
+ res
264
+ end
265
+ ##
266
+ # Passes graph's vertices and marks them visited
267
+ def dfu(graph, vertice, visited)
268
+ visited[vertice] = true
269
+ graph.vertices[vertice].each { |item| dfu(graph, item, visited) unless visited[item] }
270
+ end
271
+
272
+ def add_edge!(mst, edge, label)
273
+ mst.add_vertex!(edge[0])
274
+ mst.add_vertex!(edge[1])
275
+ mst.add_edge!(edge[0], edge[1])
276
+ mst.label_edge!(edge[0], edge[1], label)
277
+ end
278
+
279
+
280
+
281
+ ##
282
+ # "Split" graph into elements like :[from, to] = label
283
+ def graph_to_sets(graph)
284
+ labels = {}
285
+ graph.vertices.keys.each do |from|
286
+ graph.adjacted_with(from).each { |to| labels[Pair.new(from, to)] = graph.get_edge_label(from, to) }
287
+ end
288
+ labels.to_set.sort_by { |elem| elem[1] }.to_h
289
+ end
290
+
291
+ def sum_labels(graph)
292
+ labels = 0
293
+ graph.vertices.keys.each do |from|
294
+ graph.adjacted_with(from).each { |to| labels += graph.get_edge_label(from, to) }
295
+ end
296
+ labels / 2
297
+ end
298
+
299
+
300
+
301
+ ##
302
+ # Implements algorithm of Dijkstra
303
+ def dijkstra_algorithm(graph, starting_vertex)
304
+ if !graph.has_vertex?(starting_vertex)
305
+ raise GraphError.new("Graph does not contains vertex #{starting_vertex}")
306
+ end
307
+ unvisited_vertices = graph.vertices.clone.to_a
308
+ labels = {}
309
+ paths = {}
310
+ initialize_labels_and_paths(graph, labels,paths,starting_vertex)
311
+ while unvisited_vertices.size > 0
312
+ unvisited_vertices.sort { |a, b| compare_labels(a, b, labels) }
313
+ vertex = unvisited_vertices.first
314
+ vertex[1].each do |adj|
315
+ new_label = labels[vertex[0]] + graph.get_edge_label(vertex[0], adj)
316
+ if change_label?(labels[adj], new_label)
317
+ labels[adj] = new_label
318
+ paths[adj] = paths[vertex[0]].clone
319
+ paths[adj].push adj
320
+ end
321
+ end
322
+ unvisited_vertices.delete_at(0)
323
+ end
324
+ {"labels" => labels, "paths" => paths}
325
+ end
326
+
327
+ private
328
+
329
+ def initialize_labels_and_paths(graph, labels,paths,starting_vertex)
330
+ graph.vertices.each_key do |vertex|
331
+ labels[vertex] = -1
332
+ paths[vertex] = [starting_vertex]
333
+ end
334
+ labels[starting_vertex] = 0
335
+ end
336
+
337
+ def compare_labels(a, b, labels)
338
+ return -1 if labels[b[0]] == -1
339
+ return 1 if labels[a[0]] == -1
340
+ return labels[a[0]] <=> labels[b[0]]
341
+ end
342
+
343
+ def change_label?(label, new_label)
344
+ return true if label == -1
345
+ return false if new_label == -1
346
+ return new_label < label
347
+ end
348
+
349
+ end
350
+ end