流程图
数据集
att48.tsp、eil76.tsp、lin105.tsp【下载链接】
关键要素
- 贪心构造初始解
- 邻居解生成:2-opt邻域
- 解的评价:线路总距离
- 解的接受准则:Metropolis接受准则
-
t
初
温
t_{初温}
t初温=累计求和(各点距其他点的最长距离)-累计求和(各点距其他点的最短距离)
t
结
束
t_{结束}
t结束=0.01【这个自己设就行】
- 降温函数:采取指数冷却,底数取0.99
- 终止条件:外循环结束,温度降到0.01以下时;内循环结束,迭代1000次。
代码
import random
import numpy as np
import math
import pandas as pd
import copy
import matplotlib.pyplot as plt
import time
def data_deal(city):
city = np.array(city[0][6:len(city) - 1])
city_name = city.tolist()
chu_li = []
for i in range(0, len(city_name)):
temp = city_name[i].split()
del temp[0]
for x in range(0, 2):
temp[x] = eval(temp[x])
chu_li.append(temp)
return chu_li
a280 = pd.read_csv(r'a280.tsp', encoding='utf-8-sig', header=None)
att48 = pd.read_csv(r'att48.tsp', encoding='utf-8-sig', header=None)
ch150 = pd.read_csv(r'ch150.tsp', encoding='utf-8-sig', header=None)
eil76 = pd.read_csv(r'eil76.tsp', encoding='utf-8-sig', header=None)
lin105 = pd.read_csv(r'lin105.tsp', encoding='utf-8-sig', header=None)
location=data_deal(att48)
num_city=len(location)
def temperature():
sum_max=0
sum_min=0
for i in dis_mat:
temp=i[:]
del temp[temp.index(0)]
sum_max+=max(temp)
sum_min+=min(temp)
t=sum_max-sum_min
return t
def distance(city_a, city_b):
x = city_a[0] - city_b[0]
y = city_a[1] - city_b[1]
dist = (x ** 2 + y ** 2) ** 0.5
return dist
def greedy_solution(city):
temp=city[:]
for i in range(0,len(city)-1):
dis = distance(temp[i], temp[i+1])
for j in range(i+2,len(city)):
t=distance(temp[i],temp[j])
if t<dis:
dis=t
temp[i+1],temp[j]=temp[j],temp[i+1]
route=[]
for i in temp:
route.append(city.index(i))
return route
def distance_p2p_mat():
dis_mat=[]
for i in range(len(location)):
dis_mat_each=[]
for j in range(len(location)):
dis=math.sqrt(pow(location[i][0]-location[j][0],2)+pow(location[i][1]-location[j][1],2))
dis_mat_each.append(dis)
dis_mat.append(dis_mat_each)
return dis_mat
def cal_newpath(dis_mat,path):
dis=0
for j in range(num_city-1):
dis=dis_mat[path[j]][path[j+1]]+dis
dis=dis_mat[path[num_city-1]][path[0]]+dis
return dis
dis_mat=distance_p2p_mat()
path=greedy_solution(location)
dis=cal_newpath(dis_mat,path)
initial_t=temperature()
lowest_t=0.01
M=(num_city-1)*(num_city-2)/2
iteration=1000
alpha=0.99
t_current=initial_t
n=0
value=[]
start=time.time()
while (t_current>lowest_t):
count_m=0
count_iter=0
while (count_m<M and count_iter<iteration):
i=0
j=0
while(i==j):
i=random.randint(1,num_city-1)
j=random.randint(1,num_city-1)
path_new=path.copy()
path_new[i:j+1]=list(reversed(path_new[i:j+1]))
dis_new=cal_newpath(dis_mat,path_new)
dis_delta=dis_new-dis
rand=random.random()
temp=-dis_delta/t_current if -dis_delta/t_current<700 else 700
exp_d=math.exp(temp)
if dis_delta<0:
path=path_new
dis=dis_new
elif exp_d>rand:
path=path_new
dis=dis_new
else:
count_m=count_m+1
count_iter=count_iter+1
value.append(dis)
n=n+1
t_current=t_current*alpha
end=time.time()
time=end-start
dis_min=dis
path_min=path
print('运行时间:',round(time))
print('最短距离:',round(dis_min))
print('最短路径:',path_min)
x=[]
y=[]
path_min.append(path_min[0])
for i in range(0, len(path_min)):
plt.scatter(location[path_min[i]][0], location[path_min[i]][1],color='b')
x.append(location[path_min[i]][0])
y.append(location[path_min[i]][1])
plt.plot(x,y)
plt.show()
plt.plot(value,color='r')
for i in range(len(value)):
plt.scatter(i,value[i],color='b')
plt.show()
部分结果展示
数据集 | 运行时间(s) | 最短距离 | 官方距离 |
---|
att48 | 21 | 33608 | 33533 |
路线图 | 迭代下降图 |
---|
| |
数据集 | 运行时间(s) | 最短距离 | 官方距离 |
---|
eil76 | 22 | 561 | 538 |
路线图 | 迭代下降图 |
---|
| |
数据集 | 运行时间(s) | 最短距离 | 官方距离 |
---|
lin105 | 38 | 14581 | 14379 |
路线图 | 迭代下降图 |
---|
| |