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.
- checksums.yaml +7 -0
- data/lib/dijkstra_trace.rb +127 -0
- 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: []
|