简单程序实现模拟退火算法求解TSP问题(python)

介绍模拟退火算法求解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())
  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值