import numpy as np
import pandas as pd
from matplotlib.animation import FuncAnimation
import matplotlib.pyplot as plt
class TSP(object):
def __init__(self,DistanceMatrix):
self.max_T = 100
self.min_T = 0.1
self.T = self.max_T
self.best_distance = None
self.best_cities = None
self.best_cities_list = []
self.search_num = 50
self.t = 1
self.DistanceMatrix = DistanceMatrix
def get_distance(self, cities):
sumdist = 0
for i in range(-1, len(cities) - 1):
distance = self.DistanceMatrix[cities[i+1]-1,cities[i]-1]
sumdist += distance
return sumdist
def update_value(self, cities, new_cities, distance, new_distance):
P = np.exp(-(np.abs(new_distance - distance))/ self.T)
if (new_distance < distance) or (np.random.random() < P):
cities = new_cities
distance = new_distance
if distance < self.best_distance:
self.best_distance = distance
self.best_cities = cities.copy()
self.best_cities_list.append(cities)
return cities, distance
def run(self):
data = pd.read_csv('./samples/DistanceMatrix.csv',)
cities = [i for i in data.iloc[:, 0]]
np.random.shuffle(cities)
print(cities)
new_cities = cities.copy()
self.best_distance = self.get_distance(cities)
# self.best_cities = cities
while self.T >= self.min_T:
for n in range(self.search_num):
sample = np.random.randint(len(data), size= (2,))
new_cities = cities.copy()
new_cities[sample[0]], new_cities[sample[1]] = new_cities[sample[1]], new_cities[sample[0]]
distance = self.get_distance(cities)
new_distance = self.get_distance(new_cities)
cities, distance = self.update_value(cities, new_cities, distance, new_distance)
self.t += 1
self.T = self.max_T / (1 + self.t)
# print(self.T)
print(self.best_distance)
print(self.best_cities)
def update(num, x_data, y_data):
lines.set_data(x_data[num], y_data[num])
return lines,
if __name__ == '__main__':
data = pd.read_csv('./samples/DistanceMatrix.csv')
DistanceMatrix = np.zeros(shape=(len(data), len(data)))
for i in range(len(data)):
for j in range(len(data)):
distance = np.sqrt((data.iloc[i, 1] - data.iloc[j, 1]) ** 2 + (data.iloc[i, 2] - data.iloc[j, 2]) ** 2)
DistanceMatrix[i, j] = distance
tsp = TSP(DistanceMatrix)
tsp.run()
best_cities_list = tsp.best_cities_list
x_data = []
y_data = []
for cities in best_cities_list:
x = data.loc[[i - 1 for i in cities], 'x']
y = data.loc[[i - 1 for i in cities], 'y']
x_data.append(list(x))
y_data.append(list(y))
print(x_data)
fig, ax= plt.subplots(figsize=(9, 6))
ax.scatter(x_data[0], y_data[0], s = 30, c = 'r')
lines, = ax.plot(x_data[0], y_data[0])
ani = FuncAnimation(fig, update, frames = len(x_data), interval=100, fargs=[x_data, y_data])
ani.save('./samples/sa2.gif', fps = 10,dpi=10)
plt.show()
结果感觉并没有达到全局最优,可能达到了局部最优解,仍有优化空间
数据集:
id,x,y
1,6734,1453
2,2233,10
3,5530,1424
4,401,841
5,3082,1644
6,7608,4458
7,7573,3716
8,7265,1268
9,6898,1885
10,1112,2049
11,5468,2606
12,5989,2873
13,4706,2674
14,4612,2035
15,6347,2683
16,6107,669
17,7611,5184
18,7462,3590
19,7732,4723
20,5900,3561
21,4483,3369
22,6101,1110
23,5199,2182
24,1633,2809
25,4307,2322
26,675,1006
27,7555,4819
28,7541,3981
29,3177,756
30,7352,4506
31,7545,2801
32,3245,3305
33,6426,3173
34,4608,1198
35,23,2216
36,7248,3779
37,7762,4595
38,7392,2244
39,3484,2829
40,6271,2135
41,4985,140
42,1916,1569
43,7280,4899
44,7509,3239
45,10,2676
46,6807,2993
47,5185,3258
48,3023,1942