-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
145 lines (113 loc) · 4.35 KB
/
main.py
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# importing Matplotlib and Numpy Packages
import math
import random as rndm
import sys
from timeit import default_timer as timer
import matplotlib.pyplot as plt
import numpy as np
if len(sys.argv) != 3:
max_coord = int(input("Max X/Y Value: "))
max_num_of_points = pow(max_coord + 1, 2)
# if pow(max_coord + 1, 2) > 999:
# max_num_of_points = 999
# else:
# max_num_of_points = pow(max_coord + 1, 2)
num_of_points = int(input("Number of Points (Max=" + str(max_num_of_points) + "): "))
while num_of_points > max_num_of_points:
print("Can not create more than " + str(max_num_of_points) + " points")
num_of_points = int(input("Please enter a valid amount of points: "))
else:
max_coord = int(sys.argv[1])
num_of_points = int(sys.argv[2])
def sum_list(my_list):
total_sum = 0
for element in my_list:
total_sum += element
return total_sum
def generate_coord():
return [rndm.randint(0, max_coord), rndm.randint(0, max_coord)]
def generate_coords():
first_coord = generate_coord()
coordinates = []
for point in range(1, num_of_points):
new_coord = generate_coord()
while new_coord in coordinates or new_coord == first_coord:
new_coord = generate_coord()
coordinates.append(new_coord)
coordinates.sort(key=lambda k: (k[0], k[1]))
coordinates.insert(0, first_coord)
return coordinates
def get_v_between_two_points(p1, p2):
vector = []
if len(p1) != len(p2):
print("p1: " + str(p1))
print("p2: " + str(p2))
raise ValueError("Both Points must have the same amount of dimensions")
for position in range(0, len(p1)):
vector.append(p2[position] - p1[position])
return vector
def get_vector_distance(vector):
if vector[0] == 0:
return vector[1]
elif vector[1] == 0:
return vector[0]
else:
return math.sqrt(pow(vector[0], 2) + pow(vector[1], 2))
def get_nearest_point(basis_point, old_coords):
nearest_point = basis_point
distance = -1
for oc in old_coords:
vector = get_v_between_two_points(basis_point, oc)
v_distance = abs(get_vector_distance(vector))
if distance == -1 or distance > v_distance:
distance = v_distance
nearest_point = oc
return nearest_point, distance
def sort_points_nearest_neighbour(points):
next_point = []
sorted_points = []
distance = []
length = len(points)
for position in range(0, length):
if position == 0:
next_point = points[0], 0
else:
next_point = get_nearest_point(next_point[0], points)
sorted_points.append(next_point[0])
distance.append(next_point[1])
points.remove(next_point[0])
return sorted_points, distance
def nearest_neighbour(points):
start = timer()
sorted_points_nearest_neighbour, distance_arr = sort_points_nearest_neighbour(points)
end = timer()
# The data are given as list of lists (2d list)
data = np.array(sorted_points_nearest_neighbour)
# Taking transpose
x, y = data.T
# plot our list in X,Y coordinates
plt.plot(x, y)
fastest_route_text = "The fastest route is: "
for i in range(0, len(sorted_points_nearest_neighbour)):
plt.annotate("P" + str(i), (sorted_points_nearest_neighbour[i][0], sorted_points_nearest_neighbour[i][1]),
textcoords="offset points", xytext=(0, 5))
if i != len(sorted_points_nearest_neighbour) - 1:
fastest_route_text += str(sorted_points_nearest_neighbour[i]) + "(+" + str(
round(distance_arr[i], 2)) + ") --> "
else:
fastest_route_text += str(sorted_points_nearest_neighbour[i]) + "(+" + str(round(distance_arr[i], 2)) + ")"
# v = get_v_between_two_points(sorted_points_nearest_neighbour[0], sorted_points_nearest_neighbour[1])
# plt.arrow(sorted_points_nearest_neighbour[0][0], sorted_points_nearest_neighbour[0][1], v[0], v[1])
return plt, fastest_route_text, distance_arr, end - start
coords = generate_coords()
# Print Coords
print("Coords:")
print(str(coords))
plt, fastest_route, distances, time_in_seconds = nearest_neighbour(coords.copy())
print()
print("Nearest Neighbour:")
print(fastest_route)
print("Total Distance: ", str(sum_list(distances)))
print("Time in ms: ", str(time_in_seconds * 1000))
plt.show()
print()