'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