dijkstra_trace 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.
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: []