提示:以下信息来自chatgpt,以下内容仅作为个人学习记录使用
一、使用C-W算法解决TSP问题
TSP问题指的是旅行商问题(Traveling Salesman Problem),是一个经典的组合优化问题。该问题可以描述为:给定一个包含n个城市的地图,旅行商需要从一个城市出发,依次经过所有的城市并最终回到出发城市。旅行商必须走过所有的城市,且每个城市只能经过一次。旅行商可以自由选择任何一个城市作为起点,问如何规划旅行路线才能使总路程最短
C-W节约算法是一种启发式算法,用于解决旅行商问题(TSP)。它的目标是求出一条尽可能短的哈密顿回路。但是由于C-W算法是一种近似算法,因此不能保证找到TSP问题的最小解,但是对于实际问题,它的解通常非常接近最优解,并且具有良好的时间复杂度。此外,C-W算法也适用于大规模问题,这使得它在实际中非常有用。
二、代码
1.代码
代码如下:
import math
# 计算两个城市之间的距离
def dist(a, b):
return math.sqrt((a[0]-b[0])**2 + (a[1]-b[1])**2)
# 在未访问城市中查找距离当前城市最近的城市
def find_nearest(city, cities, visited):
nearest_dist = float('inf')
nearest_city = None
for c in cities:
if c not in visited and c != city:
d = dist(city, c)
if d < nearest_dist:
nearest_dist = d
nearest_city = c
return nearest_city, nearest_dist
# 计算每对城市之间的节约成本
def find_savings(cities):
savings = []
for i in range(len(cities)):
for j in range(i+1, len(cities)):
d = dist(cities[i], cities[j])
savings.append((i, j, d))
return sorted(savings, key=lambda x: x[2], reverse=True)
# 构建城市之间的最小生成树
def minimum_spanning_tree(cities):
mst = []
visited = set([cities[0]])
while len(visited) < len(cities):
nearest_dist = float('inf')
nearest_edge = None
for v in visited:
c, d = find_nearest(v, cities, visited)
if d < nearest_dist:
nearest_dist = d
nearest_edge = (v, c)
mst.append(nearest_edge)
visited.add(nearest_edge[1])
return mst
def find_euler_tour(mst):
tour = []
stack = [mst[0][0]]
while len(stack) > 0:
v = stack[-1]
for e in mst:
if e[0] == v and e[1] not in tour:
tour.append(e[1])
stack.append(e[1])
break
elif e[1] == v and e[0] not in tour:
tour.append(e[0])
stack.append(e[0])
break
else:
stack.pop()
return tour
def euler_to_tsp(euler_tour):
tsp_path = [euler_tour[0]]
for i in range(1, len(euler_tour)):
if euler_tour[i] != tsp_path[-1]:
tsp_path.append(euler_tour[i])
tsp_path.append(euler_tour[0])
return tsp_path
def solve_tsp(cities):
# 计算节约成本
savings = find_savings(cities)
# 构建最小生成树
mst = minimum_spanning_tree(cities)
# 找到欧拉回路
euler_tour = find_euler_tour(mst)
# 将欧拉回路转换为TSP路径
tsp_path = euler_to_tsp(euler_tour)
# 计算TSP路径的总长度
tsp_length = sum([dist(tsp_path[i], tsp_path[i+1]) for i in range(len(tsp_path)-1)])
return tsp_path, tsp_length
主函数:
if __name__ == '__main__':
cities = [(1,1),(1,3),(2,2),(3,1),(3,3)]
tsp_path, tsp_length=solve_tsp(cities)
print(f'tsp_path:{tsp_path}')
print(f'tsp_length:{tsp_length}')
2.输出
以上代码可以直接成功运行,在本地运行以上代码后输出了:
tsp_path:[(2, 2), (1, 1), (1, 3), (3, 1), (3, 3), (2, 2)]
tsp_length:9.656854249492381
3.城市坐标
城市坐标可以自己随意改动,按需改动即可