cvut_mi_rub_nodes_distance_solver 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 37a4eebd2a9637c18e096d34657976b795b083a8
4
+ data.tar.gz: 573bbe11f8bc1ff62939945bae8f74892587031a
5
+ SHA512:
6
+ metadata.gz: b00731d0e5174e71831f3b138131fc6c690f706eb208cc79af23cda84822009b6e0f1036cdbdb20cc5fc3edb857c9bdaa1c344af52268fe67002ca5f8477b66e
7
+ data.tar.gz: 24df050e9474d88435d2acfab335aab3547a370d005bcf2f140345bc1447450cf0de0bef024bb488bf715db946ef8610886b1dc181c38e530bb36916d86c9d1e
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in cvut_mi_rub_nodes_distance_solver.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Bc. Petr Janouch
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # CvutMiRubNodesDistanceSolver
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'cvut_mi_rub_nodes_distance_solver'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install cvut_mi_rub_nodes_distance_solver
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'nodesDistanceSolver/cli'
4
+
5
+ NodesDistance::CLI.start(ARGV)
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cvut_mi_rub_nodes_distance_solver/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "cvut_mi_rub_nodes_distance_solver"
8
+ spec.version = CvutMiRubNodesDistanceSolver::VERSION
9
+ spec.authors = ["Bc. Petr Janouch"]
10
+ spec.email = ["janoupe8@fit.cvut.cz"]
11
+ spec.description = "A gem that is used to compute distances between all nodes in graph"
12
+ spec.summary = "A gem that is used to compute distances between all nodes in graph"
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ end
@@ -0,0 +1,5 @@
1
+ require "cvut_mi_rub_nodes_distance_solver/version"
2
+
3
+ module CvutMiRubNodesDistanceSolver
4
+ # Your code goes here...
5
+ end
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+ require 'cvut_mi_rub_nodes_distance_solver/dijkstra'
3
+ require 'cvut_mi_rub_nodes_distance_solver/multiplication'
4
+ require 'cvut_mi_rub_nodes_distance_solver/floyd'
5
+ require 'cvut_mi_rub_nodes_distance_solver/distance_matrix'
6
+ require 'cvut_mi_rub_nodes_distance_solver/input_parser'
7
+ require 'thor'
8
+
9
+ module NodesDistance
10
+
11
+ class CLI < Thor
12
+ desc "floyd FILE", "finds shortest distance between all nodes in a graph using Floid's algorithm"
13
+ def floyd(file)
14
+ matrix = get_matrix(file)
15
+ solver = Floyd.new(matrix)
16
+ result = solver.solve
17
+ puts result.to_s
18
+ end
19
+
20
+ desc "dijkstra FILE", "finds shortest distance between all nodes in a graph using Dijkstra's algorithm"
21
+ def dijkstra(file)
22
+ matrix = get_matrix(file)
23
+ solver = Dijkstra.new(matrix)
24
+ result = solver.solve
25
+ puts result.to_s
26
+ end
27
+
28
+ desc "multiplication FILE", "finds shortest distance between all nodes in a graph using min-plus product"
29
+ def multiplication(file)
30
+ matrix = get_solver(file)
31
+ solver = Multiplication.new(matrix)
32
+ result = solver.solve
33
+ puts result.to_s
34
+ end
35
+
36
+ private
37
+
38
+ def get_matrix(file)
39
+ input = get_input_from_file(file)
40
+ input_parser = InputParser.new(input)
41
+ unless input_parser.is_valid?
42
+ puts 'incorrect input format'
43
+ exit
44
+ end
45
+ matrix = input_parser.create_matrix
46
+ matrix
47
+ end
48
+
49
+ def get_input_from_file(file_path)
50
+ str = ''
51
+ File.open(file_path, "r") do |f|
52
+ f.readlines.each do |line|
53
+ str += line
54
+ end
55
+ end
56
+ str
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,68 @@
1
+ #!/bin/ruby
2
+ require 'cvut_mi_rub_nodes_distance_solver/distance_matrix'
3
+ require 'cvut_mi_rub_nodes_distance_solver/input_parser'
4
+
5
+ module NodesDistance
6
+
7
+ # class containing algorithms for shortest distances computation
8
+ class NodesDistance::Dijkstra
9
+
10
+ def initialize(input_matrix)
11
+ @input_matrix = input_matrix
12
+ end
13
+
14
+ # returns a matrix of shortest distances between all nodes
15
+ # computed using dijkstra algorithm from each node
16
+ def solve
17
+ matrix = DistanceMatrix.new(@input_matrix.dimension)
18
+ @input_matrix.dimension.times do |i|
19
+ distance_vector = dijkstra_for_one_node(i)
20
+ matrix[i] = distance_vector
21
+ end
22
+ matrix
23
+ end
24
+
25
+ private
26
+
27
+ # calculates shortest distances between the starting_node and all other nodes
28
+ # Arguments: starting_node: (int) index of the node shortes path is calculated from
29
+ def dijkstra_for_one_node(starting_node)
30
+ distance_vector = Array.new(@input_matrix.dimension) do
31
+ INFINITY
32
+ end
33
+ distance_vector[starting_node] = 0
34
+
35
+ node_queue = []
36
+ @input_matrix.dimension.times do |i|
37
+ node_queue << i
38
+ end
39
+
40
+ until node_queue.empty?
41
+ node = remove_node_with_smallest_distance_from_queue(distance_vector, node_queue)
42
+ break if distance_vector[node] == INFINITY
43
+ neighbours = @input_matrix[node]
44
+ neighbours.each_with_index do |neighbour_distance, neighbour|
45
+ if distance_vector[neighbour] > distance_vector[node] + neighbour_distance
46
+ distance_vector[neighbour] = distance_vector[node] + neighbour_distance
47
+ end
48
+ end
49
+ end
50
+ distance_vector
51
+ end
52
+
53
+ # remove node with smallest distence from queue
54
+ # Arguments: distance_vector (Array) vector of distances
55
+ def remove_node_with_smallest_distance_from_queue(distance_vector, node_queue)
56
+ min_value = INFINITY
57
+ min_index = 0
58
+ node_queue.each_with_index do |node, index|
59
+ value = distance_vector[node]
60
+ if value < min_value
61
+ min_value = value
62
+ min_index = index
63
+ end
64
+ end
65
+ node_queue.delete_at(min_index)
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,170 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ module NodesDistance
4
+
5
+ INFINITY = Float::INFINITY
6
+ INFINITY_SYMBOL = 'I'
7
+
8
+ # class that represents the matrix of distances between nodes
9
+ # it also defines multiplication of matrixes using min-sum product
10
+ class DistanceMatrix
11
+
12
+ attr_reader :dimension
13
+
14
+ # expect a dimesion of the matrix
15
+ # Arguments: dimension (String)
16
+ def initialize(dimension)
17
+ @dimension = dimension
18
+ @matrix = Array.new(dimension) do
19
+ Array.new(dimension) { INFINITY }
20
+ end
21
+ end
22
+
23
+ # prints matrix in human-readible form
24
+ def to_s
25
+ res = ''
26
+ @matrix.each_with_index do |row, row_index|
27
+ res += horizontal_gap unless row_index == 0
28
+ row.each_with_index do |item, item_index|
29
+ res += ' ' unless item_index == 0
30
+ res += print_item(item)
31
+ end
32
+ res += "\n"
33
+ end
34
+ res
35
+ end
36
+
37
+ # accesses matrix item or row based on # of arguments
38
+ def [](*args)
39
+ return @matrix[args[0]] if args.length == 1
40
+ @matrix[args[0]][args[1]]
41
+ end
42
+
43
+ # sets matrix item or row based on # of arguments
44
+ def []=(*args)
45
+ if args.length == 2
46
+ @matrix[args[0]] = args[1]
47
+ else
48
+ @matrix[args[0]][args[1]] = args[2]
49
+ end
50
+ end
51
+
52
+ # returns min-sum product of the two matrixes
53
+ # Arguments: other_matrix (DistanceMatrix)
54
+ def *(other_matrix)
55
+ result = DistanceMatrix.new(@dimension)
56
+ @dimension.times do |i|
57
+ @dimension.times do |j|
58
+ sum_vector = []
59
+ @dimension.times do |k|
60
+ sum = @matrix[i][k] + other_matrix[k, j]
61
+ sum_vector << sum
62
+ end
63
+ min = minimum(sum_vector)
64
+ result[i, j] = min
65
+ end
66
+ end
67
+ result
68
+ end
69
+
70
+ # returns power of the matrix
71
+
72
+ def ^(power)
73
+ result = copy
74
+ (power - 1).times do |i|
75
+ result *= result
76
+ end
77
+ result
78
+ end
79
+
80
+ # test if the two matrixes are equal
81
+ # Arguments: other (DistanceMatrix)
82
+ def ==(other)
83
+ return false unless @dimension == other.dimension
84
+ @dimension.times do |x|
85
+ @dimension.times do |y|
86
+ return false unless @matrix[x][y] == other[x, y]
87
+ end
88
+ end
89
+ true
90
+ end
91
+
92
+ # returs a copy of the matrix
93
+ def copy
94
+ result = DistanceMatrix.new(@dimension)
95
+ iterate_all do |item, x, y|
96
+ result[x, y] = item
97
+ end
98
+ result
99
+ end
100
+
101
+ # iterates over all intems in matrix and also yields their coordinates
102
+ def iterate_all
103
+ @matrix.each_with_index do |row, x|
104
+ row.each_with_index do |item, y|
105
+ yield(item, x, y)
106
+ end
107
+ end
108
+ end
109
+
110
+ private
111
+
112
+ # prints empty line
113
+ def horizontal_gap
114
+ line = ''
115
+ max_digits = max_digits()
116
+ line_width = @dimension * (max_digits + 1) - 1
117
+ line_width.times do
118
+ line += ' '
119
+ end
120
+ line += "\n"
121
+ line
122
+ end
123
+
124
+ # returns number of digits in provided number
125
+ # Arguments: number (int)
126
+ def digits(number)
127
+ number.to_s.size
128
+ end
129
+
130
+ def max_digits
131
+ max = 1
132
+ @matrix.each do |row|
133
+ row.each do |item|
134
+ next if item == INFINITY
135
+ item_digits = digits(item)
136
+ max = item_digits if item_digits > max
137
+ end
138
+ end
139
+ max
140
+ end
141
+
142
+ # prints an item of the matrix
143
+ # Arguments: item (int)
144
+ def print_item(item)
145
+ res = ''
146
+ max_digits = max_digits()
147
+ item_digits = digits(item)
148
+ digits_diferrence = max_digits - item_digits
149
+ digits_diferrence.times do
150
+ res += ' '
151
+ end
152
+ if item == INFINITY
153
+ res += INFINITY_SYMBOL
154
+ else
155
+ res += item.to_s
156
+ end
157
+ res
158
+ end
159
+
160
+ # returns the smallest item from provided vector
161
+ # Arguments: vector (Array<int>)
162
+ def minimum(vector)
163
+ min = INFINITY
164
+ vector.each do |item|
165
+ min = item if item < min
166
+ end
167
+ min
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,29 @@
1
+ #!/bin/ruby
2
+ require 'cvut_mi_rub_nodes_distance_solver/distance_matrix'
3
+ require 'cvut_mi_rub_nodes_distance_solver/input_parser'
4
+
5
+ module NodesDistance
6
+
7
+ # class containing algorithms for shortest distances computation
8
+ class NodesDistance::Floyd
9
+
10
+ def initialize(input_matrix)
11
+ @input_matrix = input_matrix
12
+ end
13
+
14
+ # returns a matrix of shortest distances between all nodes
15
+ # computed using Floyd algorithm
16
+ def solve
17
+ matrix = @input_matrix.copy
18
+ matrix.dimension.times do |k|
19
+ matrix.dimension.times do |i|
20
+ matrix.dimension.times do |j|
21
+ matrix[i, j] = [matrix[i, j], matrix[i, k] + matrix[k, j]].min
22
+ end
23
+ end
24
+ end
25
+ matrix
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,116 @@
1
+ #!/bin/ruby
2
+ require 'cvut_mi_rub_nodes_distance_solver/distance_matrix'
3
+
4
+ module NodesDistance
5
+
6
+ class InputParser
7
+
8
+ def initialize(input)
9
+ @input = input
10
+ end
11
+
12
+ # returns true if input is valid - is square matrix,
13
+ # contains non-negative numbers or signs for infinit distance,
14
+ # the distance of each node to self is 0
15
+ def is_valid?
16
+ # is square matrix
17
+ return false unless dimensions_valid?
18
+ # non-negative numbers or signs for infinit distance
19
+ return false unless is_valid_symbol?
20
+ # the distance to self is
21
+ return false unless zeros_on_diagonal?
22
+ true
23
+ end
24
+
25
+ def create_matrix
26
+ dimension = number_of_rows
27
+ matrix = DistanceMatrix.new(dimension)
28
+ iterate_elements do |item, row_index, col_index|
29
+ if item == INFINITY_SYMBOL
30
+ item = INFINITY
31
+ else
32
+ item = item.to_i
33
+ end
34
+ matrix[row_index, col_index] = item
35
+ end
36
+ matrix
37
+ end
38
+
39
+ private
40
+
41
+ # iterates over all ellements in the input
42
+ def iterate_elements
43
+ iterate_rows do |row, row_index|
44
+ iterate_row_items(row) do |item, item_index|
45
+ yield(item, row_index, item_index)
46
+ end
47
+ end
48
+ end
49
+
50
+ # iterates over all rows in the input
51
+ def iterate_rows
52
+ @input.split(/\n/).each_with_index do |row, row_index|
53
+ row = row.strip
54
+ yield(row, row_index)
55
+ end
56
+ end
57
+
58
+ # returns number of rows in the input
59
+ def number_of_rows
60
+ row_counter = 0
61
+ iterate_rows do
62
+ row_counter += 1
63
+ end
64
+ row_counter
65
+ end
66
+
67
+ # non-negative numbers or signs for infinit distance
68
+ def is_valid_symbol?
69
+ iterate_elements do |item|
70
+ next if item == INFINITY_SYMBOL
71
+ begin
72
+ item = Float(item)
73
+ rescue ArgumentError, TypeError
74
+ return false
75
+ end
76
+ return false if item < 0
77
+ end
78
+ true
79
+ end
80
+
81
+ # is square matrix
82
+ def dimensions_valid?
83
+ row_number = number_of_rows
84
+ iterate_rows do |row|
85
+ return false unless row_size(row) == row_number
86
+ end
87
+ true
88
+ end
89
+
90
+ # returns number of items in the given row
91
+ # Arguments: row (Array)
92
+ def row_size(row)
93
+ counter = 0
94
+ iterate_row_items(row) do |item, index|
95
+ counter += 1
96
+ end
97
+ counter
98
+ end
99
+
100
+ # itertes over all row items
101
+ # Arguments: row (Array)
102
+ def iterate_row_items(row)
103
+ row.split(/ /).each_with_index do |item, index|
104
+ yield(item, index)
105
+ end
106
+ end
107
+
108
+ # the distance to self is
109
+ def zeros_on_diagonal?
110
+ iterate_elements do |item, row_index, col_index|
111
+ return false if row_index == col_index && item != '0'
112
+ end
113
+ true
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,22 @@
1
+ #!/bin/ruby
2
+ require 'cvut_mi_rub_nodes_distance_solver/distance_matrix'
3
+ require 'cvut_mi_rub_nodes_distance_solver/input_parser'
4
+
5
+ module NodesDistance
6
+
7
+ # class containing algorithms for shortest distances computation
8
+ class NodesDistance::Multiplication
9
+
10
+ def initialize(input_matrix)
11
+ @input_matrix = input_matrix
12
+ end
13
+
14
+ # returns a matrix of shortest distances between all nodes
15
+ # computed using min-plus matrix product
16
+ def solve
17
+ matrix = @input_matrix.copy
18
+ matrix = matrix ^ matrix.dimension
19
+ matrix
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ module CvutMiRubNodesDistanceSolver
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,6 @@
1
+ 0 I I 2 I 7
2
+ I 0 2 I I I
3
+ I I 0 I 3 I
4
+ I 7 I 0 1 I
5
+ I I I I 0 3
6
+ I I 1 I I 0
@@ -0,0 +1,7 @@
1
+ 0 10 I 35 I I I
2
+ I 0 15 I 40 I I
3
+ I I 0 5 20 I I
4
+ 10 I I 0 I I I
5
+ I I I I 0 20 10
6
+ I I I I I 0 5
7
+ I I I 25 I I 0
@@ -0,0 +1,8 @@
1
+ 0 5 8 I I 6 I 3
2
+ 11 0 5 I I I 9 4
3
+ 7 I 0 I I 3 I I
4
+ I I 4 0 8 3 I I
5
+ I 5 3 I 0 8 I I
6
+ 2 1 I I I 0 4 6
7
+ 5 4 I I 3 2 0 I
8
+ I I 12 7 8 I 5 0
data/spec/.DS_Store ADDED
Binary file
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH << './'
4
+ require 'rspec'
5
+ require 'spec_helper'
6
+ require 'spec_data'
7
+ require 'cvut_mi_rub_nodes_distance_solver/input_parser'
8
+ require 'cvut_mi_rub_nodes_distance_solver/dijkstra'
9
+
10
+ describe NodesDistance::Dijkstra do
11
+
12
+ subject do
13
+ input_parser = NodesDistance::InputParser.new(input)
14
+ matrix = input_parser.create_matrix
15
+ shortest = NodesDistance::Dijkstra.new(matrix)
16
+ shortest
17
+ end
18
+
19
+ describe 'shortest paths 1' do
20
+ input, result = SpecData.first
21
+ let(:input) do
22
+ input
23
+ end
24
+
25
+ rip = NodesDistance::InputParser.new(result)
26
+ result_matrix = rip.create_matrix
27
+
28
+ it 'should find the shortest paths using dijkstra algorithm' do
29
+ expect(subject.solve).to eq result_matrix
30
+ end
31
+
32
+ end
33
+
34
+ describe 'shortest paths 2' do
35
+ input, result = SpecData.second
36
+ let(:input) do
37
+ input
38
+ end
39
+
40
+ rip = NodesDistance::InputParser.new(result)
41
+ result_matrix = rip.create_matrix
42
+
43
+ it 'should find the shortest paths using dijkstra algorithm' do
44
+ expect(subject.solve).to eq result_matrix
45
+ end
46
+
47
+ end
48
+
49
+ describe 'shortest paths 3' do
50
+ input, result = SpecData.third
51
+ let(:input) do
52
+ input
53
+ end
54
+
55
+ rip = NodesDistance::InputParser.new(result)
56
+ result_matrix = rip.create_matrix
57
+
58
+ it 'should find the shortest paths using dijkstra algorithm' do
59
+ expect(subject.solve).to eq result_matrix
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH << './'
4
+ require 'rspec'
5
+ require 'spec_helper'
6
+ require 'cvut_mi_rub_nodes_distance_solver/input_parser'
7
+
8
+ describe NodesDistance::DistanceMatrix do
9
+
10
+ subject do
11
+ input_parser = NodesDistance::InputParser.new(input)
12
+ input_parser.create_matrix
13
+ end
14
+
15
+ describe 'output format' do
16
+ let(:input) do
17
+ '0 5 22
18
+ 0 0 42
19
+ 99 0 33'
20
+ end
21
+
22
+ it 'should print formated matrix' do
23
+ expected_result = " 0 5 22\n"\
24
+ " \n"\
25
+ " 0 0 42\n"\
26
+ " \n"\
27
+ "99 0 33\n"
28
+ expect(subject.to_s).to eq expected_result
29
+ end
30
+ end
31
+
32
+ describe 'accessing values' do
33
+ let(:input) do
34
+ '0 5 22
35
+ 0 0 42
36
+ 99 0 33'
37
+ end
38
+
39
+ it 'should get values' do
40
+ expect(subject[0, 0]).to eq 0
41
+ expect(subject[0, 2]).to eq 22
42
+ expect(subject[2, 2]).to eq 33
43
+ end
44
+ end
45
+
46
+ describe 'multiplication' do
47
+ let(:input) do
48
+ '1 -3 7
49
+ I 5 I
50
+ 8 2 -5'
51
+ end
52
+
53
+ it 'should do modified multiplication' do
54
+ b_input = '8 I -4
55
+ -3 0 -7
56
+ 5 -2 1'
57
+ b_ip = NodesDistance::InputParser.new(b_input)
58
+ b = b_ip.create_matrix
59
+ c_input = '-6 -3 -10
60
+ 2 5 -2
61
+ -1 -7 -5'
62
+ c_ip = NodesDistance::InputParser.new(c_input)
63
+ c = c_ip.create_matrix
64
+ expect(subject * b).to eq c
65
+ end
66
+ end
67
+
68
+ describe 'square' do
69
+ let(:input) do
70
+ '1 -3 7
71
+ I 5 I
72
+ 8 2 -5'
73
+ end
74
+
75
+ it 'should square matrix' do
76
+ res_input = '2 -2 2
77
+ I 10 I
78
+ 3 -3 -10'
79
+ res_ip = NodesDistance::InputParser.new(res_input)
80
+ res = res_ip.create_matrix
81
+ expect(subject ^ 2).to eq res
82
+ end
83
+ end
84
+
85
+ end
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH << './'
4
+ require 'rspec'
5
+ require 'spec_helper'
6
+ require 'spec_data'
7
+ require 'cvut_mi_rub_nodes_distance_solver/input_parser'
8
+ require 'cvut_mi_rub_nodes_distance_solver/floyd'
9
+
10
+ describe NodesDistance::Floyd do
11
+
12
+ subject do
13
+ input_parser = NodesDistance::InputParser.new(input)
14
+ matrix = input_parser.create_matrix
15
+ shortest = NodesDistance::Floyd.new(matrix)
16
+ shortest
17
+ end
18
+
19
+ describe 'shortest paths 1' do
20
+ input, result = SpecData.first
21
+ let(:input) do
22
+ input
23
+ end
24
+
25
+ rip = NodesDistance::InputParser.new(result)
26
+ result_matrix = rip.create_matrix
27
+
28
+ it 'should find the shortest paths using floyd algorithm' do
29
+ expect(subject.solve).to eq result_matrix
30
+ end
31
+
32
+ end
33
+
34
+ describe 'shortest paths 2' do
35
+ input, result = SpecData.second
36
+ let(:input) do
37
+ input
38
+ end
39
+
40
+ rip = NodesDistance::InputParser.new(result)
41
+ result_matrix = rip.create_matrix
42
+
43
+ it 'should find the shortest paths using floyd algorithm' do
44
+ expect(subject.solve).to eq result_matrix
45
+ end
46
+
47
+ end
48
+
49
+ describe 'shortest paths 3' do
50
+ input, result = SpecData.third
51
+ let(:input) do
52
+ input
53
+ end
54
+
55
+ rip = NodesDistance::InputParser.new(result)
56
+ result_matrix = rip.create_matrix
57
+
58
+ it 'should find the shortest paths using floyd algorithm' do
59
+ expect(subject.solve).to eq result_matrix
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH << './'
3
+ require 'spec_helper'
4
+ require 'cvut_mi_rub_nodes_distance_solver/input_parser'
5
+
6
+ describe NodesDistance::InputParser do
7
+ subject do
8
+ NodesDistance::InputParser.new(input)
9
+ end
10
+
11
+ describe 'incorrect dimensions' do
12
+ let(:input) do
13
+ '0 0 0
14
+ 0 0'
15
+ end
16
+
17
+ it 'should not pass rows of different sizes' do
18
+ expect(subject.is_valid?).to eq false
19
+ end
20
+ end
21
+
22
+ describe 'incorrect dimensions' do
23
+ let(:input) do
24
+ '0 0 0
25
+ 0 0 0'
26
+ end
27
+
28
+ it 'should not pass matrix that has width larger than height' do
29
+ expect(subject.is_valid?).to eq false
30
+ end
31
+ end
32
+
33
+ describe 'incorrect dimensions' do
34
+ let(:input) do
35
+ '0 0
36
+ 0 0
37
+ 0 0'
38
+ end
39
+
40
+ it 'should not pass matrix that has haight larger than width' do
41
+ expect(subject.is_valid?).to eq false
42
+ end
43
+ end
44
+
45
+ describe 'input values' do
46
+ let(:input) do
47
+ '0 0 0
48
+ 0 2 0
49
+ 0 0 3'
50
+ end
51
+
52
+ it 'should not pass if a node has the distance to itself other than 0' do
53
+ expect(subject.is_valid?).to eq false
54
+ end
55
+ end
56
+
57
+ describe 'input values' do
58
+ let(:input) do
59
+ '0 -5 f
60
+ ? 0 8
61
+ 0 . 0'
62
+ end
63
+
64
+ it 'should not pass if there are not possitive numbers, infinity symbols or zeros on the input' do
65
+ expect(subject.is_valid?).to eq false
66
+ end
67
+ end
68
+
69
+ describe 'input values' do
70
+ let(:input) do
71
+ '0 5 2.2
72
+ 4 0 1
73
+ 3 7 0'
74
+ end
75
+
76
+ it 'should recognize correct input' do
77
+ expect(subject.is_valid?).to eq true
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH << './'
4
+ require 'rspec'
5
+ require 'spec_helper'
6
+ require 'spec_data'
7
+ require 'cvut_mi_rub_nodes_distance_solver/input_parser'
8
+ require 'cvut_mi_rub_nodes_distance_solver/multiplication'
9
+
10
+ describe NodesDistance::Multiplication do
11
+
12
+ subject do
13
+ input_parser = NodesDistance::InputParser.new(input)
14
+ matrix = input_parser.create_matrix
15
+ shortest = NodesDistance::Multiplication.new(matrix)
16
+ shortest
17
+ end
18
+
19
+ describe 'shortest paths 1' do
20
+ input, result = SpecData.first
21
+ let(:input) do
22
+ input
23
+ end
24
+
25
+ rip = NodesDistance::InputParser.new(result)
26
+ result_matrix = rip.create_matrix
27
+
28
+ it 'should find the shortest paths using multiplication algorithm' do
29
+ expect(subject.solve).to eq result_matrix
30
+ end
31
+
32
+ end
33
+
34
+ describe 'shortest paths 2' do
35
+ input, result = SpecData.second
36
+ let(:input) do
37
+ input
38
+ end
39
+
40
+ rip = NodesDistance::InputParser.new(result)
41
+ result_matrix = rip.create_matrix
42
+
43
+ it 'should find the shortest paths using multipliation algorithm' do
44
+ expect(subject.solve).to eq result_matrix
45
+ end
46
+
47
+ end
48
+
49
+ describe 'shortest paths 3' do
50
+ input, result = SpecData.third
51
+ let(:input) do
52
+ input
53
+ end
54
+
55
+ rip = NodesDistance::InputParser.new(result)
56
+ result_matrix = rip.create_matrix
57
+
58
+ it 'should find the shortest paths using multiplication algorithm' do
59
+ expect(subject.solve).to eq result_matrix
60
+ end
61
+
62
+ end
63
+ end
data/spec/spec_data.rb ADDED
@@ -0,0 +1,59 @@
1
+
2
+ # contains data for test cases
3
+ class SpecData
4
+
5
+ def self.first
6
+ input = '0 I I 2 I 7
7
+ I 0 2 I I I
8
+ I I 0 I 3 I
9
+ I 7 I 0 1 I
10
+ I I I I 0 3
11
+ I I 1 I I 0'
12
+ result = '0 9 7 2 3 6
13
+ I 0 2 I 5 8
14
+ I I 0 I 3 6
15
+ I 7 5 0 1 4
16
+ I I 4 I 0 3
17
+ I I 1 I 4 0'
18
+ return input, result
19
+ end
20
+
21
+ def self.second
22
+ input = '0 10 I 35 I I I
23
+ I 0 15 I 40 I I
24
+ I I 0 5 20 I I
25
+ 10 I I 0 I I I
26
+ I I I I 0 20 10
27
+ I I I I I 0 5
28
+ I I I 25 I I 0'
29
+ result = '0 10 25 30 45 65 55
30
+ 30 0 15 20 35 55 45
31
+ 15 25 0 5 20 40 30
32
+ 10 20 35 0 55 75 65
33
+ 45 55 70 35 0 20 10
34
+ 40 50 65 30 85 0 5
35
+ 35 45 60 25 80 100 0'
36
+ return input, result
37
+ end
38
+
39
+ def self.third
40
+ input = '0 5 8 I I 6 I 3
41
+ 11 0 5 I I I 9 4
42
+ 7 I 0 I I 3 I I
43
+ I I 4 0 8 3 I I
44
+ I 5 3 I 0 8 I I
45
+ 2 1 I I I 0 4 6
46
+ 5 4 I I 3 2 0 I
47
+ I I 12 7 8 I 5 0'
48
+ result = '0 5 8 10 11 6 8 3
49
+ 10 0 5 11 12 8 9 4
50
+ 5 4 0 15 10 3 7 8
51
+ 5 4 4 0 8 3 7 8
52
+ 8 5 3 16 0 6 10 9
53
+ 2 1 6 12 7 0 4 5
54
+ 4 3 6 14 3 2 0 7
55
+ 9 8 11 7 8 7 5 0'
56
+ return input, result
57
+ end
58
+
59
+ end
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ RSpec.configure do |config|
4
+ config.color_enabled = true
5
+ config.formatter = :documentation
6
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cvut_mi_rub_nodes_distance_solver
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Bc. Petr Janouch
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: A gem that is used to compute distances between all nodes in graph
42
+ email:
43
+ - janoupe8@fit.cvut.cz
44
+ executables:
45
+ - cvut_mi_rub_nodes_distance_solver
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - .gitignore
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - bin/cvut_mi_rub_nodes_distance_solver
55
+ - cvut_mi_rub_nodes_distance_solver.gemspec
56
+ - lib/cvut_mi_rub_nodes_distance_solver.rb
57
+ - lib/cvut_mi_rub_nodes_distance_solver/cli.rb
58
+ - lib/cvut_mi_rub_nodes_distance_solver/dijkstra.rb
59
+ - lib/cvut_mi_rub_nodes_distance_solver/distance_matrix.rb
60
+ - lib/cvut_mi_rub_nodes_distance_solver/floyd.rb
61
+ - lib/cvut_mi_rub_nodes_distance_solver/input_parser.rb
62
+ - lib/cvut_mi_rub_nodes_distance_solver/multiplication.rb
63
+ - lib/cvut_mi_rub_nodes_distance_solver/version.rb
64
+ - sample inputs/input1
65
+ - sample inputs/input2
66
+ - sample inputs/input3
67
+ - spec/.DS_Store
68
+ - spec/dijkstra_spec.rb
69
+ - spec/distance_matrix_spec.rb
70
+ - spec/floyd_spec.rb
71
+ - spec/input_parser_spec.rb
72
+ - spec/multiplication_spec.rb
73
+ - spec/spec_data.rb
74
+ - spec/spec_helper.rb
75
+ homepage: ''
76
+ licenses:
77
+ - MIT
78
+ metadata: {}
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project:
95
+ rubygems_version: 2.1.5
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: A gem that is used to compute distances between all nodes in graph
99
+ test_files:
100
+ - spec/.DS_Store
101
+ - spec/dijkstra_spec.rb
102
+ - spec/distance_matrix_spec.rb
103
+ - spec/floyd_spec.rb
104
+ - spec/input_parser_spec.rb
105
+ - spec/multiplication_spec.rb
106
+ - spec/spec_data.rb
107
+ - spec/spec_helper.rb