问题描述
旅行商问题:假设一个商人要去往10个城市,每个城市只拜访一次,而且最后要回到出发的城市,已知城市坐标位置如下图所示,任意两个城市之间的路径长度为直线距离,求最短旅行路径。
根据示例DFS算法改写:
使用深度优先算法
先获取顶点 再遍历未经过点并寻找最优路径 未遍历的点放入点集v_path中并递归调用 调用完后再移除
import numpy as np
vertex = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
v_v = [[1, 2, 3, 4, 5, 6, 7, 8, 9],
[0, 2, 3, 4, 5, 6, 7, 8, 9],
[0, 1, 3, 4, 5, 6, 7, 8, 9],
[0, 1, 2, 4, 5, 6, 7, 8, 9],
[0, 1, 2, 3, 5, 6, 7, 8, 9],
[0, 1, 2, 3, 4, 6, 7, 8, 9],
[0, 1, 2, 3, 4, 5, 7, 8, 9],
[0, 1, 2, 3, 4, 5, 6, 8, 9],
[0, 1, 2, 3, 4, 5, 6, 7, 9],
[0, 1, 2, 3, 4, 5, 6, 7, 8]]
point = np.array([[0, 0], [1, 2], [1, 8], [3, 1], [3, 4], [5, 4], [6, 3], [6, 7], [7, 4], [7, 8]])
def tsp(v_start, v_num, v_path, dis, min_dis):
v_top = v_path[-1] # 当前所在的顶点
for i in range(len(v_v[v_top])): # 遍历与顶点v_top相连的所有边
v_start_i = v_v[v_top][i]
if v_start_i == v_start:
if v_num == len(v_path) and dis + distance(v_start_i, v_path[-1]) < min_dis[0]:
min_dis[0] = dis + distance(v_start_i, v_path[-1])
dis = 0
new_path = []
for item in v_path:
new_path.append(vertex[item])
new_path.append(vertex[v_start_i])
print("new distance:", min_dis[0], "new path:", new_path)
continue
if v_start_i in v_path:
continue
v_path.append(v_v[v_top][i])
dis += distance(v_path[-1], v_path[-2])
last = v_path[-1]
tsp(v_start, v_num, v_path, dis, min_dis)
v_path.pop()
dis -= distance(v_path[-1], last)
return None
def distance(a, b):
dis = pow(pow(point[a][0]-point[b][0], 2)+pow(point[a][1]-point[b][1], 2), 0.5)
return dis
min_dis = [10000]
for i in range(len(vertex)):
tsp(v_start=i, v_num=10, v_path=[i], dis=0, min_dis=min_dis)
预先算出两点间的距离可大大提高效率