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.
- checksums.yaml +4 -4
- data/.codeclimate.yml +3 -3
- data/.gitignore +13 -13
- data/.rakeTasks +8 -0
- data/.travis.yml +28 -25
- data/CODE_OF_CONDUCT.md +74 -74
- data/Gemfile +8 -8
- data/LICENSE.txt +21 -21
- data/Makefile +269 -269
- data/README.md +588 -46
- data/Rakefile +16 -16
- data/bin/console +14 -14
- data/bin/setup +8 -8
- data/docs/Object.html +117 -117
- data/docs/README_md.html +142 -142
- data/docs/Silicium/Combinatorics.html +270 -270
- data/docs/Silicium/Dice/Polyhedron.html +315 -315
- data/docs/Silicium/Dice/PolyhedronSet.html +321 -321
- data/docs/Silicium/Dice.html +99 -99
- data/docs/Silicium/Error.html +106 -106
- data/docs/Silicium/Geometry/Line2dCanon.html +243 -243
- data/docs/Silicium/Geometry/VariablesOrderException.html +106 -106
- data/docs/Silicium/Geometry.html +940 -940
- data/docs/Silicium/GraphVisualizer.html +226 -0
- data/docs/Silicium/Graphs/GraphError.html +106 -106
- data/docs/Silicium/Graphs/OrientedGraph.html +901 -775
- data/docs/Silicium/Graphs/UnorientedGraph.html +237 -284
- data/docs/Silicium/Graphs.html +374 -164
- data/docs/Silicium/IntegralDoesntExistError.html +106 -106
- data/docs/Silicium/NumericalIntegration.html +521 -521
- data/docs/Silicium/Optimization.html +629 -639
- data/docs/Silicium/Plotter/Image.html +297 -297
- data/docs/Silicium/Plotter.html +186 -186
- data/docs/Silicium.html +101 -101
- data/docs/created.rid +9 -9
- data/docs/css/fonts.css +167 -167
- data/docs/css/rdoc.css +619 -619
- data/docs/index.html +134 -132
- data/docs/js/darkfish.js +84 -84
- data/docs/js/navigation.js +105 -105
- data/docs/js/search.js +110 -110
- data/docs/js/search_index.js +1 -1
- data/docs/js/search_index.js.gz +0 -0
- data/docs/js/searcher.js +229 -229
- data/docs/table_of_contents.html +697 -608
- data/lib/algebra.rb +452 -0
- data/lib/algebra_diff.rb +258 -0
- data/lib/geometry/figure.rb +62 -0
- data/lib/geometry.rb +290 -236
- data/lib/geometry3d.rb +270 -0
- data/lib/graph/dfs.rb +42 -0
- data/lib/graph/kruskal.rb +36 -0
- data/lib/graph/scc.rb +97 -0
- data/lib/graph.rb +350 -164
- data/lib/graph_visualizer.rb +287 -0
- data/lib/ml_algorithms.rb +181 -0
- data/lib/numerical_integration.rb +184 -147
- data/lib/optimization.rb +209 -144
- data/lib/plotter.rb +256 -96
- data/lib/polynomial_division.rb +132 -0
- data/lib/polynomial_interpolation.rb +94 -0
- data/lib/regression.rb +120 -0
- data/lib/silicium/adding.rb +37 -0
- data/lib/silicium/conversions.rb +23 -0
- data/lib/silicium/multi.rb +82 -0
- data/lib/silicium/sparse.rb +76 -0
- data/lib/silicium/sugar.rb +37 -0
- data/lib/silicium/trans.rb +26 -0
- data/lib/silicium/version.rb +3 -3
- data/lib/silicium.rb +5 -5
- data/lib/theory_of_probability.rb +240 -226
- data/lib/topological_sort.rb +50 -0
- data/oriented_graph.png +0 -0
- data/plot.png +0 -0
- data/silicium.gemspec +38 -39
- metadata +38 -16
    
        data/lib/graph.rb
    CHANGED
    
    | @@ -1,164 +1,350 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 3 | 
            -
             | 
| 4 | 
            -
             | 
| 5 | 
            -
             | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
                end
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                 | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
                    @vertex_labels = {}
         | 
| 17 | 
            -
                     | 
| 18 | 
            -
             | 
| 19 | 
            -
                       | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
                   | 
| 29 | 
            -
             | 
| 30 | 
            -
                  def  | 
