基于模拟退火算法解决旅行商问题(Python代码)

大家好!本文为大家提供了模拟退火算法解决TSP的一种python实现。有兴趣的同学可以看看“遗传算法解决TSP问题”,你会发现二者产生新解的方式一样,但选择新解的方式不同。

import math
import random
import numpy as np
import matplotlib.pyplot as plt

# 随机生成城市信息
nCity = 10
City = np.random.uniform(-10, 10, [nCity, 2])
Dis = {}
for i in range(nCity):
    for j in range(nCity):
        if i > j:
            dis = ((City[i][0] - City[j][0]) ** 2 + (City[i][1] - City[j][1]) ** 2) ** 0.5
            Dis[(i, j)] = dis
            Dis[(j, i)] = dis

Data_BestFit =[]   #用于保存每一代蚂蚁的最优适应度

#适应度计算函数 适应值 = 路径距离
def Cal_Fit(X):
    total_dis = Dis[(X[-1],X[0])]
    for i in range(nCity-1):
        total_dis += Dis[(X[i],X[i+1])]
    return total_dis

def SAA_TSP():
    # 定义参数
    T0 = 100      # 初始温度
    T1 = 0.1      # 最终温度
    a = 0.99      # 温度衰减系数
    Markov = 100  # 马尔科夫链
    Pm = 0.3      # 变异概率
    Pc = 0.7      # 交叉概率

    # 初始化解
    Best_X = None
    Best_Fit = math.inf
    X = np.zeros([Markov,nCity])
    Fit = np.zeros([Markov])
    for i in range(Markov):
        X[i] = np.random.permutation(nCity)
        Fit[i] = Cal_Fit(X[i])
        if Fit[i] < Best_Fit:
            Best_Fit = Fit[i]
            Best_X = X[i].copy()

    # 降温过程
    T = T0
    while T >= T1:
        for i in range(Markov):
            # 变异、交叉产生新解
            x = X[i].copy()
            if random.random() < Pm:
                point1 = int(random.random() * nCity)
                point2 = int(random.random() * nCity)
                while point1 == point2:
                    point1 = int(random.random() * nCity)
                    point2 = int(random.random() * nCity)
                x[point1],x[point2] = x[point2],x[point1]

            if random.random() < Pc:
                point = int(random.random()*nCity)
                temp1 = list(x[0:point])
                temp2 = list(x[point:nCity])
                temp2.extend(temp1)
                x = np.array(temp2.copy())

            # 计算新解适应值并判断是否接受
            fit = Cal_Fit(x)
            delta = fit - Fit[i]
            if delta <= 0:
                Fit[i] = fit
                X[i] = x
                if Fit[i] < Best_Fit:
                    Best_Fit = Fit[i]
                    Best_X = X[i].copy()
            # 是否接受恶化解
            elif random.random() < math.exp(-delta/T):
                Fit[i] = fit
                X[i] = x.copy()

        Data_BestFit.append(Best_Fit)
        T *= a # 降温
        
    return Best_X, Best_Fit

# 绘制路径与迭代曲线
def Draw_City(City, X ,Best_Fit):
    X = list(X)
    X.append(X[0])
    coor_x = []
    coor_y = []
    for i in X:
        i = int(i)
        coor_x.append(City[i][0])
        coor_y.append(City[i][1])

    plt.plot(coor_x, coor_y, 'r-o')
    plt.title('TSP with Simulated Annealing Algorithm\n'+'total_dis = '+str(round(Best_Fit,3)))
    plt.show()

    plt.plot(range(len(Data_BestFit)), Data_BestFit)
    plt.title('Iteration_BestFit')
    plt.xlabel('iteration')
    plt.ylabel('fitness')
    plt.show()

if __name__ == '__main__':
    Best_X, Best_Fit = SAA_TSP()
    Draw_City(City,Best_X, Best_Fit)




  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,我可以为您介绍一下Python模拟退火算法解决旅行商问题旅行商问题(Traveling Salesman Problem,TSP)是指在所有城市之间建立完全图,每对城市之间有一条权值为正的边。旅行商要从某个城市出发,遍历所有城市一次后回到出发的城市,且使所走过的路程最短。这是一个NP难问题,因此需要采用一些启发式算法来求解。 模拟退火算法(Simulated Annealing,SA)是一种基于概率的全局优化算法,可以用于求解TSP问题。其基本思想是通过一定的概率规律,在搜索过程中跳出局部最优解,并逐渐降低温度以达到全局最优解。 下面是一个简单的Python代码实现,使用模拟退火算法解决TSP问题: ```python import random import math def distance(city1, city2): return math.sqrt((city1[0] - city2[0]) ** 2 + (city1[1] - city2[1]) ** 2) def TSP(cities, T_init, T_end, alpha, iter_max): n = len(cities) cur_solution = list(range(n)) random.shuffle(cur_solution) cur_cost = sum(distance(cities[cur_solution[i]], cities[cur_solution[i-1]]) for i in range(n)) T = T_init while T > T_end: for i in range(iter_max): new_solution = cur_solution.copy() a = random.randint(0, n-1) b = random.randint(0, n-1) new_solution[a], new_solution[b] = new_solution[b], new_solution[a] new_cost = sum(distance(cities[new_solution[i]], cities[new_solution[i-1]]) for i in range(n)) delta_cost = new_cost - cur_cost if delta_cost < 0 or math.exp(-delta_cost/T) > random.random(): cur_solution = new_solution.copy() cur_cost = new_cost T *= alpha return cur_cost, cur_solution if __name__ == '__main__': cities = [(0, 0), (1, 2), (3, 1), (5, 2), (6, 4), (4, 6), (1, 5), (2, 3)] T_init = 100 T_end = 0.1 alpha = 0.99 iter_max = 1000 cost, solution = TSP(cities, T_init, T_end, alpha, iter_max) print('最短路径长度为', cost) print('最短路径为', solution) ``` 该代码定义了一个`distance`函数用于计算两个城市之间的距离,以及一个`TSP`函数用于求解TSP问题。其中,`cities`参数是一个城市列表,`T_init`和`T_end`分别是初始温度和最终温度,`alpha`是温度下降系数,`iter_max`是每个温度下的迭代次数。代码中使用了随机交换两个城市的方法来产生新解,并使用Metropolis准则来决定是否接受新解。最终返回的是最短路径长度和最短路径的顺序。 以上就是一个简单的Python模拟退火算法解决TSP问题的例子,希望能够对您有所帮助。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值