![](/img/trans.png)
[英]PuLP Optimization Traveling Salesman Problem - Calculating arrival time for each node
[英]Dummy node for Traveling Salesman Problem
最近我一直在阅读很多关于 TSP 的内容,我需要创建一个 TSP 的变体,其中
显然,这可以使用一个虚拟节点来实现 - 到每个其他节点的距离为 0: source这是否意味着输入: cityA
, cityB
, cityC
, cityD
, cityE
矩阵表示应该如下所示:
[
[0,9,6,1,3]
[9,0,4,2,1]
[6,4,0,9,1]
[1,2,9,0,8]
[3,1,1,8,0]
[0,0,0,0,0]
]
这是正确的方法,如果不是,那为什么? 我仍然对理解为什么额外的虚拟节点工作以通过我的变体获得路径感到困惑。 谢谢
根据上面的评论,这是一个没有虚拟节点的示例:
import functools
import math
def shortest_path(arr):
n = len(arr)
bitmask = [1 << i for i in range(n)]
target = (1 << n) - 1
@functools.lru_cache(None)
def helper(city, visited):
nonlocal target, n
if visited == target:
return 0, [city]
best = math.inf, []
for neigh in range(n):
if not (visited & bitmask[neigh]):
cost, path = helper(neigh, visited | bitmask[neigh])
cost += arr[city][neigh]
path = [city] + path
if cost < best[0]:
best = cost, path
return best
best, best_path = math.inf, []
for start in range(n):
total_distance, path = helper(start, bitmask[start])
if total_distance < best:
best, best_path = total_distance, path
return best, best_path
def shortest_path_padded(arr):
n = len(arr)
bitmask = [1 << i for i in range(n)]
target = (1 << n) - 1
@functools.lru_cache(None)
def helper(city, visited):
nonlocal target, n
if visited == target:
return 0, [city]
best = math.inf, []
for neigh in range(n):
if not (visited & bitmask[neigh]):
cost, path = helper(neigh, visited | bitmask[neigh])
cost += arr[city][neigh]
path = [city] + path
if cost < best[0]:
best = cost, path
return best
return helper(0, bitmask[0])
if __name__ == "__main__":
arr = [
[0,9,6,1,3],
[9,0,4,2,1],
[6,4,0,9,1],
[1,2,9,0,8],
[3,1,1,8,0]
]
arr2 = [[0]*(len(arr[0])+1)] + [[0] + row for row in arr]
print(shortest_path(arr))
print(shortest_path_padded(arr2))
Out: (5, [0, 3, 1, 4, 2])
Out: (5, [0, 1, 4, 2, 5, 3]) # city names + 1 because city 0 is dummy city
使用虚拟节点与尝试将每个城市作为起始城市有什么不同?
没什么,如果你从一个与任何其他城市距离为 0 的虚拟节点开始,它的第一选择就是选择第一个城市到 go 到。
这个没有 for 循环和零填充数组的解决方案将与具有 for 循环和数组的解决方案相同。
#NO LIBRARIES
def shortest_path_padded_no_libs(arr):
n = len(arr)
bitmask = [1 << i for i in range(n)]
target = (1 << n) - 1
def helper(city, visited):
nonlocal target, n
h = (city, visited)
if h in memo:
return memo[h]
if visited == target:
return 0, [city]
best = float('inf'), []
for neigh in range(n):
if not (visited & bitmask[neigh]):
cost, path = helper(neigh, visited | bitmask[neigh])
cost += arr[city][neigh]
path = [city] + path
if cost < best[0]:
best = cost, path
memo[h] = best
return best
memo = {}
return helper(0, bitmask[0])
if __name__ == "__main__":
arr = [
[0,9,6,1,3],
[9,0,4,2,1],
[6,4,0,9,1],
[1,2,9,0,8],
[3,1,1,8,0]
]
arr2 = [[0]*(len(arr[0])+1)] + [[0] + row for row in arr]
print(shortest_path_padded_no_libs(arr2))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.