scipy.optimize (TSP). 2-opt, TSP . :
import numpy as np
path_distance = lambda r,c: np.sum([np.linalg.norm(c[r[p]]-c[r[p-1]]) for p in range(len(r))])
two_opt_swap = lambda r,i,k: np.concatenate((r[0:i],r[k:-len(r)+i-1:-1],r[k+1:len(r)]))
def two_opt(cities,improvement_threshold):
route = np.arange(cities.shape[0])
improvement_factor = 1
best_distance = path_distance(route,cities)
while improvement_factor > improvement_threshold:
distance_to_beat = best_distance
for swap_first in range(1,len(route)-2):
for swap_last in range(swap_first+1,len(route)):
new_route = two_opt_swap(route,swap_first,swap_last)
new_distance = path_distance(new_route,cities)
if new_distance < best_distance:
route = new_route
best_distance = new_distance
improvement_factor = 1 - best_distance/distance_to_beat
return route
:
cities = np.random.RandomState(42).rand(70,2)
route = two_opt(cities,0.001)
, :
import matplotlib.pyplot as plt
new_cities_order = np.concatenate((np.array([cities[route[i]] for i in range(len(route))]),np.array([cities[0]])))
plt.scatter(cities[:,0],cities[:,1])
plt.plot(new_cities_order[:,0],new_cities_order[:,1])
plt.show()
print("Route: " + str(route) + "\n\nDistance: " + str(path_distance(route,cities)))

, . .
:
( , , ),
path_distance = lambda r,c: np.sum([np.linalg.norm(c[r[p+1]]-c[r[p]]) for p in range(len(r)-1)])
new_cities_order = np.array([cities[route[i]] for i in range(len(route))])
cities, .
cities, swap_first , swap_first swap_last two_opt()
for swap_first in range(1,len(route)-3):
for swap_last in range(swap_first+1,len(route)-1):
, , swap_first swap_first swap_last
for swap_first in range(0,len(route)-2):
for swap_last in range(swap_first+1,len(route)):