silicium 0.0.20 → 0.0.21

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 (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