介绍模拟退火算法求解TSP问题的文章网上很多,我无意在此重复介绍。本文主要是强调本程序的以下几点:
1、“温度”的作用的不断收紧较差解可接受概率,高低是相对的。当温度趋近于零时,除非发现更优解,否则接受概率也趋于零。起始温度过高,对较差解的接受概率太大,可能出现前期退化的情况(不断接受比初始解更差的解)。起始温度过低,则收敛过快,容易直接陷入局部最优解。
2、本程序以2-opt优化方式为搜索邻域。
3、以连续未发现更优解的迭代次数超过搜索邻域长度作为触发降温的条件,以保证在某一温度下可以充分地进行局部优化。
代码如下:
import numpy as np
#准备工作
#读取城市矩阵
distance_matrix=np.load(r'distance_matrix.npy')#提前准备的距离矩阵文件
global city_num,best_route,best,distance_total_best_route#城市数,已知最优解,最优距离为全局变量
city_num=len(distance_matrix)
#计算一个解的总路程函数
def distance_total(route):
return distance_matrix[route[np.arange(city_num)-1],route].sum()
#初始最佳路径
best_route=np.random.permutation(city_num)
best=distance_total(best_route)
LOC=[(loc1,loc2) for loc1 in range(1,city_num) for loc2 in range(loc1+1,city_num+1)]#搜索邻域
neighbor=len(LOC)
T=10#初始温度,非常重要,可调整
route_accepted=best_route
distance_accepted=best
for i in range(1000):#降温次数,可调整
refuse_lbl=0#拒绝标志
not_find_best_time=0#本温度下连续未发现更优解的次数
while not_find_best_time<neighbor:#以搜索邻域长度作为同温度下的最大搜索次数
loc=np.random.randint(0,neighbor-1)
loc_1=LOC[loc][0]
loc_2=LOC[loc][1]
route_this=route_accepted.copy()
route_this[loc_1:loc_2+1]=route_this[loc_2:loc_1-1:-1]#2-opt法生成新解
distance_this=distance_total(route_this)
if distance_this<best:#发现更优解
refuse_lbl=0
not_find_best_time=0
best_route,best=route_this,distance_this
print(r"%.2f"%best,i+1)
elif distance_this<distance_accepted or np.random.rand()<np.exp((distance_accepted-distance_this)/T):#以Metropolis准则决定是否接受新解
refuse_lbl=0
not_find_best_time+=1
else:#拒绝新解
refuse_lbl=1
not_find_best_time+=1
if refuse_lbl==0:
route_accepted,distance_accepted=route_this,distance_this
T*=.98#降温
print(best,best_route.tolist())