【python】使用C-W算法解决TSP问题

提示:以下信息来自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.城市坐标

城市坐标可以自己随意改动,按需改动即可

猜你喜欢

转载自blog.csdn.net/CBCY_csdn/article/details/130393559