tsp问题-遍历算法/随机算法

旅行商问题,即TSP问题(Traveling Salesman Problem)又译为旅行推销员问题、货郎担问题,是数学领域中著名问题之一。假设有一个旅行商人要拜访n个城市,他必须选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。路径的选择目标是要求得的路径路程为所有路径之中的最小值。

 1 #!/user/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 # TSP旅行商问题:若干个城市,任意两个城市之间距离确定,要求一旅行商从某城市
 5 # 出发必须经过每一个城市且只能在每个城市逗留一次,最后回到原出发城市,试
 6 # 确定一条最短路径使旅行费用最少
 7 
 8 # 遍历算法
 9 
10 # 给定某条路径,计算它的成本
11 def distcal(path, dist):
12     # 计算路径成本(路径,距离)
13     sum_dist = 0  # 总成本
14     for j in range(0, len(path) - 1):
15         di = dist[int(path[j]) - 1][int(path[j + 1]) - 1]  # 查找第j和j+1个城市之间的成本
16         sum_dist = sum_dist + di  # 累加
17     di = dist[int(path[len(path) - 1]) - 1][path[0] - 1]  # 最后一个城市回到初始城市的成本
18     sum_dist = sum_dist + di
19     return sum_dist  # 返回路径的成本
20 
21 
22 # 递归,构造所有可能路径
23 def perm(l):  # 构造路径(城市列表)
24     if (len(l)) <= 1:  # 只有一个城市,选择这个城市
25         return [l]
26     r = []  # 空列表
27     for i in range(len(l)):  # 对每个城市,构建不包括这个城市的所有可能序列
28         s = l[:i] + l[i + 1:]  # 去除当前城市的列表
29         p = perm(s)  # 调用自身,构造不包含这个城市的序列
30         for x in p:
31             r.append(l[i:i + 1] + x)  # 将序列和该城市合并,得到完整的序列
32     return r
33 
34 
35 if __name__ == '__main__':
36     city = [1, 2, 3, 4, 5]
37 
38     dist = ((0, 1, 3, 4, 5),
39             (1, 0, 1, 2, 3),
40             (3, 1, 0, 1, 2),
41             (4, 2, 1, 0, 1),
42             (5, 3, 2, 1, 0))
43 
44     for i in range(0, 5):
45         print(dist[i][:])
46 
47     print('=============')
48 
49     allpath = perm(city)  # 调用路径产生函数,产生所有可能的路径
50 
51     optimal = 1000000  # 初始化最优路径的总成本和索引号
52 
53     index = 1
54 
55     for i in range(0, len(allpath)):
56         pd = distcal(allpath[i], dist)
57         if pd < optimal:  # 比较是否总成本更低,如果是替换最优解
58             optimal = pd
59             index = i
60         # print(pd)
61 
62     print(optimal)
63     print(allpath[index])
64 ------------------------------------------------------------------------
65 (0, 1, 3, 4, 5)
66 (1, 0, 1, 2, 3)
67 (3, 1, 0, 1, 2)
68 (4, 2, 1, 0, 1)
69 (5, 3, 2, 1, 0)
70 =============
71 9
72 [1, 2, 3, 4, 5]
遍历算法
 1 #!/user/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import random
 5 
 6 # 给定某条路径,计算它的成本
 7 def distcal(path, dist):
 8     # 计算路径成本(路径,距离)
 9     sum_dist = 0  # 总成本
10     for j in range(0, len(path) - 1):
11         di = dist[int(path[j]) - 1][int(path[j + 1]) - 1]  # 查找第j和j+1个城市之间的成本
12         sum_dist = sum_dist + di  # 累加
13     di = dist[int(path[len(path) - 1]) - 1][path[0] - 1]  # 最后一个城市回到初始城市的成本
14     sum_dist = sum_dist + di
15     return sum_dist  # 返回路径的成本
16 
17 # 构造随机路径
18 def randompath(inc):  # Inc城市列表
19     allcity = inc[:]  # 城市列表
20     path = []  # 路径
21     loop = True
22     while loop:
23         if 1 == len(allcity):  # 如果是最后一个城市
24             tmp = random.choice(allcity)
25             path.append(tmp)
26             loop = False  # 结束
27         else:  # 如果不是最后一个城市
28             tmp = random.choice(allcity)  # 在城市列表中随机选择一个城市
29             path.append(tmp)  # 添加路径
30             allcity.remove(tmp)  # 在城市列表中移除该城市
31     return path
32 
33 if __name__ == '__main__':
34     city = [1, 2, 3, 4, 5]
35 
36     dist = ((0, 1, 3, 4, 5),
37             (1, 0, 1, 2, 3),
38             (3, 1, 0, 1, 2),
39             (4, 2, 1, 0, 1),
40             (5, 3, 2, 1, 0))
41 
42     for i in range(0, 5):
43         print(dist[i][:])
44 
45     print('=============')
46 
47     num = 10  # 随机产生10条路径
48 
49     optimal = 1000000  # 初始化最优路径的总成本和索引号
50 
51     for i in range(0, num):
52         pd = distcal(randompath(city), dist)
53         if pd < optimal:  # 比较是否总成本更低,如果是替换最优解
54             optimal = pd
55         print(pd)
56 
57     print(optimal)
58 ------------------------------------------------------------
59 (0, 1, 3, 4, 5)
60 (1, 0, 1, 2, 3)
61 (3, 1, 0, 1, 2)
62 (4, 2, 1, 0, 1)
63 (5, 3, 2, 1, 0)
64 =============
65 9
66 12
67 11
68 14
69 12
70 11
71 14
72 9
73 14
74 9
75 最优: 9
随机算法