Python编程训练 模拟退火算法 TSP旅行商问题
题目:已知八个景点(1景石、2游客服务中心、3阳光草坪、4森林小剧场、5儿童科普体验区、6儿童戏水场、7湿地博物馆、8湿地商业街)两两之间的距离,求出从“景石”出发到“湿地商业街”,并且历经其他所有景点的最短路线,要求输出最短路线和最短距离。
思路:这个题目类似于旅行商问题(Traveling Salesman Problem,简称TSP),这是一种组合优化问题,主要求解路径最小值。此类问题可以描述为:给定一组城市和每对城市之间的距离,寻找一条最短的路线,使得旅行者访问每个城市恰好一次后返回起点(形成闭合回路)。而此题不太一样,本题规定起点与终点分别为“景石”、“湿地商业街”,找出最短路线和最短距离(单线)。考虑使用智能算法中的模拟退火算法。模拟退火算法(Simulated Annealing,SA)是一种启发式优化算法,灵感来源于固体退火过程中的原子运动。它通过模拟材料的退火过程,逐渐降低温度来减少系统的能量,从而寻找到全局最优解或近似最优解。
其中SA关键步骤包括:1.**初始化**:2.**生成新解**:3.**计算成本**:4.**接受新解**:5.**更新温度**:6.**终止条件**:(第一次使用CSDN不太会插入流程图)
Python代码如下:
# 必要的库
import numpy as np
# 距离矩阵
distance_matrix = [[ 0 300 360 210 590 475 500 690]
[300 0 380 270 230 285 200 390]
[360 380 0 510 230 765 580 770]
[210 270 510 0 470 265 450 640]
[590 230 230 470 0 515 260 450]
[475 285 765 265 515 0 460 650]
[500 200 580 450 260 460 0 190]
[690 390 760 640 450 650 190 0]]
# 按照题意,定义一个生成指定序列的函数
def Splicing_array():
# 生成1到6的随机排列
random_numbers = np.random.permutation(6) + 1
# 将0添加到数组的开始
array_start = np.array([0])
# 将7添加到数组的末尾
array_end = np.array([7])
# 合并数组
result_array = np.concatenate((array_start, random_numbers, array_end))
return result_array
# 计算距离的函数
def calculate_distance(route, distance_matrix):
return sum(distance_matrix[route[i], route[i+1]] for i in range(len(route)-1))
# 模拟退火解决TSP问题
def simulated_annealing(distance_matrix, initial_temp=1000, cooling_rate=0.95, iterations=10000):
n = 8
current_route = Splicing_array()
current_distance = calculate_distance(current_route, distance_matrix)
for _ in range(iterations):
new_route = Splicing_array()
new_distance = calculate_distance(new_route, distance_matrix)
if new_distance < current_distance or np.exp(-(new_distance - current_distance) / initial_temp) > np.random.rand():
current_route = new_route
current_distance = new_distance
initial_temp *= cooling_rate
return current_route, current_distance
# 运行,输出结果
route, distance = simulated_annealing(distance_matrix)
print("最短路线:", route + 1) # +1 因为索引从0开始
print("最短距离:", distance)
### The code was compiled by Zeming ###