Develop a gencric simulated annealing algorithm to solve the traveling salesmanproblem with 20 cities that are uniformly distributed within a unit squarc in a 2-dimensional plancThc coordinates of 20 cities are given below in a 2 x 20 matrix:
cities = [
(0.6606, 0.9500), (0.9695, 0.6740), (0.5906, 0.5029), (0.2124, 0.8274), (0.0398, 0.9697),
(0.1367, 0.5979), (0.9536, 0.2184), (0.6091, 0.7148), (0.8767, 0.2395), (0.8148, 0.2867),
(0.3876, 0.8200), (0.7041, 0.3296), (0.0213, 0.1649), (0.3429, 0.3025), (0.7471, 0.8192),
(0.5449, 0.9392), (0.9464, 0.8191), (0.1247, 0.4351), (0.1636, 0.8646), (0.8668, 0.6768)
]
Show the "best route you find and the associated distance with attached computer coding (withdocumentation) An example is given below for referencc.
import random
import math
import matplotlib.pyplot as plt
# 旅行商问题的数据
cities = [
(0.6606, 0.9500), (0.9695, 0.6740), (0.5906, 0.5029), (0.2124, 0.8274), (0.0398, 0.9697),
(0.1367, 0.5979), (0.9536, 0.2184), (0.6091, 0.7148), (0.8767, 0.2395), (0.8148, 0.2867),
(0.3876, 0.8200), (0.7041, 0.3296), (0.0213, 0.1649), (0.3429, 0.3025), (0.7471, 0.8192),
(0.5449, 0.9392), (0.9464, 0.8191), (0.1247, 0.4351), (0.1636, 0.8646), (0.8668, 0.6768)
]
# 计算两个城市之间的距离
def distance(city1, city2):
return math.sqrt((city1[0] - city2[0]) ** 2 + (city1[1] - city2[1]) ** 2)
# 计算路径的总长度
def path_length(path):
length = 0
for i in range(len(path)):
length += distance(cities[path[i]], cities[path[(i + 1) % len(path)]])
return length
# 构建初始解决方案(贪心算法)
def greedy_init():
path = [0]
while len(path) < len(cities):
last_city = cities[path[-1]]
nearest_city = None
nearest_distance = float('inf')
for i in range(len(cities)):
if i not in path:
d = distance(last_city, cities[i])
if d < nearest_distance:
nearest_city = i
nearest_distance = d
path.append(nearest_city)
return path
# 模拟退火算法
def simulated_annealing(path, temperature, cooling_rate):
while temperature > 1:
# 随机交换两个城市的位置
i, j = random.sample(range(len(path)), 2)
new_path = path[:]
new_path[i], new_path[j] = new_path[j], new_path[i]
# 计算新路径的长度
new_length = path_length(new_path)
# 计算路径长度的变化量
delta = new_length - path_length(path)
# 如果新路径更短,直接接受
if delta < 0:
path = new_path
# 否则以一定概率接受新路径
else:
probability = math.exp(-delta / temperature)
if random.random() < probability:
path = new_path
# 降低温度
temperature *= cooling_rate
return path
# 可视化路径
def plot_path(path):
x = [cities[i][0] for i in path]
y = [cities[i][1] for i in path]
plt.plot(x, y, 'o-')
plt.show()
# 主函数
if __name__ == '__main__':
# 构建初始解决方案
path = greedy_init()
# 模拟退火算法求解
path = simulated_annealing(path, temperature=10000, cooling_rate=0.99)
# 可视化路径
plot_path(path)