-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.rb
77 lines (62 loc) · 2.22 KB
/
app.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
require 'weighted_graph'
require 'victor'
require 'adjacency_matrix'
require 'floyd_warshall'
require './distance'
require './loader'
loader = Loader.new('coordinates.json', 'connections.json')
all_coordinates = loader.coordinates
all_connections = loader.connections
all_nodes = loader.nodes
total_distance = 0
total_path = ''
combined_svg = Victor::SVG.new width: 1200, height: 400, style: { background: '#fff' }
(0..3).each do |segment|
nodes = all_nodes[segment]
connections = all_connections[segment]
coordinates = all_coordinates[segment]
svg = Victor::SVG.new width: 1200, height: 400, style: { background: '#fff' }
coordinates.each do |name, position|
svg.circle(cx: position['x'] * 20, cy: 400 - position['y'] * 20, r: 20, fill: 'blue')
svg.text(name, x: position['x'] * 20, y: 400 - position['y'] * 20, font_size: 30, fill: 'red')
end
connections.each do |connection|
svg.line(
x1: connection['from']['x']* 20,
y1: 400 - connection['from']['y'] * 20,
x2: connection['to']['x'] * 20,
y2: 400 - connection['to']['y'] * 20,
style: { stroke: 'red' }
)
end
graph = WeightedGraph::PositiveWeightedGraph.new
connections.each do |connection|
from = connection['from']
to = connection['to']
from_name = from['name']
to_name = to['name']
dist = Distance.between(from, to)
graph.add_undirected_edge(from_name, to_name, dist)
svg.text(dist.round(3),
x: ((to['x'] + from['x'])/2) * 20,
y: 400 - ((to['y'] + from['y'])/2) * 20,
font_size: 20, fill: 'red'
)
end
svg.save "segment#{segment}.svg"
combined_svg << svg
# create matrix containing only direct distances between nodes
matrix = AdjacencyMatrix::Matrix.new(nodes, graph)
# create matrix containing shortes distances, possibly traversing other nodes
optimizer = FloydWarshall::Optimizer.new(matrix)
shortest = optimizer.run
# select shortest path between first and last node by trying all permutations
d = Distance.new(nodes, shortest)
puts "Segment: #{segment}: #{d.shortest_path}: #{d.shortest_distance}"
total_distance += d.shortest_distance
total_path << d.shortest_path + "\t"
end
combined_svg.save "path.svg"
puts "Total"
puts total_distance
puts total_path