'TSP Simulated Annealing problem doesnt converge to optimal path
My simulated annealing solution doesn't converge to optimal path length after final iteration, instead results seem random and path length doesnt seem to reduce by much. I suspect the problem lies in my accept and rejcet functions but can't seem to find whats wrong.
Any help would be appreciated!
Here's my code:
#Calculate distances between points
def point_distance(point_a, point_b):
return math.sqrt((point_a[0] - point_b[0])**2 + (point_a[1] - point_b[1])**2)
def get_distance_matrix(points):
distance_matrix = {}
for location_a in points:
distance_matrix[location_a] = {}
for location_b in points:
distance_matrix[location_a][location_b] = point_distance(
points[location_a], points[location_b])
return distance_matrix
#Create Distance Array that stores all point distances(around 300)
df = pd.DataFrame(get_distance_matrix(path))
dm = df.to_numpy()
#Calculate length of path
def path_tour(tour):
path_length = 0
distances = get_distance_matrix(tour)
locations = list(tour.keys())
for first, second in zip(locations[:-1], locations[1:]):
path_length += distances[first][second]
return path_length
#Fuction that swaps 2 points and returns delta and new path
def path_swap(path):
route_swap = route.copy()
i = np.random.randint(24)
while True:
j = np.random.randint(24)
if i!=j: break
route_swap = route.copy()
route_swap[i], route_swap[j] = route[j], route[i]
delta = dm[i-1,j] + dm[j,i+1] + dm[j-1,i] + dm[i,j+1] - dm[i-1,i] - dm[i,i+1] -dm[j-1,j] - dm[j,j+1]
path_new = dict(route_swap)
return delta, path_new
def main():
points = {
"Gate Lodge/Start": (0.8391274710, 0.5153010859),
"Ryan Institute Annex": (0.8306066802999, 0.3282329714),
"Martin Ryan Institute": (0.741308793456, 0.304047384),
"Emily Anderson Theatre": (0.707907293796, 0.6219151037),
"Education Building": (0.591683708, 0.4590325765),
"Block S": (0.580777096, 0.3529121422),
"Block E/Civil Engineering Department": (0.631220177232, 0.3909180652),
"O Donoghue Centre": (0.661554192229, 0.1929911155),
"Human Biology Building": (0.570211315610, 0.271964462),
"Aras De Brun": (0.5702113156, 0.5824284304),
"Hardiman Research Building": (0.4768234492, 0.5034550839),
"Arts Millennium Building": (0.4294478527, 0.672260612),
"Smokeys": (0.438991138377, 0.3874629812),
"Block T": (0.208929788684, 0.6145113524),
"Kingfisher": (0.114178595, 0.7359328727),
"Maths and Languages Department": (0.210974778, 0.8149062192),
"Newcastle Road Entrance": (0.27402862985, 0.8608094768),
"Pharmacology Building": (0.32344921608, 0.710266535),
"IT Building": (0.34764826175, 0.2295162883),
"Bank Of Ireland": (0.281186094, 0.4758144126),
"BioChemistry Lab": (0.52181322, 0.34501480),
"Block F": (0.6005453306, 0.7073050346),
"Student Information Desk": (0.549079754, 0.1821322804),
"Orbsen Building": (0.4536468984, 0.157946693),
"Anatomy Building": (0.5743012951, 0.6692991115)
}
route = list(points.items())
random.shuffle(route)
path = dict(route)
tInitial = 12
tFinal = 1
tNow = tInitial
alfa = 0.98
df = pd.DataFrame(get_distance_matrix(path))
dm = df.to_numpy()
iter = 0
print("Initial path length: \n", path_tour(path))
while tNow >= tFinal:
for i in range(10000):
delta, path_new = path_swap(path)
if delta <= 0:
accept = True
else:
pAccept = math.exp(-delta/tNow)
if pAccept > random.random():
accept = True
else:
accept = False
if accept == True:
path = copy.deepcopy(path_new)
tNow = tNow * alfa
iter = iter + 1
print("\nCurrent iteration: ", iter)
print("Current path length: " , path_tour(path))
print("Final Tour: \n", path_tour(path))
print("Iterations taken: \n", iter)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
