Path: blob/main/Lessons/Lesson 05 - Local Optimization/scripts/animate_tour.py
871 views
# execute this cell for a *slow* animation of the local search1from IPython.display import display, clear_output2import json3import numpy as np4import matplotlib.pyplot as plt5import seaborn as sns6sns.set_style("darkgrid")78# load problem data9with open("data/Caps48.json", "r") as tsp_data:10tsp = json.load(tsp_data)11dist_mat = tsp["DistanceMatrix"]12optimal_tour = tsp["OptTour"]13opt_dist = tsp["OptDistance"]/1000 # converted to kilometers14xy_meters = np.array(tsp["Coordinates"])1516def sub_tour_reversal(tour):17# reverse a random tour segment18num_cities = len(tour)19i, j = np.sort(np.random.choice(num_cities, 2, replace=False))20return np.concatenate((tour[0:i], tour[j:-num_cities + i - 1:-1],21tour[j + 1:num_cities]))2223def tour_distance(tour, dist_mat):24distance = dist_mat[tour[-1]][tour[0]]25for gene1, gene2 in zip(tour[0:-1], tour[1:]):26distance += dist_mat[gene1][gene2]27return distance/1000 # convert to kilometers2829# initialize with a random tour30n = 4831current_tour = np.random.permutation(np.arange(n))32current_dist = tour_distance(current_tour, dist_mat)3334# plot initial tour35meters_to_pxl = 0.000437462744106496836intercept_x = 2.46437intercept_y = 1342.54638xy_pixels = np.zeros(xy_meters.shape)39xy_pixels[:,0] = meters_to_pxl * xy_meters[:,0] + intercept_x40xy_pixels[:,1] = -meters_to_pxl * xy_meters[:,1] + intercept_y4142fig, ax = plt.subplots(1, 1, figsize=(9, 6))43im = plt.imread('images/caps48.png')44implot = ax.imshow(im)45plt.setp(ax.get_xticklabels(), visible=False)46plt.setp(ax.get_yticklabels(), visible=False)47ax.tick_params(axis='both', which='both', length=0)4849loop_tour = np.append(current_tour, current_tour[0])50lines, = ax.plot(xy_pixels[loop_tour, 0],51xy_pixels[loop_tour, 1],52c='b',53linewidth=1,54linestyle='-')55dst_label = plt.text(100, 1200, '{:d} km'.format(int(current_dist)))5657# local search with graphing58max_moves_no_improve = 500059num_moves_no_improve = 060while( num_moves_no_improve < max_moves_no_improve):61num_moves_no_improve += 162new_tour = sub_tour_reversal(current_tour)63new_dist = tour_distance(new_tour, dist_mat)64if new_dist < current_dist:65current_tour = new_tour66current_dist = new_dist67num_moves_no_improve = 06869loop_tour = np.append(current_tour, current_tour[0])70lines.set_data(xy_pixels[loop_tour, 0], xy_pixels[loop_tour, 1])71dst_label.set_text('{:d} km'.format(int(current_dist)))72clear_output(wait=True)73display(fig)7475