回溯法求解旅行商问题
回溯法和最近邻法的区别是,回溯法可以求得全局最优解,而最近邻法求得的是近似优解。
不过,由于回溯法的时间复杂度为O(n²),所以城市数量非常多时仍然不太适用。
代码:
# -*- coding: utf-8 -*-
# 回溯法求解旅行商问题
class TSP:
def __init__(self, matrix, names):
matrix.append([0]*len(matrix))
matrix.insert(0, [0]*len(matrix))
for i in range(len(matrix)):
matrix[i].insert(0, 0)
matrix[i].append(0)
self.matrix = matrix
self.names = names
self.num = len(names) # 城市个数
self.temp_path = [i for i in range(0, self.num+1)] # 当前路径
self.temp_len = 0 # 当前路径长度
self.best_path = [0] * (self.num+1) # 最短路径
self.best_len = 99999999 # 最短路径的长度
def __backtrack(self, node):
if node > self.num:
v = self.matrix[self.temp_path[self.num]][1]
if (v != 0) and (v + self.temp_len < self.best_len):
self.best_len = v + self.temp_len
for i in range(1, self.num + 1):
self.best_path[i] = self.temp_path[i]
else:
for i in range(node, self.num + 1):
v = self.matrix[self.temp_path[node-1]][self.temp_path[i]]
if (v != 0) and (v + self.temp_len < self.best_len):
self.temp_path[node], self.temp_path[i] = self.temp_path[i], self. temp_path[node]
self.temp_len += self.matrix[self.temp_path[node-1]][self.temp_path [node]]
self.__backtrack(node + 1)
self.temp_len -= self.matrix[self.temp_path[node-1]][self.temp_path [node]]
self.temp_path[node], self.temp_path[i] = self.temp_path[i], self. temp_path[node]
return
def solve(self):
self.__backtrack(2)
path_str = ""
for i in range(1, self.num+1):
path_str += self.names[self.best_path[i]]
path_str += self.names[1]
return path_str, self.best_len
if __name__ == '__main__':
# 记录两个城市之间距离的邻接矩阵
distance = [[0, 8943, 5582, 344, 8164, 9588],
[8943, 0, 3363, 9212, 12475, 11319],
[5582, 3363, 0, 5850, 11012, 10872],
[344, 9212, 5850, 0, 8238, 9739],
[8164, 12475, 11012, 8238, 0, 2103],
[9588, 11319, 10872, 9739, 2103, 0]]
# 城市名字
city_name = {1: 'L', 2: 'M', 3: 'N', 4: 'P', 5: 'B', 6: 'T'}
# 求解
tsp = TSP(distance, city_name)
shortest_path, shortest_length = tsp.solve()
# 显示结果
print("最短环为%s,其总长度为%d" % (shortest_path, shortest_length))
计算结果:
最短环为LNMTBPL,其总长度为30949