cvut_mi_rub_nodes_distance_solver 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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