| 31 | 
            -
                    if @vertices.has_key?( | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
                  #  | 
| 37 | 
            -
                  def  | 
| 38 | 
            -
                     | 
| 39 | 
            -
                     | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
                  def  | 
| 44 | 
            -
                     | 
| 45 | 
            -
             | 
| 46 | 
            -
                     | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 49 | 
            -
                   | 
| 50 | 
            -
             | 
| 51 | 
            -
                   | 
| 52 | 
            -
             | 
| 53 | 
            -
             | 
| 54 | 
            -
                     | 
| 55 | 
            -
             | 
| 56 | 
            -
             | 
| 57 | 
            -
                   | 
| 58 | 
            -
             | 
| 59 | 
            -
                   | 
| 60 | 
            -
             | 
| 61 | 
            -
             | 
| 62 | 
            -
             | 
| 63 | 
            -
             | 
| 64 | 
            -
                    @ | 
| 65 | 
            -
                  end
         | 
| 66 | 
            -
             | 
| 67 | 
            -
                   | 
| 68 | 
            -
             | 
| 69 | 
            -
             | 
| 70 | 
            -
             | 
| 71 | 
            -
             | 
| 72 | 
            -
             | 
| 73 | 
            -
             | 
| 74 | 
            -
             | 
| 75 | 
            -
                   | 
| 76 | 
            -
             | 
| 77 | 
            -
             | 
| 78 | 
            -
             | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 81 | 
            -
             | 
| 82 | 
            -
             | 
| 83 | 
            -
             | 
| 84 | 
            -
                    @ | 
| 85 | 
            -
                  end
         | 
| 86 | 
            -
             | 
| 87 | 
            -
                   | 
| 88 | 
            -
             | 
| 89 | 
            -
             | 
| 90 | 
            -
             | 
| 91 | 
            -
                     | 
| 92 | 
            -
             | 
| 93 | 
            -
             | 
| 94 | 
            -
             | 
| 95 | 
            -
             | 
| 96 | 
            -
             | 
| 97 | 
            -
                   | 
| 98 | 
            -
             | 
| 99 | 
            -
                  def  | 
| 100 | 
            -
                    @ | 
| 101 | 
            -
                  end
         | 
| 102 | 
            -
             | 
| 103 | 
            -
                   | 
| 104 | 
            -
             | 
| 105 | 
            -
             | 
| 106 | 
            -
             | 
| 107 | 
            -
                   | 
| 108 | 
            -
             | 
| 109 | 
            -
                   | 
| 110 | 
            -
             | 
| 111 | 
            -
                   | 
| 112 | 
            -
             | 
| 113 | 
            -
             | 
| 114 | 
            -
             | 
| 115 | 
            -
             | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 118 | 
            -
             | 
| 119 | 
            -
             | 
| 120 | 
            -
             | 
| 121 | 
            -
             | 
| 122 | 
            -
             | 
| 123 | 
            -
                   | 
| 124 | 
            -
             | 
| 125 | 
            -
             | 
| 126 | 
            -
             | 
| 127 | 
            -
             | 
| 128 | 
            -
             | 
| 129 | 
            -
             | 
| 130 | 
            -
             | 
| 131 | 
            -
             | 
| 132 | 
            -
             | 
| 133 | 
            -
             | 
| 134 | 
            -
             | 
| 135 | 
            -
             | 
| 136 | 
            -
             | 
| 137 | 
            -
             | 
| 138 | 
            -
                   | 
| 139 | 
            -
             | 
| 140 | 
            -
             | 
| 141 | 
            -
                     | 
| 142 | 
            -
             | 
| 143 | 
            -
                   | 
| 144 | 
            -
             | 
| 145 | 
            -
                  def  | 
| 146 | 
            -
                     | 
| 147 | 
            -
                     | 
| 148 | 
            -
             | 
| 149 | 
            -
             | 
| 150 | 
            -
             | 
| 151 | 
            -
             | 
| 152 | 
            -
             | 
| 153 | 
            -
             | 
| 154 | 
            -
             | 
| 155 | 
            -
                     | 
| 156 | 
            -
             | 
| 157 | 
            -
             | 
| 158 | 
            -
             | 
| 159 | 
            -
             | 
| 160 | 
            -
                  #
         | 
| 161 | 
            -
             | 
| 162 | 
            -
             | 
| 163 | 
            -
             | 
| 164 | 
            -
             | 
| 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
         |