dijkstra_trace 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/dijkstra_trace.rb +127 -0
  3. metadata +44 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bd376f91cad60b72fc2639445aa9838faf3155798e608633caced283b0ce402a
4
+ data.tar.gz: 34c984b24e82cca37090d9929fd2e0eef8502c72999bd4c4adaa120f1f02dcf9
5
+ SHA512:
6
+ metadata.gz: bb6b23adace7731e0eef530a5adfa81f30d90414bb17a48666590902bd23aa967977dd5e509404e6c06812a4faec112a12b824717a43d5ad17f220a34daca6e7
7
+ data.tar.gz: 7f576d601f6848a8b694a2390759451ddc951442f47f336642747d5a9cc795826aba420a3a565a568a9bc79965ce15dfac150341d19c05570eb83bda42e17b3b
@@ -0,0 +1,127 @@
1
+ module Dijkstra
2
+
3
+ # The resulting shortest path will be an object of the Path class
4
+ class Path
5
+ attr_accessor :starting_point, :ending_point, :distance, :path
6
+ # Distance variable stores the total distance of the path
7
+ # Path array has the vertices connecting the shortest path
8
+ # Starting point, ending point are used to get the source and destination of the resulting path if needed
9
+
10
+ def initialize(source, destination)
11
+ @starting_point = source
12
+ @ending_point = destination
13
+ @distance = 0
14
+ @path = []
15
+ end
16
+ end
17
+
18
+ # Trace is the main class used to find the shortest path
19
+ class Trace
20
+ # the most maximum distance value can be set by changing the infinity variable
21
+ # of the Trace after initialization
22
+
23
+ attr_accessor :infinity
24
+ # edges should be an two dimensional array, where each column should contain three elements
25
+ # Example: [1,2,45], ['a','b',37]
26
+ # edge vertices can be of any format, but the distance should be a numeric value
27
+
28
+ def initialize(edges)
29
+ @edges = edges
30
+ @map = map_vertices
31
+ @no_of_vertices = @map.count
32
+
33
+ @infinity = 9999999
34
+ end
35
+
36
+ # map_vertices function maps the given vertices to the indices
37
+ # starting from 0 to the number of vertices for better calculation
38
+ def map_vertices
39
+ result = {}
40
+ vertices = (@edges.map { |i| i[0] } + @edges.map { |i| i[1] }).uniq.sort
41
+ vertices.length.times do |i|
42
+ result[vertices[i]] = i
43
+ end
44
+ result
45
+ end
46
+
47
+ # compact_min finds the minimum integer value in the array which includes nil values
48
+ def compact_min(arr)
49
+ min = @infinity
50
+ arr.each do |i|
51
+ if i != nil && i < min
52
+ min = i
53
+ end
54
+ end
55
+ min
56
+ end
57
+
58
+ # adjacent_matrix method will produce the Adjacent matrix for the given edges
59
+ # It can be called separately after initialization without calling path method
60
+ def adjacent_matrix
61
+ adjacent = Array.new(@no_of_vertices) { Array.new(@no_of_vertices) { false } }
62
+ @edges.each do |edge|
63
+ adjacent[@map[edge[0]]] [@map[edge[1]]] = true
64
+ adjacent[@map[edge[1]]] [@map[edge[0]]] = true
65
+ end
66
+ adjacent
67
+ end
68
+
69
+ # graph_matrix method will produce the matrix representation of the graph the given edges
70
+ # It also can be called separately after initialization without calling path method
71
+ def graph_matrix
72
+ graph = Array.new(@no_of_vertices) { Array.new(@no_of_vertices) { 0 } }
73
+ @edges.each do |edge|
74
+ graph[@map[edge[0]]] [@map[edge[1]]] = edge[2]
75
+ graph[@map[edge[1]]] [@map[edge[0]]] = edge[2]
76
+ end
77
+ graph
78
+ end
79
+
80
+ # Path method is used to find the shortest path between two points (source, destination)
81
+ def path(source, destination)
82
+ # An Path object is initially created with given source and destination
83
+ result = Path.new(source, destination)
84
+
85
+ weight = Array.new(@no_of_vertices) { @infinity }
86
+ parent = Array.new(@no_of_vertices)
87
+
88
+ adjacent = adjacent_matrix
89
+ graph = graph_matrix
90
+
91
+ # the hash @map contains the index value used for calculation for the respective vertex
92
+ source = @map[source]
93
+ destination = @map[destination]
94
+
95
+ chosen = source
96
+ weight[source] = 0
97
+
98
+ # Iteration of the Dijkstra Algorithm
99
+ while chosen != destination do
100
+
101
+ adjacent[chosen].each_with_index do |neighbor, i|
102
+ next if !neighbor || weight[i] == nil
103
+ new_weight = weight[chosen] + graph[chosen][i]
104
+ if new_weight < weight[i]
105
+ weight[i] = new_weight
106
+ parent[i] = chosen
107
+ end
108
+ end
109
+
110
+ weight[chosen] = nil
111
+ chosen = weight.index compact_min(weight)
112
+ end
113
+
114
+ # the Path class object 'result' is updated with distance and actual path
115
+ result.distance = weight[destination]
116
+ current = destination
117
+
118
+ # shortest path is found by backtracking the parent array after the completion of the Dijkstra algorithm
119
+ while current != nil
120
+ result.path.unshift @map.key(current)
121
+ current = parent[current]
122
+ end
123
+
124
+ result
125
+ end
126
+ end
127
+ end
metadata ADDED
@@ -0,0 +1,44 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dijkstra_trace
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Sriram V
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-07-23 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A simple Dijkstra Algorithm to find the shortest path between any two
14
+ points in the undirected graph.
15
+ email: srira.venkat@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/dijkstra_trace.rb
21
+ homepage: https://rubygems.org/gems/dijkstra_trace
22
+ licenses:
23
+ - MIT
24
+ metadata: {}
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubygems_version: 3.1.6
41
+ signing_key:
42
+ specification_version: 4
43
+ summary: Dijkstra Algorithm
44
+ test_files: []